1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2013 Freescale Semiconductor, Inc.
4  * Copyright (C) 2014 O.S. Systems Software LTDA.
5  *
6  * Author: Fabio Estevam <festevam@gmail.com>
7  */
8 
9 #include <common.h>
10 #include <env.h>
11 #include <init.h>
12 #include <net.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/crm_regs.h>
15 #include <asm/arch/iomux.h>
16 #include <asm/arch/imx-regs.h>
17 #include <asm/arch/mx6-pins.h>
18 #include <asm/arch/sys_proto.h>
19 #include <asm/global_data.h>
20 #include <asm/gpio.h>
21 #include <asm/arch/mxc_hdmi.h>
22 #include <asm/mach-imx/video.h>
23 #include <asm/mach-imx/iomux-v3.h>
24 #include <asm/io.h>
25 #include <linux/delay.h>
26 #include <linux/sizes.h>
27 #include <miiphy.h>
28 #include <netdev.h>
29 #include <phy.h>
30 
31 DECLARE_GLOBAL_DATA_PTR;
32 
33 #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
34 	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |			\
35 	PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
36 
37 #define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
38 	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
39 
40 #define ETH_PHY_RESET		IMX_GPIO_NR(1, 26)
41 #define LVDS0_EN		IMX_GPIO_NR(2, 8)
42 #define LVDS0_BL_EN		IMX_GPIO_NR(2, 9)
43 
dram_init(void)44 int dram_init(void)
45 {
46 	gd->ram_size = imx_ddr_size();
47 
48 	return 0;
49 }
50 
51 static iomux_v3_cfg_t const uart1_pads[] = {
52 	IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
53 	IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
54 };
55 
setup_iomux_uart(void)56 static void setup_iomux_uart(void)
57 {
58 	SETUP_IOMUX_PADS(uart1_pads);
59 }
60 
61 static iomux_v3_cfg_t const lvds_pads[] = {
62 	/* lvds */
63 	IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL)),
64 	IOMUX_PADS(PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL)),
65 	IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)),
66 	IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
67 	IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03 | MUX_PAD_CTRL(NO_PAD_CTRL)),
68 };
69 
70 static iomux_v3_cfg_t const enet_pads[] = {
71 	IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
72 	IOMUX_PADS(PAD_ENET_MDC__ENET_MDC    | MUX_PAD_CTRL(ENET_PAD_CTRL)),
73 	IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
74 	IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
75 	IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
76 	IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
77 	IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
78 	IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL |
79 		   MUX_PAD_CTRL(ENET_PAD_CTRL)),
80 	IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK |
81 		   MUX_PAD_CTRL(ENET_PAD_CTRL)),
82 	IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
83 	IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
84 	IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
85 	IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
86 	IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
87 	IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
88 	/* AR8035 PHY Reset */
89         IOMUX_PADS(PAD_ENET_RXD1__GPIO1_IO26 | MUX_PAD_CTRL(NO_PAD_CTRL)),
90 };
91 
setup_iomux_enet(void)92 static void setup_iomux_enet(void)
93 {
94 	SETUP_IOMUX_PADS(enet_pads);
95 
96 	/* Reset AR8031 PHY */
97 	gpio_request(ETH_PHY_RESET, "enet_phy_reset");
98 	gpio_direction_output(ETH_PHY_RESET, 0);
99 	udelay(500);
100 	gpio_set_value(ETH_PHY_RESET, 1);
101 }
102 
103 #if defined(CONFIG_VIDEO_IPUV3)
104 static iomux_v3_cfg_t const ft5x06_wvga_pads[] = {
105 	IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK),
106 	IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02), /* HSync */
107 	IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03), /* VSync */
108 	IOMUX_PADS(PAD_DI0_PIN4__IPU1_DI0_PIN04	| MUX_PAD_CTRL(PAD_CTL_DSE_120ohm)), /* Contrast */
109 	IOMUX_PADS(PAD_DI0_PIN15__IPU1_DI0_PIN15), /* DISP0_DRDY */
110 	IOMUX_PADS(PAD_DISP0_DAT0__IPU1_DISP0_DATA00),
111 	IOMUX_PADS(PAD_DISP0_DAT1__IPU1_DISP0_DATA01),
112 	IOMUX_PADS(PAD_DISP0_DAT2__IPU1_DISP0_DATA02),
113 	IOMUX_PADS(PAD_DISP0_DAT3__IPU1_DISP0_DATA03),
114 	IOMUX_PADS(PAD_DISP0_DAT4__IPU1_DISP0_DATA04),
115 	IOMUX_PADS(PAD_DISP0_DAT5__IPU1_DISP0_DATA05),
116 	IOMUX_PADS(PAD_DISP0_DAT6__IPU1_DISP0_DATA06),
117 	IOMUX_PADS(PAD_DISP0_DAT7__IPU1_DISP0_DATA07),
118 	IOMUX_PADS(PAD_DISP0_DAT8__IPU1_DISP0_DATA08),
119 	IOMUX_PADS(PAD_DISP0_DAT9__IPU1_DISP0_DATA09),
120 	IOMUX_PADS(PAD_DISP0_DAT10__IPU1_DISP0_DATA10),
121 	IOMUX_PADS(PAD_DISP0_DAT11__IPU1_DISP0_DATA11),
122 	IOMUX_PADS(PAD_DISP0_DAT12__IPU1_DISP0_DATA12),
123 	IOMUX_PADS(PAD_DISP0_DAT13__IPU1_DISP0_DATA13),
124 	IOMUX_PADS(PAD_DISP0_DAT14__IPU1_DISP0_DATA14),
125 	IOMUX_PADS(PAD_DISP0_DAT15__IPU1_DISP0_DATA15),
126 	IOMUX_PADS(PAD_DISP0_DAT16__IPU1_DISP0_DATA16),
127 	IOMUX_PADS(PAD_DISP0_DAT17__IPU1_DISP0_DATA17),
128 	IOMUX_PADS(PAD_DISP0_DAT18__IPU1_DISP0_DATA18),
129 	IOMUX_PADS(PAD_DISP0_DAT19__IPU1_DISP0_DATA19),
130 	IOMUX_PADS(PAD_DISP0_DAT20__IPU1_DISP0_DATA20),
131 	IOMUX_PADS(PAD_DISP0_DAT21__IPU1_DISP0_DATA21),
132 	IOMUX_PADS(PAD_DISP0_DAT22__IPU1_DISP0_DATA22),
133 	IOMUX_PADS(PAD_DISP0_DAT23__IPU1_DISP0_DATA23),
134 	IOMUX_PADS(PAD_SD4_DAT2__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL)), /* DISP0_BKLEN */
135 	IOMUX_PADS(PAD_SD4_DAT3__GPIO2_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL)), /* DISP0_VDDEN */
136 };
137 
do_enable_hdmi(struct display_info_t const * dev)138 static void do_enable_hdmi(struct display_info_t const *dev)
139 {
140 	imx_enable_hdmi_phy();
141 }
142 
enable_lvds(struct display_info_t const * dev)143 static void enable_lvds(struct display_info_t const *dev)
144 {
145 	struct iomuxc *iomux = (struct iomuxc *)
146 				IOMUXC_BASE_ADDR;
147 
148 	/* set CH0 data width to 24bit (IOMUXC_GPR2:5 0=18bit, 1=24bit) */
149 	u32 reg = readl(&iomux->gpr[2]);
150 	reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT;
151 	writel(reg, &iomux->gpr[2]);
152 
153 	/* Enable Backlight - use GPIO for Brightness adjustment */
154 	SETUP_IOMUX_PAD(PAD_SD4_DAT1__GPIO2_IO09);
155 	gpio_request(IMX_GPIO_NR(2, 9), "backlight_enable");
156 	gpio_direction_output(IMX_GPIO_NR(2, 9), 1);
157 
158 	gpio_request(IMX_GPIO_NR(2, 8), "brightness");
159 	SETUP_IOMUX_PAD(PAD_SD4_DAT0__GPIO2_IO08);
160 	gpio_direction_output(IMX_GPIO_NR(2, 8), 1);
161 }
162 
enable_ft5x06_wvga(struct display_info_t const * dev)163 static void enable_ft5x06_wvga(struct display_info_t const *dev)
164 {
165 	SETUP_IOMUX_PADS(ft5x06_wvga_pads);
166 
167 	gpio_request(IMX_GPIO_NR(2, 10), "parallel_enable");
168 	gpio_request(IMX_GPIO_NR(2, 11), "parallel_brightness");
169 	gpio_direction_output(IMX_GPIO_NR(2, 10), 1);
170 	gpio_direction_output(IMX_GPIO_NR(2, 11), 1);
171 }
172 
173 struct display_info_t const displays[] = {{
174 	.bus	= 1,
175 	.addr	= 0x38,
176 	.pixfmt	= IPU_PIX_FMT_RGB24,
177 	.detect	= NULL,
178 	.enable	= enable_ft5x06_wvga,
179 	.mode	= {
180 		.name           = "FT5x06-WVGA",
181 		.refresh        = 60,
182 		.xres           = 800,
183 		.yres           = 480,
184 		.pixclock       = 30303,
185 		.left_margin    = 45,
186 		.right_margin   = 210,
187 		.upper_margin   = 22,
188 		.lower_margin   = 22,
189 		.hsync_len      = 1,
190 		.vsync_len      = 1,
191 		.sync           = 0,
192 		.vmode          = FB_VMODE_NONINTERLACED
193 } }, {
194 	.bus	= -1,
195 	.addr	= 0,
196 	.pixfmt = IPU_PIX_FMT_RGB24,
197 	.detect = NULL,
198 	.enable = enable_lvds,
199 	.mode	= {
200 		.name		= "hj070na",
201 		.refresh	= 60,
202 		.xres		= 1024,
203 		.yres		= 600,
204 		.pixclock	= 15385,
205 		.left_margin	= 220,
206 		.right_margin	= 40,
207 		.upper_margin	= 21,
208 		.lower_margin	= 7,
209 		.hsync_len	= 60,
210 		.vsync_len	= 10,
211 		.sync		= FB_SYNC_EXT,
212 		.vmode		= FB_VMODE_NONINTERLACED
213 } }, {
214 	.bus	= -1,
215 	.addr	= 0,
216 	.pixfmt	= IPU_PIX_FMT_RGB24,
217 	.detect	= detect_hdmi,
218 	.enable	= do_enable_hdmi,
219 	.mode	= {
220 		.name           = "HDMI",
221 		.refresh        = 60,
222 		.xres           = 1024,
223 		.yres           = 768,
224 		.pixclock       = 15385,
225 		.left_margin    = 220,
226 		.right_margin   = 40,
227 		.upper_margin   = 21,
228 		.lower_margin   = 7,
229 		.hsync_len      = 60,
230 		.vsync_len      = 10,
231 		.sync           = FB_SYNC_EXT,
232 		.vmode          = FB_VMODE_NONINTERLACED
233 } } };
234 size_t display_count = ARRAY_SIZE(displays);
235 
setup_display(void)236 static void setup_display(void)
237 {
238 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
239 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
240 	int reg;
241 
242 	/* Setup HSYNC, VSYNC, DISP_CLK for debugging purposes */
243 	SETUP_IOMUX_PADS(lvds_pads);
244 	gpio_request(LVDS0_EN, "lvds0_enable");
245 	gpio_request(LVDS0_BL_EN, "lvds0_bl_enable");
246 	gpio_direction_output(LVDS0_EN, 1);
247 	gpio_direction_output(LVDS0_BL_EN, 1);
248 
249 	enable_ipu_clock();
250 	imx_setup_hdmi();
251 
252 	reg = __raw_readl(&mxc_ccm->CCGR3);
253 	reg |=  MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
254 	writel(reg, &mxc_ccm->CCGR3);
255 
256 	/* set LDB0, LDB1 clk select to 011/011 */
257 	reg = readl(&mxc_ccm->cs2cdr);
258 	reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
259 		| MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
260 	reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
261 		 | (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
262 	writel(reg, &mxc_ccm->cs2cdr);
263 
264 	reg = readl(&mxc_ccm->cscmr2);
265 	reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
266 	writel(reg, &mxc_ccm->cscmr2);
267 
268 	reg = readl(&mxc_ccm->chsccdr);
269 	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
270 		<< MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
271 	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
272 		<< MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
273 	writel(reg, &mxc_ccm->chsccdr);
274 
275 	 reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
276 		| IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
277 		| IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
278 		| IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
279 		| IOMUXC_GPR2_DATA_WIDTH_CH1_24BIT
280 		| IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
281 		| IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
282 		| IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0
283 		| IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
284 	writel(reg, &iomux->gpr[2]);
285 	reg = readl(&iomux->gpr[3]);
286 
287 	reg = (reg & ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK
288 		| IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
289 		| (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
290 		<< IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
291 
292 	writel(reg, &iomux->gpr[3]);
293 }
294 #endif /* CONFIG_VIDEO_IPUV3 */
295 
board_early_init_f(void)296 int board_early_init_f(void)
297 {
298 	setup_iomux_uart();
299 
300 #if defined(CONFIG_VIDEO_IPUV3)
301 	setup_display();
302 #endif
303 
304 	return 0;
305 }
306 
board_eth_init(struct bd_info * bis)307 int board_eth_init(struct bd_info *bis)
308 {
309 	setup_iomux_enet();
310 
311 	return cpu_eth_init(bis);
312 }
313 
board_phy_config(struct phy_device * phydev)314 int board_phy_config(struct phy_device *phydev)
315 {
316 	unsigned short val;
317 
318 	/* To enable AR8035 ouput a 125MHz clk from CLK_25M */
319 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
320 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
321 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
322 
323 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
324 	val &= 0xffe7;
325 	val |= 0x18;
326 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
327 
328 	/* introduce tx clock delay */
329 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
330 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
331 	val |= 0x0100;
332 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
333 
334 	if (phydev->drv->config)
335 		phydev->drv->config(phydev);
336 
337 	return 0;
338 }
339 
overwrite_console(void)340 int overwrite_console(void)
341 {
342 	return 1;
343 }
344 
board_late_init(void)345 int board_late_init(void)
346 {
347 	if (is_mx6dq())
348 		env_set("board_rev", "MX6Q");
349 	else
350 		env_set("board_rev", "MX6DL");
351 
352 	return 0;
353 }
354 
board_init(void)355 int board_init(void)
356 {
357 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
358 
359 	return 0;
360 }
361 
checkboard(void)362 int checkboard(void)
363 {
364 	puts("Board: PICO-IMX6\n");
365 
366 	return 0;
367 }
368