xref: /rk3399_rockchip-uboot/board/grinn/liteboard/board.c (revision c9e40e65e1dcf19f518fa3811bb6de2bf407360f)
1*c9e40e65SMarcin Niestroj /*
2*c9e40e65SMarcin Niestroj  * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
3*c9e40e65SMarcin Niestroj  * Copyright (C) 2016 Grinn
4*c9e40e65SMarcin Niestroj  *
5*c9e40e65SMarcin Niestroj  * SPDX-License-Identifier:	GPL-2.0+
6*c9e40e65SMarcin Niestroj  */
7*c9e40e65SMarcin Niestroj 
8*c9e40e65SMarcin Niestroj #include <asm/arch/clock.h>
9*c9e40e65SMarcin Niestroj #include <asm/arch/iomux.h>
10*c9e40e65SMarcin Niestroj #include <asm/arch/imx-regs.h>
11*c9e40e65SMarcin Niestroj #include <asm/arch/crm_regs.h>
12*c9e40e65SMarcin Niestroj #include <asm/arch/mx6ul_pins.h>
13*c9e40e65SMarcin Niestroj #include <asm/arch/mx6-pins.h>
14*c9e40e65SMarcin Niestroj #include <asm/arch/sys_proto.h>
15*c9e40e65SMarcin Niestroj #include <asm/gpio.h>
16*c9e40e65SMarcin Niestroj #include <asm/imx-common/iomux-v3.h>
17*c9e40e65SMarcin Niestroj #include <asm/imx-common/boot_mode.h>
18*c9e40e65SMarcin Niestroj #include <asm/io.h>
19*c9e40e65SMarcin Niestroj #include <common.h>
20*c9e40e65SMarcin Niestroj #include <fsl_esdhc.h>
21*c9e40e65SMarcin Niestroj #include <linux/sizes.h>
22*c9e40e65SMarcin Niestroj #include <linux/fb.h>
23*c9e40e65SMarcin Niestroj #include <mach/litesom.h>
24*c9e40e65SMarcin Niestroj #include <miiphy.h>
25*c9e40e65SMarcin Niestroj #include <mmc.h>
26*c9e40e65SMarcin Niestroj #include <netdev.h>
27*c9e40e65SMarcin Niestroj #include <spl.h>
28*c9e40e65SMarcin Niestroj #include <usb.h>
29*c9e40e65SMarcin Niestroj #include <usb/ehci-ci.h>
30*c9e40e65SMarcin Niestroj 
31*c9e40e65SMarcin Niestroj DECLARE_GLOBAL_DATA_PTR;
32*c9e40e65SMarcin Niestroj 
33*c9e40e65SMarcin Niestroj #define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |		\
34*c9e40e65SMarcin Niestroj 	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |		\
35*c9e40e65SMarcin Niestroj 	PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
36*c9e40e65SMarcin Niestroj 
37*c9e40e65SMarcin Niestroj #define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |		\
38*c9e40e65SMarcin Niestroj 	PAD_CTL_PUS_22K_UP  | PAD_CTL_SPEED_LOW |		\
39*c9e40e65SMarcin Niestroj 	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
40*c9e40e65SMarcin Niestroj 
41*c9e40e65SMarcin Niestroj #define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE |     \
42*c9e40e65SMarcin Niestroj 	PAD_CTL_SPEED_HIGH   |                                   \
43*c9e40e65SMarcin Niestroj 	PAD_CTL_DSE_48ohm   | PAD_CTL_SRE_FAST)
44*c9e40e65SMarcin Niestroj 
45*c9e40e65SMarcin Niestroj #define MDIO_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE |     \
46*c9e40e65SMarcin Niestroj 	PAD_CTL_DSE_48ohm   | PAD_CTL_SRE_FAST | PAD_CTL_ODE)
47*c9e40e65SMarcin Niestroj 
48*c9e40e65SMarcin Niestroj #define ENET_CLK_PAD_CTRL  (PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST)
49*c9e40e65SMarcin Niestroj 
50*c9e40e65SMarcin Niestroj static iomux_v3_cfg_t const uart1_pads[] = {
51*c9e40e65SMarcin Niestroj 	MX6_PAD_UART1_TX_DATA__UART1_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
52*c9e40e65SMarcin Niestroj 	MX6_PAD_UART1_RX_DATA__UART1_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
53*c9e40e65SMarcin Niestroj };
54*c9e40e65SMarcin Niestroj 
55*c9e40e65SMarcin Niestroj static iomux_v3_cfg_t const sd_pads[] = {
56*c9e40e65SMarcin Niestroj 	MX6_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
57*c9e40e65SMarcin Niestroj 	MX6_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
58*c9e40e65SMarcin Niestroj 	MX6_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
59*c9e40e65SMarcin Niestroj 	MX6_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
60*c9e40e65SMarcin Niestroj 	MX6_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
61*c9e40e65SMarcin Niestroj 	MX6_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
62*c9e40e65SMarcin Niestroj 
63*c9e40e65SMarcin Niestroj 	/* CD */
64*c9e40e65SMarcin Niestroj 	MX6_PAD_UART1_RTS_B__GPIO1_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
65*c9e40e65SMarcin Niestroj };
66*c9e40e65SMarcin Niestroj 
67*c9e40e65SMarcin Niestroj #ifdef CONFIG_FEC_MXC
68*c9e40e65SMarcin Niestroj static iomux_v3_cfg_t const fec1_pads[] = {
69*c9e40e65SMarcin Niestroj 	MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),
70*c9e40e65SMarcin Niestroj 	MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
71*c9e40e65SMarcin Niestroj 	MX6_PAD_ENET1_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
72*c9e40e65SMarcin Niestroj 	MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
73*c9e40e65SMarcin Niestroj 	MX6_PAD_ENET1_TX_EN__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
74*c9e40e65SMarcin Niestroj 	MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),
75*c9e40e65SMarcin Niestroj 	MX6_PAD_ENET1_RX_DATA0__ENET1_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
76*c9e40e65SMarcin Niestroj 	MX6_PAD_ENET1_RX_DATA1__ENET1_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
77*c9e40e65SMarcin Niestroj 	MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),
78*c9e40e65SMarcin Niestroj 	MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
79*c9e40e65SMarcin Niestroj };
80*c9e40e65SMarcin Niestroj 
81*c9e40e65SMarcin Niestroj static void setup_iomux_fec(void)
82*c9e40e65SMarcin Niestroj {
83*c9e40e65SMarcin Niestroj 	imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads));
84*c9e40e65SMarcin Niestroj }
85*c9e40e65SMarcin Niestroj #endif
86*c9e40e65SMarcin Niestroj 
87*c9e40e65SMarcin Niestroj static void setup_iomux_uart(void)
88*c9e40e65SMarcin Niestroj {
89*c9e40e65SMarcin Niestroj 	imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
90*c9e40e65SMarcin Niestroj }
91*c9e40e65SMarcin Niestroj 
92*c9e40e65SMarcin Niestroj #ifdef CONFIG_FSL_ESDHC
93*c9e40e65SMarcin Niestroj static struct fsl_esdhc_cfg sd_cfg = {USDHC1_BASE_ADDR, 0, 4};
94*c9e40e65SMarcin Niestroj 
95*c9e40e65SMarcin Niestroj #define SD_CD_GPIO	IMX_GPIO_NR(1, 19)
96*c9e40e65SMarcin Niestroj 
97*c9e40e65SMarcin Niestroj static int mmc_get_env_devno(void)
98*c9e40e65SMarcin Niestroj {
99*c9e40e65SMarcin Niestroj 	u32 soc_sbmr = readl(SRC_BASE_ADDR + 0x4);
100*c9e40e65SMarcin Niestroj 	int dev_no;
101*c9e40e65SMarcin Niestroj 	u32 bootsel;
102*c9e40e65SMarcin Niestroj 
103*c9e40e65SMarcin Niestroj 	bootsel = (soc_sbmr & 0x000000FF) >> 6;
104*c9e40e65SMarcin Niestroj 
105*c9e40e65SMarcin Niestroj 	/* If not boot from sd/mmc, use default value */
106*c9e40e65SMarcin Niestroj 	if (bootsel != 1)
107*c9e40e65SMarcin Niestroj 		return CONFIG_SYS_MMC_ENV_DEV;
108*c9e40e65SMarcin Niestroj 
109*c9e40e65SMarcin Niestroj 	/* BOOT_CFG2[3] and BOOT_CFG2[4] */
110*c9e40e65SMarcin Niestroj 	dev_no = (soc_sbmr & 0x00001800) >> 11;
111*c9e40e65SMarcin Niestroj 
112*c9e40e65SMarcin Niestroj 	return dev_no;
113*c9e40e65SMarcin Niestroj }
114*c9e40e65SMarcin Niestroj 
115*c9e40e65SMarcin Niestroj int board_mmc_getcd(struct mmc *mmc)
116*c9e40e65SMarcin Niestroj {
117*c9e40e65SMarcin Niestroj 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
118*c9e40e65SMarcin Niestroj 	int ret = 0;
119*c9e40e65SMarcin Niestroj 
120*c9e40e65SMarcin Niestroj 	switch (cfg->esdhc_base) {
121*c9e40e65SMarcin Niestroj 	case USDHC1_BASE_ADDR:
122*c9e40e65SMarcin Niestroj 		ret = !gpio_get_value(SD_CD_GPIO);
123*c9e40e65SMarcin Niestroj 		break;
124*c9e40e65SMarcin Niestroj 	case USDHC2_BASE_ADDR:
125*c9e40e65SMarcin Niestroj 		ret = 1;
126*c9e40e65SMarcin Niestroj 		break;
127*c9e40e65SMarcin Niestroj 	}
128*c9e40e65SMarcin Niestroj 
129*c9e40e65SMarcin Niestroj 	return ret;
130*c9e40e65SMarcin Niestroj }
131*c9e40e65SMarcin Niestroj 
132*c9e40e65SMarcin Niestroj int board_mmc_init(bd_t *bis)
133*c9e40e65SMarcin Niestroj {
134*c9e40e65SMarcin Niestroj 	int ret;
135*c9e40e65SMarcin Niestroj 
136*c9e40e65SMarcin Niestroj 	/* SD */
137*c9e40e65SMarcin Niestroj 	imx_iomux_v3_setup_multiple_pads(sd_pads, ARRAY_SIZE(sd_pads));
138*c9e40e65SMarcin Niestroj 	gpio_direction_input(SD_CD_GPIO);
139*c9e40e65SMarcin Niestroj 	sd_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
140*c9e40e65SMarcin Niestroj 
141*c9e40e65SMarcin Niestroj 	ret = fsl_esdhc_initialize(bis, &sd_cfg);
142*c9e40e65SMarcin Niestroj 	if (ret) {
143*c9e40e65SMarcin Niestroj 		printf("Warning: failed to initialize mmc dev 0 (SD)\n");
144*c9e40e65SMarcin Niestroj 		return ret;
145*c9e40e65SMarcin Niestroj 	}
146*c9e40e65SMarcin Niestroj 
147*c9e40e65SMarcin Niestroj 	return litesom_mmc_init(bis);
148*c9e40e65SMarcin Niestroj }
149*c9e40e65SMarcin Niestroj 
150*c9e40e65SMarcin Niestroj static int check_mmc_autodetect(void)
151*c9e40e65SMarcin Niestroj {
152*c9e40e65SMarcin Niestroj 	char *autodetect_str = getenv("mmcautodetect");
153*c9e40e65SMarcin Niestroj 
154*c9e40e65SMarcin Niestroj 	if ((autodetect_str != NULL) &&
155*c9e40e65SMarcin Niestroj 	    (strcmp(autodetect_str, "yes") == 0)) {
156*c9e40e65SMarcin Niestroj 		return 1;
157*c9e40e65SMarcin Niestroj 	}
158*c9e40e65SMarcin Niestroj 
159*c9e40e65SMarcin Niestroj 	return 0;
160*c9e40e65SMarcin Niestroj }
161*c9e40e65SMarcin Niestroj 
162*c9e40e65SMarcin Niestroj void board_late_mmc_init(void)
163*c9e40e65SMarcin Niestroj {
164*c9e40e65SMarcin Niestroj 	char cmd[32];
165*c9e40e65SMarcin Niestroj 	char mmcblk[32];
166*c9e40e65SMarcin Niestroj 	u32 dev_no = mmc_get_env_devno();
167*c9e40e65SMarcin Niestroj 
168*c9e40e65SMarcin Niestroj 	if (!check_mmc_autodetect())
169*c9e40e65SMarcin Niestroj 		return;
170*c9e40e65SMarcin Niestroj 
171*c9e40e65SMarcin Niestroj 	setenv_ulong("mmcdev", dev_no);
172*c9e40e65SMarcin Niestroj 
173*c9e40e65SMarcin Niestroj 	/* Set mmcblk env */
174*c9e40e65SMarcin Niestroj 	sprintf(mmcblk, "/dev/mmcblk%dp2 rootwait rw",
175*c9e40e65SMarcin Niestroj 		dev_no);
176*c9e40e65SMarcin Niestroj 	setenv("mmcroot", mmcblk);
177*c9e40e65SMarcin Niestroj 
178*c9e40e65SMarcin Niestroj 	sprintf(cmd, "mmc dev %d", dev_no);
179*c9e40e65SMarcin Niestroj 	run_command(cmd, 0);
180*c9e40e65SMarcin Niestroj }
181*c9e40e65SMarcin Niestroj #endif
182*c9e40e65SMarcin Niestroj 
183*c9e40e65SMarcin Niestroj #ifdef CONFIG_FEC_MXC
184*c9e40e65SMarcin Niestroj int board_eth_init(bd_t *bis)
185*c9e40e65SMarcin Niestroj {
186*c9e40e65SMarcin Niestroj 	setup_iomux_fec();
187*c9e40e65SMarcin Niestroj 
188*c9e40e65SMarcin Niestroj 	return fecmxc_initialize(bis);
189*c9e40e65SMarcin Niestroj }
190*c9e40e65SMarcin Niestroj 
191*c9e40e65SMarcin Niestroj static int setup_fec(void)
192*c9e40e65SMarcin Niestroj {
193*c9e40e65SMarcin Niestroj 	struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
194*c9e40e65SMarcin Niestroj 	int ret;
195*c9e40e65SMarcin Niestroj 
196*c9e40e65SMarcin Niestroj 	/* Use 50M anatop loopback REF_CLK1 for ENET1, clear gpr1[13],
197*c9e40e65SMarcin Niestroj 	   set gpr1[17]*/
198*c9e40e65SMarcin Niestroj 	clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK,
199*c9e40e65SMarcin Niestroj 			IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK);
200*c9e40e65SMarcin Niestroj 
201*c9e40e65SMarcin Niestroj 	ret = enable_fec_anatop_clock(0, ENET_50MHZ);
202*c9e40e65SMarcin Niestroj 	if (ret)
203*c9e40e65SMarcin Niestroj 		return ret;
204*c9e40e65SMarcin Niestroj 
205*c9e40e65SMarcin Niestroj 	enable_enet_clk(1);
206*c9e40e65SMarcin Niestroj 
207*c9e40e65SMarcin Niestroj 	return 0;
208*c9e40e65SMarcin Niestroj }
209*c9e40e65SMarcin Niestroj #endif
210*c9e40e65SMarcin Niestroj 
211*c9e40e65SMarcin Niestroj #ifdef CONFIG_USB_EHCI_MX6
212*c9e40e65SMarcin Niestroj int board_usb_phy_mode(int port)
213*c9e40e65SMarcin Niestroj {
214*c9e40e65SMarcin Niestroj 	return USB_INIT_HOST;
215*c9e40e65SMarcin Niestroj }
216*c9e40e65SMarcin Niestroj #endif
217*c9e40e65SMarcin Niestroj 
218*c9e40e65SMarcin Niestroj int board_early_init_f(void)
219*c9e40e65SMarcin Niestroj {
220*c9e40e65SMarcin Niestroj 	setup_iomux_uart();
221*c9e40e65SMarcin Niestroj 
222*c9e40e65SMarcin Niestroj 	return 0;
223*c9e40e65SMarcin Niestroj }
224*c9e40e65SMarcin Niestroj 
225*c9e40e65SMarcin Niestroj int board_init(void)
226*c9e40e65SMarcin Niestroj {
227*c9e40e65SMarcin Niestroj 	/* Address of boot parameters */
228*c9e40e65SMarcin Niestroj 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
229*c9e40e65SMarcin Niestroj 
230*c9e40e65SMarcin Niestroj #ifdef	CONFIG_FEC_MXC
231*c9e40e65SMarcin Niestroj 	setup_fec();
232*c9e40e65SMarcin Niestroj #endif
233*c9e40e65SMarcin Niestroj 
234*c9e40e65SMarcin Niestroj 	return 0;
235*c9e40e65SMarcin Niestroj }
236*c9e40e65SMarcin Niestroj 
237*c9e40e65SMarcin Niestroj #ifdef CONFIG_CMD_BMODE
238*c9e40e65SMarcin Niestroj static const struct boot_mode board_boot_modes[] = {
239*c9e40e65SMarcin Niestroj 	/* 4 bit bus width */
240*c9e40e65SMarcin Niestroj 	{"sd",   MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)},
241*c9e40e65SMarcin Niestroj 	{"emmc", MAKE_CFGVAL(0x60, 0x48, 0x00, 0x00)},
242*c9e40e65SMarcin Niestroj 	{NULL,	 0},
243*c9e40e65SMarcin Niestroj };
244*c9e40e65SMarcin Niestroj #endif
245*c9e40e65SMarcin Niestroj 
246*c9e40e65SMarcin Niestroj int board_late_init(void)
247*c9e40e65SMarcin Niestroj {
248*c9e40e65SMarcin Niestroj #ifdef CONFIG_CMD_BMODE
249*c9e40e65SMarcin Niestroj 	add_board_boot_modes(board_boot_modes);
250*c9e40e65SMarcin Niestroj #endif
251*c9e40e65SMarcin Niestroj 
252*c9e40e65SMarcin Niestroj #ifdef CONFIG_ENV_IS_IN_MMC
253*c9e40e65SMarcin Niestroj 	board_late_mmc_init();
254*c9e40e65SMarcin Niestroj #endif
255*c9e40e65SMarcin Niestroj 
256*c9e40e65SMarcin Niestroj 	return 0;
257*c9e40e65SMarcin Niestroj }
258*c9e40e65SMarcin Niestroj 
259*c9e40e65SMarcin Niestroj int checkboard(void)
260*c9e40e65SMarcin Niestroj {
261*c9e40e65SMarcin Niestroj 	puts("Board: Grinn liteBoard\n");
262*c9e40e65SMarcin Niestroj 
263*c9e40e65SMarcin Niestroj 	return 0;
264*c9e40e65SMarcin Niestroj }
265*c9e40e65SMarcin Niestroj 
266*c9e40e65SMarcin Niestroj #ifdef CONFIG_SPL_BUILD
267*c9e40e65SMarcin Niestroj void board_boot_order(u32 *spl_boot_list)
268*c9e40e65SMarcin Niestroj {
269*c9e40e65SMarcin Niestroj 	struct src *psrc = (struct src *)SRC_BASE_ADDR;
270*c9e40e65SMarcin Niestroj 	unsigned gpr10_boot = readl(&psrc->gpr10) & (1 << 28);
271*c9e40e65SMarcin Niestroj 	unsigned reg = gpr10_boot ? readl(&psrc->gpr9) : readl(&psrc->sbmr1);
272*c9e40e65SMarcin Niestroj 	unsigned port = (reg >> 11) & 0x1;
273*c9e40e65SMarcin Niestroj 
274*c9e40e65SMarcin Niestroj 	if (port == 0) {
275*c9e40e65SMarcin Niestroj 		spl_boot_list[0] = BOOT_DEVICE_MMC1;
276*c9e40e65SMarcin Niestroj 		spl_boot_list[1] = BOOT_DEVICE_MMC2;
277*c9e40e65SMarcin Niestroj 	} else {
278*c9e40e65SMarcin Niestroj 		spl_boot_list[0] = BOOT_DEVICE_MMC2;
279*c9e40e65SMarcin Niestroj 		spl_boot_list[1] = BOOT_DEVICE_MMC1;
280*c9e40e65SMarcin Niestroj 	}
281*c9e40e65SMarcin Niestroj }
282*c9e40e65SMarcin Niestroj 
283*c9e40e65SMarcin Niestroj void board_init_f(ulong dummy)
284*c9e40e65SMarcin Niestroj {
285*c9e40e65SMarcin Niestroj 	litesom_init_f();
286*c9e40e65SMarcin Niestroj }
287*c9e40e65SMarcin Niestroj #endif
288