1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 2d81b27a2SStefano Babic /* 3d81b27a2SStefano Babic * Copyright (C) 2012, Stefano Babic <sbabic@denx.de> 4d81b27a2SStefano Babic * 5d81b27a2SStefano Babic * Based on flea3.c and mx35pdk.c 6d81b27a2SStefano Babic */ 7d81b27a2SStefano Babic 8d81b27a2SStefano Babic #include <common.h> 9d81b27a2SStefano Babic #include <asm/io.h> 101221ce45SMasahiro Yamada #include <linux/errno.h> 11d81b27a2SStefano Babic #include <asm/arch/imx-regs.h> 12d81b27a2SStefano Babic #include <asm/arch/crm_regs.h> 13d81b27a2SStefano Babic #include <asm/arch/clock.h> 148342cc37SBenoît Thébaudeau #include <asm/arch/iomux-mx35.h> 15d81b27a2SStefano Babic #include <i2c.h> 1605a860c2SStefano Babic #include <power/pmic.h> 17d81b27a2SStefano Babic #include <fsl_pmic.h> 18d81b27a2SStefano Babic #include <mc13892.h> 19d81b27a2SStefano Babic #include <mmc.h> 20d81b27a2SStefano Babic #include <fsl_esdhc.h> 21d81b27a2SStefano Babic #include <linux/types.h> 22d81b27a2SStefano Babic #include <asm/gpio.h> 23d81b27a2SStefano Babic #include <asm/arch/sys_proto.h> 24d81b27a2SStefano Babic #include <netdev.h> 25d81b27a2SStefano Babic #include <spl.h> 26d81b27a2SStefano Babic 27d81b27a2SStefano Babic #define CCM_CCMR_CONFIG 0x003F4208 28d81b27a2SStefano Babic 29d81b27a2SStefano Babic #define ESDCTL_DDR2_CONFIG 0x007FFC3F 30d81b27a2SStefano Babic 31d81b27a2SStefano Babic /* For MMC */ 32d81b27a2SStefano Babic #define GPIO_MMC_CD 7 33d81b27a2SStefano Babic #define GPIO_MMC_WP 8 34d81b27a2SStefano Babic 35d81b27a2SStefano Babic DECLARE_GLOBAL_DATA_PTR; 36d81b27a2SStefano Babic 37d81b27a2SStefano Babic int dram_init(void) 38d81b27a2SStefano Babic { 39d81b27a2SStefano Babic gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, 40d81b27a2SStefano Babic PHYS_SDRAM_1_SIZE); 41d81b27a2SStefano Babic 42d81b27a2SStefano Babic return 0; 43d81b27a2SStefano Babic } 44d81b27a2SStefano Babic 45d81b27a2SStefano Babic static void board_setup_sdram(void) 46d81b27a2SStefano Babic { 47d81b27a2SStefano Babic struct esdc_regs *esdc = (struct esdc_regs *)ESDCTL_BASE_ADDR; 48d81b27a2SStefano Babic 49d81b27a2SStefano Babic /* Initialize with default values both CSD0/1 */ 50d81b27a2SStefano Babic writel(0x2000, &esdc->esdctl0); 51d81b27a2SStefano Babic writel(0x2000, &esdc->esdctl1); 52d81b27a2SStefano Babic 53d81b27a2SStefano Babic mx3_setup_sdram_bank(CSD0_BASE_ADDR, ESDCTL_DDR2_CONFIG, 54d81b27a2SStefano Babic 13, 10, 2, 0x8080); 55d81b27a2SStefano Babic } 56d81b27a2SStefano Babic 57d81b27a2SStefano Babic static void setup_iomux_fec(void) 58d81b27a2SStefano Babic { 598342cc37SBenoît Thébaudeau static const iomux_v3_cfg_t fec_pads[] = { 608342cc37SBenoît Thébaudeau MX35_PAD_FEC_TX_CLK__FEC_TX_CLK, 618342cc37SBenoît Thébaudeau MX35_PAD_FEC_RX_CLK__FEC_RX_CLK, 628342cc37SBenoît Thébaudeau MX35_PAD_FEC_RX_DV__FEC_RX_DV, 638342cc37SBenoît Thébaudeau MX35_PAD_FEC_COL__FEC_COL, 648342cc37SBenoît Thébaudeau MX35_PAD_FEC_RDATA0__FEC_RDATA_0, 658342cc37SBenoît Thébaudeau MX35_PAD_FEC_TDATA0__FEC_TDATA_0, 668342cc37SBenoît Thébaudeau MX35_PAD_FEC_TX_EN__FEC_TX_EN, 678342cc37SBenoît Thébaudeau MX35_PAD_FEC_MDC__FEC_MDC, 688342cc37SBenoît Thébaudeau MX35_PAD_FEC_MDIO__FEC_MDIO, 698342cc37SBenoît Thébaudeau MX35_PAD_FEC_TX_ERR__FEC_TX_ERR, 708342cc37SBenoît Thébaudeau MX35_PAD_FEC_RX_ERR__FEC_RX_ERR, 718342cc37SBenoît Thébaudeau MX35_PAD_FEC_CRS__FEC_CRS, 728342cc37SBenoît Thébaudeau MX35_PAD_FEC_RDATA1__FEC_RDATA_1, 738342cc37SBenoît Thébaudeau MX35_PAD_FEC_TDATA1__FEC_TDATA_1, 748342cc37SBenoît Thébaudeau MX35_PAD_FEC_RDATA2__FEC_RDATA_2, 758342cc37SBenoît Thébaudeau MX35_PAD_FEC_TDATA2__FEC_TDATA_2, 768342cc37SBenoît Thébaudeau MX35_PAD_FEC_RDATA3__FEC_RDATA_3, 778342cc37SBenoît Thébaudeau MX35_PAD_FEC_TDATA3__FEC_TDATA_3, 788342cc37SBenoît Thébaudeau }; 798342cc37SBenoît Thébaudeau 80d81b27a2SStefano Babic /* setup pins for FEC */ 818342cc37SBenoît Thébaudeau imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads)); 82d81b27a2SStefano Babic } 83d81b27a2SStefano Babic 84d81b27a2SStefano Babic int woodburn_init(void) 85d81b27a2SStefano Babic { 86d81b27a2SStefano Babic struct ccm_regs *ccm = 87d81b27a2SStefano Babic (struct ccm_regs *)IMX_CCM_BASE; 88d81b27a2SStefano Babic 89d81b27a2SStefano Babic /* initialize PLL and clock configuration */ 90d81b27a2SStefano Babic writel(CCM_CCMR_CONFIG, &ccm->ccmr); 91d81b27a2SStefano Babic 92d81b27a2SStefano Babic /* Set-up RAM */ 93d81b27a2SStefano Babic board_setup_sdram(); 94d81b27a2SStefano Babic 95d81b27a2SStefano Babic /* enable clocks */ 96d81b27a2SStefano Babic writel(readl(&ccm->cgr0) | 97d81b27a2SStefano Babic MXC_CCM_CGR0_EMI_MASK | 98d81b27a2SStefano Babic MXC_CCM_CGR0_EDIO_MASK | 99d81b27a2SStefano Babic MXC_CCM_CGR0_EPIT1_MASK, 100d81b27a2SStefano Babic &ccm->cgr0); 101d81b27a2SStefano Babic 102d81b27a2SStefano Babic writel(readl(&ccm->cgr1) | 103d81b27a2SStefano Babic MXC_CCM_CGR1_FEC_MASK | 104d81b27a2SStefano Babic MXC_CCM_CGR1_GPIO1_MASK | 105d81b27a2SStefano Babic MXC_CCM_CGR1_GPIO2_MASK | 106d81b27a2SStefano Babic MXC_CCM_CGR1_GPIO3_MASK | 107d81b27a2SStefano Babic MXC_CCM_CGR1_I2C1_MASK | 108d81b27a2SStefano Babic MXC_CCM_CGR1_I2C2_MASK | 109d81b27a2SStefano Babic MXC_CCM_CGR1_I2C3_MASK, 110d81b27a2SStefano Babic &ccm->cgr1); 111d81b27a2SStefano Babic 112d81b27a2SStefano Babic /* Set-up NAND */ 113d81b27a2SStefano Babic __raw_writel(readl(&ccm->rcsr) | MXC_CCM_RCSR_NFC_FMS, &ccm->rcsr); 114d81b27a2SStefano Babic 115d81b27a2SStefano Babic /* Set pinmux for the required peripherals */ 116d81b27a2SStefano Babic setup_iomux_fec(); 117d81b27a2SStefano Babic 118d81b27a2SStefano Babic /* setup GPIO1_4 FEC_ENABLE signal */ 1198342cc37SBenoît Thébaudeau imx_iomux_v3_setup_pad(MX35_PAD_SCKR__GPIO1_4); 120d81b27a2SStefano Babic gpio_direction_output(4, 1); 1218342cc37SBenoît Thébaudeau imx_iomux_v3_setup_pad(MX35_PAD_HCKT__GPIO1_9); 12296346703SFabio Estevam gpio_direction_output(9, 1); 123d81b27a2SStefano Babic 124d81b27a2SStefano Babic return 0; 125d81b27a2SStefano Babic } 126d81b27a2SStefano Babic 127d81b27a2SStefano Babic #if defined(CONFIG_SPL_BUILD) 128d81b27a2SStefano Babic void board_init_f(ulong dummy) 129d81b27a2SStefano Babic { 130d81b27a2SStefano Babic /* Set the stack pointer. */ 131d81b27a2SStefano Babic asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK)); 132d81b27a2SStefano Babic 133d81b27a2SStefano Babic /* Initialize MUX and SDRAM */ 134d81b27a2SStefano Babic woodburn_init(); 135d81b27a2SStefano Babic 136d81b27a2SStefano Babic /* Clear the BSS. */ 1373929fb0aSSimon Glass memset(__bss_start, 0, __bss_end - __bss_start); 138d81b27a2SStefano Babic 139d81b27a2SStefano Babic preloader_console_init(); 140d81b27a2SStefano Babic timer_init(); 141d81b27a2SStefano Babic 142d81b27a2SStefano Babic board_init_r(NULL, 0); 143d81b27a2SStefano Babic } 144d81b27a2SStefano Babic 145d81b27a2SStefano Babic void spl_board_init(void) 146d81b27a2SStefano Babic { 147d81b27a2SStefano Babic } 148d81b27a2SStefano Babic 149d81b27a2SStefano Babic #endif 150d81b27a2SStefano Babic 151d81b27a2SStefano Babic 152d81b27a2SStefano Babic /* Booting from NOR in external mode */ 153d81b27a2SStefano Babic int board_early_init_f(void) 154d81b27a2SStefano Babic { 155d81b27a2SStefano Babic return woodburn_init(); 156d81b27a2SStefano Babic } 157d81b27a2SStefano Babic 158d81b27a2SStefano Babic 159d81b27a2SStefano Babic int board_init(void) 160d81b27a2SStefano Babic { 161d81b27a2SStefano Babic struct pmic *p; 162d81b27a2SStefano Babic u32 val; 16305a860c2SStefano Babic int ret; 164d81b27a2SStefano Babic 165d81b27a2SStefano Babic /* address of boot parameters */ 166d81b27a2SStefano Babic gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; 167d81b27a2SStefano Babic 16805a860c2SStefano Babic ret = pmic_init(I2C_PMIC); 16905a860c2SStefano Babic if (ret) 17005a860c2SStefano Babic return ret; 17105a860c2SStefano Babic 17205a860c2SStefano Babic p = pmic_get("FSL_PMIC"); 173d81b27a2SStefano Babic 174d81b27a2SStefano Babic /* 175d81b27a2SStefano Babic * Set switchers in Auto in NORMAL mode & STANDBY mode 176d81b27a2SStefano Babic * Setup the switcher mode for SW1 & SW2 177d81b27a2SStefano Babic */ 178d81b27a2SStefano Babic pmic_reg_read(p, REG_SW_4, &val); 179d81b27a2SStefano Babic val = (val & ~((SWMODE_MASK << SWMODE1_SHIFT) | 180d81b27a2SStefano Babic (SWMODE_MASK << SWMODE2_SHIFT))); 181d81b27a2SStefano Babic val |= (SWMODE_AUTO_AUTO << SWMODE1_SHIFT) | 182d81b27a2SStefano Babic (SWMODE_AUTO_AUTO << SWMODE2_SHIFT); 183d81b27a2SStefano Babic /* Set SWILIMB */ 184d81b27a2SStefano Babic val |= (1 << 22); 185d81b27a2SStefano Babic pmic_reg_write(p, REG_SW_4, val); 186d81b27a2SStefano Babic 187d81b27a2SStefano Babic /* Setup the switcher mode for SW3 & SW4 */ 188d81b27a2SStefano Babic pmic_reg_read(p, REG_SW_5, &val); 189d81b27a2SStefano Babic val &= ~((SWMODE_MASK << SWMODE4_SHIFT) | 190d81b27a2SStefano Babic (SWMODE_MASK << SWMODE3_SHIFT)); 191d81b27a2SStefano Babic val |= (SWMODE_AUTO_AUTO << SWMODE4_SHIFT) | 192d81b27a2SStefano Babic (SWMODE_AUTO_AUTO << SWMODE3_SHIFT); 193d81b27a2SStefano Babic pmic_reg_write(p, REG_SW_5, val); 194d81b27a2SStefano Babic 195d81b27a2SStefano Babic /* Set VGEN1 to 3.15V */ 196d81b27a2SStefano Babic pmic_reg_read(p, REG_SETTING_0, &val); 197d81b27a2SStefano Babic val &= ~(VGEN1_MASK); 198d81b27a2SStefano Babic val |= VGEN1_3_15; 199d81b27a2SStefano Babic pmic_reg_write(p, REG_SETTING_0, val); 200d81b27a2SStefano Babic 201d81b27a2SStefano Babic pmic_reg_read(p, REG_MODE_0, &val); 202d81b27a2SStefano Babic val |= VGEN1EN; 203d81b27a2SStefano Babic pmic_reg_write(p, REG_MODE_0, val); 204d81b27a2SStefano Babic udelay(2000); 205d81b27a2SStefano Babic 206d81b27a2SStefano Babic return 0; 207d81b27a2SStefano Babic } 208d81b27a2SStefano Babic 209d81b27a2SStefano Babic #if defined(CONFIG_FSL_ESDHC) 210d81b27a2SStefano Babic struct fsl_esdhc_cfg esdhc_cfg = {MMC_SDHC1_BASE_ADDR}; 211d81b27a2SStefano Babic 212d81b27a2SStefano Babic int board_mmc_init(bd_t *bis) 213d81b27a2SStefano Babic { 2148342cc37SBenoît Thébaudeau static const iomux_v3_cfg_t sdhc1_pads[] = { 2158342cc37SBenoît Thébaudeau MX35_PAD_SD1_CMD__ESDHC1_CMD, 2168342cc37SBenoît Thébaudeau MX35_PAD_SD1_CLK__ESDHC1_CLK, 2178342cc37SBenoît Thébaudeau MX35_PAD_SD1_DATA0__ESDHC1_DAT0, 2188342cc37SBenoît Thébaudeau MX35_PAD_SD1_DATA1__ESDHC1_DAT1, 2198342cc37SBenoît Thébaudeau MX35_PAD_SD1_DATA2__ESDHC1_DAT2, 2208342cc37SBenoît Thébaudeau MX35_PAD_SD1_DATA3__ESDHC1_DAT3, 2218342cc37SBenoît Thébaudeau }; 2228342cc37SBenoît Thébaudeau 223d81b27a2SStefano Babic /* configure pins for SDHC1 only */ 2248342cc37SBenoît Thébaudeau imx_iomux_v3_setup_multiple_pads(sdhc1_pads, ARRAY_SIZE(sdhc1_pads)); 225d81b27a2SStefano Babic 226d81b27a2SStefano Babic /* MMC Card Detect on GPIO1_7 */ 2278342cc37SBenoît Thébaudeau imx_iomux_v3_setup_pad(MX35_PAD_SCKT__GPIO1_7); 228d81b27a2SStefano Babic gpio_direction_input(GPIO_MMC_CD); 229d81b27a2SStefano Babic 2304750953eSFabio Estevam /* MMC Write Protection on GPIO1_8 */ 2318342cc37SBenoît Thébaudeau imx_iomux_v3_setup_pad(MX35_PAD_FST__GPIO1_8); 2324750953eSFabio Estevam gpio_direction_input(GPIO_MMC_WP); 233d81b27a2SStefano Babic 234d81b27a2SStefano Babic esdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK); 235d81b27a2SStefano Babic 236d81b27a2SStefano Babic return fsl_esdhc_initialize(bis, &esdhc_cfg); 237d81b27a2SStefano Babic } 238d81b27a2SStefano Babic 239d81b27a2SStefano Babic int board_mmc_getcd(struct mmc *mmc) 240d81b27a2SStefano Babic { 241d81b27a2SStefano Babic return !gpio_get_value(GPIO_MMC_CD); 242d81b27a2SStefano Babic } 243d81b27a2SStefano Babic #endif 244d81b27a2SStefano Babic 245d81b27a2SStefano Babic u32 get_board_rev(void) 246d81b27a2SStefano Babic { 247d81b27a2SStefano Babic int rev = 0; 248d81b27a2SStefano Babic 249d81b27a2SStefano Babic return (get_cpu_rev() & ~(0xF << 8)) | (rev & 0xF) << 8; 250d81b27a2SStefano Babic } 251