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