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