xref: /rk3399_rockchip-uboot/board/freescale/mx35pdk/mx35pdk.c (revision a05f4ab6cc84a92c02ff1dbe2eb8a70161de4cbb)
1eae4988bSStefano Babic /*
2eae4988bSStefano Babic  * Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
3eae4988bSStefano Babic  *
4eae4988bSStefano Babic  * (C) Copyright 2008-2010 Freescale Semiconductor, Inc.
5eae4988bSStefano Babic  *
61a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
7eae4988bSStefano Babic  */
8eae4988bSStefano Babic 
9eae4988bSStefano Babic #include <common.h>
10eae4988bSStefano Babic #include <asm/io.h>
11eae4988bSStefano Babic #include <asm/errno.h>
12eae4988bSStefano Babic #include <asm/arch/imx-regs.h>
13eae4988bSStefano Babic #include <asm/arch/crm_regs.h>
14a2ac1b3aSBenoît Thébaudeau #include <asm/arch/clock.h>
15105c9eafSBenoît Thébaudeau #include <asm/arch/iomux-mx35.h>
16eae4988bSStefano Babic #include <i2c.h>
17c7336815SŁukasz Majewski #include <power/pmic.h>
18eae4988bSStefano Babic #include <fsl_pmic.h>
193292539eSStefano Babic #include <mmc.h>
203292539eSStefano Babic #include <fsl_esdhc.h>
21eae4988bSStefano Babic #include <mc9sdz60.h>
22eae4988bSStefano Babic #include <mc13892.h>
23eae4988bSStefano Babic #include <linux/types.h>
24a4adedd4SStefano Babic #include <asm/gpio.h>
25eae4988bSStefano Babic #include <asm/arch/sys_proto.h>
26eae4988bSStefano Babic #include <netdev.h>
27eae4988bSStefano Babic 
289660e442SHelmut Raiger #ifndef CONFIG_BOARD_LATE_INIT
299660e442SHelmut Raiger #error "CONFIG_BOARD_LATE_INIT must be set for this board"
30eae4988bSStefano Babic #endif
31eae4988bSStefano Babic 
32eae4988bSStefano Babic #ifndef CONFIG_BOARD_EARLY_INIT_F
33eae4988bSStefano Babic #error "CONFIG_BOARD_EARLY_INIT_F must be set for this board"
34eae4988bSStefano Babic #endif
35eae4988bSStefano Babic 
36eae4988bSStefano Babic DECLARE_GLOBAL_DATA_PTR;
37eae4988bSStefano Babic 
38eae4988bSStefano Babic int dram_init(void)
39eae4988bSStefano Babic {
406b5acfc1SStefano Babic 	u32 size1, size2;
416b5acfc1SStefano Babic 
426b5acfc1SStefano Babic 	size1 = get_ram_size((void *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
436b5acfc1SStefano Babic 	size2 = get_ram_size((void *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE);
446b5acfc1SStefano Babic 
456b5acfc1SStefano Babic 	gd->ram_size = size1 + size2;
46eae4988bSStefano Babic 
47eae4988bSStefano Babic 	return 0;
48eae4988bSStefano Babic }
49eae4988bSStefano Babic 
506b5acfc1SStefano Babic void dram_init_banksize(void)
516b5acfc1SStefano Babic {
526b5acfc1SStefano Babic 	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
536b5acfc1SStefano Babic 	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
546b5acfc1SStefano Babic 
556b5acfc1SStefano Babic 	gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
566b5acfc1SStefano Babic 	gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
576b5acfc1SStefano Babic }
586b5acfc1SStefano Babic 
59105c9eafSBenoît Thébaudeau #define I2C_PAD_CTRL	(PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_ODE)
60105c9eafSBenoît Thébaudeau 
61eae4988bSStefano Babic static void setup_iomux_i2c(void)
62eae4988bSStefano Babic {
63105c9eafSBenoît Thébaudeau 	static const iomux_v3_cfg_t i2c1_pads[] = {
64105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_I2C1_CLK__I2C1_SCL, I2C_PAD_CTRL),
65105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_I2C1_DAT__I2C1_SDA, I2C_PAD_CTRL),
66105c9eafSBenoît Thébaudeau 	};
67eae4988bSStefano Babic 
68eae4988bSStefano Babic 	/* setup pins for I2C1 */
69105c9eafSBenoît Thébaudeau 	imx_iomux_v3_setup_multiple_pads(i2c1_pads, ARRAY_SIZE(i2c1_pads));
70eae4988bSStefano Babic }
71eae4988bSStefano Babic 
72eae4988bSStefano Babic 
73eae4988bSStefano Babic static void setup_iomux_spi(void)
74eae4988bSStefano Babic {
75105c9eafSBenoît Thébaudeau 	static const iomux_v3_cfg_t spi_pads[] = {
76105c9eafSBenoît Thébaudeau 		MX35_PAD_CSPI1_MOSI__CSPI1_MOSI,
77105c9eafSBenoît Thébaudeau 		MX35_PAD_CSPI1_MISO__CSPI1_MISO,
78105c9eafSBenoît Thébaudeau 		MX35_PAD_CSPI1_SS0__CSPI1_SS0,
79105c9eafSBenoît Thébaudeau 		MX35_PAD_CSPI1_SS1__CSPI1_SS1,
80105c9eafSBenoît Thébaudeau 		MX35_PAD_CSPI1_SCLK__CSPI1_SCLK,
81105c9eafSBenoît Thébaudeau 	};
82105c9eafSBenoît Thébaudeau 
83105c9eafSBenoît Thébaudeau 	imx_iomux_v3_setup_multiple_pads(spi_pads, ARRAY_SIZE(spi_pads));
84eae4988bSStefano Babic }
85eae4988bSStefano Babic 
86105c9eafSBenoît Thébaudeau #define USBOTG_IN_PAD_CTRL	(PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | \
87105c9eafSBenoît Thébaudeau 				 PAD_CTL_DSE_LOW | PAD_CTL_SRE_SLOW)
88105c9eafSBenoît Thébaudeau #define USBOTG_OUT_PAD_CTRL	(PAD_CTL_DSE_LOW | PAD_CTL_SRE_SLOW)
89105c9eafSBenoît Thébaudeau 
90961a7628SBenoît Thébaudeau static void setup_iomux_usbotg(void)
91961a7628SBenoît Thébaudeau {
92105c9eafSBenoît Thébaudeau 	static const iomux_v3_cfg_t usbotg_pads[] = {
93105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
94105c9eafSBenoît Thébaudeau 				USBOTG_OUT_PAD_CTRL),
95105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
96105c9eafSBenoît Thébaudeau 				USBOTG_IN_PAD_CTRL),
97105c9eafSBenoît Thébaudeau 	};
98961a7628SBenoît Thébaudeau 
99961a7628SBenoît Thébaudeau 	/* Set up pins for USBOTG. */
100105c9eafSBenoît Thébaudeau 	imx_iomux_v3_setup_multiple_pads(usbotg_pads, ARRAY_SIZE(usbotg_pads));
101961a7628SBenoît Thébaudeau }
102961a7628SBenoît Thébaudeau 
103105c9eafSBenoît Thébaudeau #define FEC_PAD_CTRL	(PAD_CTL_DSE_LOW | PAD_CTL_SRE_SLOW)
104105c9eafSBenoît Thébaudeau 
105eae4988bSStefano Babic static void setup_iomux_fec(void)
106eae4988bSStefano Babic {
107105c9eafSBenoît Thébaudeau 	static const iomux_v3_cfg_t fec_pads[] = {
108105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_TX_CLK__FEC_TX_CLK, FEC_PAD_CTRL |
109105c9eafSBenoît Thébaudeau 					PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
110105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_RX_CLK__FEC_RX_CLK, FEC_PAD_CTRL |
111105c9eafSBenoît Thébaudeau 					PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
112105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_RX_DV__FEC_RX_DV, FEC_PAD_CTRL |
113105c9eafSBenoît Thébaudeau 					PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
114105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_COL__FEC_COL, FEC_PAD_CTRL |
115105c9eafSBenoît Thébaudeau 					PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
116105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_RDATA0__FEC_RDATA_0, FEC_PAD_CTRL |
117105c9eafSBenoît Thébaudeau 					PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
118105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_TDATA0__FEC_TDATA_0, FEC_PAD_CTRL),
119105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_TX_EN__FEC_TX_EN, FEC_PAD_CTRL),
120105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_MDC__FEC_MDC, FEC_PAD_CTRL),
121105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_MDIO__FEC_MDIO, FEC_PAD_CTRL |
122105c9eafSBenoît Thébaudeau 					PAD_CTL_HYS | PAD_CTL_PUS_22K_UP),
123105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_TX_ERR__FEC_TX_ERR, FEC_PAD_CTRL),
124105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_RX_ERR__FEC_RX_ERR, FEC_PAD_CTRL |
125105c9eafSBenoît Thébaudeau 					PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
126105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_CRS__FEC_CRS, FEC_PAD_CTRL |
127105c9eafSBenoît Thébaudeau 					PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
128105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_RDATA1__FEC_RDATA_1, FEC_PAD_CTRL |
129105c9eafSBenoît Thébaudeau 					PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
130105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_TDATA1__FEC_TDATA_1, FEC_PAD_CTRL),
131105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_RDATA2__FEC_RDATA_2, FEC_PAD_CTRL |
132105c9eafSBenoît Thébaudeau 					PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
133105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_TDATA2__FEC_TDATA_2, FEC_PAD_CTRL),
134105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_RDATA3__FEC_RDATA_3, FEC_PAD_CTRL |
135105c9eafSBenoît Thébaudeau 					PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
136105c9eafSBenoît Thébaudeau 		NEW_PAD_CTRL(MX35_PAD_FEC_TDATA3__FEC_TDATA_3, FEC_PAD_CTRL),
137105c9eafSBenoît Thébaudeau 	};
138eae4988bSStefano Babic 
139eae4988bSStefano Babic 	/* setup pins for FEC */
140105c9eafSBenoît Thébaudeau 	imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads));
141eae4988bSStefano Babic }
142eae4988bSStefano Babic 
143eae4988bSStefano Babic int board_early_init_f(void)
144eae4988bSStefano Babic {
145eae4988bSStefano Babic 	struct ccm_regs *ccm =
146eae4988bSStefano Babic 		(struct ccm_regs *)IMX_CCM_BASE;
147eae4988bSStefano Babic 
148eae4988bSStefano Babic 	/* enable clocks */
149eae4988bSStefano Babic 	writel(readl(&ccm->cgr0) |
150eae4988bSStefano Babic 		MXC_CCM_CGR0_EMI_MASK |
15134a31bf5SBenoît Thébaudeau 		MXC_CCM_CGR0_EDIO_MASK |
152eae4988bSStefano Babic 		MXC_CCM_CGR0_EPIT1_MASK,
153eae4988bSStefano Babic 		&ccm->cgr0);
154eae4988bSStefano Babic 
155eae4988bSStefano Babic 	writel(readl(&ccm->cgr1) |
156eae4988bSStefano Babic 		MXC_CCM_CGR1_FEC_MASK |
157eae4988bSStefano Babic 		MXC_CCM_CGR1_GPIO1_MASK |
158eae4988bSStefano Babic 		MXC_CCM_CGR1_GPIO2_MASK |
159eae4988bSStefano Babic 		MXC_CCM_CGR1_GPIO3_MASK |
160eae4988bSStefano Babic 		MXC_CCM_CGR1_I2C1_MASK |
161eae4988bSStefano Babic 		MXC_CCM_CGR1_I2C2_MASK |
162eae4988bSStefano Babic 		MXC_CCM_CGR1_IPU_MASK,
163eae4988bSStefano Babic 		&ccm->cgr1);
164eae4988bSStefano Babic 
165eae4988bSStefano Babic 	/* Setup NAND */
166eae4988bSStefano Babic 	__raw_writel(readl(&ccm->rcsr) | MXC_CCM_RCSR_NFC_FMS, &ccm->rcsr);
167eae4988bSStefano Babic 
168eae4988bSStefano Babic 	setup_iomux_i2c();
169961a7628SBenoît Thébaudeau 	setup_iomux_usbotg();
170eae4988bSStefano Babic 	setup_iomux_fec();
171eae4988bSStefano Babic 	setup_iomux_spi();
172eae4988bSStefano Babic 
173eae4988bSStefano Babic 	return 0;
174eae4988bSStefano Babic }
175eae4988bSStefano Babic 
176eae4988bSStefano Babic int board_init(void)
177eae4988bSStefano Babic {
178eae4988bSStefano Babic 	gd->bd->bi_arch_number = MACH_TYPE_MX35_3DS;	/* board id for linux */
179eae4988bSStefano Babic 	/* address of boot parameters */
180eae4988bSStefano Babic 	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
181eae4988bSStefano Babic 
182eae4988bSStefano Babic 	return 0;
183eae4988bSStefano Babic }
184eae4988bSStefano Babic 
185eae4988bSStefano Babic static inline int pmic_detect(void)
186eae4988bSStefano Babic {
1875213d6e4SStefano Babic 	unsigned int id;
188c7336815SŁukasz Majewski 	struct pmic *p = pmic_get("FSL_PMIC");
189c7336815SŁukasz Majewski 	if (!p)
190c7336815SŁukasz Majewski 		return -ENODEV;
191eae4988bSStefano Babic 
1925213d6e4SStefano Babic 	pmic_reg_read(p, REG_IDENTIFICATION, &id);
193eae4988bSStefano Babic 
194eae4988bSStefano Babic 	id = (id >> 6) & 0x7;
195eae4988bSStefano Babic 	if (id == 0x7)
196eae4988bSStefano Babic 		return 1;
197eae4988bSStefano Babic 	return 0;
198eae4988bSStefano Babic }
199eae4988bSStefano Babic 
200eae4988bSStefano Babic u32 get_board_rev(void)
201eae4988bSStefano Babic {
202eae4988bSStefano Babic 	int rev;
203eae4988bSStefano Babic 
204eae4988bSStefano Babic 	rev = pmic_detect();
205eae4988bSStefano Babic 
206eae4988bSStefano Babic 	return (get_cpu_rev() & ~(0xF << 8)) | (rev & 0xF) << 8;
207eae4988bSStefano Babic }
208eae4988bSStefano Babic 
209eae4988bSStefano Babic int board_late_init(void)
210eae4988bSStefano Babic {
211eae4988bSStefano Babic 	u8 val;
212eae4988bSStefano Babic 	u32 pmic_val;
2135213d6e4SStefano Babic 	struct pmic *p;
214c7336815SŁukasz Majewski 	int ret;
215eae4988bSStefano Babic 
216c7336815SŁukasz Majewski 	ret = pmic_init(I2C_PMIC);
217c7336815SŁukasz Majewski 	if (ret)
218c7336815SŁukasz Majewski 		return ret;
219c7336815SŁukasz Majewski 
220eae4988bSStefano Babic 	if (pmic_detect()) {
221c7336815SŁukasz Majewski 		p = pmic_get("FSL_PMIC");
222105c9eafSBenoît Thébaudeau 		imx_iomux_v3_setup_pad(MX35_PAD_WDOG_RST__WDOG_WDOG_B);
223eae4988bSStefano Babic 
2245213d6e4SStefano Babic 		pmic_reg_read(p, REG_SETTING_0, &pmic_val);
2255213d6e4SStefano Babic 		pmic_reg_write(p, REG_SETTING_0,
2265213d6e4SStefano Babic 			pmic_val | VO_1_30V | VO_1_50V);
2275213d6e4SStefano Babic 		pmic_reg_read(p, REG_MODE_0, &pmic_val);
2285213d6e4SStefano Babic 		pmic_reg_write(p, REG_MODE_0, pmic_val | VGEN3EN);
229eae4988bSStefano Babic 
230105c9eafSBenoît Thébaudeau 		imx_iomux_v3_setup_pad(MX35_PAD_COMPARE__GPIO1_5);
231eae4988bSStefano Babic 
23268088ceeSBenoît Thébaudeau 		gpio_direction_output(IMX_GPIO_NR(1, 5), 1);
233eae4988bSStefano Babic 	}
234eae4988bSStefano Babic 
235eae4988bSStefano Babic 	val = mc9sdz60_reg_read(MC9SDZ60_REG_GPIO_1) | 0x04;
236eae4988bSStefano Babic 	mc9sdz60_reg_write(MC9SDZ60_REG_GPIO_1, val);
237eae4988bSStefano Babic 	mdelay(200);
238eae4988bSStefano Babic 
239eae4988bSStefano Babic 	val = mc9sdz60_reg_read(MC9SDZ60_REG_RESET_1) & 0x7F;
240eae4988bSStefano Babic 	mc9sdz60_reg_write(MC9SDZ60_REG_RESET_1, val);
241eae4988bSStefano Babic 	mdelay(200);
242eae4988bSStefano Babic 
243eae4988bSStefano Babic 	val |= 0x80;
244eae4988bSStefano Babic 	mc9sdz60_reg_write(MC9SDZ60_REG_RESET_1, val);
245eae4988bSStefano Babic 
246eae4988bSStefano Babic 	/* Print board revision */
247ba901df4SFabio Estevam 	printf("Board: MX35 PDK %d.0\n", ((get_board_rev() >> 8) + 1) & 0x0F);
248eae4988bSStefano Babic 
249eae4988bSStefano Babic 	return 0;
250eae4988bSStefano Babic }
251eae4988bSStefano Babic 
252eae4988bSStefano Babic int board_eth_init(bd_t *bis)
253eae4988bSStefano Babic {
254eae4988bSStefano Babic #if defined(CONFIG_SMC911X)
255*a05f4ab6SFabio Estevam 	int rc = smc911x_initialize(0, CONFIG_SMC911X_BASE);
256*a05f4ab6SFabio Estevam 	if (rc)
257eae4988bSStefano Babic 		return rc;
258*a05f4ab6SFabio Estevam #endif
259*a05f4ab6SFabio Estevam 	return cpu_eth_init(bis);
260eae4988bSStefano Babic }
2613292539eSStefano Babic 
2623292539eSStefano Babic #if defined(CONFIG_FSL_ESDHC)
2633292539eSStefano Babic 
2643292539eSStefano Babic struct fsl_esdhc_cfg esdhc_cfg = {MMC_SDHC1_BASE_ADDR};
2653292539eSStefano Babic 
2663292539eSStefano Babic int board_mmc_init(bd_t *bis)
2673292539eSStefano Babic {
268105c9eafSBenoît Thébaudeau 	static const iomux_v3_cfg_t sdhc1_pads[] = {
269105c9eafSBenoît Thébaudeau 		MX35_PAD_SD1_CMD__ESDHC1_CMD,
270105c9eafSBenoît Thébaudeau 		MX35_PAD_SD1_CLK__ESDHC1_CLK,
271105c9eafSBenoît Thébaudeau 		MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
272105c9eafSBenoît Thébaudeau 		MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
273105c9eafSBenoît Thébaudeau 		MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
274105c9eafSBenoît Thébaudeau 		MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
275105c9eafSBenoît Thébaudeau 	};
276105c9eafSBenoît Thébaudeau 
2773292539eSStefano Babic 	/* configure pins for SDHC1 only */
278105c9eafSBenoît Thébaudeau 	imx_iomux_v3_setup_multiple_pads(sdhc1_pads, ARRAY_SIZE(sdhc1_pads));
2793292539eSStefano Babic 
280a2ac1b3aSBenoît Thébaudeau 	esdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK);
2813292539eSStefano Babic 	return fsl_esdhc_initialize(bis, &esdhc_cfg);
2823292539eSStefano Babic }
2833292539eSStefano Babic 
2843292539eSStefano Babic int board_mmc_getcd(struct mmc *mmc)
2853292539eSStefano Babic {
2863292539eSStefano Babic 	return !(mc9sdz60_reg_read(MC9SDZ60_REG_DES_FLAG) & 0x4);
2873292539eSStefano Babic }
2883292539eSStefano Babic #endif
289