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 void gpr_init(void)
802 {
803 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
804 
805 	/* enable AXI cache for VDOA/VPU/IPU */
806 	writel(0xF00000CF, &iomux->gpr[4]);
807 	if (is_mx6dqp()) {
808 		/* set IPU AXI-id1 Qos=0x1 AXI-id0/2/3 Qos=0x7 */
809 		writel(0x77177717, &iomux->gpr[6]);
810 		writel(0x77177717, &iomux->gpr[7]);
811 	} else {
812 		/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
813 		writel(0x007F007F, &iomux->gpr[6]);
814 		writel(0x007F007F, &iomux->gpr[7]);
815 	}
816 }
817 
818 static int mx6q_dcd_table[] = {
819 	0x020e0798, 0x000C0000,
820 	0x020e0758, 0x00000000,
821 	0x020e0588, 0x00000030,
822 	0x020e0594, 0x00000030,
823 	0x020e056c, 0x00000030,
824 	0x020e0578, 0x00000030,
825 	0x020e074c, 0x00000030,
826 	0x020e057c, 0x00000030,
827 	0x020e058c, 0x00000000,
828 	0x020e059c, 0x00000030,
829 	0x020e05a0, 0x00000030,
830 	0x020e078c, 0x00000030,
831 	0x020e0750, 0x00020000,
832 	0x020e05a8, 0x00000028,
833 	0x020e05b0, 0x00000028,
834 	0x020e0524, 0x00000028,
835 	0x020e051c, 0x00000028,
836 	0x020e0518, 0x00000028,
837 	0x020e050c, 0x00000028,
838 	0x020e05b8, 0x00000028,
839 	0x020e05c0, 0x00000028,
840 	0x020e0774, 0x00020000,
841 	0x020e0784, 0x00000028,
842 	0x020e0788, 0x00000028,
843 	0x020e0794, 0x00000028,
844 	0x020e079c, 0x00000028,
845 	0x020e07a0, 0x00000028,
846 	0x020e07a4, 0x00000028,
847 	0x020e07a8, 0x00000028,
848 	0x020e0748, 0x00000028,
849 	0x020e05ac, 0x00000028,
850 	0x020e05b4, 0x00000028,
851 	0x020e0528, 0x00000028,
852 	0x020e0520, 0x00000028,
853 	0x020e0514, 0x00000028,
854 	0x020e0510, 0x00000028,
855 	0x020e05bc, 0x00000028,
856 	0x020e05c4, 0x00000028,
857 	0x021b0800, 0xa1390003,
858 	0x021b080c, 0x001F001F,
859 	0x021b0810, 0x001F001F,
860 	0x021b480c, 0x001F001F,
861 	0x021b4810, 0x001F001F,
862 	0x021b083c, 0x43260335,
863 	0x021b0840, 0x031A030B,
864 	0x021b483c, 0x4323033B,
865 	0x021b4840, 0x0323026F,
866 	0x021b0848, 0x483D4545,
867 	0x021b4848, 0x44433E48,
868 	0x021b0850, 0x41444840,
869 	0x021b4850, 0x4835483E,
870 	0x021b081c, 0x33333333,
871 	0x021b0820, 0x33333333,
872 	0x021b0824, 0x33333333,
873 	0x021b0828, 0x33333333,
874 	0x021b481c, 0x33333333,
875 	0x021b4820, 0x33333333,
876 	0x021b4824, 0x33333333,
877 	0x021b4828, 0x33333333,
878 	0x021b08b8, 0x00000800,
879 	0x021b48b8, 0x00000800,
880 	0x021b0004, 0x00020036,
881 	0x021b0008, 0x09444040,
882 	0x021b000c, 0x8A8F7955,
883 	0x021b0010, 0xFF328F64,
884 	0x021b0014, 0x01FF00DB,
885 	0x021b0018, 0x00001740,
886 	0x021b001c, 0x00008000,
887 	0x021b002c, 0x000026d2,
888 	0x021b0030, 0x008F1023,
889 	0x021b0040, 0x00000047,
890 	0x021b0000, 0x841A0000,
891 	0x021b001c, 0x04088032,
892 	0x021b001c, 0x00008033,
893 	0x021b001c, 0x00048031,
894 	0x021b001c, 0x09408030,
895 	0x021b001c, 0x04008040,
896 	0x021b0020, 0x00005800,
897 	0x021b0818, 0x00011117,
898 	0x021b4818, 0x00011117,
899 	0x021b0004, 0x00025576,
900 	0x021b0404, 0x00011006,
901 	0x021b001c, 0x00000000,
902 	0x020c4068, 0x00C03F3F,
903 	0x020c406c, 0x0030FC03,
904 	0x020c4070, 0x0FFFC000,
905 	0x020c4074, 0x3FF00000,
906 	0x020c4078, 0xFFFFF300,
907 	0x020c407c, 0x0F0000F3,
908 	0x020c4080, 0x00000FFF,
909 	0x020e0010, 0xF00000CF,
910 	0x020e0018, 0x007F007F,
911 	0x020e001c, 0x007F007F,
912 };
913 
914 static int mx6qp_dcd_table[] = {
915 	0x020e0798, 0x000C0000,
916 	0x020e0758, 0x00000000,
917 	0x020e0588, 0x00000030,
918 	0x020e0594, 0x00000030,
919 	0x020e056c, 0x00000030,
920 	0x020e0578, 0x00000030,
921 	0x020e074c, 0x00000030,
922 	0x020e057c, 0x00000030,
923 	0x020e058c, 0x00000000,
924 	0x020e059c, 0x00000030,
925 	0x020e05a0, 0x00000030,
926 	0x020e078c, 0x00000030,
927 	0x020e0750, 0x00020000,
928 	0x020e05a8, 0x00000030,
929 	0x020e05b0, 0x00000030,
930 	0x020e0524, 0x00000030,
931 	0x020e051c, 0x00000030,
932 	0x020e0518, 0x00000030,
933 	0x020e050c, 0x00000030,
934 	0x020e05b8, 0x00000030,
935 	0x020e05c0, 0x00000030,
936 	0x020e0774, 0x00020000,
937 	0x020e0784, 0x00000030,
938 	0x020e0788, 0x00000030,
939 	0x020e0794, 0x00000030,
940 	0x020e079c, 0x00000030,
941 	0x020e07a0, 0x00000030,
942 	0x020e07a4, 0x00000030,
943 	0x020e07a8, 0x00000030,
944 	0x020e0748, 0x00000030,
945 	0x020e05ac, 0x00000030,
946 	0x020e05b4, 0x00000030,
947 	0x020e0528, 0x00000030,
948 	0x020e0520, 0x00000030,
949 	0x020e0514, 0x00000030,
950 	0x020e0510, 0x00000030,
951 	0x020e05bc, 0x00000030,
952 	0x020e05c4, 0x00000030,
953 	0x021b0800, 0xa1390003,
954 	0x021b080c, 0x001b001e,
955 	0x021b0810, 0x002e0029,
956 	0x021b480c, 0x001b002a,
957 	0x021b4810, 0x0019002c,
958 	0x021b083c, 0x43240334,
959 	0x021b0840, 0x0324031a,
960 	0x021b483c, 0x43340344,
961 	0x021b4840, 0x03280276,
962 	0x021b0848, 0x44383A3E,
963 	0x021b4848, 0x3C3C3846,
964 	0x021b0850, 0x2e303230,
965 	0x021b4850, 0x38283E34,
966 	0x021b081c, 0x33333333,
967 	0x021b0820, 0x33333333,
968 	0x021b0824, 0x33333333,
969 	0x021b0828, 0x33333333,
970 	0x021b481c, 0x33333333,
971 	0x021b4820, 0x33333333,
972 	0x021b4824, 0x33333333,
973 	0x021b4828, 0x33333333,
974 	0x021b08c0, 0x24912492,
975 	0x021b48c0, 0x24912492,
976 	0x021b08b8, 0x00000800,
977 	0x021b48b8, 0x00000800,
978 	0x021b0004, 0x00020036,
979 	0x021b0008, 0x09444040,
980 	0x021b000c, 0x898E7955,
981 	0x021b0010, 0xFF328F64,
982 	0x021b0014, 0x01FF00DB,
983 	0x021b0018, 0x00001740,
984 	0x021b001c, 0x00008000,
985 	0x021b002c, 0x000026d2,
986 	0x021b0030, 0x008E1023,
987 	0x021b0040, 0x00000047,
988 	0x021b0400, 0x14420000,
989 	0x021b0000, 0x841A0000,
990 	0x00bb0008, 0x00000004,
991 	0x00bb000c, 0x2891E41A,
992 	0x00bb0038, 0x00000564,
993 	0x00bb0014, 0x00000040,
994 	0x00bb0028, 0x00000020,
995 	0x00bb002c, 0x00000020,
996 	0x021b001c, 0x04088032,
997 	0x021b001c, 0x00008033,
998 	0x021b001c, 0x00048031,
999 	0x021b001c, 0x09408030,
1000 	0x021b001c, 0x04008040,
1001 	0x021b0020, 0x00005800,
1002 	0x021b0818, 0x00011117,
1003 	0x021b4818, 0x00011117,
1004 	0x021b0004, 0x00025576,
1005 	0x021b0404, 0x00011006,
1006 	0x021b001c, 0x00000000,
1007 	0x020c4068, 0x00C03F3F,
1008 	0x020c406c, 0x0030FC03,
1009 	0x020c4070, 0x0FFFC000,
1010 	0x020c4074, 0x3FF00000,
1011 	0x020c4078, 0xFFFFF300,
1012 	0x020c407c, 0x0F0000F3,
1013 	0x020c4080, 0x00000FFF,
1014 	0x020e0010, 0xF00000CF,
1015 	0x020e0018, 0x77177717,
1016 	0x020e001c, 0x77177717,
1017 };
1018 
1019 static int mx6dl_dcd_table[] = {
1020 	0x020e0774, 0x000C0000,
1021 	0x020e0754, 0x00000000,
1022 	0x020e04ac, 0x00000030,
1023 	0x020e04b0, 0x00000030,
1024 	0x020e0464, 0x00000030,
1025 	0x020e0490, 0x00000030,
1026 	0x020e074c, 0x00000030,
1027 	0x020e0494, 0x00000030,
1028 	0x020e04a0, 0x00000000,
1029 	0x020e04b4, 0x00000030,
1030 	0x020e04b8, 0x00000030,
1031 	0x020e076c, 0x00000030,
1032 	0x020e0750, 0x00020000,
1033 	0x020e04bc, 0x00000028,
1034 	0x020e04c0, 0x00000028,
1035 	0x020e04c4, 0x00000028,
1036 	0x020e04c8, 0x00000028,
1037 	0x020e04cc, 0x00000028,
1038 	0x020e04d0, 0x00000028,
1039 	0x020e04d4, 0x00000028,
1040 	0x020e04d8, 0x00000028,
1041 	0x020e0760, 0x00020000,
1042 	0x020e0764, 0x00000028,
1043 	0x020e0770, 0x00000028,
1044 	0x020e0778, 0x00000028,
1045 	0x020e077c, 0x00000028,
1046 	0x020e0780, 0x00000028,
1047 	0x020e0784, 0x00000028,
1048 	0x020e078c, 0x00000028,
1049 	0x020e0748, 0x00000028,
1050 	0x020e0470, 0x00000028,
1051 	0x020e0474, 0x00000028,
1052 	0x020e0478, 0x00000028,
1053 	0x020e047c, 0x00000028,
1054 	0x020e0480, 0x00000028,
1055 	0x020e0484, 0x00000028,
1056 	0x020e0488, 0x00000028,
1057 	0x020e048c, 0x00000028,
1058 	0x021b0800, 0xa1390003,
1059 	0x021b080c, 0x001F001F,
1060 	0x021b0810, 0x001F001F,
1061 	0x021b480c, 0x001F001F,
1062 	0x021b4810, 0x001F001F,
1063 	0x021b083c, 0x42190217,
1064 	0x021b0840, 0x017B017B,
1065 	0x021b483c, 0x4176017B,
1066 	0x021b4840, 0x015F016C,
1067 	0x021b0848, 0x4C4C4D4C,
1068 	0x021b4848, 0x4A4D4C48,
1069 	0x021b0850, 0x3F3F3F40,
1070 	0x021b4850, 0x3538382E,
1071 	0x021b081c, 0x33333333,
1072 	0x021b0820, 0x33333333,
1073 	0x021b0824, 0x33333333,
1074 	0x021b0828, 0x33333333,
1075 	0x021b481c, 0x33333333,
1076 	0x021b4820, 0x33333333,
1077 	0x021b4824, 0x33333333,
1078 	0x021b4828, 0x33333333,
1079 	0x021b08b8, 0x00000800,
1080 	0x021b48b8, 0x00000800,
1081 	0x021b0004, 0x00020025,
1082 	0x021b0008, 0x00333030,
1083 	0x021b000c, 0x676B5313,
1084 	0x021b0010, 0xB66E8B63,
1085 	0x021b0014, 0x01FF00DB,
1086 	0x021b0018, 0x00001740,
1087 	0x021b001c, 0x00008000,
1088 	0x021b002c, 0x000026d2,
1089 	0x021b0030, 0x006B1023,
1090 	0x021b0040, 0x00000047,
1091 	0x021b0000, 0x841A0000,
1092 	0x021b001c, 0x04008032,
1093 	0x021b001c, 0x00008033,
1094 	0x021b001c, 0x00048031,
1095 	0x021b001c, 0x05208030,
1096 	0x021b001c, 0x04008040,
1097 	0x021b0020, 0x00005800,
1098 	0x021b0818, 0x00011117,
1099 	0x021b4818, 0x00011117,
1100 	0x021b0004, 0x00025565,
1101 	0x021b0404, 0x00011006,
1102 	0x021b001c, 0x00000000,
1103 	0x020c4068, 0x00C03F3F,
1104 	0x020c406c, 0x0030FC03,
1105 	0x020c4070, 0x0FFFC000,
1106 	0x020c4074, 0x3FF00000,
1107 	0x020c4078, 0xFFFFF300,
1108 	0x020c407c, 0x0F0000C3,
1109 	0x020c4080, 0x00000FFF,
1110 	0x020e0010, 0xF00000CF,
1111 	0x020e0018, 0x007F007F,
1112 	0x020e001c, 0x007F007F,
1113 };
1114 
1115 static void ddr_init(int *table, int size)
1116 {
1117 	int i;
1118 
1119 	for (i = 0; i < size / 2 ; i++)
1120 		writel(table[2 * i + 1], table[2 * i]);
1121 }
1122 
1123 static void spl_dram_init(void)
1124 {
1125 	if (is_mx6dq())
1126 		ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table));
1127 	else if (is_mx6dqp())
1128 		ddr_init(mx6qp_dcd_table, ARRAY_SIZE(mx6qp_dcd_table));
1129 	else if (is_mx6sdl())
1130 		ddr_init(mx6dl_dcd_table, ARRAY_SIZE(mx6dl_dcd_table));
1131 }
1132 
1133 void board_init_f(ulong dummy)
1134 {
1135 	/* DDR initialization */
1136 	spl_dram_init();
1137 
1138 	/* setup AIPS and disable watchdog */
1139 	arch_cpu_init();
1140 
1141 	ccgr_init();
1142 	gpr_init();
1143 
1144 	/* iomux and setup of i2c */
1145 	board_early_init_f();
1146 
1147 	/* setup GP timer */
1148 	timer_init();
1149 
1150 	/* UART clocks enabled and gd valid - init serial console */
1151 	preloader_console_init();
1152 
1153 	/* Clear the BSS. */
1154 	memset(__bss_start, 0, __bss_end - __bss_start);
1155 
1156 	/* load/boot image from boot device */
1157 	board_init_r(NULL, 0);
1158 }
1159 #endif
1160