1 /*
2  * Copyright (C) 2012 Freescale Semiconductor, Inc.
3  *
4  * Author: Fabio Estevam <fabio.estevam@freescale.com>
5  *
6  * SPDX-License-Identifier:	GPL-2.0+
7  */
8 
9 #include <common.h>
10 #include <asm/io.h>
11 #include <asm/arch/clock.h>
12 #include <asm/arch/imx-regs.h>
13 #include <asm/arch/iomux.h>
14 #include <asm/arch/mx6-pins.h>
15 #include <linux/errno.h>
16 #include <asm/gpio.h>
17 #include <asm/mach-imx/iomux-v3.h>
18 #include <asm/mach-imx/mxc_i2c.h>
19 #include <asm/mach-imx/boot_mode.h>
20 #include <asm/mach-imx/spi.h>
21 #include <mmc.h>
22 #include <fsl_esdhc.h>
23 #include <miiphy.h>
24 #include <netdev.h>
25 #include <asm/arch/sys_proto.h>
26 #include <i2c.h>
27 #include <asm/arch/mxc_hdmi.h>
28 #include <asm/mach-imx/video.h>
29 #include <asm/arch/crm_regs.h>
30 #include <pca953x.h>
31 #include <power/pmic.h>
32 #include <power/pfuze100_pmic.h>
33 #include "../common/pfuze.h"
34 
35 DECLARE_GLOBAL_DATA_PTR;
36 
37 #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
38 	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |			\
39 	PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
40 
41 #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |			\
42 	PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |			\
43 	PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
44 
45 #define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
46 	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
47 
48 #define I2C_PAD_CTRL	(PAD_CTL_PUS_100K_UP |			\
49 	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |	\
50 	PAD_CTL_ODE | PAD_CTL_SRE_FAST)
51 
52 #define GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
53 #define GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
54 			PAD_CTL_SRE_FAST)
55 #define GPMI_PAD_CTRL2 (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
56 
57 #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
58 
59 #define WEIM_NOR_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |          \
60 	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
61 	PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST)
62 
63 #define I2C_PMIC	1
64 
65 int dram_init(void)
66 {
67 	gd->ram_size = imx_ddr_size();
68 
69 	return 0;
70 }
71 
72 static iomux_v3_cfg_t const uart4_pads[] = {
73 	IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
74 	IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
75 };
76 
77 static iomux_v3_cfg_t const enet_pads[] = {
78 	IOMUX_PADS(PAD_KEY_COL1__ENET_MDIO		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
79 	IOMUX_PADS(PAD_KEY_COL2__ENET_MDC		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
80 	IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
81 	IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
82 	IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
83 	IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
84 	IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
85 	IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL)),
86 	IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK	| MUX_PAD_CTRL(ENET_PAD_CTRL)),
87 	IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
88 	IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
89 	IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
90 	IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
91 	IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3		| MUX_PAD_CTRL(ENET_PAD_CTRL)),
92 	IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL)),
93 };
94 
95 /* I2C2 PMIC, iPod, Tuner, Codec, Touch, HDMI EDID, MIPI CSI2 card */
96 static struct i2c_pads_info mx6q_i2c_pad_info1 = {
97 	.scl = {
98 		.i2c_mode = MX6Q_PAD_EIM_EB2__I2C2_SCL | PC,
99 		.gpio_mode = MX6Q_PAD_EIM_EB2__GPIO2_IO30 | PC,
100 		.gp = IMX_GPIO_NR(2, 30)
101 	},
102 	.sda = {
103 		.i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | PC,
104 		.gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 | PC,
105 		.gp = IMX_GPIO_NR(4, 13)
106 	}
107 };
108 
109 static struct i2c_pads_info mx6dl_i2c_pad_info1 = {
110 	.scl = {
111 		.i2c_mode = MX6DL_PAD_EIM_EB2__I2C2_SCL | PC,
112 		.gpio_mode = MX6DL_PAD_EIM_EB2__GPIO2_IO30 | PC,
113 		.gp = IMX_GPIO_NR(2, 30)
114 	},
115 	.sda = {
116 		.i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA | PC,
117 		.gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13 | PC,
118 		.gp = IMX_GPIO_NR(4, 13)
119 	}
120 };
121 
122 #ifndef CONFIG_SYS_FLASH_CFI
123 /*
124  * I2C3 MLB, Port Expanders (A, B, C), Video ADC, Light Sensor,
125  * Compass Sensor, Accelerometer, Res Touch
126  */
127 static struct i2c_pads_info mx6q_i2c_pad_info2 = {
128 	.scl = {
129 		.i2c_mode = MX6Q_PAD_GPIO_3__I2C3_SCL | PC,
130 		.gpio_mode = MX6Q_PAD_GPIO_3__GPIO1_IO03 | PC,
131 		.gp = IMX_GPIO_NR(1, 3)
132 	},
133 	.sda = {
134 		.i2c_mode = MX6Q_PAD_EIM_D18__I2C3_SDA | PC,
135 		.gpio_mode = MX6Q_PAD_EIM_D18__GPIO3_IO18 | PC,
136 		.gp = IMX_GPIO_NR(3, 18)
137 	}
138 };
139 
140 static struct i2c_pads_info mx6dl_i2c_pad_info2 = {
141 	.scl = {
142 		.i2c_mode = MX6DL_PAD_GPIO_3__I2C3_SCL | PC,
143 		.gpio_mode = MX6DL_PAD_GPIO_3__GPIO1_IO03 | PC,
144 		.gp = IMX_GPIO_NR(1, 3)
145 	},
146 	.sda = {
147 		.i2c_mode = MX6DL_PAD_EIM_D18__I2C3_SDA | PC,
148 		.gpio_mode = MX6DL_PAD_EIM_D18__GPIO3_IO18 | PC,
149 		.gp = IMX_GPIO_NR(3, 18)
150 	}
151 };
152 #endif
153 
154 static iomux_v3_cfg_t const i2c3_pads[] = {
155 	IOMUX_PADS(PAD_EIM_A24__GPIO5_IO04	| MUX_PAD_CTRL(NO_PAD_CTRL)),
156 };
157 
158 static iomux_v3_cfg_t const port_exp[] = {
159 	IOMUX_PADS(PAD_SD2_DAT0__GPIO1_IO15	| MUX_PAD_CTRL(NO_PAD_CTRL)),
160 };
161 
162 /*Define for building port exp gpio, pin starts from 0*/
163 #define PORTEXP_IO_NR(chip, pin) \
164 	((chip << 5) + pin)
165 
166 /*Get the chip addr from a ioexp gpio*/
167 #define PORTEXP_IO_TO_CHIP(gpio_nr) \
168 	(gpio_nr >> 5)
169 
170 /*Get the pin number from a ioexp gpio*/
171 #define PORTEXP_IO_TO_PIN(gpio_nr) \
172 	(gpio_nr & 0x1f)
173 
174 static int port_exp_direction_output(unsigned gpio, int value)
175 {
176 	int ret;
177 
178 	i2c_set_bus_num(2);
179 	ret = i2c_probe(PORTEXP_IO_TO_CHIP(gpio));
180 	if (ret)
181 		return ret;
182 
183 	ret = pca953x_set_dir(PORTEXP_IO_TO_CHIP(gpio),
184 		(1 << PORTEXP_IO_TO_PIN(gpio)),
185 		(PCA953X_DIR_OUT << PORTEXP_IO_TO_PIN(gpio)));
186 
187 	if (ret)
188 		return ret;
189 
190 	ret = pca953x_set_val(PORTEXP_IO_TO_CHIP(gpio),
191 		(1 << PORTEXP_IO_TO_PIN(gpio)),
192 		(value << PORTEXP_IO_TO_PIN(gpio)));
193 
194 	if (ret)
195 		return ret;
196 
197 	return 0;
198 }
199 
200 #ifdef CONFIG_MTD_NOR_FLASH
201 static iomux_v3_cfg_t const eimnor_pads[] = {
202 	IOMUX_PADS(PAD_EIM_D16__EIM_DATA16	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
203 	IOMUX_PADS(PAD_EIM_D17__EIM_DATA17	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
204 	IOMUX_PADS(PAD_EIM_D18__EIM_DATA18	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
205 	IOMUX_PADS(PAD_EIM_D19__EIM_DATA19	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
206 	IOMUX_PADS(PAD_EIM_D20__EIM_DATA20	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
207 	IOMUX_PADS(PAD_EIM_D21__EIM_DATA21	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
208 	IOMUX_PADS(PAD_EIM_D22__EIM_DATA22	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
209 	IOMUX_PADS(PAD_EIM_D23__EIM_DATA23	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
210 	IOMUX_PADS(PAD_EIM_D24__EIM_DATA24	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
211 	IOMUX_PADS(PAD_EIM_D25__EIM_DATA25	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
212 	IOMUX_PADS(PAD_EIM_D26__EIM_DATA26	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
213 	IOMUX_PADS(PAD_EIM_D27__EIM_DATA27	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
214 	IOMUX_PADS(PAD_EIM_D28__EIM_DATA28	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
215 	IOMUX_PADS(PAD_EIM_D29__EIM_DATA29	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
216 	IOMUX_PADS(PAD_EIM_D30__EIM_DATA30	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
217 	IOMUX_PADS(PAD_EIM_D31__EIM_DATA31	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
218 	IOMUX_PADS(PAD_EIM_DA0__EIM_AD00	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
219 	IOMUX_PADS(PAD_EIM_DA1__EIM_AD01	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
220 	IOMUX_PADS(PAD_EIM_DA2__EIM_AD02	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
221 	IOMUX_PADS(PAD_EIM_DA3__EIM_AD03	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
222 	IOMUX_PADS(PAD_EIM_DA4__EIM_AD04	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
223 	IOMUX_PADS(PAD_EIM_DA5__EIM_AD05	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
224 	IOMUX_PADS(PAD_EIM_DA6__EIM_AD06	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
225 	IOMUX_PADS(PAD_EIM_DA7__EIM_AD07	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
226 	IOMUX_PADS(PAD_EIM_DA8__EIM_AD08	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
227 	IOMUX_PADS(PAD_EIM_DA9__EIM_AD09	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
228 	IOMUX_PADS(PAD_EIM_DA10__EIM_AD10	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
229 	IOMUX_PADS(PAD_EIM_DA11__EIM_AD11	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
230 	IOMUX_PADS(PAD_EIM_DA12__EIM_AD12	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
231 	IOMUX_PADS(PAD_EIM_DA13__EIM_AD13	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
232 	IOMUX_PADS(PAD_EIM_DA14__EIM_AD14	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
233 	IOMUX_PADS(PAD_EIM_DA15__EIM_AD15	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
234 	IOMUX_PADS(PAD_EIM_A16__EIM_ADDR16	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
235 	IOMUX_PADS(PAD_EIM_A17__EIM_ADDR17	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
236 	IOMUX_PADS(PAD_EIM_A18__EIM_ADDR18	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
237 	IOMUX_PADS(PAD_EIM_A19__EIM_ADDR19	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
238 	IOMUX_PADS(PAD_EIM_A20__EIM_ADDR20	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
239 	IOMUX_PADS(PAD_EIM_A21__EIM_ADDR21	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
240 	IOMUX_PADS(PAD_EIM_A22__EIM_ADDR22	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
241 	IOMUX_PADS(PAD_EIM_A23__EIM_ADDR23	| MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
242 	IOMUX_PADS(PAD_EIM_OE__EIM_OE_B		| MUX_PAD_CTRL(NO_PAD_CTRL)),
243 	IOMUX_PADS(PAD_EIM_RW__EIM_RW		| MUX_PAD_CTRL(NO_PAD_CTRL)),
244 	IOMUX_PADS(PAD_EIM_CS0__EIM_CS0_B	| MUX_PAD_CTRL(NO_PAD_CTRL)),
245 };
246 
247 static void eimnor_cs_setup(void)
248 {
249 	struct weim *weim_regs = (struct weim *)WEIM_BASE_ADDR;
250 
251 	writel(0x00020181, &weim_regs->cs0gcr1);
252 	writel(0x00000001, &weim_regs->cs0gcr2);
253 	writel(0x0a020000, &weim_regs->cs0rcr1);
254 	writel(0x0000c000, &weim_regs->cs0rcr2);
255 	writel(0x0804a240, &weim_regs->cs0wcr1);
256 	writel(0x00000120, &weim_regs->wcr);
257 
258 	set_chipselect_size(CS0_128);
259 }
260 
261 static void eim_clk_setup(void)
262 {
263 	struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
264 	int cscmr1, ccgr6;
265 
266 
267 	/* Turn off EIM clock */
268 	ccgr6 = readl(&imx_ccm->CCGR6);
269 	ccgr6 &= ~(0x3 << 10);
270 	writel(ccgr6, &imx_ccm->CCGR6);
271 
272 	/*
273 	 * Configure clk_eim_slow_sel = 00 --> derive clock from AXI clk root
274 	 * and aclk_eim_slow_podf = 01 --> divide by 2
275 	 * so that we can have EIM at the maximum clock of 132MHz
276 	 */
277 	cscmr1 = readl(&imx_ccm->cscmr1);
278 	cscmr1 &= ~(MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK |
279 		    MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK);
280 	cscmr1 |= (1 << MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET);
281 	writel(cscmr1, &imx_ccm->cscmr1);
282 
283 	/* Turn on EIM clock */
284 	ccgr6 |= (0x3 << 10);
285 	writel(ccgr6, &imx_ccm->CCGR6);
286 }
287 
288 static void setup_iomux_eimnor(void)
289 {
290 	SETUP_IOMUX_PADS(eimnor_pads);
291 
292 	gpio_direction_output(IMX_GPIO_NR(5, 4), 0);
293 
294 	eimnor_cs_setup();
295 }
296 #endif
297 
298 static void setup_iomux_enet(void)
299 {
300 	SETUP_IOMUX_PADS(enet_pads);
301 }
302 
303 static iomux_v3_cfg_t const usdhc3_pads[] = {
304 	IOMUX_PADS(PAD_SD3_CLK__SD3_CLK		| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
305 	IOMUX_PADS(PAD_SD3_CMD__SD3_CMD		| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
306 	IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
307 	IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
308 	IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
309 	IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
310 	IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
311 	IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
312 	IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
313 	IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
314 	IOMUX_PADS(PAD_GPIO_18__SD3_VSELECT	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
315 	IOMUX_PADS(PAD_NANDF_CS2__GPIO6_IO15	| MUX_PAD_CTRL(NO_PAD_CTRL)),
316 };
317 
318 static void setup_iomux_uart(void)
319 {
320 	SETUP_IOMUX_PADS(uart4_pads);
321 }
322 
323 #ifdef CONFIG_FSL_ESDHC
324 static struct fsl_esdhc_cfg usdhc_cfg[1] = {
325 	{USDHC3_BASE_ADDR},
326 };
327 
328 int board_mmc_getcd(struct mmc *mmc)
329 {
330 	gpio_direction_input(IMX_GPIO_NR(6, 15));
331 	return !gpio_get_value(IMX_GPIO_NR(6, 15));
332 }
333 
334 int board_mmc_init(bd_t *bis)
335 {
336 	SETUP_IOMUX_PADS(usdhc3_pads);
337 
338 	usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
339 	return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
340 }
341 #endif
342 
343 #ifdef CONFIG_NAND_MXS
344 static iomux_v3_cfg_t gpmi_pads[] = {
345 	IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
346 	IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
347 	IOMUX_PADS(PAD_NANDF_WP_B__NAND_WP_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
348 	IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL0)),
349 	IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
350 	IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
351 	IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
352 	IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
353 	IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
354 	IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
355 	IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
356 	IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
357 	IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
358 	IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
359 	IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
360 	IOMUX_PADS(PAD_SD4_DAT0__NAND_DQS	| MUX_PAD_CTRL(GPMI_PAD_CTRL1)),
361 };
362 
363 static void setup_gpmi_nand(void)
364 {
365 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
366 
367 	/* config gpmi nand iomux */
368 	SETUP_IOMUX_PADS(gpmi_pads);
369 
370 	setup_gpmi_io_clk((MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
371 			MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
372 			MXC_CCM_CS2CDR_ENFC_CLK_SEL(3)));
373 
374 	/* enable apbh clock gating */
375 	setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
376 }
377 #endif
378 
379 static void setup_fec(void)
380 {
381 	if (is_mx6dqp()) {
382 		/*
383 		 * select ENET MAC0 TX clock from PLL
384 		 */
385 		imx_iomux_set_gpr_register(5, 9, 1, 1);
386 		enable_fec_anatop_clock(0, ENET_125MHZ);
387 	}
388 
389 	setup_iomux_enet();
390 }
391 
392 int board_eth_init(bd_t *bis)
393 {
394 	setup_fec();
395 
396 	return cpu_eth_init(bis);
397 }
398 
399 #define BOARD_REV_B  0x200
400 #define BOARD_REV_A  0x100
401 
402 static int mx6sabre_rev(void)
403 {
404 	/*
405 	 * Get Board ID information from OCOTP_GP1[15:8]
406 	 * i.MX6Q ARD RevA: 0x01
407 	 * i.MX6Q ARD RevB: 0x02
408 	 */
409 	struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
410 	struct fuse_bank *bank = &ocotp->bank[4];
411 	struct fuse_bank4_regs *fuse =
412 			(struct fuse_bank4_regs *)bank->fuse_regs;
413 	int reg = readl(&fuse->gp1);
414 	int ret;
415 
416 	switch (reg >> 8 & 0x0F) {
417 	case 0x02:
418 		ret = BOARD_REV_B;
419 		break;
420 	case 0x01:
421 	default:
422 		ret = BOARD_REV_A;
423 		break;
424 	}
425 
426 	return ret;
427 }
428 
429 u32 get_board_rev(void)
430 {
431 	int rev = mx6sabre_rev();
432 
433 	return (get_cpu_rev() & ~(0xF << 8)) | rev;
434 }
435 
436 static int ar8031_phy_fixup(struct phy_device *phydev)
437 {
438 	unsigned short val;
439 
440 	/* To enable AR8031 ouput a 125MHz clk from CLK_25M */
441 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
442 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
443 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
444 
445 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
446 	val &= 0xffe3;
447 	val |= 0x18;
448 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
449 
450 	/* introduce tx clock delay */
451 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
452 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
453 	val |= 0x0100;
454 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
455 
456 	return 0;
457 }
458 
459 int board_phy_config(struct phy_device *phydev)
460 {
461 	ar8031_phy_fixup(phydev);
462 
463 	if (phydev->drv->config)
464 		phydev->drv->config(phydev);
465 
466 	return 0;
467 }
468 
469 #if defined(CONFIG_VIDEO_IPUV3)
470 static void disable_lvds(struct display_info_t const *dev)
471 {
472 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
473 
474 	clrbits_le32(&iomux->gpr[2],
475 		     IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
476 		     IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
477 }
478 
479 static void do_enable_hdmi(struct display_info_t const *dev)
480 {
481 	disable_lvds(dev);
482 	imx_enable_hdmi_phy();
483 }
484 
485 struct display_info_t const displays[] = {{
486 	.bus	= -1,
487 	.addr	= 0,
488 	.pixfmt	= IPU_PIX_FMT_RGB666,
489 	.detect	= NULL,
490 	.enable	= NULL,
491 	.mode	= {
492 		.name           = "Hannstar-XGA",
493 		.refresh        = 60,
494 		.xres           = 1024,
495 		.yres           = 768,
496 		.pixclock       = 15385,
497 		.left_margin    = 220,
498 		.right_margin   = 40,
499 		.upper_margin   = 21,
500 		.lower_margin   = 7,
501 		.hsync_len      = 60,
502 		.vsync_len      = 10,
503 		.sync           = FB_SYNC_EXT,
504 		.vmode          = FB_VMODE_NONINTERLACED
505 } }, {
506 	.bus	= -1,
507 	.addr	= 0,
508 	.pixfmt	= IPU_PIX_FMT_RGB24,
509 	.detect	= detect_hdmi,
510 	.enable	= do_enable_hdmi,
511 	.mode	= {
512 		.name           = "HDMI",
513 		.refresh        = 60,
514 		.xres           = 1024,
515 		.yres           = 768,
516 		.pixclock       = 15385,
517 		.left_margin    = 220,
518 		.right_margin   = 40,
519 		.upper_margin   = 21,
520 		.lower_margin   = 7,
521 		.hsync_len      = 60,
522 		.vsync_len      = 10,
523 		.sync           = FB_SYNC_EXT,
524 		.vmode          = FB_VMODE_NONINTERLACED,
525 } } };
526 size_t display_count = ARRAY_SIZE(displays);
527 
528 iomux_v3_cfg_t const backlight_pads[] = {
529 	IOMUX_PADS(PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
530 };
531 
532 static void setup_iomux_backlight(void)
533 {
534 	gpio_direction_output(IMX_GPIO_NR(2, 9), 1);
535 	SETUP_IOMUX_PADS(backlight_pads);
536 }
537 
538 static void setup_display(void)
539 {
540 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
541 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
542 	int reg;
543 
544 	setup_iomux_backlight();
545 	enable_ipu_clock();
546 	imx_setup_hdmi();
547 
548 	/* Turn on LDB_DI0 and LDB_DI1 clocks */
549 	reg = readl(&mxc_ccm->CCGR3);
550 	reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
551 	writel(reg, &mxc_ccm->CCGR3);
552 
553 	/* Set LDB_DI0 and LDB_DI1 clk select to 3b'011 */
554 	reg = readl(&mxc_ccm->cs2cdr);
555 	reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
556 		 MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
557 	reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
558 	       (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
559 	writel(reg, &mxc_ccm->cs2cdr);
560 
561 	reg = readl(&mxc_ccm->cscmr2);
562 	reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
563 	writel(reg, &mxc_ccm->cscmr2);
564 
565 	reg = readl(&mxc_ccm->chsccdr);
566 	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
567 		<< MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
568 	reg |= (CHSCCDR_CLK_SEL_LDB_DI0 <<
569 		MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
570 	writel(reg, &mxc_ccm->chsccdr);
571 
572 	reg = IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW |
573 	      IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW |
574 	      IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG |
575 	      IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT |
576 	      IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG |
577 	      IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT |
578 	      IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0 |
579 	      IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED;
580 	writel(reg, &iomux->gpr[2]);
581 
582 	reg = readl(&iomux->gpr[3]);
583 	reg &= ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK |
584 		 IOMUXC_GPR3_HDMI_MUX_CTL_MASK);
585 	reg |= (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
586 		IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET) |
587 	       (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
588 		IOMUXC_GPR3_HDMI_MUX_CTL_OFFSET);
589 	writel(reg, &iomux->gpr[3]);
590 }
591 #endif /* CONFIG_VIDEO_IPUV3 */
592 
593 /*
594  * Do not overwrite the console
595  * Use always serial for U-Boot console
596  */
597 int overwrite_console(void)
598 {
599 	return 1;
600 }
601 
602 int board_early_init_f(void)
603 {
604 	setup_iomux_uart();
605 
606 #ifdef CONFIG_NAND_MXS
607 	setup_gpmi_nand();
608 #endif
609 
610 #ifdef CONFIG_MTD_NOR_FLASH
611 	eim_clk_setup();
612 #endif
613 	return 0;
614 }
615 
616 int board_init(void)
617 {
618 	/* address of boot parameters */
619 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
620 
621 	/* I2C 2 and 3 setup - I2C 3 hw mux with EIM */
622 	if (is_mx6dq() || is_mx6dqp())
623 		setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1);
624 	else
625 		setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1);
626 	/* I2C 3 Steer */
627 	gpio_direction_output(IMX_GPIO_NR(5, 4), 1);
628 	SETUP_IOMUX_PADS(i2c3_pads);
629 #ifndef CONFIG_SYS_FLASH_CFI
630 	if (is_mx6dq() || is_mx6dqp())
631 		setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info2);
632 	else
633 		setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info2);
634 #endif
635 	gpio_direction_output(IMX_GPIO_NR(1, 15), 1);
636 	SETUP_IOMUX_PADS(port_exp);
637 
638 #ifdef CONFIG_VIDEO_IPUV3
639 	setup_display();
640 #endif
641 
642 #ifdef CONFIG_MTD_NOR_FLASH
643 	setup_iomux_eimnor();
644 #endif
645 	return 0;
646 }
647 
648 #ifdef CONFIG_MXC_SPI
649 int board_spi_cs_gpio(unsigned bus, unsigned cs)
650 {
651 	return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
652 }
653 #endif
654 
655 int power_init_board(void)
656 {
657 	struct pmic *p;
658 	unsigned int value;
659 
660 	p = pfuze_common_init(I2C_PMIC);
661 	if (!p)
662 		return -ENODEV;
663 
664 	if (is_mx6dqp()) {
665 		/* set SW2 staby volatage 0.975V*/
666 		pmic_reg_read(p, PFUZE100_SW2STBY, &value);
667 		value &= ~0x3f;
668 		value |= 0x17;
669 		pmic_reg_write(p, PFUZE100_SW2STBY, value);
670 	}
671 
672 	return pfuze_mode_init(p, APS_PFM);
673 }
674 
675 #ifdef CONFIG_CMD_BMODE
676 static const struct boot_mode board_boot_modes[] = {
677 	/* 4 bit bus width */
678 	{"mmc0", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
679 	{NULL,   0},
680 };
681 #endif
682 
683 int board_late_init(void)
684 {
685 #ifdef CONFIG_CMD_BMODE
686 	add_board_boot_modes(board_boot_modes);
687 #endif
688 
689 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
690 	env_set("board_name", "SABREAUTO");
691 
692 	if (is_mx6dqp())
693 		env_set("board_rev", "MX6QP");
694 	else if (is_mx6dq())
695 		env_set("board_rev", "MX6Q");
696 	else if (is_mx6sdl())
697 		env_set("board_rev", "MX6DL");
698 #endif
699 
700 	return 0;
701 }
702 
703 int checkboard(void)
704 {
705 	int rev = mx6sabre_rev();
706 	char *revname;
707 
708 	switch (rev) {
709 	case BOARD_REV_B:
710 		revname = "B";
711 		break;
712 	case BOARD_REV_A:
713 	default:
714 		revname = "A";
715 		break;
716 	}
717 
718 	printf("Board: MX6Q-Sabreauto rev%s\n", revname);
719 
720 	return 0;
721 }
722 
723 #ifdef CONFIG_USB_EHCI_MX6
724 #define USB_HOST1_PWR     PORTEXP_IO_NR(0x32, 7)
725 #define USB_OTG_PWR       PORTEXP_IO_NR(0x34, 1)
726 
727 iomux_v3_cfg_t const usb_otg_pads[] = {
728 	IOMUX_PADS(PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL)),
729 };
730 
731 int board_ehci_hcd_init(int port)
732 {
733 	switch (port) {
734 	case 0:
735 		SETUP_IOMUX_PADS(usb_otg_pads);
736 
737 		/*
738 		  * Set daisy chain for otg_pin_id on 6q.
739 		 *  For 6dl, this bit is reserved.
740 		 */
741 		imx_iomux_set_gpr_register(1, 13, 1, 0);
742 		break;
743 	case 1:
744 		break;
745 	default:
746 		printf("MXC USB port %d not yet supported\n", port);
747 		return -EINVAL;
748 	}
749 	return 0;
750 }
751 
752 int board_ehci_power(int port, int on)
753 {
754 	switch (port) {
755 	case 0:
756 		if (on)
757 			port_exp_direction_output(USB_OTG_PWR, 1);
758 		else
759 			port_exp_direction_output(USB_OTG_PWR, 0);
760 		break;
761 	case 1:
762 		if (on)
763 			port_exp_direction_output(USB_HOST1_PWR, 1);
764 		else
765 			port_exp_direction_output(USB_HOST1_PWR, 0);
766 		break;
767 	default:
768 		printf("MXC USB port %d not yet supported\n", port);
769 		return -EINVAL;
770 	}
771 
772 	return 0;
773 }
774 #endif
775 
776 #ifdef CONFIG_SPL_BUILD
777 #include <asm/arch/mx6-ddr.h>
778 #include <spl.h>
779 #include <libfdt.h>
780 
781 #ifdef CONFIG_SPL_OS_BOOT
782 int spl_start_uboot(void)
783 {
784 	return 0;
785 }
786 #endif
787 
788 static void ccgr_init(void)
789 {
790 	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
791 
792 	writel(0x00C03F3F, &ccm->CCGR0);
793 	writel(0x0030FC03, &ccm->CCGR1);
794 	writel(0x0FFFC000, &ccm->CCGR2);
795 	writel(0x3FF00000, &ccm->CCGR3);
796 	writel(0x00FFF300, &ccm->CCGR4);
797 	writel(0x0F0000C3, &ccm->CCGR5);
798 	writel(0x000003FF, &ccm->CCGR6);
799 }
800 
801 static int mx6q_dcd_table[] = {
802 	0x020e0798, 0x000C0000,
803 	0x020e0758, 0x00000000,
804 	0x020e0588, 0x00000030,
805 	0x020e0594, 0x00000030,
806 	0x020e056c, 0x00000030,
807 	0x020e0578, 0x00000030,
808 	0x020e074c, 0x00000030,
809 	0x020e057c, 0x00000030,
810 	0x020e058c, 0x00000000,
811 	0x020e059c, 0x00000030,
812 	0x020e05a0, 0x00000030,
813 	0x020e078c, 0x00000030,
814 	0x020e0750, 0x00020000,
815 	0x020e05a8, 0x00000028,
816 	0x020e05b0, 0x00000028,
817 	0x020e0524, 0x00000028,
818 	0x020e051c, 0x00000028,
819 	0x020e0518, 0x00000028,
820 	0x020e050c, 0x00000028,
821 	0x020e05b8, 0x00000028,
822 	0x020e05c0, 0x00000028,
823 	0x020e0774, 0x00020000,
824 	0x020e0784, 0x00000028,
825 	0x020e0788, 0x00000028,
826 	0x020e0794, 0x00000028,
827 	0x020e079c, 0x00000028,
828 	0x020e07a0, 0x00000028,
829 	0x020e07a4, 0x00000028,
830 	0x020e07a8, 0x00000028,
831 	0x020e0748, 0x00000028,
832 	0x020e05ac, 0x00000028,
833 	0x020e05b4, 0x00000028,
834 	0x020e0528, 0x00000028,
835 	0x020e0520, 0x00000028,
836 	0x020e0514, 0x00000028,
837 	0x020e0510, 0x00000028,
838 	0x020e05bc, 0x00000028,
839 	0x020e05c4, 0x00000028,
840 	0x021b0800, 0xa1390003,
841 	0x021b080c, 0x001F001F,
842 	0x021b0810, 0x001F001F,
843 	0x021b480c, 0x001F001F,
844 	0x021b4810, 0x001F001F,
845 	0x021b083c, 0x43260335,
846 	0x021b0840, 0x031A030B,
847 	0x021b483c, 0x4323033B,
848 	0x021b4840, 0x0323026F,
849 	0x021b0848, 0x483D4545,
850 	0x021b4848, 0x44433E48,
851 	0x021b0850, 0x41444840,
852 	0x021b4850, 0x4835483E,
853 	0x021b081c, 0x33333333,
854 	0x021b0820, 0x33333333,
855 	0x021b0824, 0x33333333,
856 	0x021b0828, 0x33333333,
857 	0x021b481c, 0x33333333,
858 	0x021b4820, 0x33333333,
859 	0x021b4824, 0x33333333,
860 	0x021b4828, 0x33333333,
861 	0x021b08b8, 0x00000800,
862 	0x021b48b8, 0x00000800,
863 	0x021b0004, 0x00020036,
864 	0x021b0008, 0x09444040,
865 	0x021b000c, 0x8A8F7955,
866 	0x021b0010, 0xFF328F64,
867 	0x021b0014, 0x01FF00DB,
868 	0x021b0018, 0x00001740,
869 	0x021b001c, 0x00008000,
870 	0x021b002c, 0x000026d2,
871 	0x021b0030, 0x008F1023,
872 	0x021b0040, 0x00000047,
873 	0x021b0000, 0x841A0000,
874 	0x021b001c, 0x04088032,
875 	0x021b001c, 0x00008033,
876 	0x021b001c, 0x00048031,
877 	0x021b001c, 0x09408030,
878 	0x021b001c, 0x04008040,
879 	0x021b0020, 0x00005800,
880 	0x021b0818, 0x00011117,
881 	0x021b4818, 0x00011117,
882 	0x021b0004, 0x00025576,
883 	0x021b0404, 0x00011006,
884 	0x021b001c, 0x00000000,
885 	0x020c4068, 0x00C03F3F,
886 	0x020c406c, 0x0030FC03,
887 	0x020c4070, 0x0FFFC000,
888 	0x020c4074, 0x3FF00000,
889 	0x020c4078, 0xFFFFF300,
890 	0x020c407c, 0x0F0000F3,
891 	0x020c4080, 0x00000FFF,
892 	0x020e0010, 0xF00000CF,
893 	0x020e0018, 0x007F007F,
894 	0x020e001c, 0x007F007F,
895 };
896 
897 static int mx6qp_dcd_table[] = {
898 	0x020e0798, 0x000C0000,
899 	0x020e0758, 0x00000000,
900 	0x020e0588, 0x00000030,
901 	0x020e0594, 0x00000030,
902 	0x020e056c, 0x00000030,
903 	0x020e0578, 0x00000030,
904 	0x020e074c, 0x00000030,
905 	0x020e057c, 0x00000030,
906 	0x020e058c, 0x00000000,
907 	0x020e059c, 0x00000030,
908 	0x020e05a0, 0x00000030,
909 	0x020e078c, 0x00000030,
910 	0x020e0750, 0x00020000,
911 	0x020e05a8, 0x00000030,
912 	0x020e05b0, 0x00000030,
913 	0x020e0524, 0x00000030,
914 	0x020e051c, 0x00000030,
915 	0x020e0518, 0x00000030,
916 	0x020e050c, 0x00000030,
917 	0x020e05b8, 0x00000030,
918 	0x020e05c0, 0x00000030,
919 	0x020e0774, 0x00020000,
920 	0x020e0784, 0x00000030,
921 	0x020e0788, 0x00000030,
922 	0x020e0794, 0x00000030,
923 	0x020e079c, 0x00000030,
924 	0x020e07a0, 0x00000030,
925 	0x020e07a4, 0x00000030,
926 	0x020e07a8, 0x00000030,
927 	0x020e0748, 0x00000030,
928 	0x020e05ac, 0x00000030,
929 	0x020e05b4, 0x00000030,
930 	0x020e0528, 0x00000030,
931 	0x020e0520, 0x00000030,
932 	0x020e0514, 0x00000030,
933 	0x020e0510, 0x00000030,
934 	0x020e05bc, 0x00000030,
935 	0x020e05c4, 0x00000030,
936 	0x021b0800, 0xa1390003,
937 	0x021b080c, 0x001b001e,
938 	0x021b0810, 0x002e0029,
939 	0x021b480c, 0x001b002a,
940 	0x021b4810, 0x0019002c,
941 	0x021b083c, 0x43240334,
942 	0x021b0840, 0x0324031a,
943 	0x021b483c, 0x43340344,
944 	0x021b4840, 0x03280276,
945 	0x021b0848, 0x44383A3E,
946 	0x021b4848, 0x3C3C3846,
947 	0x021b0850, 0x2e303230,
948 	0x021b4850, 0x38283E34,
949 	0x021b081c, 0x33333333,
950 	0x021b0820, 0x33333333,
951 	0x021b0824, 0x33333333,
952 	0x021b0828, 0x33333333,
953 	0x021b481c, 0x33333333,
954 	0x021b4820, 0x33333333,
955 	0x021b4824, 0x33333333,
956 	0x021b4828, 0x33333333,
957 	0x021b08c0, 0x24912492,
958 	0x021b48c0, 0x24912492,
959 	0x021b08b8, 0x00000800,
960 	0x021b48b8, 0x00000800,
961 	0x021b0004, 0x00020036,
962 	0x021b0008, 0x09444040,
963 	0x021b000c, 0x898E7955,
964 	0x021b0010, 0xFF328F64,
965 	0x021b0014, 0x01FF00DB,
966 	0x021b0018, 0x00001740,
967 	0x021b001c, 0x00008000,
968 	0x021b002c, 0x000026d2,
969 	0x021b0030, 0x008E1023,
970 	0x021b0040, 0x00000047,
971 	0x021b0400, 0x14420000,
972 	0x021b0000, 0x841A0000,
973 	0x00bb0008, 0x00000004,
974 	0x00bb000c, 0x2891E41A,
975 	0x00bb0038, 0x00000564,
976 	0x00bb0014, 0x00000040,
977 	0x00bb0028, 0x00000020,
978 	0x00bb002c, 0x00000020,
979 	0x021b001c, 0x04088032,
980 	0x021b001c, 0x00008033,
981 	0x021b001c, 0x00048031,
982 	0x021b001c, 0x09408030,
983 	0x021b001c, 0x04008040,
984 	0x021b0020, 0x00005800,
985 	0x021b0818, 0x00011117,
986 	0x021b4818, 0x00011117,
987 	0x021b0004, 0x00025576,
988 	0x021b0404, 0x00011006,
989 	0x021b001c, 0x00000000,
990 	0x020c4068, 0x00C03F3F,
991 	0x020c406c, 0x0030FC03,
992 	0x020c4070, 0x0FFFC000,
993 	0x020c4074, 0x3FF00000,
994 	0x020c4078, 0xFFFFF300,
995 	0x020c407c, 0x0F0000F3,
996 	0x020c4080, 0x00000FFF,
997 	0x020e0010, 0xF00000CF,
998 	0x020e0018, 0x77177717,
999 	0x020e001c, 0x77177717,
1000 };
1001 
1002 static int mx6dl_dcd_table[] = {
1003 	0x020e0774, 0x000C0000,
1004 	0x020e0754, 0x00000000,
1005 	0x020e04ac, 0x00000030,
1006 	0x020e04b0, 0x00000030,
1007 	0x020e0464, 0x00000030,
1008 	0x020e0490, 0x00000030,
1009 	0x020e074c, 0x00000030,
1010 	0x020e0494, 0x00000030,
1011 	0x020e04a0, 0x00000000,
1012 	0x020e04b4, 0x00000030,
1013 	0x020e04b8, 0x00000030,
1014 	0x020e076c, 0x00000030,
1015 	0x020e0750, 0x00020000,
1016 	0x020e04bc, 0x00000028,
1017 	0x020e04c0, 0x00000028,
1018 	0x020e04c4, 0x00000028,
1019 	0x020e04c8, 0x00000028,
1020 	0x020e04cc, 0x00000028,
1021 	0x020e04d0, 0x00000028,
1022 	0x020e04d4, 0x00000028,
1023 	0x020e04d8, 0x00000028,
1024 	0x020e0760, 0x00020000,
1025 	0x020e0764, 0x00000028,
1026 	0x020e0770, 0x00000028,
1027 	0x020e0778, 0x00000028,
1028 	0x020e077c, 0x00000028,
1029 	0x020e0780, 0x00000028,
1030 	0x020e0784, 0x00000028,
1031 	0x020e078c, 0x00000028,
1032 	0x020e0748, 0x00000028,
1033 	0x020e0470, 0x00000028,
1034 	0x020e0474, 0x00000028,
1035 	0x020e0478, 0x00000028,
1036 	0x020e047c, 0x00000028,
1037 	0x020e0480, 0x00000028,
1038 	0x020e0484, 0x00000028,
1039 	0x020e0488, 0x00000028,
1040 	0x020e048c, 0x00000028,
1041 	0x021b0800, 0xa1390003,
1042 	0x021b080c, 0x001F001F,
1043 	0x021b0810, 0x001F001F,
1044 	0x021b480c, 0x001F001F,
1045 	0x021b4810, 0x001F001F,
1046 	0x021b083c, 0x42190217,
1047 	0x021b0840, 0x017B017B,
1048 	0x021b483c, 0x4176017B,
1049 	0x021b4840, 0x015F016C,
1050 	0x021b0848, 0x4C4C4D4C,
1051 	0x021b4848, 0x4A4D4C48,
1052 	0x021b0850, 0x3F3F3F40,
1053 	0x021b4850, 0x3538382E,
1054 	0x021b081c, 0x33333333,
1055 	0x021b0820, 0x33333333,
1056 	0x021b0824, 0x33333333,
1057 	0x021b0828, 0x33333333,
1058 	0x021b481c, 0x33333333,
1059 	0x021b4820, 0x33333333,
1060 	0x021b4824, 0x33333333,
1061 	0x021b4828, 0x33333333,
1062 	0x021b08b8, 0x00000800,
1063 	0x021b48b8, 0x00000800,
1064 	0x021b0004, 0x00020025,
1065 	0x021b0008, 0x00333030,
1066 	0x021b000c, 0x676B5313,
1067 	0x021b0010, 0xB66E8B63,
1068 	0x021b0014, 0x01FF00DB,
1069 	0x021b0018, 0x00001740,
1070 	0x021b001c, 0x00008000,
1071 	0x021b002c, 0x000026d2,
1072 	0x021b0030, 0x006B1023,
1073 	0x021b0040, 0x00000047,
1074 	0x021b0000, 0x841A0000,
1075 	0x021b001c, 0x04008032,
1076 	0x021b001c, 0x00008033,
1077 	0x021b001c, 0x00048031,
1078 	0x021b001c, 0x05208030,
1079 	0x021b001c, 0x04008040,
1080 	0x021b0020, 0x00005800,
1081 	0x021b0818, 0x00011117,
1082 	0x021b4818, 0x00011117,
1083 	0x021b0004, 0x00025565,
1084 	0x021b0404, 0x00011006,
1085 	0x021b001c, 0x00000000,
1086 	0x020c4068, 0x00C03F3F,
1087 	0x020c406c, 0x0030FC03,
1088 	0x020c4070, 0x0FFFC000,
1089 	0x020c4074, 0x3FF00000,
1090 	0x020c4078, 0xFFFFF300,
1091 	0x020c407c, 0x0F0000C3,
1092 	0x020c4080, 0x00000FFF,
1093 	0x020e0010, 0xF00000CF,
1094 	0x020e0018, 0x007F007F,
1095 	0x020e001c, 0x007F007F,
1096 };
1097 
1098 static void ddr_init(int *table, int size)
1099 {
1100 	int i;
1101 
1102 	for (i = 0; i < size / 2 ; i++)
1103 		writel(table[2 * i + 1], table[2 * i]);
1104 }
1105 
1106 static void spl_dram_init(void)
1107 {
1108 	if (is_mx6dq())
1109 		ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table));
1110 	else if (is_mx6dqp())
1111 		ddr_init(mx6qp_dcd_table, ARRAY_SIZE(mx6qp_dcd_table));
1112 	else if (is_mx6sdl())
1113 		ddr_init(mx6dl_dcd_table, ARRAY_SIZE(mx6dl_dcd_table));
1114 }
1115 
1116 void board_init_f(ulong dummy)
1117 {
1118 	/* DDR initialization */
1119 	spl_dram_init();
1120 
1121 	/* setup AIPS and disable watchdog */
1122 	arch_cpu_init();
1123 
1124 	ccgr_init();
1125 	gpr_init();
1126 
1127 	/* iomux and setup of i2c */
1128 	board_early_init_f();
1129 
1130 	/* setup GP timer */
1131 	timer_init();
1132 
1133 	/* UART clocks enabled and gd valid - init serial console */
1134 	preloader_console_init();
1135 
1136 	/* Clear the BSS. */
1137 	memset(__bss_start, 0, __bss_end - __bss_start);
1138 
1139 	/* load/boot image from boot device */
1140 	board_init_r(NULL, 0);
1141 }
1142 #endif
1143