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