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