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