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