1deb53483SStefano Babic /* 2deb53483SStefano Babic * Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de> 3deb53483SStefano Babic * 4deb53483SStefano Babic * (C) Copyright 2008-2010 Freescale Semiconductor, Inc. 5deb53483SStefano Babic * 6deb53483SStefano Babic * Copyright (C) 2011, Stefano Babic <sbabic@denx.de> 7deb53483SStefano Babic * 8deb53483SStefano Babic * See file CREDITS for list of people who contributed to this 9deb53483SStefano Babic * project. 10deb53483SStefano Babic * 11deb53483SStefano Babic * This program is free software; you can redistribute it and/or 12deb53483SStefano Babic * modify it under the terms of the GNU General Public License as 13deb53483SStefano Babic * published by the Free Software Foundation; either version 2 of 14deb53483SStefano Babic * the License, or (at your option) any later version. 15deb53483SStefano Babic * 16deb53483SStefano Babic * This program is distributed in the hope that it will be useful, 17deb53483SStefano Babic * but WITHOUT ANY WARRANTY; without even the implied warranty of 18deb53483SStefano Babic * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19deb53483SStefano Babic * GNU General Public License for more details. 20deb53483SStefano Babic * 21deb53483SStefano Babic * You should have received a copy of the GNU General Public License 22deb53483SStefano Babic * along with this program; if not, write to the Free Software 23deb53483SStefano Babic * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 24deb53483SStefano Babic * MA 02111-1307 USA 25deb53483SStefano Babic */ 26deb53483SStefano Babic 27deb53483SStefano Babic #include <common.h> 28deb53483SStefano Babic #include <asm/io.h> 29deb53483SStefano Babic #include <asm/errno.h> 30deb53483SStefano Babic #include <asm/arch/imx-regs.h> 31deb53483SStefano Babic #include <asm/arch/crm_regs.h> 32*686e1448SBenoît Thébaudeau #include <asm/arch/iomux-mx35.h> 33deb53483SStefano Babic #include <i2c.h> 34deb53483SStefano Babic #include <linux/types.h> 35deb53483SStefano Babic #include <asm/gpio.h> 36deb53483SStefano Babic #include <asm/arch/sys_proto.h> 37deb53483SStefano Babic #include <netdev.h> 38deb53483SStefano Babic 39deb53483SStefano Babic #ifndef CONFIG_BOARD_EARLY_INIT_F 40deb53483SStefano Babic #error "CONFIG_BOARD_EARLY_INIT_F must be set for this board" 41deb53483SStefano Babic #endif 42deb53483SStefano Babic 43deb53483SStefano Babic #define CCM_CCMR_CONFIG 0x003F4208 44deb53483SStefano Babic 45deb53483SStefano Babic #define ESDCTL_DDR2_CONFIG 0x007FFC3F 46deb53483SStefano Babic #define ESDCTL_0x92220000 0x92220000 47deb53483SStefano Babic #define ESDCTL_0xA2220000 0xA2220000 48deb53483SStefano Babic #define ESDCTL_0xB2220000 0xB2220000 49deb53483SStefano Babic #define ESDCTL_0x82228080 0x82228080 50deb53483SStefano Babic #define ESDCTL_DDR2_EMR2 0x04000000 51deb53483SStefano Babic #define ESDCTL_DDR2_EMR3 0x06000000 52deb53483SStefano Babic #define ESDCTL_PRECHARGE 0x00000400 53deb53483SStefano Babic #define ESDCTL_DDR2_EN_DLL 0x02000400 54deb53483SStefano Babic #define ESDCTL_DDR2_RESET_DLL 0x00000333 55deb53483SStefano Babic #define ESDCTL_DDR2_MR 0x00000233 56deb53483SStefano Babic #define ESDCTL_DDR2_OCD_DEFAULT 0x02000780 57deb53483SStefano Babic #define ESDCTL_DELAY_LINE5 0x00F49F00 58deb53483SStefano Babic 59deb53483SStefano Babic static inline void dram_wait(unsigned int count) 60deb53483SStefano Babic { 61deb53483SStefano Babic volatile unsigned int wait = count; 62deb53483SStefano Babic 63deb53483SStefano Babic while (wait--) 64deb53483SStefano Babic ; 65deb53483SStefano Babic } 66deb53483SStefano Babic 67deb53483SStefano Babic DECLARE_GLOBAL_DATA_PTR; 68deb53483SStefano Babic 69deb53483SStefano Babic int dram_init(void) 70deb53483SStefano Babic { 71deb53483SStefano Babic gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, 72deb53483SStefano Babic PHYS_SDRAM_1_SIZE); 73deb53483SStefano Babic 74deb53483SStefano Babic return 0; 75deb53483SStefano Babic } 76deb53483SStefano Babic 77deb53483SStefano Babic static void board_setup_sdram_bank(u32 start_address) 78deb53483SStefano Babic 79deb53483SStefano Babic { 80deb53483SStefano Babic struct esdc_regs *esdc = (struct esdc_regs *)ESDCTL_BASE_ADDR; 81deb53483SStefano Babic u32 *cfg_reg, *ctl_reg; 82deb53483SStefano Babic u32 val; 83deb53483SStefano Babic 84deb53483SStefano Babic switch (start_address) { 85deb53483SStefano Babic case CSD0_BASE_ADDR: 86deb53483SStefano Babic cfg_reg = &esdc->esdcfg0; 87deb53483SStefano Babic ctl_reg = &esdc->esdctl0; 88deb53483SStefano Babic break; 89deb53483SStefano Babic case CSD1_BASE_ADDR: 90deb53483SStefano Babic cfg_reg = &esdc->esdcfg1; 91deb53483SStefano Babic ctl_reg = &esdc->esdctl1; 92deb53483SStefano Babic break; 93deb53483SStefano Babic default: 94deb53483SStefano Babic return; 95deb53483SStefano Babic } 96deb53483SStefano Babic 97deb53483SStefano Babic /* Initialize MISC register for DDR2 */ 98deb53483SStefano Babic val = ESDC_MISC_RST | ESDC_MISC_MDDR_EN | ESDC_MISC_MDDR_DL_RST | 99deb53483SStefano Babic ESDC_MISC_DDR_EN | ESDC_MISC_DDR2_EN; 100deb53483SStefano Babic writel(val, &esdc->esdmisc); 101deb53483SStefano Babic val &= ~(ESDC_MISC_RST | ESDC_MISC_MDDR_DL_RST); 102deb53483SStefano Babic writel(val, &esdc->esdmisc); 103deb53483SStefano Babic 104deb53483SStefano Babic /* 105deb53483SStefano Babic * according to DDR2 specs, wait a while before 106deb53483SStefano Babic * the PRECHARGE_ALL command 107deb53483SStefano Babic */ 108deb53483SStefano Babic dram_wait(0x20000); 109deb53483SStefano Babic 110deb53483SStefano Babic /* Load DDR2 config and timing */ 111deb53483SStefano Babic writel(ESDCTL_DDR2_CONFIG, cfg_reg); 112deb53483SStefano Babic 113deb53483SStefano Babic /* Precharge ALL */ 114deb53483SStefano Babic writel(ESDCTL_0x92220000, 115deb53483SStefano Babic ctl_reg); 116deb53483SStefano Babic writel(0xda, start_address + ESDCTL_PRECHARGE); 117deb53483SStefano Babic 118deb53483SStefano Babic /* Load mode */ 119deb53483SStefano Babic writel(ESDCTL_0xB2220000, 120deb53483SStefano Babic ctl_reg); 121deb53483SStefano Babic writeb(0xda, start_address + ESDCTL_DDR2_EMR2); /* EMRS2 */ 122deb53483SStefano Babic writeb(0xda, start_address + ESDCTL_DDR2_EMR3); /* EMRS3 */ 123deb53483SStefano Babic writeb(0xda, start_address + ESDCTL_DDR2_EN_DLL); /* Enable DLL */ 124deb53483SStefano Babic writeb(0xda, start_address + ESDCTL_DDR2_RESET_DLL); /* Reset DLL */ 125deb53483SStefano Babic 126deb53483SStefano Babic /* Precharge ALL */ 127deb53483SStefano Babic writel(ESDCTL_0x92220000, 128deb53483SStefano Babic ctl_reg); 129deb53483SStefano Babic writel(0xda, start_address + ESDCTL_PRECHARGE); 130deb53483SStefano Babic 131deb53483SStefano Babic /* Set mode auto refresh : at least two refresh are required */ 132deb53483SStefano Babic writel(ESDCTL_0xA2220000, 133deb53483SStefano Babic ctl_reg); 134deb53483SStefano Babic writel(0xda, start_address); 135deb53483SStefano Babic writel(0xda, start_address); 136deb53483SStefano Babic 137deb53483SStefano Babic writel(ESDCTL_0xB2220000, 138deb53483SStefano Babic ctl_reg); 139deb53483SStefano Babic writeb(0xda, start_address + ESDCTL_DDR2_MR); 140deb53483SStefano Babic writeb(0xda, start_address + ESDCTL_DDR2_OCD_DEFAULT); 141deb53483SStefano Babic 142deb53483SStefano Babic /* OCD mode exit */ 143deb53483SStefano Babic writeb(0xda, start_address + ESDCTL_DDR2_EN_DLL); /* Enable DLL */ 144deb53483SStefano Babic 145deb53483SStefano Babic /* Set normal mode */ 146deb53483SStefano Babic writel(ESDCTL_0x82228080, 147deb53483SStefano Babic ctl_reg); 148deb53483SStefano Babic 149deb53483SStefano Babic dram_wait(0x20000); 150deb53483SStefano Babic 151deb53483SStefano Babic /* Do not set delay lines, only for MDDR */ 152deb53483SStefano Babic } 153deb53483SStefano Babic 154deb53483SStefano Babic static void board_setup_sdram(void) 155deb53483SStefano Babic { 156deb53483SStefano Babic struct esdc_regs *esdc = (struct esdc_regs *)ESDCTL_BASE_ADDR; 157deb53483SStefano Babic 158deb53483SStefano Babic /* Initialize with default values both CSD0/1 */ 159deb53483SStefano Babic writel(0x2000, &esdc->esdctl0); 160deb53483SStefano Babic writel(0x2000, &esdc->esdctl1); 161deb53483SStefano Babic 162fda241d5SStefano Babic board_setup_sdram_bank(CSD0_BASE_ADDR); 163deb53483SStefano Babic } 164deb53483SStefano Babic 165deb53483SStefano Babic static void setup_iomux_uart3(void) 166deb53483SStefano Babic { 167*686e1448SBenoît Thébaudeau static const iomux_v3_cfg_t uart3_pads[] = { 168*686e1448SBenoît Thébaudeau MX35_PAD_RTS2__UART3_RXD_MUX, 169*686e1448SBenoît Thébaudeau MX35_PAD_CTS2__UART3_TXD_MUX, 170*686e1448SBenoît Thébaudeau }; 171*686e1448SBenoît Thébaudeau 172*686e1448SBenoît Thébaudeau imx_iomux_v3_setup_multiple_pads(uart3_pads, ARRAY_SIZE(uart3_pads)); 173deb53483SStefano Babic } 174deb53483SStefano Babic 175*686e1448SBenoît Thébaudeau #define I2C_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_ODE) 176*686e1448SBenoît Thébaudeau 177deb53483SStefano Babic static void setup_iomux_i2c(void) 178deb53483SStefano Babic { 179*686e1448SBenoît Thébaudeau static const iomux_v3_cfg_t i2c_pads[] = { 180*686e1448SBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_I2C1_CLK__I2C1_SCL, I2C_PAD_CTRL), 181*686e1448SBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_I2C1_DAT__I2C1_SDA, I2C_PAD_CTRL), 182deb53483SStefano Babic 183*686e1448SBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_TX3_RX2__I2C3_SCL, I2C_PAD_CTRL), 184*686e1448SBenoît Thébaudeau NEW_PAD_CTRL(MX35_PAD_TX2_RX3__I2C3_SDA, I2C_PAD_CTRL), 185*686e1448SBenoît Thébaudeau }; 186deb53483SStefano Babic 187*686e1448SBenoît Thébaudeau imx_iomux_v3_setup_multiple_pads(i2c_pads, ARRAY_SIZE(i2c_pads)); 188deb53483SStefano Babic } 189deb53483SStefano Babic 190deb53483SStefano Babic 191deb53483SStefano Babic static void setup_iomux_spi(void) 192deb53483SStefano Babic { 193*686e1448SBenoît Thébaudeau static const iomux_v3_cfg_t spi_pads[] = { 194*686e1448SBenoît Thébaudeau MX35_PAD_CSPI1_MOSI__CSPI1_MOSI, 195*686e1448SBenoît Thébaudeau MX35_PAD_CSPI1_MISO__CSPI1_MISO, 196*686e1448SBenoît Thébaudeau MX35_PAD_CSPI1_SS0__CSPI1_SS0, 197*686e1448SBenoît Thébaudeau MX35_PAD_CSPI1_SS1__CSPI1_SS1, 198*686e1448SBenoît Thébaudeau MX35_PAD_CSPI1_SCLK__CSPI1_SCLK, 199*686e1448SBenoît Thébaudeau }; 200*686e1448SBenoît Thébaudeau 201*686e1448SBenoît Thébaudeau imx_iomux_v3_setup_multiple_pads(spi_pads, ARRAY_SIZE(spi_pads)); 202deb53483SStefano Babic } 203deb53483SStefano Babic 204deb53483SStefano Babic static void setup_iomux_fec(void) 205deb53483SStefano Babic { 206*686e1448SBenoît Thébaudeau static const iomux_v3_cfg_t fec_pads[] = { 207*686e1448SBenoît Thébaudeau MX35_PAD_FEC_TX_CLK__FEC_TX_CLK, 208*686e1448SBenoît Thébaudeau MX35_PAD_FEC_RX_CLK__FEC_RX_CLK, 209*686e1448SBenoît Thébaudeau MX35_PAD_FEC_RX_DV__FEC_RX_DV, 210*686e1448SBenoît Thébaudeau MX35_PAD_FEC_COL__FEC_COL, 211*686e1448SBenoît Thébaudeau MX35_PAD_FEC_RDATA0__FEC_RDATA_0, 212*686e1448SBenoît Thébaudeau MX35_PAD_FEC_TDATA0__FEC_TDATA_0, 213*686e1448SBenoît Thébaudeau MX35_PAD_FEC_TX_EN__FEC_TX_EN, 214*686e1448SBenoît Thébaudeau MX35_PAD_FEC_MDC__FEC_MDC, 215*686e1448SBenoît Thébaudeau MX35_PAD_FEC_MDIO__FEC_MDIO, 216*686e1448SBenoît Thébaudeau MX35_PAD_FEC_TX_ERR__FEC_TX_ERR, 217*686e1448SBenoît Thébaudeau MX35_PAD_FEC_RX_ERR__FEC_RX_ERR, 218*686e1448SBenoît Thébaudeau MX35_PAD_FEC_CRS__FEC_CRS, 219*686e1448SBenoît Thébaudeau MX35_PAD_FEC_RDATA1__FEC_RDATA_1, 220*686e1448SBenoît Thébaudeau MX35_PAD_FEC_TDATA1__FEC_TDATA_1, 221*686e1448SBenoît Thébaudeau MX35_PAD_FEC_RDATA2__FEC_RDATA_2, 222*686e1448SBenoît Thébaudeau MX35_PAD_FEC_TDATA2__FEC_TDATA_2, 223*686e1448SBenoît Thébaudeau MX35_PAD_FEC_RDATA3__FEC_RDATA_3, 224*686e1448SBenoît Thébaudeau MX35_PAD_FEC_TDATA3__FEC_TDATA_3, 225*686e1448SBenoît Thébaudeau }; 226deb53483SStefano Babic 227*686e1448SBenoît Thébaudeau /* setup pins for FEC */ 228*686e1448SBenoît Thébaudeau imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads)); 229deb53483SStefano Babic } 230deb53483SStefano Babic 231deb53483SStefano Babic int board_early_init_f(void) 232deb53483SStefano Babic { 233deb53483SStefano Babic struct ccm_regs *ccm = 234deb53483SStefano Babic (struct ccm_regs *)IMX_CCM_BASE; 235deb53483SStefano Babic 236deb53483SStefano Babic /* setup GPIO3_1 to set HighVCore signal */ 237*686e1448SBenoît Thébaudeau imx_iomux_v3_setup_pad(MX35_PAD_ATA_DA1__GPIO3_1); 238deb53483SStefano Babic gpio_direction_output(65, 1); 239deb53483SStefano Babic 240deb53483SStefano Babic /* initialize PLL and clock configuration */ 241deb53483SStefano Babic writel(CCM_CCMR_CONFIG, &ccm->ccmr); 242deb53483SStefano Babic 243deb53483SStefano Babic writel(CCM_MPLL_532_HZ, &ccm->mpctl); 244deb53483SStefano Babic writel(CCM_PPLL_300_HZ, &ccm->ppctl); 245deb53483SStefano Babic 246deb53483SStefano Babic /* Set the core to run at 532 Mhz */ 247deb53483SStefano Babic writel(0x00001000, &ccm->pdr0); 248deb53483SStefano Babic 249deb53483SStefano Babic /* Set-up RAM */ 250deb53483SStefano Babic board_setup_sdram(); 251deb53483SStefano Babic 252deb53483SStefano Babic /* enable clocks */ 253deb53483SStefano Babic writel(readl(&ccm->cgr0) | 254deb53483SStefano Babic MXC_CCM_CGR0_EMI_MASK | 25534a31bf5SBenoît Thébaudeau MXC_CCM_CGR0_EDIO_MASK | 256deb53483SStefano Babic MXC_CCM_CGR0_EPIT1_MASK, 257deb53483SStefano Babic &ccm->cgr0); 258deb53483SStefano Babic 259deb53483SStefano Babic writel(readl(&ccm->cgr1) | 260deb53483SStefano Babic MXC_CCM_CGR1_FEC_MASK | 261deb53483SStefano Babic MXC_CCM_CGR1_GPIO1_MASK | 262deb53483SStefano Babic MXC_CCM_CGR1_GPIO2_MASK | 263deb53483SStefano Babic MXC_CCM_CGR1_GPIO3_MASK | 264deb53483SStefano Babic MXC_CCM_CGR1_I2C1_MASK | 265deb53483SStefano Babic MXC_CCM_CGR1_I2C2_MASK | 266deb53483SStefano Babic MXC_CCM_CGR1_I2C3_MASK, 267deb53483SStefano Babic &ccm->cgr1); 268deb53483SStefano Babic 269deb53483SStefano Babic /* Set-up NAND */ 270deb53483SStefano Babic __raw_writel(readl(&ccm->rcsr) | MXC_CCM_RCSR_NFC_FMS, &ccm->rcsr); 271deb53483SStefano Babic 272deb53483SStefano Babic /* Set pinmux for the required peripherals */ 273deb53483SStefano Babic setup_iomux_uart3(); 274deb53483SStefano Babic setup_iomux_i2c(); 275deb53483SStefano Babic setup_iomux_fec(); 276deb53483SStefano Babic setup_iomux_spi(); 277deb53483SStefano Babic 278deb53483SStefano Babic return 0; 279deb53483SStefano Babic } 280deb53483SStefano Babic 281deb53483SStefano Babic int board_init(void) 282deb53483SStefano Babic { 283deb53483SStefano Babic /* address of boot parameters */ 284deb53483SStefano Babic gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; 285deb53483SStefano Babic 286deb53483SStefano Babic return 0; 287deb53483SStefano Babic } 288deb53483SStefano Babic 289deb53483SStefano Babic u32 get_board_rev(void) 290deb53483SStefano Babic { 291deb53483SStefano Babic int rev = 0; 292deb53483SStefano Babic 293deb53483SStefano Babic return (get_cpu_rev() & ~(0xF << 8)) | (rev & 0xF) << 8; 294deb53483SStefano Babic } 295