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