1 /* 2 * Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de> 3 * 4 * (C) Copyright 2008-2010 Freescale Semiconductor, Inc. 5 * 6 * See file CREDITS for list of people who contributed to this 7 * project. 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation; either version 2 of 12 * the License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 22 * MA 02111-1307 USA 23 */ 24 25 #include <common.h> 26 #include <asm/io.h> 27 #include <asm/errno.h> 28 #include <asm/arch/imx-regs.h> 29 #include <asm/arch/crm_regs.h> 30 #include <asm/arch/clock.h> 31 #include <asm/arch/iomux-mx35.h> 32 #include <i2c.h> 33 #include <power/pmic.h> 34 #include <fsl_pmic.h> 35 #include <mmc.h> 36 #include <fsl_esdhc.h> 37 #include <mc9sdz60.h> 38 #include <mc13892.h> 39 #include <linux/types.h> 40 #include <asm/gpio.h> 41 #include <asm/arch/sys_proto.h> 42 #include <netdev.h> 43 44 #ifndef CONFIG_BOARD_LATE_INIT 45 #error "CONFIG_BOARD_LATE_INIT must be set for this board" 46 #endif 47 48 #ifndef CONFIG_BOARD_EARLY_INIT_F 49 #error "CONFIG_BOARD_EARLY_INIT_F must be set for this board" 50 #endif 51 52 DECLARE_GLOBAL_DATA_PTR; 53 54 int dram_init(void) 55 { 56 u32 size1, size2; 57 58 size1 = get_ram_size((void *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE); 59 size2 = get_ram_size((void *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE); 60 61 gd->ram_size = size1 + size2; 62 63 return 0; 64 } 65 66 void dram_init_banksize(void) 67 { 68 gd->bd->bi_dram[0].start = PHYS_SDRAM_1; 69 gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; 70 71 gd->bd->bi_dram[1].start = PHYS_SDRAM_2; 72 gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; 73 } 74 75 #define I2C_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_ODE) 76 77 static void setup_iomux_i2c(void) 78 { 79 static const iomux_v3_cfg_t i2c1_pads[] = { 80 NEW_PAD_CTRL(MX35_PAD_I2C1_CLK__I2C1_SCL, I2C_PAD_CTRL), 81 NEW_PAD_CTRL(MX35_PAD_I2C1_DAT__I2C1_SDA, I2C_PAD_CTRL), 82 }; 83 84 /* setup pins for I2C1 */ 85 imx_iomux_v3_setup_multiple_pads(i2c1_pads, ARRAY_SIZE(i2c1_pads)); 86 } 87 88 89 static void setup_iomux_spi(void) 90 { 91 static const iomux_v3_cfg_t spi_pads[] = { 92 MX35_PAD_CSPI1_MOSI__CSPI1_MOSI, 93 MX35_PAD_CSPI1_MISO__CSPI1_MISO, 94 MX35_PAD_CSPI1_SS0__CSPI1_SS0, 95 MX35_PAD_CSPI1_SS1__CSPI1_SS1, 96 MX35_PAD_CSPI1_SCLK__CSPI1_SCLK, 97 }; 98 99 imx_iomux_v3_setup_multiple_pads(spi_pads, ARRAY_SIZE(spi_pads)); 100 } 101 102 #define USBOTG_IN_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | \ 103 PAD_CTL_DSE_LOW | PAD_CTL_SRE_SLOW) 104 #define USBOTG_OUT_PAD_CTRL (PAD_CTL_DSE_LOW | PAD_CTL_SRE_SLOW) 105 106 static void setup_iomux_usbotg(void) 107 { 108 static const iomux_v3_cfg_t usbotg_pads[] = { 109 NEW_PAD_CTRL(MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR, 110 USBOTG_OUT_PAD_CTRL), 111 NEW_PAD_CTRL(MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC, 112 USBOTG_IN_PAD_CTRL), 113 }; 114 115 /* Set up pins for USBOTG. */ 116 imx_iomux_v3_setup_multiple_pads(usbotg_pads, ARRAY_SIZE(usbotg_pads)); 117 } 118 119 #define FEC_PAD_CTRL (PAD_CTL_DSE_LOW | PAD_CTL_SRE_SLOW) 120 121 static void setup_iomux_fec(void) 122 { 123 static const iomux_v3_cfg_t fec_pads[] = { 124 NEW_PAD_CTRL(MX35_PAD_FEC_TX_CLK__FEC_TX_CLK, FEC_PAD_CTRL | 125 PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN), 126 NEW_PAD_CTRL(MX35_PAD_FEC_RX_CLK__FEC_RX_CLK, FEC_PAD_CTRL | 127 PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN), 128 NEW_PAD_CTRL(MX35_PAD_FEC_RX_DV__FEC_RX_DV, FEC_PAD_CTRL | 129 PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN), 130 NEW_PAD_CTRL(MX35_PAD_FEC_COL__FEC_COL, FEC_PAD_CTRL | 131 PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN), 132 NEW_PAD_CTRL(MX35_PAD_FEC_RDATA0__FEC_RDATA_0, FEC_PAD_CTRL | 133 PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN), 134 NEW_PAD_CTRL(MX35_PAD_FEC_TDATA0__FEC_TDATA_0, FEC_PAD_CTRL), 135 NEW_PAD_CTRL(MX35_PAD_FEC_TX_EN__FEC_TX_EN, FEC_PAD_CTRL), 136 NEW_PAD_CTRL(MX35_PAD_FEC_MDC__FEC_MDC, FEC_PAD_CTRL), 137 NEW_PAD_CTRL(MX35_PAD_FEC_MDIO__FEC_MDIO, FEC_PAD_CTRL | 138 PAD_CTL_HYS | PAD_CTL_PUS_22K_UP), 139 NEW_PAD_CTRL(MX35_PAD_FEC_TX_ERR__FEC_TX_ERR, FEC_PAD_CTRL), 140 NEW_PAD_CTRL(MX35_PAD_FEC_RX_ERR__FEC_RX_ERR, FEC_PAD_CTRL | 141 PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN), 142 NEW_PAD_CTRL(MX35_PAD_FEC_CRS__FEC_CRS, FEC_PAD_CTRL | 143 PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN), 144 NEW_PAD_CTRL(MX35_PAD_FEC_RDATA1__FEC_RDATA_1, FEC_PAD_CTRL | 145 PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN), 146 NEW_PAD_CTRL(MX35_PAD_FEC_TDATA1__FEC_TDATA_1, FEC_PAD_CTRL), 147 NEW_PAD_CTRL(MX35_PAD_FEC_RDATA2__FEC_RDATA_2, FEC_PAD_CTRL | 148 PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN), 149 NEW_PAD_CTRL(MX35_PAD_FEC_TDATA2__FEC_TDATA_2, FEC_PAD_CTRL), 150 NEW_PAD_CTRL(MX35_PAD_FEC_RDATA3__FEC_RDATA_3, FEC_PAD_CTRL | 151 PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN), 152 NEW_PAD_CTRL(MX35_PAD_FEC_TDATA3__FEC_TDATA_3, FEC_PAD_CTRL), 153 }; 154 155 /* setup pins for FEC */ 156 imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads)); 157 } 158 159 int board_early_init_f(void) 160 { 161 struct ccm_regs *ccm = 162 (struct ccm_regs *)IMX_CCM_BASE; 163 164 /* enable clocks */ 165 writel(readl(&ccm->cgr0) | 166 MXC_CCM_CGR0_EMI_MASK | 167 MXC_CCM_CGR0_EDIO_MASK | 168 MXC_CCM_CGR0_EPIT1_MASK, 169 &ccm->cgr0); 170 171 writel(readl(&ccm->cgr1) | 172 MXC_CCM_CGR1_FEC_MASK | 173 MXC_CCM_CGR1_GPIO1_MASK | 174 MXC_CCM_CGR1_GPIO2_MASK | 175 MXC_CCM_CGR1_GPIO3_MASK | 176 MXC_CCM_CGR1_I2C1_MASK | 177 MXC_CCM_CGR1_I2C2_MASK | 178 MXC_CCM_CGR1_IPU_MASK, 179 &ccm->cgr1); 180 181 /* Setup NAND */ 182 __raw_writel(readl(&ccm->rcsr) | MXC_CCM_RCSR_NFC_FMS, &ccm->rcsr); 183 184 setup_iomux_i2c(); 185 setup_iomux_usbotg(); 186 setup_iomux_fec(); 187 setup_iomux_spi(); 188 189 return 0; 190 } 191 192 int board_init(void) 193 { 194 gd->bd->bi_arch_number = MACH_TYPE_MX35_3DS; /* board id for linux */ 195 /* address of boot parameters */ 196 gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; 197 198 return 0; 199 } 200 201 static inline int pmic_detect(void) 202 { 203 unsigned int id; 204 struct pmic *p = pmic_get("FSL_PMIC"); 205 if (!p) 206 return -ENODEV; 207 208 pmic_reg_read(p, REG_IDENTIFICATION, &id); 209 210 id = (id >> 6) & 0x7; 211 if (id == 0x7) 212 return 1; 213 return 0; 214 } 215 216 u32 get_board_rev(void) 217 { 218 int rev; 219 220 rev = pmic_detect(); 221 222 return (get_cpu_rev() & ~(0xF << 8)) | (rev & 0xF) << 8; 223 } 224 225 int board_late_init(void) 226 { 227 u8 val; 228 u32 pmic_val; 229 struct pmic *p; 230 int ret; 231 232 ret = pmic_init(I2C_PMIC); 233 if (ret) 234 return ret; 235 236 if (pmic_detect()) { 237 p = pmic_get("FSL_PMIC"); 238 imx_iomux_v3_setup_pad(MX35_PAD_WDOG_RST__WDOG_WDOG_B); 239 240 pmic_reg_read(p, REG_SETTING_0, &pmic_val); 241 pmic_reg_write(p, REG_SETTING_0, 242 pmic_val | VO_1_30V | VO_1_50V); 243 pmic_reg_read(p, REG_MODE_0, &pmic_val); 244 pmic_reg_write(p, REG_MODE_0, pmic_val | VGEN3EN); 245 246 imx_iomux_v3_setup_pad(MX35_PAD_COMPARE__GPIO1_5); 247 248 gpio_direction_output(IMX_GPIO_NR(1, 5), 1); 249 } 250 251 val = mc9sdz60_reg_read(MC9SDZ60_REG_GPIO_1) | 0x04; 252 mc9sdz60_reg_write(MC9SDZ60_REG_GPIO_1, val); 253 mdelay(200); 254 255 val = mc9sdz60_reg_read(MC9SDZ60_REG_RESET_1) & 0x7F; 256 mc9sdz60_reg_write(MC9SDZ60_REG_RESET_1, val); 257 mdelay(200); 258 259 val |= 0x80; 260 mc9sdz60_reg_write(MC9SDZ60_REG_RESET_1, val); 261 262 /* Print board revision */ 263 printf("Board: MX35 PDK %d.0\n", ((get_board_rev() >> 8) + 1) & 0x0F); 264 265 return 0; 266 } 267 268 int board_eth_init(bd_t *bis) 269 { 270 int rc = -ENODEV; 271 #if defined(CONFIG_SMC911X) 272 rc = smc911x_initialize(0, CONFIG_SMC911X_BASE); 273 #endif 274 275 cpu_eth_init(bis); 276 277 return rc; 278 } 279 280 #if defined(CONFIG_FSL_ESDHC) 281 282 struct fsl_esdhc_cfg esdhc_cfg = {MMC_SDHC1_BASE_ADDR}; 283 284 int board_mmc_init(bd_t *bis) 285 { 286 static const iomux_v3_cfg_t sdhc1_pads[] = { 287 MX35_PAD_SD1_CMD__ESDHC1_CMD, 288 MX35_PAD_SD1_CLK__ESDHC1_CLK, 289 MX35_PAD_SD1_DATA0__ESDHC1_DAT0, 290 MX35_PAD_SD1_DATA1__ESDHC1_DAT1, 291 MX35_PAD_SD1_DATA2__ESDHC1_DAT2, 292 MX35_PAD_SD1_DATA3__ESDHC1_DAT3, 293 }; 294 295 /* configure pins for SDHC1 only */ 296 imx_iomux_v3_setup_multiple_pads(sdhc1_pads, ARRAY_SIZE(sdhc1_pads)); 297 298 esdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK); 299 return fsl_esdhc_initialize(bis, &esdhc_cfg); 300 } 301 302 int board_mmc_getcd(struct mmc *mmc) 303 { 304 return !(mc9sdz60_reg_read(MC9SDZ60_REG_DES_FLAG) & 0x4); 305 } 306 #endif 307