177eea280SJavier Martinez Canillas /* 277eea280SJavier Martinez Canillas * (C) Copyright 2010 377eea280SJavier Martinez Canillas * ISEE 2007 SL, <www.iseebcn.com> 477eea280SJavier Martinez Canillas * 51a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 677eea280SJavier Martinez Canillas */ 777eea280SJavier Martinez Canillas #include <common.h> 8f3b4bc45SEnric Balletbo i Serra #include <status_led.h> 9b3f4ca11SSimon Glass #include <dm.h> 10b3f4ca11SSimon Glass #include <ns16550.h> 1177eea280SJavier Martinez Canillas #include <twl4030.h> 1277eea280SJavier Martinez Canillas #include <netdev.h> 13fe9f6289SLadislav Michl #include <spl.h> 1477eea280SJavier Martinez Canillas #include <asm/gpio.h> 1577eea280SJavier Martinez Canillas #include <asm/io.h> 1677eea280SJavier Martinez Canillas #include <asm/arch/mem.h> 1777eea280SJavier Martinez Canillas #include <asm/arch/mmc_host_def.h> 1877eea280SJavier Martinez Canillas #include <asm/arch/mux.h> 1977eea280SJavier Martinez Canillas #include <asm/arch/sys_proto.h> 2077eea280SJavier Martinez Canillas #include <asm/mach-types.h> 21a5debaa3SLadislav Michl #include <linux/mtd/mtd.h> 2297ee7060SLadislav Michl #include <linux/mtd/nand.h> 2397ee7060SLadislav Michl #include <linux/mtd/nand.h> 2497ee7060SLadislav Michl #include <linux/mtd/onenand.h> 2597ee7060SLadislav Michl #include <jffs2/load_kernel.h> 26568b471eSLadislav Michl #include <mtd_node.h> 27568b471eSLadislav Michl #include <fdt_support.h> 2877eea280SJavier Martinez Canillas #include "igep00x0.h" 2977eea280SJavier Martinez Canillas 3077eea280SJavier Martinez Canillas DECLARE_GLOBAL_DATA_PTR; 3177eea280SJavier Martinez Canillas 32b3f4ca11SSimon Glass static const struct ns16550_platdata igep_serial = { 332f6ed3b8SAdam Ford .base = OMAP34XX_UART3, 342f6ed3b8SAdam Ford .reg_shift = 2, 35*17fa0326SHeiko Schocher .clock = V_NS16550_CLK, 36*17fa0326SHeiko Schocher .fcr = UART_FCR_DEFVAL, 37b3f4ca11SSimon Glass }; 38b3f4ca11SSimon Glass 39b3f4ca11SSimon Glass U_BOOT_DEVICE(igep_uart) = { 40c7b9686dSThomas Chou "ns16550_serial", 41b3f4ca11SSimon Glass &igep_serial 42b3f4ca11SSimon Glass }; 43b3f4ca11SSimon Glass 4477eea280SJavier Martinez Canillas /* 4577eea280SJavier Martinez Canillas * Routine: board_init 4677eea280SJavier Martinez Canillas * Description: Early hardware init. 4777eea280SJavier Martinez Canillas */ 4877eea280SJavier Martinez Canillas int board_init(void) 4977eea280SJavier Martinez Canillas { 5097ee7060SLadislav Michl int loops = 100; 5197ee7060SLadislav Michl 5297ee7060SLadislav Michl /* find out flash memory type, assume NAND first */ 5397ee7060SLadislav Michl gpmc_cs0_flash = MTD_DEV_TYPE_NAND; 5497ee7060SLadislav Michl gpmc_init(); 5597ee7060SLadislav Michl 5697ee7060SLadislav Michl /* Issue a RESET and then READID */ 5797ee7060SLadislav Michl writeb(NAND_CMD_RESET, &gpmc_cfg->cs[0].nand_cmd); 5897ee7060SLadislav Michl writeb(NAND_CMD_STATUS, &gpmc_cfg->cs[0].nand_cmd); 5997ee7060SLadislav Michl while ((readl(&gpmc_cfg->cs[0].nand_dat) & NAND_STATUS_READY) 6097ee7060SLadislav Michl != NAND_STATUS_READY) { 6197ee7060SLadislav Michl udelay(1); 6297ee7060SLadislav Michl if (--loops == 0) { 6397ee7060SLadislav Michl gpmc_cs0_flash = MTD_DEV_TYPE_ONENAND; 6497ee7060SLadislav Michl gpmc_init(); /* reinitialize for OneNAND */ 6597ee7060SLadislav Michl break; 6697ee7060SLadislav Michl } 6797ee7060SLadislav Michl } 6897ee7060SLadislav Michl 6977eea280SJavier Martinez Canillas /* boot param addr */ 7077eea280SJavier Martinez Canillas gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100); 7177eea280SJavier Martinez Canillas 72f3b4bc45SEnric Balletbo i Serra #if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) 73f3b4bc45SEnric Balletbo i Serra status_led_set(STATUS_LED_BOOT, STATUS_LED_ON); 74f3b4bc45SEnric Balletbo i Serra #endif 75f3b4bc45SEnric Balletbo i Serra 7677eea280SJavier Martinez Canillas return 0; 7777eea280SJavier Martinez Canillas } 7877eea280SJavier Martinez Canillas 7977eea280SJavier Martinez Canillas #ifdef CONFIG_SPL_BUILD 8077eea280SJavier Martinez Canillas /* 8177eea280SJavier Martinez Canillas * Routine: get_board_mem_timings 8277eea280SJavier Martinez Canillas * Description: If we use SPL then there is no x-loader nor config header 8377eea280SJavier Martinez Canillas * so we have to setup the DDR timings ourself on both banks. 8477eea280SJavier Martinez Canillas */ 8577eea280SJavier Martinez Canillas void get_board_mem_timings(struct board_sdrc_timings *timings) 8677eea280SJavier Martinez Canillas { 8797ee7060SLadislav Michl int mfr, id, err = identify_nand_chip(&mfr, &id); 8897ee7060SLadislav Michl 8977eea280SJavier Martinez Canillas timings->mr = MICRON_V_MR_165; 904fa72bd3SLadislav Michl if (!err) { 914fa72bd3SLadislav Michl switch (mfr) { 924fa72bd3SLadislav Michl case NAND_MFR_HYNIX: 934fa72bd3SLadislav Michl timings->mcfg = HYNIX_V_MCFG_200(256 << 20); 944fa72bd3SLadislav Michl timings->ctrla = HYNIX_V_ACTIMA_200; 954fa72bd3SLadislav Michl timings->ctrlb = HYNIX_V_ACTIMB_200; 964fa72bd3SLadislav Michl break; 974fa72bd3SLadislav Michl case NAND_MFR_MICRON: 9877eea280SJavier Martinez Canillas timings->mcfg = MICRON_V_MCFG_200(256 << 20); 9977eea280SJavier Martinez Canillas timings->ctrla = MICRON_V_ACTIMA_200; 10077eea280SJavier Martinez Canillas timings->ctrlb = MICRON_V_ACTIMB_200; 1014fa72bd3SLadislav Michl break; 1024fa72bd3SLadislav Michl default: 1034fa72bd3SLadislav Michl /* Should not happen... */ 1044fa72bd3SLadislav Michl break; 1054fa72bd3SLadislav Michl } 10677eea280SJavier Martinez Canillas timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz; 10797ee7060SLadislav Michl gpmc_cs0_flash = MTD_DEV_TYPE_NAND; 10897ee7060SLadislav Michl } else { 10977eea280SJavier Martinez Canillas if (get_cpu_family() == CPU_OMAP34XX) { 11077eea280SJavier Martinez Canillas timings->mcfg = NUMONYX_V_MCFG_165(256 << 20); 11177eea280SJavier Martinez Canillas timings->ctrla = NUMONYX_V_ACTIMA_165; 11277eea280SJavier Martinez Canillas timings->ctrlb = NUMONYX_V_ACTIMB_165; 11377eea280SJavier Martinez Canillas timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz; 11477eea280SJavier Martinez Canillas } else { 11577eea280SJavier Martinez Canillas timings->mcfg = NUMONYX_V_MCFG_200(256 << 20); 11677eea280SJavier Martinez Canillas timings->ctrla = NUMONYX_V_ACTIMA_200; 11777eea280SJavier Martinez Canillas timings->ctrlb = NUMONYX_V_ACTIMB_200; 11877eea280SJavier Martinez Canillas timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz; 11977eea280SJavier Martinez Canillas } 12097ee7060SLadislav Michl gpmc_cs0_flash = MTD_DEV_TYPE_ONENAND; 12197ee7060SLadislav Michl } 12277eea280SJavier Martinez Canillas } 123fe9f6289SLadislav Michl 124fe9f6289SLadislav Michl #ifdef CONFIG_SPL_OS_BOOT 125fe9f6289SLadislav Michl int spl_start_uboot(void) 126fe9f6289SLadislav Michl { 127fe9f6289SLadislav Michl /* break into full u-boot on 'c' */ 128fe9f6289SLadislav Michl if (serial_tstc() && serial_getc() == 'c') 129fe9f6289SLadislav Michl return 1; 130fe9f6289SLadislav Michl 131fe9f6289SLadislav Michl return 0; 132fe9f6289SLadislav Michl } 133fe9f6289SLadislav Michl #endif 13477eea280SJavier Martinez Canillas #endif 13577eea280SJavier Martinez Canillas 13697ee7060SLadislav Michl int onenand_board_init(struct mtd_info *mtd) 13797ee7060SLadislav Michl { 13897ee7060SLadislav Michl if (gpmc_cs0_flash == MTD_DEV_TYPE_ONENAND) { 13997ee7060SLadislav Michl struct onenand_chip *this = mtd->priv; 14097ee7060SLadislav Michl this->base = (void *)CONFIG_SYS_ONENAND_BASE; 14197ee7060SLadislav Michl return 0; 14297ee7060SLadislav Michl } 14397ee7060SLadislav Michl return 1; 14497ee7060SLadislav Michl } 14597ee7060SLadislav Michl 14677eea280SJavier Martinez Canillas #if defined(CONFIG_CMD_NET) 1476ed75ba7SLadislav Michl static void reset_net_chip(int gpio) 1486ed75ba7SLadislav Michl { 1496ed75ba7SLadislav Michl if (!gpio_request(gpio, "eth nrst")) { 1506ed75ba7SLadislav Michl gpio_direction_output(gpio, 1); 1516ed75ba7SLadislav Michl udelay(1); 1526ed75ba7SLadislav Michl gpio_set_value(gpio, 0); 1536ed75ba7SLadislav Michl udelay(40); 1546ed75ba7SLadislav Michl gpio_set_value(gpio, 1); 1556ed75ba7SLadislav Michl mdelay(10); 1566ed75ba7SLadislav Michl } 1576ed75ba7SLadislav Michl } 1586ed75ba7SLadislav Michl 15977eea280SJavier Martinez Canillas /* 16077eea280SJavier Martinez Canillas * Routine: setup_net_chip 16177eea280SJavier Martinez Canillas * Description: Setting up the configuration GPMC registers specific to the 16277eea280SJavier Martinez Canillas * Ethernet hardware. 16377eea280SJavier Martinez Canillas */ 16477eea280SJavier Martinez Canillas static void setup_net_chip(void) 16577eea280SJavier Martinez Canillas { 16677eea280SJavier Martinez Canillas struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE; 167b0c47633SLadislav Michl static const u32 gpmc_lan_config[] = { 168b0c47633SLadislav Michl NET_LAN9221_GPMC_CONFIG1, 169b0c47633SLadislav Michl NET_LAN9221_GPMC_CONFIG2, 170b0c47633SLadislav Michl NET_LAN9221_GPMC_CONFIG3, 171b0c47633SLadislav Michl NET_LAN9221_GPMC_CONFIG4, 172b0c47633SLadislav Michl NET_LAN9221_GPMC_CONFIG5, 173b0c47633SLadislav Michl NET_LAN9221_GPMC_CONFIG6, 174b0c47633SLadislav Michl }; 17577eea280SJavier Martinez Canillas 1766ed75ba7SLadislav Michl enable_gpmc_cs_config(gpmc_lan_config, &gpmc_cfg->cs[5], 1776ed75ba7SLadislav Michl CONFIG_SMC911X_BASE, GPMC_SIZE_16M); 17877eea280SJavier Martinez Canillas 17977eea280SJavier Martinez Canillas /* Enable off mode for NWE in PADCONF_GPMC_NWE register */ 18077eea280SJavier Martinez Canillas writew(readw(&ctrl_base->gpmc_nwe) | 0x0E00, &ctrl_base->gpmc_nwe); 18177eea280SJavier Martinez Canillas /* Enable off mode for NOE in PADCONF_GPMC_NADV_ALE register */ 18277eea280SJavier Martinez Canillas writew(readw(&ctrl_base->gpmc_noe) | 0x0E00, &ctrl_base->gpmc_noe); 18377eea280SJavier Martinez Canillas /* Enable off mode for ALE in PADCONF_GPMC_NADV_ALE register */ 18477eea280SJavier Martinez Canillas writew(readw(&ctrl_base->gpmc_nadv_ale) | 0x0E00, 18577eea280SJavier Martinez Canillas &ctrl_base->gpmc_nadv_ale); 18677eea280SJavier Martinez Canillas 1876ed75ba7SLadislav Michl reset_net_chip(64); 18877eea280SJavier Martinez Canillas } 189b0c47633SLadislav Michl 190b0c47633SLadislav Michl int board_eth_init(bd_t *bis) 191b0c47633SLadislav Michl { 192b0c47633SLadislav Michl #ifdef CONFIG_SMC911X 193b0c47633SLadislav Michl return smc911x_initialize(0, CONFIG_SMC911X_BASE); 194b0c47633SLadislav Michl #else 195b0c47633SLadislav Michl return 0; 196b0c47633SLadislav Michl #endif 197b0c47633SLadislav Michl } 19877eea280SJavier Martinez Canillas #else 19977eea280SJavier Martinez Canillas static inline void setup_net_chip(void) {} 20077eea280SJavier Martinez Canillas #endif 20177eea280SJavier Martinez Canillas 20277eea280SJavier Martinez Canillas #if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD) 20377eea280SJavier Martinez Canillas int board_mmc_init(bd_t *bis) 20477eea280SJavier Martinez Canillas { 205e3913f56SNikita Kiryanov return omap_mmc_init(0, 0, 0, -1, -1); 20677eea280SJavier Martinez Canillas } 20777eea280SJavier Martinez Canillas #endif 20877eea280SJavier Martinez Canillas 209aac5450eSPaul Kocialkowski #if defined(CONFIG_GENERIC_MMC) 210aac5450eSPaul Kocialkowski void board_mmc_power_init(void) 211aac5450eSPaul Kocialkowski { 212aac5450eSPaul Kocialkowski twl4030_power_mmc_init(0); 213aac5450eSPaul Kocialkowski } 214aac5450eSPaul Kocialkowski #endif 215aac5450eSPaul Kocialkowski 216568b471eSLadislav Michl #ifdef CONFIG_OF_BOARD_SETUP 217568b471eSLadislav Michl int ft_board_setup(void *blob, bd_t *bd) 218568b471eSLadislav Michl { 219568b471eSLadislav Michl #ifdef CONFIG_FDT_FIXUP_PARTITIONS 220568b471eSLadislav Michl static struct node_info nodes[] = { 221568b471eSLadislav Michl { "ti,omap2-nand", MTD_DEV_TYPE_NAND, }, 222568b471eSLadislav Michl { "ti,omap2-onenand", MTD_DEV_TYPE_ONENAND, }, 223568b471eSLadislav Michl }; 224568b471eSLadislav Michl 225568b471eSLadislav Michl fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); 226568b471eSLadislav Michl #endif 227568b471eSLadislav Michl return 0; 228568b471eSLadislav Michl } 229568b471eSLadislav Michl #endif 230568b471eSLadislav Michl 231a2fa28bcSJavier Martinez Canillas void set_fdt(void) 232a2fa28bcSJavier Martinez Canillas { 233a2fa28bcSJavier Martinez Canillas switch (gd->bd->bi_arch_number) { 234a2fa28bcSJavier Martinez Canillas case MACH_TYPE_IGEP0020: 23540372244SEnric Balletbò i Serra setenv("fdtfile", "omap3-igep0020.dtb"); 236a2fa28bcSJavier Martinez Canillas break; 237a2fa28bcSJavier Martinez Canillas case MACH_TYPE_IGEP0030: 23840372244SEnric Balletbò i Serra setenv("fdtfile", "omap3-igep0030.dtb"); 239a2fa28bcSJavier Martinez Canillas break; 240a2fa28bcSJavier Martinez Canillas } 241a2fa28bcSJavier Martinez Canillas } 242a2fa28bcSJavier Martinez Canillas 24377eea280SJavier Martinez Canillas /* 24477eea280SJavier Martinez Canillas * Routine: misc_init_r 24577eea280SJavier Martinez Canillas * Description: Configure board specific parts 24677eea280SJavier Martinez Canillas */ 24777eea280SJavier Martinez Canillas int misc_init_r(void) 24877eea280SJavier Martinez Canillas { 24977eea280SJavier Martinez Canillas twl4030_power_init(); 25077eea280SJavier Martinez Canillas 25177eea280SJavier Martinez Canillas setup_net_chip(); 25277eea280SJavier Martinez Canillas 253679f82c3SPaul Kocialkowski omap_die_id_display(); 25477eea280SJavier Martinez Canillas 255a2fa28bcSJavier Martinez Canillas set_fdt(); 256a2fa28bcSJavier Martinez Canillas 25777eea280SJavier Martinez Canillas return 0; 25877eea280SJavier Martinez Canillas } 25977eea280SJavier Martinez Canillas 260a5debaa3SLadislav Michl void board_mtdparts_default(const char **mtdids, const char **mtdparts) 261a5debaa3SLadislav Michl { 262a5debaa3SLadislav Michl struct mtd_info *mtd = get_mtd_device(NULL, 0); 263a5debaa3SLadislav Michl if (mtd) { 264a5debaa3SLadislav Michl static char ids[24]; 265a5debaa3SLadislav Michl static char parts[48]; 266a5debaa3SLadislav Michl const char *linux_name = "omap2-nand"; 267a5debaa3SLadislav Michl if (strncmp(mtd->name, "onenand0", 8) == 0) 268a5debaa3SLadislav Michl linux_name = "omap2-onenand"; 269a5debaa3SLadislav Michl snprintf(ids, sizeof(ids), "%s=%s", mtd->name, linux_name); 270a5debaa3SLadislav Michl snprintf(parts, sizeof(parts), "mtdparts=%s:%dk(SPL),-(UBI)", 271a5debaa3SLadislav Michl linux_name, 4 * mtd->erasesize >> 10); 272a5debaa3SLadislav Michl *mtdids = ids; 273a5debaa3SLadislav Michl *mtdparts = parts; 274a5debaa3SLadislav Michl } 275a5debaa3SLadislav Michl } 276a5debaa3SLadislav Michl 27777eea280SJavier Martinez Canillas /* 27877eea280SJavier Martinez Canillas * Routine: set_muxconf_regs 27977eea280SJavier Martinez Canillas * Description: Setting up the configuration Mux registers specific to the 28077eea280SJavier Martinez Canillas * hardware. Many pins need to be moved from protect to primary 28177eea280SJavier Martinez Canillas * mode. 28277eea280SJavier Martinez Canillas */ 28377eea280SJavier Martinez Canillas void set_muxconf_regs(void) 28477eea280SJavier Martinez Canillas { 28577eea280SJavier Martinez Canillas MUX_DEFAULT(); 28677eea280SJavier Martinez Canillas 28777eea280SJavier Martinez Canillas #if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0020) 28877eea280SJavier Martinez Canillas MUX_IGEP0020(); 28977eea280SJavier Martinez Canillas #endif 29077eea280SJavier Martinez Canillas 29177eea280SJavier Martinez Canillas #if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0030) 29277eea280SJavier Martinez Canillas MUX_IGEP0030(); 29377eea280SJavier Martinez Canillas #endif 29477eea280SJavier Martinez Canillas } 295