1 /*
2  * Copyright (C) 2012 Freescale Semiconductor, Inc.
3  *
4  * Author: Fabio Estevam <fabio.estevam@freescale.com>
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  */
19 
20 #include <asm/arch/clock.h>
21 #include <asm/arch/imx-regs.h>
22 #include <asm/arch/iomux.h>
23 #include <asm/arch/mx6-pins.h>
24 #include <asm/errno.h>
25 #include <asm/gpio.h>
26 #include <asm/imx-common/iomux-v3.h>
27 #include <asm/imx-common/boot_mode.h>
28 #include <mmc.h>
29 #include <fsl_esdhc.h>
30 #include <miiphy.h>
31 #include <netdev.h>
32 
33 DECLARE_GLOBAL_DATA_PTR;
34 
35 #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
36 	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |			\
37 	PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
38 
39 #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |			\
40 	PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |			\
41 	PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
42 
43 #define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
44 	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
45 
46 int dram_init(void)
47 {
48 	gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
49 
50 	return 0;
51 }
52 
53 iomux_v3_cfg_t const uart1_pads[] = {
54 	MX6_PAD_CSI0_DAT10__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
55 	MX6_PAD_CSI0_DAT11__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
56 };
57 
58 iomux_v3_cfg_t const enet_pads[] = {
59 	MX6_PAD_ENET_MDIO__ENET_MDIO		| MUX_PAD_CTRL(ENET_PAD_CTRL),
60 	MX6_PAD_ENET_MDC__ENET_MDC		| MUX_PAD_CTRL(ENET_PAD_CTRL),
61 	MX6_PAD_RGMII_TXC__ENET_RGMII_TXC	| MUX_PAD_CTRL(ENET_PAD_CTRL),
62 	MX6_PAD_RGMII_TD0__ENET_RGMII_TD0	| MUX_PAD_CTRL(ENET_PAD_CTRL),
63 	MX6_PAD_RGMII_TD1__ENET_RGMII_TD1	| MUX_PAD_CTRL(ENET_PAD_CTRL),
64 	MX6_PAD_RGMII_TD2__ENET_RGMII_TD2	| MUX_PAD_CTRL(ENET_PAD_CTRL),
65 	MX6_PAD_RGMII_TD3__ENET_RGMII_TD3	| MUX_PAD_CTRL(ENET_PAD_CTRL),
66 	MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL),
67 	MX6_PAD_ENET_REF_CLK__ENET_TX_CLK	| MUX_PAD_CTRL(ENET_PAD_CTRL),
68 	MX6_PAD_RGMII_RXC__ENET_RGMII_RXC	| MUX_PAD_CTRL(ENET_PAD_CTRL),
69 	MX6_PAD_RGMII_RD0__ENET_RGMII_RD0	| MUX_PAD_CTRL(ENET_PAD_CTRL),
70 	MX6_PAD_RGMII_RD1__ENET_RGMII_RD1	| MUX_PAD_CTRL(ENET_PAD_CTRL),
71 	MX6_PAD_RGMII_RD2__ENET_RGMII_RD2	| MUX_PAD_CTRL(ENET_PAD_CTRL),
72 	MX6_PAD_RGMII_RD3__ENET_RGMII_RD3	| MUX_PAD_CTRL(ENET_PAD_CTRL),
73 	MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL),
74 	/* AR8031 PHY Reset */
75 	MX6_PAD_ENET_CRS_DV__GPIO_1_25		| MUX_PAD_CTRL(NO_PAD_CTRL),
76 };
77 
78 static void setup_iomux_enet(void)
79 {
80 	imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
81 
82 	/* Reset AR8031 PHY */
83 	gpio_direction_output(IMX_GPIO_NR(1, 25) , 0);
84 	udelay(500);
85 	gpio_set_value(IMX_GPIO_NR(1, 25), 1);
86 }
87 
88 iomux_v3_cfg_t const usdhc2_pads[] = {
89 	MX6_PAD_SD2_CLK__USDHC2_CLK	| MUX_PAD_CTRL(USDHC_PAD_CTRL),
90 	MX6_PAD_SD2_CMD__USDHC2_CMD	| MUX_PAD_CTRL(USDHC_PAD_CTRL),
91 	MX6_PAD_SD2_DAT0__USDHC2_DAT0	| MUX_PAD_CTRL(USDHC_PAD_CTRL),
92 	MX6_PAD_SD2_DAT1__USDHC2_DAT1	| MUX_PAD_CTRL(USDHC_PAD_CTRL),
93 	MX6_PAD_SD2_DAT2__USDHC2_DAT2	| MUX_PAD_CTRL(USDHC_PAD_CTRL),
94 	MX6_PAD_SD2_DAT3__USDHC2_DAT3	| MUX_PAD_CTRL(USDHC_PAD_CTRL),
95 	MX6_PAD_NANDF_D4__USDHC2_DAT4	| MUX_PAD_CTRL(USDHC_PAD_CTRL),
96 	MX6_PAD_NANDF_D5__USDHC2_DAT5	| MUX_PAD_CTRL(USDHC_PAD_CTRL),
97 	MX6_PAD_NANDF_D6__USDHC2_DAT6	| MUX_PAD_CTRL(USDHC_PAD_CTRL),
98 	MX6_PAD_NANDF_D7__USDHC2_DAT7	| MUX_PAD_CTRL(USDHC_PAD_CTRL),
99 	MX6_PAD_NANDF_D2__GPIO_2_2	| MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
100 };
101 
102 iomux_v3_cfg_t const usdhc3_pads[] = {
103 	MX6_PAD_SD3_CLK__USDHC3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
104 	MX6_PAD_SD3_CMD__USDHC3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
105 	MX6_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
106 	MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
107 	MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
108 	MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
109 	MX6_PAD_SD3_DAT4__USDHC3_DAT4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
110 	MX6_PAD_SD3_DAT5__USDHC3_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
111 	MX6_PAD_SD3_DAT6__USDHC3_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
112 	MX6_PAD_SD3_DAT7__USDHC3_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
113 	MX6_PAD_NANDF_D0__GPIO_2_0    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
114 };
115 
116 iomux_v3_cfg_t const usdhc4_pads[] = {
117 	MX6_PAD_SD4_CLK__USDHC4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
118 	MX6_PAD_SD4_CMD__USDHC4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
119 	MX6_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
120 	MX6_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
121 	MX6_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
122 	MX6_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
123 	MX6_PAD_SD4_DAT4__USDHC4_DAT4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
124 	MX6_PAD_SD4_DAT5__USDHC4_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
125 	MX6_PAD_SD4_DAT6__USDHC4_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
126 	MX6_PAD_SD4_DAT7__USDHC4_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
127 };
128 
129 static void setup_iomux_uart(void)
130 {
131 	imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
132 }
133 
134 #ifdef CONFIG_FSL_ESDHC
135 struct fsl_esdhc_cfg usdhc_cfg[3] = {
136 	{USDHC2_BASE_ADDR},
137 	{USDHC3_BASE_ADDR},
138 	{USDHC4_BASE_ADDR},
139 };
140 
141 #define USDHC2_CD_GPIO	IMX_GPIO_NR(2, 2)
142 #define USDHC3_CD_GPIO	IMX_GPIO_NR(2, 0)
143 
144 int board_mmc_getcd(struct mmc *mmc)
145 {
146 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
147 	int ret = 0;
148 
149 	switch (cfg->esdhc_base) {
150 	case USDHC2_BASE_ADDR:
151 		ret = !gpio_get_value(USDHC2_CD_GPIO);
152 		break;
153 	case USDHC3_BASE_ADDR:
154 		ret = !gpio_get_value(USDHC3_CD_GPIO);
155 		break;
156 	case USDHC4_BASE_ADDR:
157 		ret = 1; /* eMMC/uSDHC4 is always present */
158 		break;
159 	}
160 
161 	return ret;
162 }
163 
164 int board_mmc_init(bd_t *bis)
165 {
166 	s32 status = 0;
167 	int i;
168 
169 	/*
170 	 * According to the board_mmc_init() the following map is done:
171 	 * (U-boot device node)    (Physical Port)
172 	 * mmc0                    SD2
173 	 * mmc1                    SD3
174 	 * mmc2                    eMMC
175 	 */
176 	for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
177 		switch (i) {
178 		case 0:
179 			imx_iomux_v3_setup_multiple_pads(
180 				usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
181 			gpio_direction_input(USDHC2_CD_GPIO);
182 			usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
183 			break;
184 		case 1:
185 			imx_iomux_v3_setup_multiple_pads(
186 				usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
187 			gpio_direction_input(USDHC3_CD_GPIO);
188 			usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
189 			break;
190 		case 2:
191 			imx_iomux_v3_setup_multiple_pads(
192 				usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
193 			usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
194 			break;
195 		default:
196 			printf("Warning: you configured more USDHC controllers"
197 			       "(%d) then supported by the board (%d)\n",
198 			       i + 1, CONFIG_SYS_FSL_USDHC_NUM);
199 			return status;
200 		}
201 
202 		status |= fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
203 	}
204 
205 	return status;
206 }
207 #endif
208 
209 int mx6_rgmii_rework(struct phy_device *phydev)
210 {
211 	unsigned short val;
212 
213 	/* To enable AR8031 ouput a 125MHz clk from CLK_25M */
214 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
215 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
216 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
217 
218 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
219 	val &= 0xffe3;
220 	val |= 0x18;
221 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
222 
223 	/* introduce tx clock delay */
224 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
225 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
226 	val |= 0x0100;
227 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
228 
229 	return 0;
230 }
231 
232 int board_phy_config(struct phy_device *phydev)
233 {
234 	mx6_rgmii_rework(phydev);
235 
236 	if (phydev->drv->config)
237 		phydev->drv->config(phydev);
238 
239 	return 0;
240 }
241 
242 int board_eth_init(bd_t *bis)
243 {
244 	int ret;
245 
246 	setup_iomux_enet();
247 
248 	ret = cpu_eth_init(bis);
249 	if (ret)
250 		printf("FEC MXC: %s:failed\n", __func__);
251 
252 	return 0;
253 }
254 
255 int board_early_init_f(void)
256 {
257 	setup_iomux_uart();
258 
259 	return 0;
260 }
261 
262 int board_init(void)
263 {
264 	/* address of boot parameters */
265 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
266 
267 	return 0;
268 }
269 
270 #ifdef CONFIG_CMD_BMODE
271 static const struct boot_mode board_boot_modes[] = {
272 	/* 4 bit bus width */
273 	{"sd2",	 MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
274 	{"sd3",	 MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
275 	/* 8 bit bus width */
276 	{"emmc", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
277 	{NULL,	 0},
278 };
279 #endif
280 
281 int board_late_init(void)
282 {
283 #ifdef CONFIG_CMD_BMODE
284 	add_board_boot_modes(board_boot_modes);
285 #endif
286 
287 	return 0;
288 }
289 
290 int checkboard(void)
291 {
292 	puts("Board: MX6-SabreSD\n");
293 	return 0;
294 }
295