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 #if defined(CONFIG_VIDEO_IPUV3)
437 static void disable_lvds(struct display_info_t const *dev)
438 {
439 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
440 
441 	clrbits_le32(&iomux->gpr[2],
442 		     IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
443 		     IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
444 }
445 
446 static void do_enable_hdmi(struct display_info_t const *dev)
447 {
448 	disable_lvds(dev);
449 	imx_enable_hdmi_phy();
450 }
451 
452 struct display_info_t const displays[] = {{
453 	.bus	= -1,
454 	.addr	= 0,
455 	.pixfmt	= IPU_PIX_FMT_RGB666,
456 	.detect	= NULL,
457 	.enable	= NULL,
458 	.mode	= {
459 		.name           = "Hannstar-XGA",
460 		.refresh        = 60,
461 		.xres           = 1024,
462 		.yres           = 768,
463 		.pixclock       = 15385,
464 		.left_margin    = 220,
465 		.right_margin   = 40,
466 		.upper_margin   = 21,
467 		.lower_margin   = 7,
468 		.hsync_len      = 60,
469 		.vsync_len      = 10,
470 		.sync           = FB_SYNC_EXT,
471 		.vmode          = FB_VMODE_NONINTERLACED
472 } }, {
473 	.bus	= -1,
474 	.addr	= 0,
475 	.pixfmt	= IPU_PIX_FMT_RGB24,
476 	.detect	= detect_hdmi,
477 	.enable	= do_enable_hdmi,
478 	.mode	= {
479 		.name           = "HDMI",
480 		.refresh        = 60,
481 		.xres           = 1024,
482 		.yres           = 768,
483 		.pixclock       = 15385,
484 		.left_margin    = 220,
485 		.right_margin   = 40,
486 		.upper_margin   = 21,
487 		.lower_margin   = 7,
488 		.hsync_len      = 60,
489 		.vsync_len      = 10,
490 		.sync           = FB_SYNC_EXT,
491 		.vmode          = FB_VMODE_NONINTERLACED,
492 } } };
493 size_t display_count = ARRAY_SIZE(displays);
494 
495 iomux_v3_cfg_t const backlight_pads[] = {
496 	IOMUX_PADS(PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
497 };
498 
499 static void setup_iomux_backlight(void)
500 {
501 	gpio_direction_output(IMX_GPIO_NR(2, 9), 1);
502 	SETUP_IOMUX_PADS(backlight_pads);
503 }
504 
505 static void setup_display(void)
506 {
507 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
508 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
509 	int reg;
510 
511 	setup_iomux_backlight();
512 	enable_ipu_clock();
513 	imx_setup_hdmi();
514 
515 	/* Turn on LDB_DI0 and LDB_DI1 clocks */
516 	reg = readl(&mxc_ccm->CCGR3);
517 	reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
518 	writel(reg, &mxc_ccm->CCGR3);
519 
520 	/* Set LDB_DI0 and LDB_DI1 clk select to 3b'011 */
521 	reg = readl(&mxc_ccm->cs2cdr);
522 	reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
523 		 MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
524 	reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
525 	       (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
526 	writel(reg, &mxc_ccm->cs2cdr);
527 
528 	reg = readl(&mxc_ccm->cscmr2);
529 	reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
530 	writel(reg, &mxc_ccm->cscmr2);
531 
532 	reg = readl(&mxc_ccm->chsccdr);
533 	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
534 		<< MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
535 	reg |= (CHSCCDR_CLK_SEL_LDB_DI0 <<
536 		MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
537 	writel(reg, &mxc_ccm->chsccdr);
538 
539 	reg = IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW |
540 	      IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW |
541 	      IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG |
542 	      IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT |
543 	      IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG |
544 	      IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT |
545 	      IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0 |
546 	      IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED;
547 	writel(reg, &iomux->gpr[2]);
548 
549 	reg = readl(&iomux->gpr[3]);
550 	reg &= ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK |
551 		 IOMUXC_GPR3_HDMI_MUX_CTL_MASK);
552 	reg |= (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
553 		IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET) |
554 	       (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
555 		IOMUXC_GPR3_HDMI_MUX_CTL_OFFSET);
556 	writel(reg, &iomux->gpr[3]);
557 }
558 #endif /* CONFIG_VIDEO_IPUV3 */
559 
560 /*
561  * Do not overwrite the console
562  * Use always serial for U-Boot console
563  */
564 int overwrite_console(void)
565 {
566 	return 1;
567 }
568 
569 int board_early_init_f(void)
570 {
571 	setup_iomux_uart();
572 
573 #ifdef CONFIG_NAND_MXS
574 	setup_gpmi_nand();
575 #endif
576 
577 #ifdef CONFIG_MTD_NOR_FLASH
578 	eim_clk_setup();
579 #endif
580 	return 0;
581 }
582 
583 int board_init(void)
584 {
585 	/* address of boot parameters */
586 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
587 
588 	/* I2C 2 and 3 setup - I2C 3 hw mux with EIM */
589 	if (is_mx6dq() || is_mx6dqp())
590 		setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1);
591 	else
592 		setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1);
593 	/* I2C 3 Steer */
594 	gpio_direction_output(IMX_GPIO_NR(5, 4), 1);
595 	SETUP_IOMUX_PADS(i2c3_pads);
596 #ifndef CONFIG_SYS_FLASH_CFI
597 	if (is_mx6dq() || is_mx6dqp())
598 		setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info2);
599 	else
600 		setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info2);
601 #endif
602 	gpio_direction_output(IMX_GPIO_NR(1, 15), 1);
603 	SETUP_IOMUX_PADS(port_exp);
604 
605 #ifdef CONFIG_VIDEO_IPUV3
606 	setup_display();
607 #endif
608 
609 #ifdef CONFIG_MTD_NOR_FLASH
610 	setup_iomux_eimnor();
611 #endif
612 	return 0;
613 }
614 
615 #ifdef CONFIG_MXC_SPI
616 int board_spi_cs_gpio(unsigned bus, unsigned cs)
617 {
618 	return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
619 }
620 #endif
621 
622 int power_init_board(void)
623 {
624 	struct pmic *p;
625 	unsigned int value;
626 
627 	p = pfuze_common_init(I2C_PMIC);
628 	if (!p)
629 		return -ENODEV;
630 
631 	if (is_mx6dqp()) {
632 		/* set SW2 staby volatage 0.975V*/
633 		pmic_reg_read(p, PFUZE100_SW2STBY, &value);
634 		value &= ~0x3f;
635 		value |= 0x17;
636 		pmic_reg_write(p, PFUZE100_SW2STBY, value);
637 	}
638 
639 	return pfuze_mode_init(p, APS_PFM);
640 }
641 
642 #ifdef CONFIG_CMD_BMODE
643 static const struct boot_mode board_boot_modes[] = {
644 	/* 4 bit bus width */
645 	{"mmc0", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
646 	{NULL,   0},
647 };
648 #endif
649 
650 int board_late_init(void)
651 {
652 #ifdef CONFIG_CMD_BMODE
653 	add_board_boot_modes(board_boot_modes);
654 #endif
655 
656 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
657 	setenv("board_name", "SABREAUTO");
658 
659 	if (is_mx6dqp())
660 		setenv("board_rev", "MX6QP");
661 	else if (is_mx6dq())
662 		setenv("board_rev", "MX6Q");
663 	else if (is_mx6sdl())
664 		setenv("board_rev", "MX6DL");
665 #endif
666 
667 	return 0;
668 }
669 
670 int checkboard(void)
671 {
672 	int rev = mx6sabre_rev();
673 	char *revname;
674 
675 	switch (rev) {
676 	case BOARD_REV_B:
677 		revname = "B";
678 		break;
679 	case BOARD_REV_A:
680 	default:
681 		revname = "A";
682 		break;
683 	}
684 
685 	printf("Board: MX6Q-Sabreauto rev%s\n", revname);
686 
687 	return 0;
688 }
689 
690 #ifdef CONFIG_USB_EHCI_MX6
691 #define USB_HOST1_PWR     PORTEXP_IO_NR(0x32, 7)
692 #define USB_OTG_PWR       PORTEXP_IO_NR(0x34, 1)
693 
694 iomux_v3_cfg_t const usb_otg_pads[] = {
695 	IOMUX_PADS(PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL)),
696 };
697 
698 int board_ehci_hcd_init(int port)
699 {
700 	switch (port) {
701 	case 0:
702 		SETUP_IOMUX_PADS(usb_otg_pads);
703 
704 		/*
705 		  * Set daisy chain for otg_pin_id on 6q.
706 		 *  For 6dl, this bit is reserved.
707 		 */
708 		imx_iomux_set_gpr_register(1, 13, 1, 0);
709 		break;
710 	case 1:
711 		break;
712 	default:
713 		printf("MXC USB port %d not yet supported\n", port);
714 		return -EINVAL;
715 	}
716 	return 0;
717 }
718 
719 int board_ehci_power(int port, int on)
720 {
721 	switch (port) {
722 	case 0:
723 		if (on)
724 			port_exp_direction_output(USB_OTG_PWR, 1);
725 		else
726 			port_exp_direction_output(USB_OTG_PWR, 0);
727 		break;
728 	case 1:
729 		if (on)
730 			port_exp_direction_output(USB_HOST1_PWR, 1);
731 		else
732 			port_exp_direction_output(USB_HOST1_PWR, 0);
733 		break;
734 	default:
735 		printf("MXC USB port %d not yet supported\n", port);
736 		return -EINVAL;
737 	}
738 
739 	return 0;
740 }
741 #endif
742 
743 #ifdef CONFIG_SPL_BUILD
744 #include <asm/arch/mx6-ddr.h>
745 #include <spl.h>
746 #include <libfdt.h>
747 
748 static void ccgr_init(void)
749 {
750 	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
751 
752 	writel(0x00C03F3F, &ccm->CCGR0);
753 	writel(0x0030FC03, &ccm->CCGR1);
754 	writel(0x0FFFC000, &ccm->CCGR2);
755 	writel(0x3FF00000, &ccm->CCGR3);
756 	writel(0x00FFF300, &ccm->CCGR4);
757 	writel(0x0F0000C3, &ccm->CCGR5);
758 	writel(0x000003FF, &ccm->CCGR6);
759 }
760 
761 static void gpr_init(void)
762 {
763 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
764 
765 	/* enable AXI cache for VDOA/VPU/IPU */
766 	writel(0xF00000CF, &iomux->gpr[4]);
767 	if (is_mx6dqp()) {
768 		/* set IPU AXI-id1 Qos=0x1 AXI-id0/2/3 Qos=0x7 */
769 		writel(0x007F007F, &iomux->gpr[6]);
770 		writel(0x007F007F, &iomux->gpr[7]);
771 	} else {
772 		/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
773 		writel(0x007F007F, &iomux->gpr[6]);
774 		writel(0x007F007F, &iomux->gpr[7]);
775 	}
776 }
777 
778 static int mx6q_dcd_table[] = {
779 	0x020e0798, 0x000C0000,
780 	0x020e0758, 0x00000000,
781 	0x020e0588, 0x00000030,
782 	0x020e0594, 0x00000030,
783 	0x020e056c, 0x00000030,
784 	0x020e0578, 0x00000030,
785 	0x020e074c, 0x00000030,
786 	0x020e057c, 0x00000030,
787 	0x020e058c, 0x00000000,
788 	0x020e059c, 0x00000030,
789 	0x020e05a0, 0x00000030,
790 	0x020e078c, 0x00000030,
791 	0x020e0750, 0x00020000,
792 	0x020e05a8, 0x00000028,
793 	0x020e05b0, 0x00000028,
794 	0x020e0524, 0x00000028,
795 	0x020e051c, 0x00000028,
796 	0x020e0518, 0x00000028,
797 	0x020e050c, 0x00000028,
798 	0x020e05b8, 0x00000028,
799 	0x020e05c0, 0x00000028,
800 	0x020e0774, 0x00020000,
801 	0x020e0784, 0x00000028,
802 	0x020e0788, 0x00000028,
803 	0x020e0794, 0x00000028,
804 	0x020e079c, 0x00000028,
805 	0x020e07a0, 0x00000028,
806 	0x020e07a4, 0x00000028,
807 	0x020e07a8, 0x00000028,
808 	0x020e0748, 0x00000028,
809 	0x020e05ac, 0x00000028,
810 	0x020e05b4, 0x00000028,
811 	0x020e0528, 0x00000028,
812 	0x020e0520, 0x00000028,
813 	0x020e0514, 0x00000028,
814 	0x020e0510, 0x00000028,
815 	0x020e05bc, 0x00000028,
816 	0x020e05c4, 0x00000028,
817 	0x021b0800, 0xa1390003,
818 	0x021b080c, 0x001F001F,
819 	0x021b0810, 0x001F001F,
820 	0x021b480c, 0x001F001F,
821 	0x021b4810, 0x001F001F,
822 	0x021b083c, 0x43260335,
823 	0x021b0840, 0x031A030B,
824 	0x021b483c, 0x4323033B,
825 	0x021b4840, 0x0323026F,
826 	0x021b0848, 0x483D4545,
827 	0x021b4848, 0x44433E48,
828 	0x021b0850, 0x41444840,
829 	0x021b4850, 0x4835483E,
830 	0x021b081c, 0x33333333,
831 	0x021b0820, 0x33333333,
832 	0x021b0824, 0x33333333,
833 	0x021b0828, 0x33333333,
834 	0x021b481c, 0x33333333,
835 	0x021b4820, 0x33333333,
836 	0x021b4824, 0x33333333,
837 	0x021b4828, 0x33333333,
838 	0x021b08b8, 0x00000800,
839 	0x021b48b8, 0x00000800,
840 	0x021b0004, 0x00020036,
841 	0x021b0008, 0x09444040,
842 	0x021b000c, 0x8A8F7955,
843 	0x021b0010, 0xFF328F64,
844 	0x021b0014, 0x01FF00DB,
845 	0x021b0018, 0x00001740,
846 	0x021b001c, 0x00008000,
847 	0x021b002c, 0x000026d2,
848 	0x021b0030, 0x008F1023,
849 	0x021b0040, 0x00000047,
850 	0x021b0000, 0x841A0000,
851 	0x021b001c, 0x04088032,
852 	0x021b001c, 0x00008033,
853 	0x021b001c, 0x00048031,
854 	0x021b001c, 0x09408030,
855 	0x021b001c, 0x04008040,
856 	0x021b0020, 0x00005800,
857 	0x021b0818, 0x00011117,
858 	0x021b4818, 0x00011117,
859 	0x021b0004, 0x00025576,
860 	0x021b0404, 0x00011006,
861 	0x021b001c, 0x00000000,
862 	0x020c4068, 0x00C03F3F,
863 	0x020c406c, 0x0030FC03,
864 	0x020c4070, 0x0FFFC000,
865 	0x020c4074, 0x3FF00000,
866 	0x020c4078, 0xFFFFF300,
867 	0x020c407c, 0x0F0000F3,
868 	0x020c4080, 0x00000FFF,
869 	0x020e0010, 0xF00000CF,
870 	0x020e0018, 0x007F007F,
871 	0x020e001c, 0x007F007F,
872 };
873 
874 static int mx6qp_dcd_table[] = {
875 	0x020e0798, 0x000C0000,
876 	0x020e0758, 0x00000000,
877 	0x020e0588, 0x00000030,
878 	0x020e0594, 0x00000030,
879 	0x020e056c, 0x00000030,
880 	0x020e0578, 0x00000030,
881 	0x020e074c, 0x00000030,
882 	0x020e057c, 0x00000030,
883 	0x020e058c, 0x00000000,
884 	0x020e059c, 0x00000030,
885 	0x020e05a0, 0x00000030,
886 	0x020e078c, 0x00000030,
887 	0x020e0750, 0x00020000,
888 	0x020e05a8, 0x00000030,
889 	0x020e05b0, 0x00000030,
890 	0x020e0524, 0x00000030,
891 	0x020e051c, 0x00000030,
892 	0x020e0518, 0x00000030,
893 	0x020e050c, 0x00000030,
894 	0x020e05b8, 0x00000030,
895 	0x020e05c0, 0x00000030,
896 	0x020e0774, 0x00020000,
897 	0x020e0784, 0x00000030,
898 	0x020e0788, 0x00000030,
899 	0x020e0794, 0x00000030,
900 	0x020e079c, 0x00000030,
901 	0x020e07a0, 0x00000030,
902 	0x020e07a4, 0x00000030,
903 	0x020e07a8, 0x00000030,
904 	0x020e0748, 0x00000030,
905 	0x020e05ac, 0x00000030,
906 	0x020e05b4, 0x00000030,
907 	0x020e0528, 0x00000030,
908 	0x020e0520, 0x00000030,
909 	0x020e0514, 0x00000030,
910 	0x020e0510, 0x00000030,
911 	0x020e05bc, 0x00000030,
912 	0x020e05c4, 0x00000030,
913 	0x021b0800, 0xa1390003,
914 	0x021b080c, 0x001b001e,
915 	0x021b0810, 0x002e0029,
916 	0x021b480c, 0x001b002a,
917 	0x021b4810, 0x0019002c,
918 	0x021b083c, 0x43240334,
919 	0x021b0840, 0x0324031a,
920 	0x021b483c, 0x43340344,
921 	0x021b4840, 0x03280276,
922 	0x021b0848, 0x44383A3E,
923 	0x021b4848, 0x3C3C3846,
924 	0x021b0850, 0x2e303230,
925 	0x021b4850, 0x38283E34,
926 	0x021b081c, 0x33333333,
927 	0x021b0820, 0x33333333,
928 	0x021b0824, 0x33333333,
929 	0x021b0828, 0x33333333,
930 	0x021b481c, 0x33333333,
931 	0x021b4820, 0x33333333,
932 	0x021b4824, 0x33333333,
933 	0x021b4828, 0x33333333,
934 	0x021b08c0, 0x24912492,
935 	0x021b48c0, 0x24912492,
936 	0x021b08b8, 0x00000800,
937 	0x021b48b8, 0x00000800,
938 	0x021b0004, 0x00020036,
939 	0x021b0008, 0x09444040,
940 	0x021b000c, 0x898E7955,
941 	0x021b0010, 0xFF328F64,
942 	0x021b0014, 0x01FF00DB,
943 	0x021b0018, 0x00001740,
944 	0x021b001c, 0x00008000,
945 	0x021b002c, 0x000026d2,
946 	0x021b0030, 0x008E1023,
947 	0x021b0040, 0x00000047,
948 	0x021b0400, 0x14420000,
949 	0x021b0000, 0x841A0000,
950 	0x00bb0008, 0x00000004,
951 	0x00bb000c, 0x2891E41A,
952 	0x00bb0038, 0x00000564,
953 	0x00bb0014, 0x00000040,
954 	0x00bb0028, 0x00000020,
955 	0x00bb002c, 0x00000020,
956 	0x021b001c, 0x04088032,
957 	0x021b001c, 0x00008033,
958 	0x021b001c, 0x00048031,
959 	0x021b001c, 0x09408030,
960 	0x021b001c, 0x04008040,
961 	0x021b0020, 0x00005800,
962 	0x021b0818, 0x00011117,
963 	0x021b4818, 0x00011117,
964 	0x021b0004, 0x00025576,
965 	0x021b0404, 0x00011006,
966 	0x021b001c, 0x00000000,
967 	0x020c4068, 0x00C03F3F,
968 	0x020c406c, 0x0030FC03,
969 	0x020c4070, 0x0FFFC000,
970 	0x020c4074, 0x3FF00000,
971 	0x020c4078, 0xFFFFF300,
972 	0x020c407c, 0x0F0000F3,
973 	0x020c4080, 0x00000FFF,
974 	0x020e0010, 0xF00000CF,
975 	0x020e0018, 0x77177717,
976 	0x020e001c, 0x77177717,
977 };
978 
979 static int mx6dl_dcd_table[] = {
980 	0x020e0774, 0x000C0000,
981 	0x020e0754, 0x00000000,
982 	0x020e04ac, 0x00000030,
983 	0x020e04b0, 0x00000030,
984 	0x020e0464, 0x00000030,
985 	0x020e0490, 0x00000030,
986 	0x020e074c, 0x00000030,
987 	0x020e0494, 0x00000030,
988 	0x020e04a0, 0x00000000,
989 	0x020e04b4, 0x00000030,
990 	0x020e04b8, 0x00000030,
991 	0x020e076c, 0x00000030,
992 	0x020e0750, 0x00020000,
993 	0x020e04bc, 0x00000028,
994 	0x020e04c0, 0x00000028,
995 	0x020e04c4, 0x00000028,
996 	0x020e04c8, 0x00000028,
997 	0x020e04cc, 0x00000028,
998 	0x020e04d0, 0x00000028,
999 	0x020e04d4, 0x00000028,
1000 	0x020e04d8, 0x00000028,
1001 	0x020e0760, 0x00020000,
1002 	0x020e0764, 0x00000028,
1003 	0x020e0770, 0x00000028,
1004 	0x020e0778, 0x00000028,
1005 	0x020e077c, 0x00000028,
1006 	0x020e0780, 0x00000028,
1007 	0x020e0784, 0x00000028,
1008 	0x020e078c, 0x00000028,
1009 	0x020e0748, 0x00000028,
1010 	0x020e0470, 0x00000028,
1011 	0x020e0474, 0x00000028,
1012 	0x020e0478, 0x00000028,
1013 	0x020e047c, 0x00000028,
1014 	0x020e0480, 0x00000028,
1015 	0x020e0484, 0x00000028,
1016 	0x020e0488, 0x00000028,
1017 	0x020e048c, 0x00000028,
1018 	0x021b0800, 0xa1390003,
1019 	0x021b080c, 0x001F001F,
1020 	0x021b0810, 0x001F001F,
1021 	0x021b480c, 0x001F001F,
1022 	0x021b4810, 0x001F001F,
1023 	0x021b083c, 0x42190217,
1024 	0x021b0840, 0x017B017B,
1025 	0x021b483c, 0x4176017B,
1026 	0x021b4840, 0x015F016C,
1027 	0x021b0848, 0x4C4C4D4C,
1028 	0x021b4848, 0x4A4D4C48,
1029 	0x021b0850, 0x3F3F3F40,
1030 	0x021b4850, 0x3538382E,
1031 	0x021b081c, 0x33333333,
1032 	0x021b0820, 0x33333333,
1033 	0x021b0824, 0x33333333,
1034 	0x021b0828, 0x33333333,
1035 	0x021b481c, 0x33333333,
1036 	0x021b4820, 0x33333333,
1037 	0x021b4824, 0x33333333,
1038 	0x021b4828, 0x33333333,
1039 	0x021b08b8, 0x00000800,
1040 	0x021b48b8, 0x00000800,
1041 	0x021b0004, 0x00020025,
1042 	0x021b0008, 0x00333030,
1043 	0x021b000c, 0x676B5313,
1044 	0x021b0010, 0xB66E8B63,
1045 	0x021b0014, 0x01FF00DB,
1046 	0x021b0018, 0x00001740,
1047 	0x021b001c, 0x00008000,
1048 	0x021b002c, 0x000026d2,
1049 	0x021b0030, 0x006B1023,
1050 	0x021b0040, 0x00000047,
1051 	0x021b0000, 0x841A0000,
1052 	0x021b001c, 0x04008032,
1053 	0x021b001c, 0x00008033,
1054 	0x021b001c, 0x00048031,
1055 	0x021b001c, 0x05208030,
1056 	0x021b001c, 0x04008040,
1057 	0x021b0020, 0x00005800,
1058 	0x021b0818, 0x00011117,
1059 	0x021b4818, 0x00011117,
1060 	0x021b0004, 0x00025565,
1061 	0x021b0404, 0x00011006,
1062 	0x021b001c, 0x00000000,
1063 	0x020c4068, 0x00C03F3F,
1064 	0x020c406c, 0x0030FC03,
1065 	0x020c4070, 0x0FFFC000,
1066 	0x020c4074, 0x3FF00000,
1067 	0x020c4078, 0xFFFFF300,
1068 	0x020c407c, 0x0F0000C3,
1069 	0x020c4080, 0x00000FFF,
1070 	0x020e0010, 0xF00000CF,
1071 	0x020e0018, 0x007F007F,
1072 	0x020e001c, 0x007F007F,
1073 };
1074 
1075 static void ddr_init(int *table, int size)
1076 {
1077 	int i;
1078 
1079 	for (i = 0; i < size / 2 ; i++)
1080 		writel(table[2 * i + 1], table[2 * i]);
1081 }
1082 
1083 static void spl_dram_init(void)
1084 {
1085 	if (is_mx6dq())
1086 		ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table));
1087 	else if (is_mx6dqp())
1088 		ddr_init(mx6qp_dcd_table, ARRAY_SIZE(mx6qp_dcd_table));
1089 	else if (is_mx6sdl())
1090 		ddr_init(mx6dl_dcd_table, ARRAY_SIZE(mx6dl_dcd_table));
1091 }
1092 
1093 void board_init_f(ulong dummy)
1094 {
1095 	/* DDR initialization */
1096 	spl_dram_init();
1097 
1098 	/* setup AIPS and disable watchdog */
1099 	arch_cpu_init();
1100 
1101 	ccgr_init();
1102 	gpr_init();
1103 
1104 	/* iomux and setup of i2c */
1105 	board_early_init_f();
1106 
1107 	/* setup GP timer */
1108 	timer_init();
1109 
1110 	/* UART clocks enabled and gd valid - init serial console */
1111 	preloader_console_init();
1112 
1113 	/* Clear the BSS. */
1114 	memset(__bss_start, 0, __bss_end - __bss_start);
1115 
1116 	/* load/boot image from boot device */
1117 	board_init_r(NULL, 0);
1118 }
1119 #endif
1120