Merge tag 'u-boot-amlogic-20220809' of https://source.denx.de/u-boot/custodians/u...
[platform/kernel/u-boot.git] / board / freescale / mx6sabresd / mx6sabresd.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 <image.h>
9 #include <init.h>
10 #include <net.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 <asm/global_data.h>
16 #include <asm/mach-imx/spi.h>
17 #include <env.h>
18 #include <linux/errno.h>
19 #include <asm/gpio.h>
20 #include <asm/mach-imx/mxc_i2c.h>
21 #include <asm/mach-imx/iomux-v3.h>
22 #include <asm/mach-imx/boot_mode.h>
23 #include <asm/mach-imx/video.h>
24 #include <mmc.h>
25 #include <fsl_esdhc_imx.h>
26 #include <miiphy.h>
27 #include <asm/arch/mxc_hdmi.h>
28 #include <asm/arch/crm_regs.h>
29 #include <asm/io.h>
30 #include <asm/arch/sys_proto.h>
31 #include <i2c.h>
32 #include <input.h>
33 #include <power/pmic.h>
34 #include <power/pfuze100_pmic.h>
35 #include "../common/pfuze.h"
36 #include <usb.h>
37 #include <usb/ehci-ci.h>
38
39 DECLARE_GLOBAL_DATA_PTR;
40
41 #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                   \
42         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |                 \
43         PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
44
45 #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |                    \
46         PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |                 \
47         PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
48
49 #define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
50                       PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
51
52 #define I2C_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                    \
53         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |   \
54         PAD_CTL_ODE | PAD_CTL_SRE_FAST)
55
56 #define I2C_PMIC        1
57
58 #define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL)
59
60 #define DISP0_PWR_EN    IMX_GPIO_NR(1, 21)
61
62 #define KEY_VOL_UP      IMX_GPIO_NR(1, 4)
63
64 int dram_init(void)
65 {
66         gd->ram_size = imx_ddr_size();
67         return 0;
68 }
69
70 static iomux_v3_cfg_t const uart1_pads[] = {
71         IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
72         IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
73 };
74
75 static iomux_v3_cfg_t const usdhc2_pads[] = {
76         IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
77         IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
78         IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
79         IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
80         IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
81         IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
82         IOMUX_PADS(PAD_NANDF_D4__SD2_DATA4      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
83         IOMUX_PADS(PAD_NANDF_D5__SD2_DATA5      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
84         IOMUX_PADS(PAD_NANDF_D6__SD2_DATA6      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
85         IOMUX_PADS(PAD_NANDF_D7__SD2_DATA7      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
86         IOMUX_PADS(PAD_NANDF_D2__GPIO2_IO02     | MUX_PAD_CTRL(NO_PAD_CTRL)), /* CD */
87 };
88
89 static iomux_v3_cfg_t const usdhc3_pads[] = {
90         IOMUX_PADS(PAD_SD3_CLK__SD3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
91         IOMUX_PADS(PAD_SD3_CMD__SD3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
92         IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
93         IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
94         IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
95         IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
96         IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
97         IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
98         IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
99         IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
100         IOMUX_PADS(PAD_NANDF_D0__GPIO2_IO00    | MUX_PAD_CTRL(NO_PAD_CTRL)), /* CD */
101 };
102
103 static iomux_v3_cfg_t const usdhc4_pads[] = {
104         IOMUX_PADS(PAD_SD4_CLK__SD4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
105         IOMUX_PADS(PAD_SD4_CMD__SD4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
106         IOMUX_PADS(PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
107         IOMUX_PADS(PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
108         IOMUX_PADS(PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
109         IOMUX_PADS(PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
110         IOMUX_PADS(PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
111         IOMUX_PADS(PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
112         IOMUX_PADS(PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
113         IOMUX_PADS(PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
114 };
115
116 static iomux_v3_cfg_t const ecspi1_pads[] = {
117         IOMUX_PADS(PAD_KEY_COL0__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL)),
118         IOMUX_PADS(PAD_KEY_COL1__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL)),
119         IOMUX_PADS(PAD_KEY_ROW0__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL)),
120         IOMUX_PADS(PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL)),
121 };
122
123 static iomux_v3_cfg_t const rgb_pads[] = {
124         IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)),
125         IOMUX_PADS(PAD_DI0_PIN15__IPU1_DI0_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
126         IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
127         IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03 | MUX_PAD_CTRL(NO_PAD_CTRL)),
128         IOMUX_PADS(PAD_DI0_PIN4__IPU1_DI0_PIN04 | MUX_PAD_CTRL(NO_PAD_CTRL)),
129         IOMUX_PADS(PAD_DISP0_DAT0__IPU1_DISP0_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL)),
130         IOMUX_PADS(PAD_DISP0_DAT1__IPU1_DISP0_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL)),
131         IOMUX_PADS(PAD_DISP0_DAT2__IPU1_DISP0_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
132         IOMUX_PADS(PAD_DISP0_DAT3__IPU1_DISP0_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL)),
133         IOMUX_PADS(PAD_DISP0_DAT4__IPU1_DISP0_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL)),
134         IOMUX_PADS(PAD_DISP0_DAT5__IPU1_DISP0_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL)),
135         IOMUX_PADS(PAD_DISP0_DAT6__IPU1_DISP0_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
136         IOMUX_PADS(PAD_DISP0_DAT7__IPU1_DISP0_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
137         IOMUX_PADS(PAD_DISP0_DAT8__IPU1_DISP0_DATA08 | MUX_PAD_CTRL(NO_PAD_CTRL)),
138         IOMUX_PADS(PAD_DISP0_DAT9__IPU1_DISP0_DATA09 | MUX_PAD_CTRL(NO_PAD_CTRL)),
139         IOMUX_PADS(PAD_DISP0_DAT10__IPU1_DISP0_DATA10 | MUX_PAD_CTRL(NO_PAD_CTRL)),
140         IOMUX_PADS(PAD_DISP0_DAT11__IPU1_DISP0_DATA11 | MUX_PAD_CTRL(NO_PAD_CTRL)),
141         IOMUX_PADS(PAD_DISP0_DAT12__IPU1_DISP0_DATA12 | MUX_PAD_CTRL(NO_PAD_CTRL)),
142         IOMUX_PADS(PAD_DISP0_DAT13__IPU1_DISP0_DATA13 | MUX_PAD_CTRL(NO_PAD_CTRL)),
143         IOMUX_PADS(PAD_DISP0_DAT14__IPU1_DISP0_DATA14 | MUX_PAD_CTRL(NO_PAD_CTRL)),
144         IOMUX_PADS(PAD_DISP0_DAT15__IPU1_DISP0_DATA15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
145         IOMUX_PADS(PAD_DISP0_DAT16__IPU1_DISP0_DATA16 | MUX_PAD_CTRL(NO_PAD_CTRL)),
146         IOMUX_PADS(PAD_DISP0_DAT17__IPU1_DISP0_DATA17 | MUX_PAD_CTRL(NO_PAD_CTRL)),
147         IOMUX_PADS(PAD_DISP0_DAT18__IPU1_DISP0_DATA18 | MUX_PAD_CTRL(NO_PAD_CTRL)),
148         IOMUX_PADS(PAD_DISP0_DAT19__IPU1_DISP0_DATA19 | MUX_PAD_CTRL(NO_PAD_CTRL)),
149         IOMUX_PADS(PAD_DISP0_DAT20__IPU1_DISP0_DATA20 | MUX_PAD_CTRL(NO_PAD_CTRL)),
150         IOMUX_PADS(PAD_DISP0_DAT21__IPU1_DISP0_DATA21 | MUX_PAD_CTRL(NO_PAD_CTRL)),
151         IOMUX_PADS(PAD_DISP0_DAT22__IPU1_DISP0_DATA22 | MUX_PAD_CTRL(NO_PAD_CTRL)),
152         IOMUX_PADS(PAD_DISP0_DAT23__IPU1_DISP0_DATA23 | MUX_PAD_CTRL(NO_PAD_CTRL)),
153 };
154
155 static iomux_v3_cfg_t const bl_pads[] = {
156         IOMUX_PADS(PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL)),
157 };
158
159 static void enable_backlight(void)
160 {
161         SETUP_IOMUX_PADS(bl_pads);
162         gpio_request(DISP0_PWR_EN, "Display Power Enable");
163         gpio_direction_output(DISP0_PWR_EN, 1);
164 }
165
166 static void enable_rgb(struct display_info_t const *dev)
167 {
168         SETUP_IOMUX_PADS(rgb_pads);
169         enable_backlight();
170 }
171
172 static void enable_lvds(struct display_info_t const *dev)
173 {
174         enable_backlight();
175 }
176
177 static struct i2c_pads_info mx6q_i2c_pad_info1 = {
178         .scl = {
179                 .i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL | I2C_PAD,
180                 .gpio_mode = MX6Q_PAD_KEY_COL3__GPIO4_IO12 | I2C_PAD,
181                 .gp = IMX_GPIO_NR(4, 12)
182         },
183         .sda = {
184                 .i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | I2C_PAD,
185                 .gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 | I2C_PAD,
186                 .gp = IMX_GPIO_NR(4, 13)
187         }
188 };
189
190 static struct i2c_pads_info mx6dl_i2c_pad_info1 = {
191         .scl = {
192                 .i2c_mode = MX6DL_PAD_KEY_COL3__I2C2_SCL | I2C_PAD,
193                 .gpio_mode = MX6DL_PAD_KEY_COL3__GPIO4_IO12 | I2C_PAD,
194                 .gp = IMX_GPIO_NR(4, 12)
195         },
196         .sda = {
197                 .i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA | I2C_PAD,
198                 .gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13 | I2C_PAD,
199                 .gp = IMX_GPIO_NR(4, 13)
200         }
201 };
202
203 static void setup_spi(void)
204 {
205         SETUP_IOMUX_PADS(ecspi1_pads);
206 }
207
208 iomux_v3_cfg_t const di0_pads[] = {
209         IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK),        /* DISP0_CLK */
210         IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02),               /* DISP0_HSYNC */
211         IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03),               /* DISP0_VSYNC */
212 };
213
214 static void setup_iomux_uart(void)
215 {
216         SETUP_IOMUX_PADS(uart1_pads);
217 }
218
219 #ifdef CONFIG_FSL_ESDHC_IMX
220 struct fsl_esdhc_cfg usdhc_cfg[3] = {
221         {USDHC2_BASE_ADDR},
222         {USDHC3_BASE_ADDR},
223         {USDHC4_BASE_ADDR},
224 };
225
226 #define USDHC2_CD_GPIO  IMX_GPIO_NR(2, 2)
227 #define USDHC3_CD_GPIO  IMX_GPIO_NR(2, 0)
228
229 int board_mmc_get_env_dev(int devno)
230 {
231         return devno - 1;
232 }
233
234 int board_mmc_getcd(struct mmc *mmc)
235 {
236         struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
237         int ret = 0;
238
239         switch (cfg->esdhc_base) {
240         case USDHC2_BASE_ADDR:
241                 ret = !gpio_get_value(USDHC2_CD_GPIO);
242                 break;
243         case USDHC3_BASE_ADDR:
244                 ret = !gpio_get_value(USDHC3_CD_GPIO);
245                 break;
246         case USDHC4_BASE_ADDR:
247                 ret = 1; /* eMMC/uSDHC4 is always present */
248                 break;
249         }
250
251         return ret;
252 }
253
254 int board_mmc_init(struct bd_info *bis)
255 {
256         struct src *psrc = (struct src *)SRC_BASE_ADDR;
257         unsigned reg = readl(&psrc->sbmr1) >> 11;
258         /*
259          * Upon reading BOOT_CFG register the following map is done:
260          * Bit 11 and 12 of BOOT_CFG register can determine the current
261          * mmc port
262          * 0x1                  SD1
263          * 0x2                  SD2
264          * 0x3                  SD4
265          */
266
267         switch (reg & 0x3) {
268         case 0x1:
269                 SETUP_IOMUX_PADS(usdhc2_pads);
270                 usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
271                 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
272                 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
273                 break;
274         case 0x2:
275                 SETUP_IOMUX_PADS(usdhc3_pads);
276                 usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
277                 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
278                 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
279                 break;
280         case 0x3:
281                 SETUP_IOMUX_PADS(usdhc4_pads);
282                 usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
283                 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
284                 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
285                 break;
286         }
287
288         return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
289 }
290 #endif
291
292 static int ar8031_phy_fixup(struct phy_device *phydev)
293 {
294         unsigned short val;
295
296         /* To enable AR8031 ouput a 125MHz clk from CLK_25M */
297         phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
298         phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
299         phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
300
301         val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
302         val &= 0xffe3;
303         val |= 0x18;
304         phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
305
306         /* introduce tx clock delay */
307         phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
308         val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
309         val |= 0x0100;
310         phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
311
312         return 0;
313 }
314
315 int board_phy_config(struct phy_device *phydev)
316 {
317         ar8031_phy_fixup(phydev);
318
319         if (phydev->drv->config)
320                 phydev->drv->config(phydev);
321
322         return 0;
323 }
324
325 #if defined(CONFIG_VIDEO_IPUV3)
326 static void disable_lvds(struct display_info_t const *dev)
327 {
328         struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
329
330         int reg = readl(&iomux->gpr[2]);
331
332         reg &= ~(IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
333                  IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
334
335         writel(reg, &iomux->gpr[2]);
336 }
337
338 static void do_enable_hdmi(struct display_info_t const *dev)
339 {
340         disable_lvds(dev);
341         imx_enable_hdmi_phy();
342 }
343
344 struct display_info_t const displays[] = {{
345         .bus    = -1,
346         .addr   = 0,
347         .pixfmt = IPU_PIX_FMT_RGB666,
348         .detect = NULL,
349         .enable = enable_lvds,
350         .mode   = {
351                 .name           = "Hannstar-XGA",
352                 .refresh        = 60,
353                 .xres           = 1024,
354                 .yres           = 768,
355                 .pixclock       = 15384,
356                 .left_margin    = 160,
357                 .right_margin   = 24,
358                 .upper_margin   = 29,
359                 .lower_margin   = 3,
360                 .hsync_len      = 136,
361                 .vsync_len      = 6,
362                 .sync           = FB_SYNC_EXT,
363                 .vmode          = FB_VMODE_NONINTERLACED
364 } }, {
365         .bus    = -1,
366         .addr   = 0,
367         .pixfmt = IPU_PIX_FMT_RGB24,
368         .detect = detect_hdmi,
369         .enable = do_enable_hdmi,
370         .mode   = {
371                 .name           = "HDMI",
372                 .refresh        = 60,
373                 .xres           = 1024,
374                 .yres           = 768,
375                 .pixclock       = 15384,
376                 .left_margin    = 160,
377                 .right_margin   = 24,
378                 .upper_margin   = 29,
379                 .lower_margin   = 3,
380                 .hsync_len      = 136,
381                 .vsync_len      = 6,
382                 .sync           = FB_SYNC_EXT,
383                 .vmode          = FB_VMODE_NONINTERLACED
384 } }, {
385         .bus    = 0,
386         .addr   = 0,
387         .pixfmt = IPU_PIX_FMT_RGB24,
388         .detect = NULL,
389         .enable = enable_rgb,
390         .mode   = {
391                 .name           = "SEIKO-WVGA",
392                 .refresh        = 60,
393                 .xres           = 800,
394                 .yres           = 480,
395                 .pixclock       = 29850,
396                 .left_margin    = 89,
397                 .right_margin   = 164,
398                 .upper_margin   = 23,
399                 .lower_margin   = 10,
400                 .hsync_len      = 10,
401                 .vsync_len      = 10,
402                 .sync           = 0,
403                 .vmode          = FB_VMODE_NONINTERLACED
404 } } };
405 size_t display_count = ARRAY_SIZE(displays);
406
407 static void setup_display(void)
408 {
409         struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
410         struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
411         int reg;
412
413         /* Setup HSYNC, VSYNC, DISP_CLK for debugging purposes */
414         SETUP_IOMUX_PADS(di0_pads);
415
416         enable_ipu_clock();
417         imx_setup_hdmi();
418
419         /* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
420         reg = readl(&mxc_ccm->CCGR3);
421         reg |=  MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
422         writel(reg, &mxc_ccm->CCGR3);
423
424         /* set LDB0, LDB1 clk select to 011/011 */
425         reg = readl(&mxc_ccm->cs2cdr);
426         reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
427                  | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
428         reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
429               | (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
430         writel(reg, &mxc_ccm->cs2cdr);
431
432         reg = readl(&mxc_ccm->cscmr2);
433         reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
434         writel(reg, &mxc_ccm->cscmr2);
435
436         reg = readl(&mxc_ccm->chsccdr);
437         reg |= (CHSCCDR_CLK_SEL_LDB_DI0
438                 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
439         reg |= (CHSCCDR_CLK_SEL_LDB_DI0
440                 << MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
441         writel(reg, &mxc_ccm->chsccdr);
442
443         reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
444              | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
445              | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
446              | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
447              | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
448              | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
449              | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
450              | IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED
451              | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
452         writel(reg, &iomux->gpr[2]);
453
454         reg = readl(&iomux->gpr[3]);
455         reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK
456                         | IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
457             | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
458                << IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
459         writel(reg, &iomux->gpr[3]);
460 }
461 #endif /* CONFIG_VIDEO_IPUV3 */
462
463 /*
464  * Do not overwrite the console
465  * Use always serial for U-Boot console
466  */
467 int overwrite_console(void)
468 {
469         return 1;
470 }
471
472 #ifdef CONFIG_USB_EHCI_MX6
473 static void setup_usb(void)
474 {
475         /*
476          * set daisy chain for otg_pin_id on 6q.
477          * for 6dl, this bit is reserved
478          */
479         imx_iomux_set_gpr_register(1, 13, 1, 0);
480 }
481 #endif
482
483 int board_early_init_f(void)
484 {
485         setup_iomux_uart();
486
487         return 0;
488 }
489
490 int board_init(void)
491 {
492         /* address of boot parameters */
493         gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
494
495 #ifdef CONFIG_MXC_SPI
496         setup_spi();
497 #endif
498         if (is_mx6dq() || is_mx6dqp())
499                 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1);
500         else
501                 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1);
502 #if defined(CONFIG_VIDEO_IPUV3)
503         setup_display();
504 #endif
505 #ifdef CONFIG_USB_EHCI_MX6
506         setup_usb();
507 #endif
508
509         return 0;
510 }
511
512 int power_init_board(void)
513 {
514         struct pmic *p;
515         unsigned int reg;
516         int ret;
517
518         p = pfuze_common_init(I2C_PMIC);
519         if (!p)
520                 return -ENODEV;
521
522         ret = pfuze_mode_init(p, APS_PFM);
523         if (ret < 0)
524                 return ret;
525
526         /* Increase VGEN3 from 2.5 to 2.8V */
527         pmic_reg_read(p, PFUZE100_VGEN3VOL, &reg);
528         reg &= ~LDO_VOL_MASK;
529         reg |= LDOB_2_80V;
530         pmic_reg_write(p, PFUZE100_VGEN3VOL, reg);
531
532         /* Increase VGEN5 from 2.8 to 3V */
533         pmic_reg_read(p, PFUZE100_VGEN5VOL, &reg);
534         reg &= ~LDO_VOL_MASK;
535         reg |= LDOB_3_00V;
536         pmic_reg_write(p, PFUZE100_VGEN5VOL, reg);
537
538         return 0;
539 }
540
541 #ifdef CONFIG_MXC_SPI
542 int board_spi_cs_gpio(unsigned bus, unsigned cs)
543 {
544         return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
545 }
546 #endif
547
548 #ifdef CONFIG_CMD_BMODE
549 static const struct boot_mode board_boot_modes[] = {
550         /* 4 bit bus width */
551         {"sd2",  MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
552         {"sd3",  MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
553         /* 8 bit bus width */
554         {"emmc", MAKE_CFGVAL(0x60, 0x58, 0x00, 0x00)},
555         {NULL,   0},
556 };
557 #endif
558
559 int board_late_init(void)
560 {
561 #ifdef CONFIG_CMD_BMODE
562         add_board_boot_modes(board_boot_modes);
563 #endif
564
565 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
566         env_set("board_name", "SABRESD");
567
568         if (is_mx6dqp())
569                 env_set("board_rev", "MX6QP");
570         else if (is_mx6dq())
571                 env_set("board_rev", "MX6Q");
572         else if (is_mx6sdl())
573                 env_set("board_rev", "MX6DL");
574 #endif
575
576         return 0;
577 }
578
579 #ifdef CONFIG_SPL_BUILD
580 #include <asm/arch/mx6-ddr.h>
581 #include <spl.h>
582 #include <linux/libfdt.h>
583
584 #ifdef CONFIG_SPL_OS_BOOT
585 int spl_start_uboot(void)
586 {
587         gpio_request(KEY_VOL_UP, "KEY Volume UP");
588         gpio_direction_input(KEY_VOL_UP);
589
590         /* Only enter in Falcon mode if KEY_VOL_UP is pressed */
591         return gpio_get_value(KEY_VOL_UP);
592 }
593 #endif
594
595 static void ccgr_init(void)
596 {
597         struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
598
599         writel(0x00C03F3F, &ccm->CCGR0);
600         writel(0x0030FC03, &ccm->CCGR1);
601         writel(0x0FFFC000, &ccm->CCGR2);
602         writel(0x3FF00000, &ccm->CCGR3);
603         writel(0x00FFF300, &ccm->CCGR4);
604         writel(0x0F0000C3, &ccm->CCGR5);
605         writel(0x000003FF, &ccm->CCGR6);
606 }
607
608 static int mx6q_dcd_table[] = {
609         0x020e0798, 0x000C0000,
610         0x020e0758, 0x00000000,
611         0x020e0588, 0x00000030,
612         0x020e0594, 0x00000030,
613         0x020e056c, 0x00000030,
614         0x020e0578, 0x00000030,
615         0x020e074c, 0x00000030,
616         0x020e057c, 0x00000030,
617         0x020e058c, 0x00000000,
618         0x020e059c, 0x00000030,
619         0x020e05a0, 0x00000030,
620         0x020e078c, 0x00000030,
621         0x020e0750, 0x00020000,
622         0x020e05a8, 0x00000030,
623         0x020e05b0, 0x00000030,
624         0x020e0524, 0x00000030,
625         0x020e051c, 0x00000030,
626         0x020e0518, 0x00000030,
627         0x020e050c, 0x00000030,
628         0x020e05b8, 0x00000030,
629         0x020e05c0, 0x00000030,
630         0x020e0774, 0x00020000,
631         0x020e0784, 0x00000030,
632         0x020e0788, 0x00000030,
633         0x020e0794, 0x00000030,
634         0x020e079c, 0x00000030,
635         0x020e07a0, 0x00000030,
636         0x020e07a4, 0x00000030,
637         0x020e07a8, 0x00000030,
638         0x020e0748, 0x00000030,
639         0x020e05ac, 0x00000030,
640         0x020e05b4, 0x00000030,
641         0x020e0528, 0x00000030,
642         0x020e0520, 0x00000030,
643         0x020e0514, 0x00000030,
644         0x020e0510, 0x00000030,
645         0x020e05bc, 0x00000030,
646         0x020e05c4, 0x00000030,
647         0x021b0800, 0xa1390003,
648         0x021b080c, 0x001F001F,
649         0x021b0810, 0x001F001F,
650         0x021b480c, 0x001F001F,
651         0x021b4810, 0x001F001F,
652         0x021b083c, 0x43270338,
653         0x021b0840, 0x03200314,
654         0x021b483c, 0x431A032F,
655         0x021b4840, 0x03200263,
656         0x021b0848, 0x4B434748,
657         0x021b4848, 0x4445404C,
658         0x021b0850, 0x38444542,
659         0x021b4850, 0x4935493A,
660         0x021b081c, 0x33333333,
661         0x021b0820, 0x33333333,
662         0x021b0824, 0x33333333,
663         0x021b0828, 0x33333333,
664         0x021b481c, 0x33333333,
665         0x021b4820, 0x33333333,
666         0x021b4824, 0x33333333,
667         0x021b4828, 0x33333333,
668         0x021b08b8, 0x00000800,
669         0x021b48b8, 0x00000800,
670         0x021b0004, 0x00020036,
671         0x021b0008, 0x09444040,
672         0x021b000c, 0x555A7975,
673         0x021b0010, 0xFF538F64,
674         0x021b0014, 0x01FF00DB,
675         0x021b0018, 0x00001740,
676         0x021b001c, 0x00008000,
677         0x021b002c, 0x000026d2,
678         0x021b0030, 0x005A1023,
679         0x021b0040, 0x00000027,
680         0x021b0000, 0x831A0000,
681         0x021b001c, 0x04088032,
682         0x021b001c, 0x00008033,
683         0x021b001c, 0x00048031,
684         0x021b001c, 0x09408030,
685         0x021b001c, 0x04008040,
686         0x021b0020, 0x00005800,
687         0x021b0818, 0x00011117,
688         0x021b4818, 0x00011117,
689         0x021b0004, 0x00025576,
690         0x021b0404, 0x00011006,
691         0x021b001c, 0x00000000,
692 };
693
694 static int mx6qp_dcd_table[] = {
695         0x020e0798, 0x000c0000,
696         0x020e0758, 0x00000000,
697         0x020e0588, 0x00000030,
698         0x020e0594, 0x00000030,
699         0x020e056c, 0x00000030,
700         0x020e0578, 0x00000030,
701         0x020e074c, 0x00000030,
702         0x020e057c, 0x00000030,
703         0x020e058c, 0x00000000,
704         0x020e059c, 0x00000030,
705         0x020e05a0, 0x00000030,
706         0x020e078c, 0x00000030,
707         0x020e0750, 0x00020000,
708         0x020e05a8, 0x00000030,
709         0x020e05b0, 0x00000030,
710         0x020e0524, 0x00000030,
711         0x020e051c, 0x00000030,
712         0x020e0518, 0x00000030,
713         0x020e050c, 0x00000030,
714         0x020e05b8, 0x00000030,
715         0x020e05c0, 0x00000030,
716         0x020e0774, 0x00020000,
717         0x020e0784, 0x00000030,
718         0x020e0788, 0x00000030,
719         0x020e0794, 0x00000030,
720         0x020e079c, 0x00000030,
721         0x020e07a0, 0x00000030,
722         0x020e07a4, 0x00000030,
723         0x020e07a8, 0x00000030,
724         0x020e0748, 0x00000030,
725         0x020e05ac, 0x00000030,
726         0x020e05b4, 0x00000030,
727         0x020e0528, 0x00000030,
728         0x020e0520, 0x00000030,
729         0x020e0514, 0x00000030,
730         0x020e0510, 0x00000030,
731         0x020e05bc, 0x00000030,
732         0x020e05c4, 0x00000030,
733         0x021b0800, 0xa1390003,
734         0x021b080c, 0x001b001e,
735         0x021b0810, 0x002e0029,
736         0x021b480c, 0x001b002a,
737         0x021b4810, 0x0019002c,
738         0x021b083c, 0x43240334,
739         0x021b0840, 0x0324031a,
740         0x021b483c, 0x43340344,
741         0x021b4840, 0x03280276,
742         0x021b0848, 0x44383A3E,
743         0x021b4848, 0x3C3C3846,
744         0x021b0850, 0x2e303230,
745         0x021b4850, 0x38283E34,
746         0x021b081c, 0x33333333,
747         0x021b0820, 0x33333333,
748         0x021b0824, 0x33333333,
749         0x021b0828, 0x33333333,
750         0x021b481c, 0x33333333,
751         0x021b4820, 0x33333333,
752         0x021b4824, 0x33333333,
753         0x021b4828, 0x33333333,
754         0x021b08c0, 0x24912249,
755         0x021b48c0, 0x24914289,
756         0x021b08b8, 0x00000800,
757         0x021b48b8, 0x00000800,
758         0x021b0004, 0x00020036,
759         0x021b0008, 0x24444040,
760         0x021b000c, 0x555A7955,
761         0x021b0010, 0xFF320F64,
762         0x021b0014, 0x01ff00db,
763         0x021b0018, 0x00001740,
764         0x021b001c, 0x00008000,
765         0x021b002c, 0x000026d2,
766         0x021b0030, 0x005A1023,
767         0x021b0040, 0x00000027,
768         0x021b0400, 0x14420000,
769         0x021b0000, 0x831A0000,
770         0x021b0890, 0x00400C58,
771         0x00bb0008, 0x00000000,
772         0x00bb000c, 0x2891E41A,
773         0x00bb0038, 0x00000564,
774         0x00bb0014, 0x00000040,
775         0x00bb0028, 0x00000020,
776         0x00bb002c, 0x00000020,
777         0x021b001c, 0x04088032,
778         0x021b001c, 0x00008033,
779         0x021b001c, 0x00048031,
780         0x021b001c, 0x09408030,
781         0x021b001c, 0x04008040,
782         0x021b0020, 0x00005800,
783         0x021b0818, 0x00011117,
784         0x021b4818, 0x00011117,
785         0x021b0004, 0x00025576,
786         0x021b0404, 0x00011006,
787         0x021b001c, 0x00000000,
788 };
789
790 static int mx6dl_dcd_table[] = {
791         0x020e0774, 0x000C0000,
792         0x020e0754, 0x00000000,
793         0x020e04ac, 0x00000030,
794         0x020e04b0, 0x00000030,
795         0x020e0464, 0x00000030,
796         0x020e0490, 0x00000030,
797         0x020e074c, 0x00000030,
798         0x020e0494, 0x00000030,
799         0x020e04a0, 0x00000000,
800         0x020e04b4, 0x00000030,
801         0x020e04b8, 0x00000030,
802         0x020e076c, 0x00000030,
803         0x020e0750, 0x00020000,
804         0x020e04bc, 0x00000030,
805         0x020e04c0, 0x00000030,
806         0x020e04c4, 0x00000030,
807         0x020e04c8, 0x00000030,
808         0x020e04cc, 0x00000030,
809         0x020e04d0, 0x00000030,
810         0x020e04d4, 0x00000030,
811         0x020e04d8, 0x00000030,
812         0x020e0760, 0x00020000,
813         0x020e0764, 0x00000030,
814         0x020e0770, 0x00000030,
815         0x020e0778, 0x00000030,
816         0x020e077c, 0x00000030,
817         0x020e0780, 0x00000030,
818         0x020e0784, 0x00000030,
819         0x020e078c, 0x00000030,
820         0x020e0748, 0x00000030,
821         0x020e0470, 0x00000030,
822         0x020e0474, 0x00000030,
823         0x020e0478, 0x00000030,
824         0x020e047c, 0x00000030,
825         0x020e0480, 0x00000030,
826         0x020e0484, 0x00000030,
827         0x020e0488, 0x00000030,
828         0x020e048c, 0x00000030,
829         0x021b0800, 0xa1390003,
830         0x021b080c, 0x001F001F,
831         0x021b0810, 0x001F001F,
832         0x021b480c, 0x001F001F,
833         0x021b4810, 0x001F001F,
834         0x021b083c, 0x4220021F,
835         0x021b0840, 0x0207017E,
836         0x021b483c, 0x4201020C,
837         0x021b4840, 0x01660172,
838         0x021b0848, 0x4A4D4E4D,
839         0x021b4848, 0x4A4F5049,
840         0x021b0850, 0x3F3C3D31,
841         0x021b4850, 0x3238372B,
842         0x021b081c, 0x33333333,
843         0x021b0820, 0x33333333,
844         0x021b0824, 0x33333333,
845         0x021b0828, 0x33333333,
846         0x021b481c, 0x33333333,
847         0x021b4820, 0x33333333,
848         0x021b4824, 0x33333333,
849         0x021b4828, 0x33333333,
850         0x021b08b8, 0x00000800,
851         0x021b48b8, 0x00000800,
852         0x021b0004, 0x0002002D,
853         0x021b0008, 0x00333030,
854         0x021b000c, 0x3F435313,
855         0x021b0010, 0xB66E8B63,
856         0x021b0014, 0x01FF00DB,
857         0x021b0018, 0x00001740,
858         0x021b001c, 0x00008000,
859         0x021b002c, 0x000026d2,
860         0x021b0030, 0x00431023,
861         0x021b0040, 0x00000027,
862         0x021b0000, 0x831A0000,
863         0x021b001c, 0x04008032,
864         0x021b001c, 0x00008033,
865         0x021b001c, 0x00048031,
866         0x021b001c, 0x05208030,
867         0x021b001c, 0x04008040,
868         0x021b0020, 0x00005800,
869         0x021b0818, 0x00011117,
870         0x021b4818, 0x00011117,
871         0x021b0004, 0x0002556D,
872         0x021b0404, 0x00011006,
873         0x021b001c, 0x00000000,
874 };
875
876 static void ddr_init(int *table, int size)
877 {
878         int i;
879
880         for (i = 0; i < size / 2 ; i++)
881                 writel(table[2 * i + 1], table[2 * i]);
882 }
883
884 static void spl_dram_init(void)
885 {
886         if (is_mx6dq())
887                 ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table));
888         else if (is_mx6dqp())
889                 ddr_init(mx6qp_dcd_table, ARRAY_SIZE(mx6qp_dcd_table));
890         else if (is_mx6sdl())
891                 ddr_init(mx6dl_dcd_table, ARRAY_SIZE(mx6dl_dcd_table));
892 }
893
894 void board_init_f(ulong dummy)
895 {
896         /* DDR initialization */
897         spl_dram_init();
898
899         /* setup AIPS and disable watchdog */
900         arch_cpu_init();
901
902         ccgr_init();
903         gpr_init();
904
905         /* iomux and setup of i2c */
906         board_early_init_f();
907
908         /* setup GP timer */
909         timer_init();
910
911         /* UART clocks enabled and gd valid - init serial console */
912         preloader_console_init();
913
914         /* Clear the BSS. */
915         memset(__bss_start, 0, __bss_end - __bss_start);
916
917         /* load/boot image from boot device */
918         board_init_r(NULL, 0);
919 }
920 #endif
921
922 #ifdef CONFIG_SPL_LOAD_FIT
923 int board_fit_config_name_match(const char *name)
924 {
925         if (is_mx6dq()) {
926                 if (!strcmp(name, "imx6q-sabresd"))
927                         return 0;
928         } else if (is_mx6dqp()) {
929                 if (!strcmp(name, "imx6qp-sabresd"))
930                         return 0;
931         } else if (is_mx6dl()) {
932                 if (!strcmp(name, "imx6dl-sabresd"))
933                         return 0;
934         }
935
936         return -1;
937 }
938 #endif