xref: /rk3399_rockchip-uboot/arch/arm/mach-imx/mx6/opos6ul.c (revision 0e00a84cdedf7a1949486746225b35984b351eca)
1552a848eSStefano Babic /*
2552a848eSStefano Babic  * Copyright (C) 2017 Armadeus Systems
3552a848eSStefano Babic  *
4552a848eSStefano Babic  * SPDX-License-Identifier:	GPL-2.0+
5552a848eSStefano Babic  */
6552a848eSStefano Babic 
7552a848eSStefano Babic #include <asm/arch/clock.h>
8552a848eSStefano Babic #include <asm/arch/crm_regs.h>
9552a848eSStefano Babic #include <asm/arch/imx-regs.h>
10552a848eSStefano Babic #include <asm/arch/iomux.h>
11552a848eSStefano Babic #include <asm/arch/mx6-pins.h>
12552a848eSStefano Babic #include <asm/arch/mx6ul_pins.h>
13552a848eSStefano Babic #include <asm/arch/sys_proto.h>
14552a848eSStefano Babic #include <asm/gpio.h>
15552a848eSStefano Babic #include <asm/mach-imx/iomux-v3.h>
16552a848eSStefano Babic #include <asm/io.h>
17552a848eSStefano Babic #include <common.h>
18552a848eSStefano Babic #include <environment.h>
19552a848eSStefano Babic #include <fsl_esdhc.h>
20552a848eSStefano Babic #include <mmc.h>
21552a848eSStefano Babic 
22552a848eSStefano Babic DECLARE_GLOBAL_DATA_PTR;
23552a848eSStefano Babic 
24552a848eSStefano Babic #ifdef CONFIG_FEC_MXC
25552a848eSStefano Babic #include <miiphy.h>
26552a848eSStefano Babic 
27552a848eSStefano Babic #define MDIO_PAD_CTRL ( \
28552a848eSStefano Babic 	PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
29552a848eSStefano Babic 	PAD_CTL_DSE_40ohm \
30552a848eSStefano Babic )
31552a848eSStefano Babic 
32552a848eSStefano Babic #define ENET_PAD_CTRL_PU ( \
33552a848eSStefano Babic 	PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
34552a848eSStefano Babic 	PAD_CTL_DSE_40ohm \
35552a848eSStefano Babic )
36552a848eSStefano Babic 
37552a848eSStefano Babic #define ENET_PAD_CTRL_PD ( \
38552a848eSStefano Babic 	PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED | \
39552a848eSStefano Babic 	PAD_CTL_DSE_40ohm \
40552a848eSStefano Babic )
41552a848eSStefano Babic 
42552a848eSStefano Babic #define ENET_CLK_PAD_CTRL ( \
43552a848eSStefano Babic 	PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \
44552a848eSStefano Babic 	PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST \
45552a848eSStefano Babic )
46552a848eSStefano Babic 
47552a848eSStefano Babic static iomux_v3_cfg_t const fec1_pads[] = {
48552a848eSStefano Babic 	MX6_PAD_GPIO1_IO06__ENET1_MDIO        | MUX_PAD_CTRL(MDIO_PAD_CTRL),
49552a848eSStefano Babic 	MX6_PAD_GPIO1_IO07__ENET1_MDC         | MUX_PAD_CTRL(MDIO_PAD_CTRL),
50552a848eSStefano Babic 	MX6_PAD_ENET1_RX_ER__ENET1_RX_ER      | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
51552a848eSStefano Babic 	MX6_PAD_ENET1_RX_EN__ENET1_RX_EN      | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
52552a848eSStefano Babic 	MX6_PAD_ENET1_RX_DATA1__ENET1_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
53552a848eSStefano Babic 	MX6_PAD_ENET1_RX_DATA0__ENET1_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
54552a848eSStefano Babic 	MX6_PAD_ENET1_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL_PU),
55552a848eSStefano Babic 	MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL_PU),
56552a848eSStefano Babic 	MX6_PAD_ENET1_TX_EN__ENET1_TX_EN      | MUX_PAD_CTRL(ENET_PAD_CTRL_PU),
57552a848eSStefano Babic 	/* PHY Int */
58552a848eSStefano Babic 	MX6_PAD_NAND_DQS__GPIO4_IO16          | MUX_PAD_CTRL(ENET_PAD_CTRL_PU),
59552a848eSStefano Babic 	/* PHY Reset */
60552a848eSStefano Babic 	MX6_PAD_NAND_DATA00__GPIO4_IO02       | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
61552a848eSStefano Babic 	MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),
62552a848eSStefano Babic };
63552a848eSStefano Babic 
board_phy_config(struct phy_device * phydev)64552a848eSStefano Babic int board_phy_config(struct phy_device *phydev)
65552a848eSStefano Babic {
66552a848eSStefano Babic 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x8190);
67552a848eSStefano Babic 
68552a848eSStefano Babic 	if (phydev->drv->config)
69552a848eSStefano Babic 		phydev->drv->config(phydev);
70552a848eSStefano Babic 
71552a848eSStefano Babic 	return 0;
72552a848eSStefano Babic }
73552a848eSStefano Babic 
board_eth_init(bd_t * bis)74552a848eSStefano Babic int board_eth_init(bd_t *bis)
75552a848eSStefano Babic {
76552a848eSStefano Babic 	struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
77552a848eSStefano Babic 	struct gpio_desc rst;
78552a848eSStefano Babic 	int ret;
79552a848eSStefano Babic 
80552a848eSStefano Babic 	/* Use 50M anatop loopback REF_CLK1 for ENET1,
81552a848eSStefano Babic 	 * clear gpr1[13], set gpr1[17] */
82552a848eSStefano Babic 	clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK,
83552a848eSStefano Babic 			IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK);
84552a848eSStefano Babic 
85552a848eSStefano Babic 	ret = enable_fec_anatop_clock(0, ENET_50MHZ);
86552a848eSStefano Babic 	if (ret)
87552a848eSStefano Babic 		return ret;
88552a848eSStefano Babic 
89552a848eSStefano Babic 	enable_enet_clk(1);
90552a848eSStefano Babic 
91552a848eSStefano Babic 	imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads));
92552a848eSStefano Babic 
93552a848eSStefano Babic 	ret = dm_gpio_lookup_name("GPIO4_2", &rst);
94552a848eSStefano Babic 	if (ret) {
95552a848eSStefano Babic 		printf("Cannot get GPIO4_2\n");
96552a848eSStefano Babic 		return ret;
97552a848eSStefano Babic 	}
98552a848eSStefano Babic 
99552a848eSStefano Babic 	ret = dm_gpio_request(&rst, "phy-rst");
100552a848eSStefano Babic 	if (ret) {
101552a848eSStefano Babic 		printf("Cannot request GPIO4_2\n");
102552a848eSStefano Babic 		return ret;
103552a848eSStefano Babic 	}
104552a848eSStefano Babic 
105552a848eSStefano Babic 	dm_gpio_set_dir_flags(&rst, GPIOD_IS_OUT);
106552a848eSStefano Babic 	dm_gpio_set_value(&rst, 0);
107552a848eSStefano Babic 	udelay(1000);
108552a848eSStefano Babic 	dm_gpio_set_value(&rst, 1);
109552a848eSStefano Babic 
110552a848eSStefano Babic 	return fecmxc_initialize(bis);
111552a848eSStefano Babic }
112552a848eSStefano Babic #endif /* CONFIG_FEC_MXC */
113552a848eSStefano Babic 
board_init(void)114552a848eSStefano Babic int board_init(void)
115552a848eSStefano Babic {
116552a848eSStefano Babic 	/* Address of boot parameters */
117552a848eSStefano Babic 	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
118552a848eSStefano Babic 
119552a848eSStefano Babic 	return 0;
120552a848eSStefano Babic }
121552a848eSStefano Babic 
opos6ul_board_late_init(void)122552a848eSStefano Babic int __weak opos6ul_board_late_init(void)
123552a848eSStefano Babic {
124552a848eSStefano Babic 	return 0;
125552a848eSStefano Babic }
126552a848eSStefano Babic 
board_late_init(void)127552a848eSStefano Babic int board_late_init(void)
128552a848eSStefano Babic {
129552a848eSStefano Babic 	struct src *psrc = (struct src *)SRC_BASE_ADDR;
130552a848eSStefano Babic 	unsigned reg = readl(&psrc->sbmr2);
131552a848eSStefano Babic 
132552a848eSStefano Babic 	/* In bootstrap don't use the env vars */
133552a848eSStefano Babic 	if (((reg & 0x3000000) >> 24) == 0x1) {
134552a848eSStefano Babic 		set_default_env(NULL);
135382bee57SSimon Glass 		env_set("preboot", "");
136552a848eSStefano Babic 	}
137552a848eSStefano Babic 
138552a848eSStefano Babic 	return opos6ul_board_late_init();
139552a848eSStefano Babic }
140552a848eSStefano Babic 
board_mmc_getcd(struct mmc * mmc)141552a848eSStefano Babic int board_mmc_getcd(struct mmc *mmc)
142552a848eSStefano Babic {
143552a848eSStefano Babic 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
144552a848eSStefano Babic 	return cfg->esdhc_base == USDHC1_BASE_ADDR;
145552a848eSStefano Babic }
146552a848eSStefano Babic 
dram_init(void)147552a848eSStefano Babic int dram_init(void)
148552a848eSStefano Babic {
149552a848eSStefano Babic 	gd->ram_size = imx_ddr_size();
150552a848eSStefano Babic 
151552a848eSStefano Babic 	return 0;
152552a848eSStefano Babic }
153552a848eSStefano Babic 
154552a848eSStefano Babic #ifdef CONFIG_SPL_BUILD
155552a848eSStefano Babic #include <asm/arch/mx6-ddr.h>
156552a848eSStefano Babic #include <asm/arch/opos6ul.h>
157*0e00a84cSMasahiro Yamada #include <linux/libfdt.h>
158552a848eSStefano Babic #include <spl.h>
159552a848eSStefano Babic 
160552a848eSStefano Babic #define USDHC_PAD_CTRL (                                       \
161552a848eSStefano Babic 	PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_MED | \
162552a848eSStefano Babic 	PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST                   \
163552a848eSStefano Babic )
164552a848eSStefano Babic 
165552a848eSStefano Babic struct fsl_esdhc_cfg usdhc_cfg[1] = {
166552a848eSStefano Babic 	{USDHC1_BASE_ADDR, 0, 8},
167552a848eSStefano Babic };
168552a848eSStefano Babic 
169552a848eSStefano Babic static iomux_v3_cfg_t const usdhc1_pads[] = {
170552a848eSStefano Babic 	MX6_PAD_SD1_CLK__USDHC1_CLK        | MUX_PAD_CTRL(USDHC_PAD_CTRL),
171552a848eSStefano Babic 	MX6_PAD_SD1_CMD__USDHC1_CMD        | MUX_PAD_CTRL(USDHC_PAD_CTRL),
172552a848eSStefano Babic 	MX6_PAD_SD1_DATA0__USDHC1_DATA0    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
173552a848eSStefano Babic 	MX6_PAD_SD1_DATA1__USDHC1_DATA1    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
174552a848eSStefano Babic 	MX6_PAD_SD1_DATA2__USDHC1_DATA2    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
175552a848eSStefano Babic 	MX6_PAD_SD1_DATA3__USDHC1_DATA3    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
176552a848eSStefano Babic 	MX6_PAD_NAND_READY_B__USDHC1_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
177552a848eSStefano Babic 	MX6_PAD_NAND_CE0_B__USDHC1_DATA5   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
178552a848eSStefano Babic 	MX6_PAD_NAND_CE1_B__USDHC1_DATA6   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
179552a848eSStefano Babic 	MX6_PAD_NAND_CLE__USDHC1_DATA7     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
180552a848eSStefano Babic };
181552a848eSStefano Babic 
182552a848eSStefano Babic static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = {
183552a848eSStefano Babic 	.grp_addds = 0x00000030,
184552a848eSStefano Babic 	.grp_ddrmode_ctl = 0x00020000,
185552a848eSStefano Babic 	.grp_b0ds = 0x00000030,
186552a848eSStefano Babic 	.grp_ctlds = 0x00000030,
187552a848eSStefano Babic 	.grp_b1ds = 0x00000030,
188552a848eSStefano Babic 	.grp_ddrpke = 0x00000000,
189552a848eSStefano Babic 	.grp_ddrmode = 0x00020000,
190552a848eSStefano Babic 	.grp_ddr_type = 0x000c0000,
191552a848eSStefano Babic };
192552a848eSStefano Babic 
193552a848eSStefano Babic static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = {
194552a848eSStefano Babic 	.dram_dqm0 = 0x00000030,
195552a848eSStefano Babic 	.dram_dqm1 = 0x00000030,
196552a848eSStefano Babic 	.dram_ras = 0x00000030,
197552a848eSStefano Babic 	.dram_cas = 0x00000030,
198552a848eSStefano Babic 	.dram_odt0 = 0x00000030,
199552a848eSStefano Babic 	.dram_odt1 = 0x00000030,
200552a848eSStefano Babic 	.dram_sdba2 = 0x00000000,
201552a848eSStefano Babic 	.dram_sdclk_0 = 0x00000008,
202552a848eSStefano Babic 	.dram_sdqs0 = 0x00000038,
203552a848eSStefano Babic 	.dram_sdqs1 = 0x00000030,
204552a848eSStefano Babic 	.dram_reset = 0x00000030,
205552a848eSStefano Babic };
206552a848eSStefano Babic 
207552a848eSStefano Babic static struct mx6_mmdc_calibration mx6_mmcd_calib = {
208552a848eSStefano Babic 	.p0_mpwldectrl0 = 0x00070007,
209552a848eSStefano Babic 	.p0_mpdgctrl0 = 0x41490145,
210552a848eSStefano Babic 	.p0_mprddlctl = 0x40404546,
211552a848eSStefano Babic 	.p0_mpwrdlctl = 0x4040524D,
212552a848eSStefano Babic };
213552a848eSStefano Babic 
214552a848eSStefano Babic struct mx6_ddr_sysinfo ddr_sysinfo = {
215552a848eSStefano Babic 	.dsize = 0,
216552a848eSStefano Babic 	.cs_density = 20,
217552a848eSStefano Babic 	.ncs = 1,
218552a848eSStefano Babic 	.cs1_mirror = 0,
219552a848eSStefano Babic 	.rtt_wr = 2,
220552a848eSStefano Babic 	.rtt_nom = 1,		/* RTT_Nom = RZQ/2 */
221552a848eSStefano Babic 	.walat = 1,		/* Write additional latency */
222552a848eSStefano Babic 	.ralat = 5,		/* Read additional latency */
223552a848eSStefano Babic 	.mif3_mode = 3,		/* Command prediction working mode */
224552a848eSStefano Babic 	.bi_on = 1,		/* Bank interleaving enabled */
225552a848eSStefano Babic 	.sde_to_rst = 0x10,	/* 14 cycles, 200us (JEDEC default) */
226552a848eSStefano Babic 	.rst_to_cke = 0x23,	/* 33 cycles, 500us (JEDEC default) */
227552a848eSStefano Babic 	.ddr_type = DDR_TYPE_DDR3,
228552a848eSStefano Babic };
229552a848eSStefano Babic 
230552a848eSStefano Babic static struct mx6_ddr3_cfg mem_ddr = {
231552a848eSStefano Babic 	.mem_speed = 800,
232552a848eSStefano Babic 	.density = 2,
233552a848eSStefano Babic 	.width = 16,
234552a848eSStefano Babic 	.banks = 8,
235552a848eSStefano Babic 	.rowaddr = 14,
236552a848eSStefano Babic 	.coladdr = 10,
237552a848eSStefano Babic 	.pagesz = 2,
238552a848eSStefano Babic 	.trcd = 1500,
239552a848eSStefano Babic 	.trcmin = 5250,
240552a848eSStefano Babic 	.trasmin = 3750,
241552a848eSStefano Babic };
242552a848eSStefano Babic 
board_mmc_init(bd_t * bis)243552a848eSStefano Babic int board_mmc_init(bd_t *bis)
244552a848eSStefano Babic {
245552a848eSStefano Babic 	imx_iomux_v3_setup_multiple_pads(usdhc1_pads, ARRAY_SIZE(usdhc1_pads));
246552a848eSStefano Babic 	usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
247552a848eSStefano Babic 	return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
248552a848eSStefano Babic }
249552a848eSStefano Babic 
ccgr_init(void)250552a848eSStefano Babic static void ccgr_init(void)
251552a848eSStefano Babic {
252552a848eSStefano Babic 	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
253552a848eSStefano Babic 
254552a848eSStefano Babic 	writel(0xFFFFFFFF, &ccm->CCGR0);
255552a848eSStefano Babic 	writel(0xFFFFFFFF, &ccm->CCGR1);
256552a848eSStefano Babic 	writel(0xFFFFFFFF, &ccm->CCGR2);
257552a848eSStefano Babic 	writel(0xFFFFFFFF, &ccm->CCGR3);
258552a848eSStefano Babic 	writel(0xFFFFFFFF, &ccm->CCGR4);
259552a848eSStefano Babic 	writel(0xFFFFFFFF, &ccm->CCGR5);
260552a848eSStefano Babic 	writel(0xFFFFFFFF, &ccm->CCGR6);
261552a848eSStefano Babic 	writel(0xFFFFFFFF, &ccm->CCGR7);
262552a848eSStefano Babic }
263552a848eSStefano Babic 
spl_dram_init(void)264552a848eSStefano Babic static void spl_dram_init(void)
265552a848eSStefano Babic {
266552a848eSStefano Babic 	struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
267552a848eSStefano Babic 	struct fuse_bank *bank = &ocotp->bank[4];
268552a848eSStefano Babic 	struct fuse_bank4_regs *fuse =
269552a848eSStefano Babic 		(struct fuse_bank4_regs *)bank->fuse_regs;
270552a848eSStefano Babic 	int reg = readl(&fuse->gp1);
271552a848eSStefano Babic 
272552a848eSStefano Babic 	/* 512MB of RAM */
273552a848eSStefano Babic 	if (reg & 0x1) {
274552a848eSStefano Babic 		mem_ddr.density = 4;
275552a848eSStefano Babic 		mem_ddr.rowaddr = 15;
276552a848eSStefano Babic 		mem_ddr.trcd = 1375;
277552a848eSStefano Babic 		mem_ddr.trcmin = 4875;
278552a848eSStefano Babic 		mem_ddr.trasmin = 3500;
279552a848eSStefano Babic 	}
280552a848eSStefano Babic 
281552a848eSStefano Babic 	mx6ul_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
282552a848eSStefano Babic 	mx6_dram_cfg(&ddr_sysinfo, &mx6_mmcd_calib, &mem_ddr);
283552a848eSStefano Babic }
284552a848eSStefano Babic 
board_init_f(ulong dummy)285552a848eSStefano Babic void board_init_f(ulong dummy)
286552a848eSStefano Babic {
287552a848eSStefano Babic 	ccgr_init();
288552a848eSStefano Babic 
289552a848eSStefano Babic 	/* setup AIPS and disable watchdog */
290552a848eSStefano Babic 	arch_cpu_init();
291552a848eSStefano Babic 
292552a848eSStefano Babic 	/* setup GP timer */
293552a848eSStefano Babic 	timer_init();
294552a848eSStefano Babic 
295552a848eSStefano Babic 	/* UART clocks enabled and gd valid - init serial console */
296552a848eSStefano Babic 	opos6ul_setup_uart_debug();
297552a848eSStefano Babic 	preloader_console_init();
298552a848eSStefano Babic 
299552a848eSStefano Babic 	/* DDR initialization */
300552a848eSStefano Babic 	spl_dram_init();
301552a848eSStefano Babic }
302552a848eSStefano Babic #endif /* CONFIG_SPL_BUILD */
303