1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2012 Freescale Semiconductor, Inc.
4 * Author: Fabio Estevam <fabio.estevam@freescale.com>
5 *
6 * Copyright (C) 2013, 2014 TQ-Systems (ported SabreSD to TQMa6x)
7 * Author: Markus Niebel <markus.niebel@tq-group.com>
8 */
9
10#include <init.h>
11#include <net.h>
12#include <asm/io.h>
13#include <asm/arch/clock.h>
14#include <asm/arch/mx6-pins.h>
15#include <asm/arch/imx-regs.h>
16#include <asm/arch/iomux.h>
17#include <asm/arch/sys_proto.h>
18#include <linux/delay.h>
19#include <linux/errno.h>
20#include <asm/gpio.h>
21#include <asm/mach-imx/mxc_i2c.h>
22
23#include <common.h>
24#include <fsl_esdhc_imx.h>
25#include <linux/libfdt.h>
26#include <malloc.h>
27#include <i2c.h>
28#include <micrel.h>
29#include <miiphy.h>
30#include <mmc.h>
31#include <netdev.h>
32
33#include "tqma6_bb.h"
34
35#define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
36	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
37
38#define USDHC_CLK_PAD_CTRL (PAD_CTL_PUS_47K_UP  | PAD_CTL_SPEED_LOW | \
39	PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
40
41#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP  | PAD_CTL_SPEED_LOW | \
42	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
43
44#define GPIO_OUT_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \
45	PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
46
47#define GPIO_IN_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \
48	PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
49
50#define SPI_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
51	PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
52
53#define I2C_PAD_CTRL	(PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
54	PAD_CTL_DSE_80ohm | PAD_CTL_HYS |			\
55	PAD_CTL_ODE | PAD_CTL_SRE_FAST)
56
57#if defined(CONFIG_TQMA6Q)
58
59#define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII	0x02e0790
60#define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM	0x02e07ac
61
62#elif defined(CONFIG_TQMA6S) || defined(CONFIG_TQMA6DL)
63
64#define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII	0x02e0768
65#define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM	0x02e0788
66
67#else
68
69#error "need to select module"
70
71#endif
72
73/* disable on die termination for RGMII */
74#define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE	0x00000000
75/* optimised drive strength for 1.0 .. 1.3 V signal on RGMII */
76#define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P2V	0x00080000
77/* optimised drive strength for 1.3 .. 2.5 V signal on RGMII */
78#define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V	0x000C0000
79
80static void mba6_setup_iomuxc_enet(void)
81{
82	struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
83
84	/* clear gpr1[ENET_CLK_SEL] for externel clock */
85	clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK);
86
87	__raw_writel(IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE,
88		     (void *)IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM);
89	__raw_writel(IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V,
90		     (void *)IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII);
91}
92
93static iomux_v3_cfg_t const mba6_uart2_pads[] = {
94	NEW_PAD_CTRL(MX6_PAD_SD4_DAT4__UART2_RX_DATA, UART_PAD_CTRL),
95	NEW_PAD_CTRL(MX6_PAD_SD4_DAT7__UART2_TX_DATA, UART_PAD_CTRL),
96};
97
98static void mba6_setup_iomuxc_uart(void)
99{
100	imx_iomux_v3_setup_multiple_pads(mba6_uart2_pads,
101					 ARRAY_SIZE(mba6_uart2_pads));
102}
103
104int board_mmc_get_env_dev(int devno)
105{
106	/*
107	 * This assumes that the baseboard registered
108	 * the boot device first ...
109	 * Note: SDHC3 == idx2
110	 */
111	return (2 == devno) ? 0 : 1;
112}
113
114int board_phy_config(struct phy_device *phydev)
115{
116/*
117 * optimized pad skew values depends on CPU variant on the TQMa6x module:
118 * CONFIG_TQMA6Q: i.MX6Q/D
119 * CONFIG_TQMA6S: i.MX6S
120 * CONFIG_TQMA6DL: i.MX6DL
121 */
122#if defined(CONFIG_TQMA6Q)
123#define MBA6X_KSZ9031_CTRL_SKEW	0x0032
124#define MBA6X_KSZ9031_CLK_SKEW	0x03ff
125#define MBA6X_KSZ9031_RX_SKEW	0x3333
126#define MBA6X_KSZ9031_TX_SKEW	0x2036
127#elif defined(CONFIG_TQMA6S) || defined(CONFIG_TQMA6DL)
128#define MBA6X_KSZ9031_CTRL_SKEW	0x0030
129#define MBA6X_KSZ9031_CLK_SKEW	0x03ff
130#define MBA6X_KSZ9031_RX_SKEW	0x3333
131#define MBA6X_KSZ9031_TX_SKEW	0x2052
132#else
133#error
134#endif
135	/* min rx/tx ctrl delay */
136	ksz9031_phy_extended_write(phydev, 2,
137				   MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
138				   MII_KSZ9031_MOD_DATA_NO_POST_INC,
139				   MBA6X_KSZ9031_CTRL_SKEW);
140	/* min rx delay */
141	ksz9031_phy_extended_write(phydev, 2,
142				   MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
143				   MII_KSZ9031_MOD_DATA_NO_POST_INC,
144				   MBA6X_KSZ9031_RX_SKEW);
145	/* max tx delay */
146	ksz9031_phy_extended_write(phydev, 2,
147				   MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
148				   MII_KSZ9031_MOD_DATA_NO_POST_INC,
149				   MBA6X_KSZ9031_TX_SKEW);
150	/* rx/tx clk skew */
151	ksz9031_phy_extended_write(phydev, 2,
152				   MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
153				   MII_KSZ9031_MOD_DATA_NO_POST_INC,
154				   MBA6X_KSZ9031_CLK_SKEW);
155
156	phydev->drv->config(phydev);
157
158	return 0;
159}
160
161int tqma6_bb_board_early_init_f(void)
162{
163	mba6_setup_iomuxc_uart();
164
165	return 0;
166}
167
168int tqma6_bb_board_init(void)
169{
170	mba6_setup_iomuxc_enet();
171
172	return 0;
173}
174
175int tqma6_bb_board_late_init(void)
176{
177	return 0;
178}
179
180const char *tqma6_bb_get_boardname(void)
181{
182	return "MBa6x";
183}
184
185/*
186 * Device Tree Support
187 */
188#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
189void tqma6_bb_ft_board_setup(void *blob, struct bd_info *bd)
190{
191 /* TBD */
192}
193#endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */
194