1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2012 Freescale Semiconductor, Inc.
4  *
5  * Author: Fabio Estevam <fabio.estevam@freescale.com>
6  */
7 
8 #include <common.h>
9 #include <asm/io.h>
10 #include <asm/arch/clock.h>
11 #include <asm/arch/imx-regs.h>
12 #include <asm/arch/iomux.h>
13 #include <asm/arch/mx6-pins.h>
14 #include <linux/errno.h>
15 #include <asm/gpio.h>
16 #include <asm/mach-imx/iomux-v3.h>
17 #include <asm/mach-imx/mxc_i2c.h>
18 #include <asm/mach-imx/boot_mode.h>
19 #include <asm/mach-imx/spi.h>
20 #include <mmc.h>
21 #include <fsl_esdhc.h>
22 #include <miiphy.h>
23 #include <netdev.h>
24 #include <asm/arch/sys_proto.h>
25 #include <i2c.h>
26 #include <input.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 u32 get_board_rev(void)
400 {
401 	int rev = nxp_board_rev();
402 
403 	return (get_cpu_rev() & ~(0xF << 8)) | rev;
404 }
405 
406 static int ar8031_phy_fixup(struct phy_device *phydev)
407 {
408 	unsigned short val;
409 
410 	/* To enable AR8031 ouput a 125MHz clk from CLK_25M */
411 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
412 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
413 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
414 
415 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
416 	val &= 0xffe3;
417 	val |= 0x18;
418 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
419 
420 	/* introduce tx clock delay */
421 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
422 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
423 	val |= 0x0100;
424 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
425 
426 	return 0;
427 }
428 
429 int board_phy_config(struct phy_device *phydev)
430 {
431 	ar8031_phy_fixup(phydev);
432 
433 	if (phydev->drv->config)
434 		phydev->drv->config(phydev);
435 
436 	return 0;
437 }
438 
439 #if defined(CONFIG_VIDEO_IPUV3)
440 static void disable_lvds(struct display_info_t const *dev)
441 {
442 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
443 
444 	clrbits_le32(&iomux->gpr[2],
445 		     IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
446 		     IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
447 }
448 
449 static void do_enable_hdmi(struct display_info_t const *dev)
450 {
451 	disable_lvds(dev);
452 	imx_enable_hdmi_phy();
453 }
454 
455 struct display_info_t const displays[] = {{
456 	.bus	= -1,
457 	.addr	= 0,
458 	.pixfmt	= IPU_PIX_FMT_RGB666,
459 	.detect	= NULL,
460 	.enable	= NULL,
461 	.mode	= {
462 		.name           = "Hannstar-XGA",
463 		.refresh        = 60,
464 		.xres           = 1024,
465 		.yres           = 768,
466 		.pixclock       = 15385,
467 		.left_margin    = 220,
468 		.right_margin   = 40,
469 		.upper_margin   = 21,
470 		.lower_margin   = 7,
471 		.hsync_len      = 60,
472 		.vsync_len      = 10,
473 		.sync           = FB_SYNC_EXT,
474 		.vmode          = FB_VMODE_NONINTERLACED
475 } }, {
476 	.bus	= -1,
477 	.addr	= 0,
478 	.pixfmt	= IPU_PIX_FMT_RGB24,
479 	.detect	= detect_hdmi,
480 	.enable	= do_enable_hdmi,
481 	.mode	= {
482 		.name           = "HDMI",
483 		.refresh        = 60,
484 		.xres           = 1024,
485 		.yres           = 768,
486 		.pixclock       = 15385,
487 		.left_margin    = 220,
488 		.right_margin   = 40,
489 		.upper_margin   = 21,
490 		.lower_margin   = 7,
491 		.hsync_len      = 60,
492 		.vsync_len      = 10,
493 		.sync           = FB_SYNC_EXT,
494 		.vmode          = FB_VMODE_NONINTERLACED,
495 } } };
496 size_t display_count = ARRAY_SIZE(displays);
497 
498 iomux_v3_cfg_t const backlight_pads[] = {
499 	IOMUX_PADS(PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
500 };
501 
502 static void setup_iomux_backlight(void)
503 {
504 	gpio_request(IMX_GPIO_NR(2, 9), "backlight");
505 	gpio_direction_output(IMX_GPIO_NR(2, 9), 1);
506 	SETUP_IOMUX_PADS(backlight_pads);
507 }
508 
509 static void setup_display(void)
510 {
511 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
512 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
513 	int reg;
514 
515 	setup_iomux_backlight();
516 	enable_ipu_clock();
517 	imx_setup_hdmi();
518 
519 	/* Turn on LDB_DI0 and LDB_DI1 clocks */
520 	reg = readl(&mxc_ccm->CCGR3);
521 	reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
522 	writel(reg, &mxc_ccm->CCGR3);
523 
524 	/* Set LDB_DI0 and LDB_DI1 clk select to 3b'011 */
525 	reg = readl(&mxc_ccm->cs2cdr);
526 	reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
527 		 MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
528 	reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
529 	       (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
530 	writel(reg, &mxc_ccm->cs2cdr);
531 
532 	reg = readl(&mxc_ccm->cscmr2);
533 	reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
534 	writel(reg, &mxc_ccm->cscmr2);
535 
536 	reg = readl(&mxc_ccm->chsccdr);
537 	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
538 		<< MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
539 	reg |= (CHSCCDR_CLK_SEL_LDB_DI0 <<
540 		MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
541 	writel(reg, &mxc_ccm->chsccdr);
542 
543 	reg = IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW |
544 	      IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW |
545 	      IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG |
546 	      IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT |
547 	      IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG |
548 	      IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT |
549 	      IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0 |
550 	      IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED;
551 	writel(reg, &iomux->gpr[2]);
552 
553 	reg = readl(&iomux->gpr[3]);
554 	reg &= ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK |
555 		 IOMUXC_GPR3_HDMI_MUX_CTL_MASK);
556 	reg |= (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
557 		IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET) |
558 	       (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
559 		IOMUXC_GPR3_HDMI_MUX_CTL_OFFSET);
560 	writel(reg, &iomux->gpr[3]);
561 }
562 #endif /* CONFIG_VIDEO_IPUV3 */
563 
564 /*
565  * Do not overwrite the console
566  * Use always serial for U-Boot console
567  */
568 int overwrite_console(void)
569 {
570 	return 1;
571 }
572 
573 int board_early_init_f(void)
574 {
575 	setup_iomux_uart();
576 
577 #ifdef CONFIG_NAND_MXS
578 	setup_gpmi_nand();
579 #endif
580 
581 #ifdef CONFIG_MTD_NOR_FLASH
582 	eim_clk_setup();
583 #endif
584 	return 0;
585 }
586 
587 int board_init(void)
588 {
589 	/* address of boot parameters */
590 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
591 
592 	/* I2C 2 and 3 setup - I2C 3 hw mux with EIM */
593 	if (is_mx6dq() || is_mx6dqp())
594 		setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1);
595 	else
596 		setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1);
597 	/* I2C 3 Steer */
598 	gpio_request(IMX_GPIO_NR(5, 4), "steer logic");
599 	gpio_direction_output(IMX_GPIO_NR(5, 4), 1);
600 	SETUP_IOMUX_PADS(i2c3_pads);
601 #ifndef CONFIG_SYS_FLASH_CFI
602 	if (is_mx6dq() || is_mx6dqp())
603 		setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info2);
604 	else
605 		setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info2);
606 #endif
607 	gpio_request(IMX_GPIO_NR(1, 15), "expander en");
608 	gpio_direction_output(IMX_GPIO_NR(1, 15), 1);
609 	SETUP_IOMUX_PADS(port_exp);
610 
611 #ifdef CONFIG_VIDEO_IPUV3
612 	setup_display();
613 #endif
614 
615 #ifdef CONFIG_MTD_NOR_FLASH
616 	setup_iomux_eimnor();
617 #endif
618 	return 0;
619 }
620 
621 #ifdef CONFIG_MXC_SPI
622 int board_spi_cs_gpio(unsigned bus, unsigned cs)
623 {
624 	return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
625 }
626 #endif
627 
628 int power_init_board(void)
629 {
630 	struct pmic *p;
631 	unsigned int value;
632 
633 	p = pfuze_common_init(I2C_PMIC);
634 	if (!p)
635 		return -ENODEV;
636 
637 	if (is_mx6dqp()) {
638 		/* set SW2 staby volatage 0.975V*/
639 		pmic_reg_read(p, PFUZE100_SW2STBY, &value);
640 		value &= ~0x3f;
641 		value |= 0x17;
642 		pmic_reg_write(p, PFUZE100_SW2STBY, value);
643 	}
644 
645 	return pfuze_mode_init(p, APS_PFM);
646 }
647 
648 #ifdef CONFIG_CMD_BMODE
649 static const struct boot_mode board_boot_modes[] = {
650 	/* 4 bit bus width */
651 	{"mmc0", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
652 	{NULL,   0},
653 };
654 #endif
655 
656 int board_late_init(void)
657 {
658 #ifdef CONFIG_CMD_BMODE
659 	add_board_boot_modes(board_boot_modes);
660 #endif
661 
662 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
663 	env_set("board_name", "SABREAUTO");
664 
665 	if (is_mx6dqp())
666 		env_set("board_rev", "MX6QP");
667 	else if (is_mx6dq())
668 		env_set("board_rev", "MX6Q");
669 	else if (is_mx6sdl())
670 		env_set("board_rev", "MX6DL");
671 #endif
672 
673 	return 0;
674 }
675 
676 int checkboard(void)
677 {
678 	printf("Board: MX6Q-Sabreauto rev%c\n", nxp_board_rev_string());
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 <linux/libfdt.h>
740 
741 #ifdef CONFIG_SPL_OS_BOOT
742 int spl_start_uboot(void)
743 {
744 	return 0;
745 }
746 #endif
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 int mx6q_dcd_table[] = {
762 	0x020e0798, 0x000C0000,
763 	0x020e0758, 0x00000000,
764 	0x020e0588, 0x00000030,
765 	0x020e0594, 0x00000030,
766 	0x020e056c, 0x00000030,
767 	0x020e0578, 0x00000030,
768 	0x020e074c, 0x00000030,
769 	0x020e057c, 0x00000030,
770 	0x020e058c, 0x00000000,
771 	0x020e059c, 0x00000030,
772 	0x020e05a0, 0x00000030,
773 	0x020e078c, 0x00000030,
774 	0x020e0750, 0x00020000,
775 	0x020e05a8, 0x00000028,
776 	0x020e05b0, 0x00000028,
777 	0x020e0524, 0x00000028,
778 	0x020e051c, 0x00000028,
779 	0x020e0518, 0x00000028,
780 	0x020e050c, 0x00000028,
781 	0x020e05b8, 0x00000028,
782 	0x020e05c0, 0x00000028,
783 	0x020e0774, 0x00020000,
784 	0x020e0784, 0x00000028,
785 	0x020e0788, 0x00000028,
786 	0x020e0794, 0x00000028,
787 	0x020e079c, 0x00000028,
788 	0x020e07a0, 0x00000028,
789 	0x020e07a4, 0x00000028,
790 	0x020e07a8, 0x00000028,
791 	0x020e0748, 0x00000028,
792 	0x020e05ac, 0x00000028,
793 	0x020e05b4, 0x00000028,
794 	0x020e0528, 0x00000028,
795 	0x020e0520, 0x00000028,
796 	0x020e0514, 0x00000028,
797 	0x020e0510, 0x00000028,
798 	0x020e05bc, 0x00000028,
799 	0x020e05c4, 0x00000028,
800 	0x021b0800, 0xa1390003,
801 	0x021b080c, 0x001F001F,
802 	0x021b0810, 0x001F001F,
803 	0x021b480c, 0x001F001F,
804 	0x021b4810, 0x001F001F,
805 	0x021b083c, 0x43260335,
806 	0x021b0840, 0x031A030B,
807 	0x021b483c, 0x4323033B,
808 	0x021b4840, 0x0323026F,
809 	0x021b0848, 0x483D4545,
810 	0x021b4848, 0x44433E48,
811 	0x021b0850, 0x41444840,
812 	0x021b4850, 0x4835483E,
813 	0x021b081c, 0x33333333,
814 	0x021b0820, 0x33333333,
815 	0x021b0824, 0x33333333,
816 	0x021b0828, 0x33333333,
817 	0x021b481c, 0x33333333,
818 	0x021b4820, 0x33333333,
819 	0x021b4824, 0x33333333,
820 	0x021b4828, 0x33333333,
821 	0x021b08b8, 0x00000800,
822 	0x021b48b8, 0x00000800,
823 	0x021b0004, 0x00020036,
824 	0x021b0008, 0x09444040,
825 	0x021b000c, 0x8A8F7955,
826 	0x021b0010, 0xFF328F64,
827 	0x021b0014, 0x01FF00DB,
828 	0x021b0018, 0x00001740,
829 	0x021b001c, 0x00008000,
830 	0x021b002c, 0x000026d2,
831 	0x021b0030, 0x008F1023,
832 	0x021b0040, 0x00000047,
833 	0x021b0000, 0x841A0000,
834 	0x021b001c, 0x04088032,
835 	0x021b001c, 0x00008033,
836 	0x021b001c, 0x00048031,
837 	0x021b001c, 0x09408030,
838 	0x021b001c, 0x04008040,
839 	0x021b0020, 0x00005800,
840 	0x021b0818, 0x00011117,
841 	0x021b4818, 0x00011117,
842 	0x021b0004, 0x00025576,
843 	0x021b0404, 0x00011006,
844 	0x021b001c, 0x00000000,
845 	0x020c4068, 0x00C03F3F,
846 	0x020c406c, 0x0030FC03,
847 	0x020c4070, 0x0FFFC000,
848 	0x020c4074, 0x3FF00000,
849 	0x020c4078, 0xFFFFF300,
850 	0x020c407c, 0x0F0000F3,
851 	0x020c4080, 0x00000FFF,
852 	0x020e0010, 0xF00000CF,
853 	0x020e0018, 0x007F007F,
854 	0x020e001c, 0x007F007F,
855 };
856 
857 static int mx6qp_dcd_table[] = {
858 	0x020e0798, 0x000C0000,
859 	0x020e0758, 0x00000000,
860 	0x020e0588, 0x00000030,
861 	0x020e0594, 0x00000030,
862 	0x020e056c, 0x00000030,
863 	0x020e0578, 0x00000030,
864 	0x020e074c, 0x00000030,
865 	0x020e057c, 0x00000030,
866 	0x020e058c, 0x00000000,
867 	0x020e059c, 0x00000030,
868 	0x020e05a0, 0x00000030,
869 	0x020e078c, 0x00000030,
870 	0x020e0750, 0x00020000,
871 	0x020e05a8, 0x00000030,
872 	0x020e05b0, 0x00000030,
873 	0x020e0524, 0x00000030,
874 	0x020e051c, 0x00000030,
875 	0x020e0518, 0x00000030,
876 	0x020e050c, 0x00000030,
877 	0x020e05b8, 0x00000030,
878 	0x020e05c0, 0x00000030,
879 	0x020e0774, 0x00020000,
880 	0x020e0784, 0x00000030,
881 	0x020e0788, 0x00000030,
882 	0x020e0794, 0x00000030,
883 	0x020e079c, 0x00000030,
884 	0x020e07a0, 0x00000030,
885 	0x020e07a4, 0x00000030,
886 	0x020e07a8, 0x00000030,
887 	0x020e0748, 0x00000030,
888 	0x020e05ac, 0x00000030,
889 	0x020e05b4, 0x00000030,
890 	0x020e0528, 0x00000030,
891 	0x020e0520, 0x00000030,
892 	0x020e0514, 0x00000030,
893 	0x020e0510, 0x00000030,
894 	0x020e05bc, 0x00000030,
895 	0x020e05c4, 0x00000030,
896 	0x021b0800, 0xa1390003,
897 	0x021b080c, 0x001b001e,
898 	0x021b0810, 0x002e0029,
899 	0x021b480c, 0x001b002a,
900 	0x021b4810, 0x0019002c,
901 	0x021b083c, 0x43240334,
902 	0x021b0840, 0x0324031a,
903 	0x021b483c, 0x43340344,
904 	0x021b4840, 0x03280276,
905 	0x021b0848, 0x44383A3E,
906 	0x021b4848, 0x3C3C3846,
907 	0x021b0850, 0x2e303230,
908 	0x021b4850, 0x38283E34,
909 	0x021b081c, 0x33333333,
910 	0x021b0820, 0x33333333,
911 	0x021b0824, 0x33333333,
912 	0x021b0828, 0x33333333,
913 	0x021b481c, 0x33333333,
914 	0x021b4820, 0x33333333,
915 	0x021b4824, 0x33333333,
916 	0x021b4828, 0x33333333,
917 	0x021b08c0, 0x24912492,
918 	0x021b48c0, 0x24912492,
919 	0x021b08b8, 0x00000800,
920 	0x021b48b8, 0x00000800,
921 	0x021b0004, 0x00020036,
922 	0x021b0008, 0x09444040,
923 	0x021b000c, 0x898E7955,
924 	0x021b0010, 0xFF328F64,
925 	0x021b0014, 0x01FF00DB,
926 	0x021b0018, 0x00001740,
927 	0x021b001c, 0x00008000,
928 	0x021b002c, 0x000026d2,
929 	0x021b0030, 0x008E1023,
930 	0x021b0040, 0x00000047,
931 	0x021b0400, 0x14420000,
932 	0x021b0000, 0x841A0000,
933 	0x00bb0008, 0x00000004,
934 	0x00bb000c, 0x2891E41A,
935 	0x00bb0038, 0x00000564,
936 	0x00bb0014, 0x00000040,
937 	0x00bb0028, 0x00000020,
938 	0x00bb002c, 0x00000020,
939 	0x021b001c, 0x04088032,
940 	0x021b001c, 0x00008033,
941 	0x021b001c, 0x00048031,
942 	0x021b001c, 0x09408030,
943 	0x021b001c, 0x04008040,
944 	0x021b0020, 0x00005800,
945 	0x021b0818, 0x00011117,
946 	0x021b4818, 0x00011117,
947 	0x021b0004, 0x00025576,
948 	0x021b0404, 0x00011006,
949 	0x021b001c, 0x00000000,
950 	0x020c4068, 0x00C03F3F,
951 	0x020c406c, 0x0030FC03,
952 	0x020c4070, 0x0FFFC000,
953 	0x020c4074, 0x3FF00000,
954 	0x020c4078, 0xFFFFF300,
955 	0x020c407c, 0x0F0000F3,
956 	0x020c4080, 0x00000FFF,
957 	0x020e0010, 0xF00000CF,
958 	0x020e0018, 0x77177717,
959 	0x020e001c, 0x77177717,
960 };
961 
962 static int mx6dl_dcd_table[] = {
963 	0x020e0774, 0x000C0000,
964 	0x020e0754, 0x00000000,
965 	0x020e04ac, 0x00000030,
966 	0x020e04b0, 0x00000030,
967 	0x020e0464, 0x00000030,
968 	0x020e0490, 0x00000030,
969 	0x020e074c, 0x00000030,
970 	0x020e0494, 0x00000030,
971 	0x020e04a0, 0x00000000,
972 	0x020e04b4, 0x00000030,
973 	0x020e04b8, 0x00000030,
974 	0x020e076c, 0x00000030,
975 	0x020e0750, 0x00020000,
976 	0x020e04bc, 0x00000028,
977 	0x020e04c0, 0x00000028,
978 	0x020e04c4, 0x00000028,
979 	0x020e04c8, 0x00000028,
980 	0x020e04cc, 0x00000028,
981 	0x020e04d0, 0x00000028,
982 	0x020e04d4, 0x00000028,
983 	0x020e04d8, 0x00000028,
984 	0x020e0760, 0x00020000,
985 	0x020e0764, 0x00000028,
986 	0x020e0770, 0x00000028,
987 	0x020e0778, 0x00000028,
988 	0x020e077c, 0x00000028,
989 	0x020e0780, 0x00000028,
990 	0x020e0784, 0x00000028,
991 	0x020e078c, 0x00000028,
992 	0x020e0748, 0x00000028,
993 	0x020e0470, 0x00000028,
994 	0x020e0474, 0x00000028,
995 	0x020e0478, 0x00000028,
996 	0x020e047c, 0x00000028,
997 	0x020e0480, 0x00000028,
998 	0x020e0484, 0x00000028,
999 	0x020e0488, 0x00000028,
1000 	0x020e048c, 0x00000028,
1001 	0x021b0800, 0xa1390003,
1002 	0x021b080c, 0x001F001F,
1003 	0x021b0810, 0x001F001F,
1004 	0x021b480c, 0x001F001F,
1005 	0x021b4810, 0x001F001F,
1006 	0x021b083c, 0x42190217,
1007 	0x021b0840, 0x017B017B,
1008 	0x021b483c, 0x4176017B,
1009 	0x021b4840, 0x015F016C,
1010 	0x021b0848, 0x4C4C4D4C,
1011 	0x021b4848, 0x4A4D4C48,
1012 	0x021b0850, 0x3F3F3F40,
1013 	0x021b4850, 0x3538382E,
1014 	0x021b081c, 0x33333333,
1015 	0x021b0820, 0x33333333,
1016 	0x021b0824, 0x33333333,
1017 	0x021b0828, 0x33333333,
1018 	0x021b481c, 0x33333333,
1019 	0x021b4820, 0x33333333,
1020 	0x021b4824, 0x33333333,
1021 	0x021b4828, 0x33333333,
1022 	0x021b08b8, 0x00000800,
1023 	0x021b48b8, 0x00000800,
1024 	0x021b0004, 0x00020025,
1025 	0x021b0008, 0x00333030,
1026 	0x021b000c, 0x676B5313,
1027 	0x021b0010, 0xB66E8B63,
1028 	0x021b0014, 0x01FF00DB,
1029 	0x021b0018, 0x00001740,
1030 	0x021b001c, 0x00008000,
1031 	0x021b002c, 0x000026d2,
1032 	0x021b0030, 0x006B1023,
1033 	0x021b0040, 0x00000047,
1034 	0x021b0000, 0x841A0000,
1035 	0x021b001c, 0x04008032,
1036 	0x021b001c, 0x00008033,
1037 	0x021b001c, 0x00048031,
1038 	0x021b001c, 0x05208030,
1039 	0x021b001c, 0x04008040,
1040 	0x021b0020, 0x00005800,
1041 	0x021b0818, 0x00011117,
1042 	0x021b4818, 0x00011117,
1043 	0x021b0004, 0x00025565,
1044 	0x021b0404, 0x00011006,
1045 	0x021b001c, 0x00000000,
1046 	0x020c4068, 0x00C03F3F,
1047 	0x020c406c, 0x0030FC03,
1048 	0x020c4070, 0x0FFFC000,
1049 	0x020c4074, 0x3FF00000,
1050 	0x020c4078, 0xFFFFF300,
1051 	0x020c407c, 0x0F0000C3,
1052 	0x020c4080, 0x00000FFF,
1053 	0x020e0010, 0xF00000CF,
1054 	0x020e0018, 0x007F007F,
1055 	0x020e001c, 0x007F007F,
1056 };
1057 
1058 static void ddr_init(int *table, int size)
1059 {
1060 	int i;
1061 
1062 	for (i = 0; i < size / 2 ; i++)
1063 		writel(table[2 * i + 1], table[2 * i]);
1064 }
1065 
1066 static void spl_dram_init(void)
1067 {
1068 	if (is_mx6dq())
1069 		ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table));
1070 	else if (is_mx6dqp())
1071 		ddr_init(mx6qp_dcd_table, ARRAY_SIZE(mx6qp_dcd_table));
1072 	else if (is_mx6sdl())
1073 		ddr_init(mx6dl_dcd_table, ARRAY_SIZE(mx6dl_dcd_table));
1074 }
1075 
1076 void board_init_f(ulong dummy)
1077 {
1078 	/* DDR initialization */
1079 	spl_dram_init();
1080 
1081 	/* setup AIPS and disable watchdog */
1082 	arch_cpu_init();
1083 
1084 	ccgr_init();
1085 	gpr_init();
1086 
1087 	/* iomux and setup of i2c */
1088 	board_early_init_f();
1089 
1090 	/* setup GP timer */
1091 	timer_init();
1092 
1093 	/* UART clocks enabled and gd valid - init serial console */
1094 	preloader_console_init();
1095 
1096 	/* Clear the BSS. */
1097 	memset(__bss_start, 0, __bss_end - __bss_start);
1098 
1099 	/* load/boot image from boot device */
1100 	board_init_r(NULL, 0);
1101 }
1102 #endif
1103 
1104 #ifdef CONFIG_SPL_LOAD_FIT
1105 int board_fit_config_name_match(const char *name)
1106 {
1107 	if (is_mx6dq()) {
1108 		if (!strcmp(name, "imx6q-sabreauto"))
1109 			return 0;
1110 	} else if (is_mx6dqp()) {
1111 		if (!strcmp(name, "imx6qp-sabreauto"))
1112 			return 0;
1113 	} else if (is_mx6dl()) {
1114 		if (!strcmp(name, "imx6dl-sabreauto"))
1115 			return 0;
1116 	}
1117 
1118 	return -1;
1119 }
1120 #endif
1121