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>
111221ce45SMasahiro Yamada #include <linux/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>
27*c62db35dSSimon Glass #include <asm/mach-types.h>
28eae4988bSStefano Babic
299660e442SHelmut Raiger #ifndef CONFIG_BOARD_LATE_INIT
309660e442SHelmut Raiger #error "CONFIG_BOARD_LATE_INIT must be set for this board"
31eae4988bSStefano Babic #endif
32eae4988bSStefano Babic
33eae4988bSStefano Babic #ifndef CONFIG_BOARD_EARLY_INIT_F
34eae4988bSStefano Babic #error "CONFIG_BOARD_EARLY_INIT_F must be set for this board"
35eae4988bSStefano Babic #endif
36eae4988bSStefano Babic
37eae4988bSStefano Babic DECLARE_GLOBAL_DATA_PTR;
38eae4988bSStefano Babic
dram_init(void)39eae4988bSStefano Babic int dram_init(void)
40eae4988bSStefano Babic {
416b5acfc1SStefano Babic u32 size1, size2;
426b5acfc1SStefano Babic
436b5acfc1SStefano Babic size1 = get_ram_size((void *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
446b5acfc1SStefano Babic size2 = get_ram_size((void *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE);
456b5acfc1SStefano Babic
466b5acfc1SStefano Babic gd->ram_size = size1 + size2;
47eae4988bSStefano Babic
48eae4988bSStefano Babic return 0;
49eae4988bSStefano Babic }
50eae4988bSStefano Babic
dram_init_banksize(void)5176b00acaSSimon Glass int dram_init_banksize(void)
526b5acfc1SStefano Babic {
536b5acfc1SStefano Babic gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
546b5acfc1SStefano Babic gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
556b5acfc1SStefano Babic
566b5acfc1SStefano Babic gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
576b5acfc1SStefano Babic gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
5876b00acaSSimon Glass
5976b00acaSSimon Glass return 0;
606b5acfc1SStefano Babic }
616b5acfc1SStefano Babic
62105c9eafSBenoît Thébaudeau #define I2C_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_ODE)
63105c9eafSBenoît Thébaudeau
setup_iomux_i2c(void)64eae4988bSStefano Babic static void setup_iomux_i2c(void)
65eae4988bSStefano Babic {
66105c9eafSBenoît Thébaudeau static const iomux_v3_cfg_t i2c1_pads[] = {
67105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_I2C1_CLK__I2C1_SCL, I2C_PAD_CTRL),
68105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_I2C1_DAT__I2C1_SDA, I2C_PAD_CTRL),
69105c9eafSBenoît Thébaudeau };
70eae4988bSStefano Babic
71eae4988bSStefano Babic /* setup pins for I2C1 */
72105c9eafSBenoît Thébaudeau imx_iomux_v3_setup_multiple_pads(i2c1_pads, ARRAY_SIZE(i2c1_pads));
73eae4988bSStefano Babic }
74eae4988bSStefano Babic
75eae4988bSStefano Babic
setup_iomux_spi(void)76eae4988bSStefano Babic static void setup_iomux_spi(void)
77eae4988bSStefano Babic {
78105c9eafSBenoît Thébaudeau static const iomux_v3_cfg_t spi_pads[] = {
79105c9eafSBenoît Thébaudeau MX35_PAD_CSPI1_MOSI__CSPI1_MOSI,
80105c9eafSBenoît Thébaudeau MX35_PAD_CSPI1_MISO__CSPI1_MISO,
81105c9eafSBenoît Thébaudeau MX35_PAD_CSPI1_SS0__CSPI1_SS0,
82105c9eafSBenoît Thébaudeau MX35_PAD_CSPI1_SS1__CSPI1_SS1,
83105c9eafSBenoît Thébaudeau MX35_PAD_CSPI1_SCLK__CSPI1_SCLK,
84105c9eafSBenoît Thébaudeau };
85105c9eafSBenoît Thébaudeau
86105c9eafSBenoît Thébaudeau imx_iomux_v3_setup_multiple_pads(spi_pads, ARRAY_SIZE(spi_pads));
87eae4988bSStefano Babic }
88eae4988bSStefano Babic
89105c9eafSBenoît Thébaudeau #define USBOTG_IN_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | \
90105c9eafSBenoît Thébaudeau PAD_CTL_DSE_LOW | PAD_CTL_SRE_SLOW)
91105c9eafSBenoît Thébaudeau #define USBOTG_OUT_PAD_CTRL (PAD_CTL_DSE_LOW | PAD_CTL_SRE_SLOW)
92105c9eafSBenoît Thébaudeau
setup_iomux_usbotg(void)93961a7628SBenoît Thébaudeau static void setup_iomux_usbotg(void)
94961a7628SBenoît Thébaudeau {
95105c9eafSBenoît Thébaudeau static const iomux_v3_cfg_t usbotg_pads[] = {
96105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
97105c9eafSBenoît Thébaudeau USBOTG_OUT_PAD_CTRL),
98105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
99105c9eafSBenoît Thébaudeau USBOTG_IN_PAD_CTRL),
100105c9eafSBenoît Thébaudeau };
101961a7628SBenoît Thébaudeau
102961a7628SBenoît Thébaudeau /* Set up pins for USBOTG. */
103105c9eafSBenoît Thébaudeau imx_iomux_v3_setup_multiple_pads(usbotg_pads, ARRAY_SIZE(usbotg_pads));
104961a7628SBenoît Thébaudeau }
105961a7628SBenoît Thébaudeau
106105c9eafSBenoît Thébaudeau #define FEC_PAD_CTRL (PAD_CTL_DSE_LOW | PAD_CTL_SRE_SLOW)
107105c9eafSBenoît Thébaudeau
setup_iomux_fec(void)108eae4988bSStefano Babic static void setup_iomux_fec(void)
109eae4988bSStefano Babic {
110105c9eafSBenoît Thébaudeau static const iomux_v3_cfg_t fec_pads[] = {
111105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_TX_CLK__FEC_TX_CLK, FEC_PAD_CTRL |
112105c9eafSBenoît Thébaudeau PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
113105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_RX_CLK__FEC_RX_CLK, FEC_PAD_CTRL |
114105c9eafSBenoît Thébaudeau PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
115105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_RX_DV__FEC_RX_DV, FEC_PAD_CTRL |
116105c9eafSBenoît Thébaudeau PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
117105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_COL__FEC_COL, FEC_PAD_CTRL |
118105c9eafSBenoît Thébaudeau PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
119105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_RDATA0__FEC_RDATA_0, FEC_PAD_CTRL |
120105c9eafSBenoît Thébaudeau PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
121105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_TDATA0__FEC_TDATA_0, FEC_PAD_CTRL),
122105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_TX_EN__FEC_TX_EN, FEC_PAD_CTRL),
123105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_MDC__FEC_MDC, FEC_PAD_CTRL),
124105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_MDIO__FEC_MDIO, FEC_PAD_CTRL |
125105c9eafSBenoît Thébaudeau PAD_CTL_HYS | PAD_CTL_PUS_22K_UP),
126105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_TX_ERR__FEC_TX_ERR, FEC_PAD_CTRL),
127105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_RX_ERR__FEC_RX_ERR, FEC_PAD_CTRL |
128105c9eafSBenoît Thébaudeau PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
129105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_CRS__FEC_CRS, FEC_PAD_CTRL |
130105c9eafSBenoît Thébaudeau PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
131105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_RDATA1__FEC_RDATA_1, 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_TDATA1__FEC_TDATA_1, FEC_PAD_CTRL),
134105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_RDATA2__FEC_RDATA_2, 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_TDATA2__FEC_TDATA_2, FEC_PAD_CTRL),
137105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_RDATA3__FEC_RDATA_3, FEC_PAD_CTRL |
138105c9eafSBenoît Thébaudeau PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN),
139105c9eafSBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_FEC_TDATA3__FEC_TDATA_3, FEC_PAD_CTRL),
140105c9eafSBenoît Thébaudeau };
141eae4988bSStefano Babic
142eae4988bSStefano Babic /* setup pins for FEC */
143105c9eafSBenoît Thébaudeau imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads));
144eae4988bSStefano Babic }
145eae4988bSStefano Babic
board_early_init_f(void)146eae4988bSStefano Babic int board_early_init_f(void)
147eae4988bSStefano Babic {
148eae4988bSStefano Babic struct ccm_regs *ccm =
149eae4988bSStefano Babic (struct ccm_regs *)IMX_CCM_BASE;
150eae4988bSStefano Babic
151eae4988bSStefano Babic /* enable clocks */
152eae4988bSStefano Babic writel(readl(&ccm->cgr0) |
153eae4988bSStefano Babic MXC_CCM_CGR0_EMI_MASK |
15434a31bf5SBenoît Thébaudeau MXC_CCM_CGR0_EDIO_MASK |
155eae4988bSStefano Babic MXC_CCM_CGR0_EPIT1_MASK,
156eae4988bSStefano Babic &ccm->cgr0);
157eae4988bSStefano Babic
158eae4988bSStefano Babic writel(readl(&ccm->cgr1) |
159eae4988bSStefano Babic MXC_CCM_CGR1_FEC_MASK |
160eae4988bSStefano Babic MXC_CCM_CGR1_GPIO1_MASK |
161eae4988bSStefano Babic MXC_CCM_CGR1_GPIO2_MASK |
162eae4988bSStefano Babic MXC_CCM_CGR1_GPIO3_MASK |
163eae4988bSStefano Babic MXC_CCM_CGR1_I2C1_MASK |
164eae4988bSStefano Babic MXC_CCM_CGR1_I2C2_MASK |
165eae4988bSStefano Babic MXC_CCM_CGR1_IPU_MASK,
166eae4988bSStefano Babic &ccm->cgr1);
167eae4988bSStefano Babic
168eae4988bSStefano Babic /* Setup NAND */
169eae4988bSStefano Babic __raw_writel(readl(&ccm->rcsr) | MXC_CCM_RCSR_NFC_FMS, &ccm->rcsr);
170eae4988bSStefano Babic
171eae4988bSStefano Babic setup_iomux_i2c();
172961a7628SBenoît Thébaudeau setup_iomux_usbotg();
173eae4988bSStefano Babic setup_iomux_fec();
174eae4988bSStefano Babic setup_iomux_spi();
175eae4988bSStefano Babic
176eae4988bSStefano Babic return 0;
177eae4988bSStefano Babic }
178eae4988bSStefano Babic
board_init(void)179eae4988bSStefano Babic int board_init(void)
180eae4988bSStefano Babic {
181eae4988bSStefano Babic gd->bd->bi_arch_number = MACH_TYPE_MX35_3DS; /* board id for linux */
182eae4988bSStefano Babic /* address of boot parameters */
183eae4988bSStefano Babic gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
184eae4988bSStefano Babic
185eae4988bSStefano Babic return 0;
186eae4988bSStefano Babic }
187eae4988bSStefano Babic
pmic_detect(void)188eae4988bSStefano Babic static inline int pmic_detect(void)
189eae4988bSStefano Babic {
1905213d6e4SStefano Babic unsigned int id;
191c7336815SŁukasz Majewski struct pmic *p = pmic_get("FSL_PMIC");
192c7336815SŁukasz Majewski if (!p)
193c7336815SŁukasz Majewski return -ENODEV;
194eae4988bSStefano Babic
1955213d6e4SStefano Babic pmic_reg_read(p, REG_IDENTIFICATION, &id);
196eae4988bSStefano Babic
197eae4988bSStefano Babic id = (id >> 6) & 0x7;
198eae4988bSStefano Babic if (id == 0x7)
199eae4988bSStefano Babic return 1;
200eae4988bSStefano Babic return 0;
201eae4988bSStefano Babic }
202eae4988bSStefano Babic
get_board_rev(void)203eae4988bSStefano Babic u32 get_board_rev(void)
204eae4988bSStefano Babic {
205eae4988bSStefano Babic int rev;
206eae4988bSStefano Babic
207eae4988bSStefano Babic rev = pmic_detect();
208eae4988bSStefano Babic
209eae4988bSStefano Babic return (get_cpu_rev() & ~(0xF << 8)) | (rev & 0xF) << 8;
210eae4988bSStefano Babic }
211eae4988bSStefano Babic
board_late_init(void)212eae4988bSStefano Babic int board_late_init(void)
213eae4988bSStefano Babic {
214eae4988bSStefano Babic u8 val;
215eae4988bSStefano Babic u32 pmic_val;
2165213d6e4SStefano Babic struct pmic *p;
217c7336815SŁukasz Majewski int ret;
218eae4988bSStefano Babic
219570aa2faSFabio Estevam ret = pmic_init(I2C_0);
220c7336815SŁukasz Majewski if (ret)
221c7336815SŁukasz Majewski return ret;
222c7336815SŁukasz Majewski
223eae4988bSStefano Babic if (pmic_detect()) {
224c7336815SŁukasz Majewski p = pmic_get("FSL_PMIC");
225105c9eafSBenoît Thébaudeau imx_iomux_v3_setup_pad(MX35_PAD_WDOG_RST__WDOG_WDOG_B);
226eae4988bSStefano Babic
2275213d6e4SStefano Babic pmic_reg_read(p, REG_SETTING_0, &pmic_val);
2285213d6e4SStefano Babic pmic_reg_write(p, REG_SETTING_0,
2295213d6e4SStefano Babic pmic_val | VO_1_30V | VO_1_50V);
2305213d6e4SStefano Babic pmic_reg_read(p, REG_MODE_0, &pmic_val);
2315213d6e4SStefano Babic pmic_reg_write(p, REG_MODE_0, pmic_val | VGEN3EN);
232eae4988bSStefano Babic
233105c9eafSBenoît Thébaudeau imx_iomux_v3_setup_pad(MX35_PAD_COMPARE__GPIO1_5);
234eae4988bSStefano Babic
23568088ceeSBenoît Thébaudeau gpio_direction_output(IMX_GPIO_NR(1, 5), 1);
236eae4988bSStefano Babic }
237eae4988bSStefano Babic
238eae4988bSStefano Babic val = mc9sdz60_reg_read(MC9SDZ60_REG_GPIO_1) | 0x04;
239eae4988bSStefano Babic mc9sdz60_reg_write(MC9SDZ60_REG_GPIO_1, val);
240eae4988bSStefano Babic mdelay(200);
241eae4988bSStefano Babic
242eae4988bSStefano Babic val = mc9sdz60_reg_read(MC9SDZ60_REG_RESET_1) & 0x7F;
243eae4988bSStefano Babic mc9sdz60_reg_write(MC9SDZ60_REG_RESET_1, val);
244eae4988bSStefano Babic mdelay(200);
245eae4988bSStefano Babic
246eae4988bSStefano Babic val |= 0x80;
247eae4988bSStefano Babic mc9sdz60_reg_write(MC9SDZ60_REG_RESET_1, val);
248eae4988bSStefano Babic
249eae4988bSStefano Babic /* Print board revision */
250ba901df4SFabio Estevam printf("Board: MX35 PDK %d.0\n", ((get_board_rev() >> 8) + 1) & 0x0F);
251eae4988bSStefano Babic
252eae4988bSStefano Babic return 0;
253eae4988bSStefano Babic }
254eae4988bSStefano Babic
board_eth_init(bd_t * bis)255eae4988bSStefano Babic int board_eth_init(bd_t *bis)
256eae4988bSStefano Babic {
257eae4988bSStefano Babic #if defined(CONFIG_SMC911X)
258a05f4ab6SFabio Estevam int rc = smc911x_initialize(0, CONFIG_SMC911X_BASE);
259a05f4ab6SFabio Estevam if (rc)
260eae4988bSStefano Babic return rc;
261a05f4ab6SFabio Estevam #endif
262a05f4ab6SFabio Estevam return cpu_eth_init(bis);
263eae4988bSStefano Babic }
2643292539eSStefano Babic
2653292539eSStefano Babic #if defined(CONFIG_FSL_ESDHC)
2663292539eSStefano Babic
2673292539eSStefano Babic struct fsl_esdhc_cfg esdhc_cfg = {MMC_SDHC1_BASE_ADDR};
2683292539eSStefano Babic
board_mmc_init(bd_t * bis)2693292539eSStefano Babic int board_mmc_init(bd_t *bis)
2703292539eSStefano Babic {
271105c9eafSBenoît Thébaudeau static const iomux_v3_cfg_t sdhc1_pads[] = {
272105c9eafSBenoît Thébaudeau MX35_PAD_SD1_CMD__ESDHC1_CMD,
273105c9eafSBenoît Thébaudeau MX35_PAD_SD1_CLK__ESDHC1_CLK,
274105c9eafSBenoît Thébaudeau MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
275105c9eafSBenoît Thébaudeau MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
276105c9eafSBenoît Thébaudeau MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
277105c9eafSBenoît Thébaudeau MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
278105c9eafSBenoît Thébaudeau };
279105c9eafSBenoît Thébaudeau
2803292539eSStefano Babic /* configure pins for SDHC1 only */
281105c9eafSBenoît Thébaudeau imx_iomux_v3_setup_multiple_pads(sdhc1_pads, ARRAY_SIZE(sdhc1_pads));
2823292539eSStefano Babic
283a2ac1b3aSBenoît Thébaudeau esdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK);
2843292539eSStefano Babic return fsl_esdhc_initialize(bis, &esdhc_cfg);
2853292539eSStefano Babic }
2863292539eSStefano Babic
board_mmc_getcd(struct mmc * mmc)2873292539eSStefano Babic int board_mmc_getcd(struct mmc *mmc)
2883292539eSStefano Babic {
2893292539eSStefano Babic return !(mc9sdz60_reg_read(MC9SDZ60_REG_DES_FLAG) & 0x4);
2903292539eSStefano Babic }
2913292539eSStefano Babic #endif
292