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