/* * (C) Copyright 2011 * Logic Product Development * * Author : * Peter Barada * * Derived from Beagle Board and 3430 SDP code by * Richard Woodruff * Syed Mohammed Khasim * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "logic.h" #include "product_id.h" #include "logic-proto.h" DECLARE_GLOBAL_DATA_PTR; #define MUX_LOGIC_HSUSB0_D5_GPIO_MUX() \ MUX_VAL(CP(HSUSB0_DATA5), (IEN | PTD | DIS | M4)) /*GPIO_189*/ #define MUX_LOGIC_HSUSB0_D5_DATA5() \ MUX_VAL(CP(HSUSB0_DATA5), (IEN | PTD | DIS | M0)) /*HSUSB0_DATA5*/ /* * Routine: logic_identify * Description: Detect if we are running on a Logic or Torpedo. * This can be done by GPIO_189. If its low after driving it high, * then its a SOM LV, else Torpedo. */ unsigned int logic_identify(void) { unsigned int val = 0; u32 cpu_family = get_cpu_family(); int i; MUX_LOGIC_HSUSB0_D5_GPIO_MUX(); if (!omap_request_gpio(189)) { twl4030_usb_ulpi_init(); omap_set_gpio_direction(189, 0); omap_set_gpio_dataout(189, 1); /* Let it soak for a bit */ for (i=0; i<0x100; ++i) asm("nop"); omap_set_gpio_direction(189, 1); val = omap_get_gpio_datain(189); omap_free_gpio(189); printf("Board:"); if (cpu_family == CPU_OMAP36XX) { printf(" DM37xx"); if (val) { printf(" Torpedo\n"); val = MACH_TYPE_DM3730_TORPEDO; } else { printf(" SOM LV\n"); val = MACH_TYPE_DM3730_SOM_LV; } } else { printf(" OMAP35xx"); if (val) { printf(" Torpedo\n"); val = MACH_TYPE_OMAP3_TORPEDO; } else { printf(" SOM LV\n"); val = MACH_TYPE_OMAP3530_LV_SOM; } } } MUX_LOGIC_HSUSB0_D5_DATA5(); return val; } /* * Set the default NAND ECC method used for the environment */ static enum omap_nand_ecc_mode omap3logic_nand_default; void nand_setup_default_ecc_method(void) { omap3logic_nand_default = OMAP_ECC_NONE; #ifdef CONFIG_SYSCFG_NAND_ECC_SOFT_BCH omap3logic_nand_default = OMAP_ECC_SOFT_BCH; #endif if (omap_nand_chip_has_ecc()) { #ifdef CONFIG_SYSCFG_NAND_ECC_IN_CHIP omap3logic_nand_default = OMAP_ECC_CHIP; #endif } /* If no ECC then default to HW as the default */ if (omap3logic_nand_default == OMAP_ECC_NONE) omap3logic_nand_default = OMAP_ECC_HW; omap_nand_switch_ecc(omap3logic_nand_default); } /* * Switch NAND ECC method to that used for the environment, * returning the current ECC method through *method */ void nand_switch_ecc_default(int *method) { enum omap_nand_ecc_mode curr_mode; curr_mode = omap_nand_current_ecc_method(); *method = (int) curr_mode; if (curr_mode != omap3logic_nand_default) omap_nand_switch_ecc(omap3logic_nand_default); } /* * Switch ECC method */ void nand_switch_ecc_method(int method) { enum omap_nand_ecc_mode curr_mode, new_mode; curr_mode = omap_nand_current_ecc_method(); new_mode = (enum omap_nand_ecc_mode)method; if (curr_mode != new_mode) omap_nand_switch_ecc(new_mode); } /* Non-zero if NOR flash exists on SOM */ int omap3logic_nor_exists; /* Dynamic MTD id/parts default value functions */ static char *omap3logic_mtdparts_default; static char *omap3logic_mtdids_default; char *get_mtdparts_default(void) { char str[strlen(MTDPARTS_NAND_DEFAULT) + strlen(MTDPARTS_NOR_DEFAULT) + 10]; if (!omap3logic_mtdparts_default) { str[0] = '\0'; if (nand_size()) strcpy(str, MTDPARTS_NAND_DEFAULT); if (omap3logic_nor_exists) { if (strlen(str)) strcat(str, ";"); strcat(str, MTDPARTS_NOR_DEFAULT); } omap3logic_mtdparts_default = malloc(strlen(str) + 1); if (omap3logic_mtdparts_default) strcpy(omap3logic_mtdparts_default, str); } return omap3logic_mtdparts_default; } char *get_mtdids_default(void) { char str[strlen(MTDIDS_NAND_DEFAULT) + strlen(MTDIDS_NOR_DEFAULT) + 10]; if (!omap3logic_mtdids_default) { str[0] = '\0'; if (nand_size()) strcpy(str, MTDIDS_NAND_DEFAULT); if (omap3logic_nor_exists) { if (strlen(str)) strcat(str, ","); strcat(str, MTDIDS_NOR_DEFAULT); } omap3logic_mtdids_default = malloc(strlen(str) + 1); if (omap3logic_mtdids_default) strcpy(omap3logic_mtdids_default, str); } return omap3logic_mtdids_default; } char *get_mtdflags_default(void) { #if defined(MTDFLAGS_NAND_DEFAULT) || defined(MTDFLAGS_NOR_DEFAULT) static char str[ # ifdef MTDFLAGS_NOR_DEFAULT ARRAY_SIZE(MTDFLAGS_NOR_DEFAULT) + # endif # ifdef MTDFLAGS_NAND_DEFAULT ARRAY_SIZE(MTDFLAGS_NAND_DEFAULT) + # endif 10] = ""; if (str[0] == '\0') { str[0] = '\0'; #ifdef MTDFLAGS_NAND_DEFAULT if (nand_size()) strcpy(str, MTDFLAGS_NAND_DEFAULT); #endif #ifdef MTDFLAGS_NOR_DEFAULT if (omap3logic_nor_exists) { if (strlen(str)) strcat(str, ";"); strcat(str, MTDFLAGS_NOR_DEFAULT); } #endif } return str; #else return NULL; #endif } /* * Touchup the environment, specificaly "defaultecc", the display, * and mtdids/mtdparts on default environment */ void touchup_env(int initial_env) { /* Set the defaultecc environment variable to the "natural" * ECC method supported by the NAND chip */ if (omap3logic_nand_default == OMAP_ECC_CHIP) setenv("defaultecc", "chip"); else if (omap3logic_nand_default == OMAP_ECC_HW) setenv("defaultecc", "hw"); else if (omap3logic_nand_default == OMAP_ECC_SOFT_BCH) setenv("defaultecc", "bch"); else setenv("defaultecc", "soft"); /* touchup the display environment variable(s) */ touchup_display_env(); if (initial_env) { /* Need to set mdtids/mtdparts to computed defaults */ setenv("mtdparts", get_mtdparts_default()); setenv("mtdids", get_mtdids_default()); setenv("mtdflags", get_mtdflags_default()); } } /* * If the user tries to 'setenv foo', check if 'foo' is a "reserved" name. * certain system variables should not be changed as they are board-specific * variables */ int setenv_reserved_name(const char *name) { if (!strcmp(name, "defaultecc")) return 1; return 0; } #ifdef CONFIG_USB_OMAP3 /* * MUSB port on OMAP3EVM Rev >= E requires extvbus programming. */ u8 omap3_evm_need_extvbus(void) { u8 retval = 0; retval = 1; return retval; } #endif static void setup_nand_settings(void); static void setup_isp176x_settings(void); static void setup_compact_flash_settings(void); static void fix_flash_sync(void); /* * Routine: board_init * Description: Early hardware init. */ int board_init(void) { gpmc_init(); /* in SRAM or SDRAM, finish GPMC */ /* board id for Linux */ gd->bd->bi_arch_number = logic_identify(); /* boot param addr */ gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100); /* Update NAND settings */ setup_nand_settings(); /* Setup ISP176x settings */ if (gd->bd->bi_arch_number == MACH_TYPE_DM3730_TORPEDO || gd->bd->bi_arch_number == MACH_TYPE_OMAP3_TORPEDO) setup_isp176x_settings(); /* Setup ComactFlash GPMC settings */ if (gd->bd->bi_arch_number == MACH_TYPE_DM3730_SOM_LV || gd->bd->bi_arch_number == MACH_TYPE_OMAP3530_LV_SOM) setup_compact_flash_settings(); /* Probe for NOR and if found put into sync mode */ fix_flash_sync(); /* Initialize twl4030 voltages */ twl4030_power_init(); /* If we're a Torpedo, enable BBCHEN charge the backup battery */ if (gd->bd->bi_arch_number == MACH_TYPE_DM3730_TORPEDO || gd->bd->bi_arch_number == MACH_TYPE_OMAP3_TORPEDO) { twl4030_enable_bb_charging(3200, 25); /* 3.2V @ 25uA */ } return 0; } int board_late_init(void) { unsigned char enetaddr[6]; dump_production_data(); /* Fetch the ethaddr of the LAN */ board_get_nth_enetaddr(enetaddr, 0, 0); #ifdef CONFIG_HAS_ETH1 /* Fetch the ethaddr of the WiFi */ board_get_nth_enetaddr(enetaddr, 1, 1); #endif #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK if (nand_size()) nand_unlock(&nand_info[0], 0x0, nand_info[0].size); #endif #ifdef CONFIG_ENABLE_TWL4030_CHARGING /* Enable charging on Torpedo unless $disablecharging == yes */ if (gd->bd->bi_arch_number == MACH_TYPE_OMAP3_TORPEDO) { char *str; str = getenv("disablecharging"); if (!str || strcmp(str, "yes") != 0) { printf("Torpedo: Enabling battery charging\n"); twl4030_enable_charging(); } } #endif #ifdef CONFIG_CMD_CACHE dcache_enable(); printf ("Data (writethrough) Cache is %s\n", dcache_status() ? "ON" : "OFF"); #endif return 0; } /* Mux I2C bus pins appropriately for this board */ int i2c_mux_bux_pins(int bus) { switch(bus) { case 0: /* I2C1_SCA/I2C1_SDL are *always* mixed for I2C */ break; case 1: MUX_VAL(CP(I2C2_SCL), (IEN | PTU | EN | M0)); MUX_VAL(CP(I2C2_SDA), (IEN | PTU | EN | M0)); break; case 2: MUX_VAL(CP(I2C3_SCL), (IEN | PTU | EN | M0)); MUX_VAL(CP(I2C3_SDA), (IEN | PTU | EN | M0)); break; default: return -1; } return 0; } /* * Check _SYSCONFIG registers and fixup bootrom code leaving them in * non forced-idle/smart-stdby mode */ static void check_sysconfig_regs(void) { unsigned int temp, temp2; /* Since DM3730Logic boards have bootorder of 0x2f, the bootrom * attempts to boot via USB and leaves OTG_SYSCONFIG in non-idle */ temp = *(unsigned int *)OTG_SYSCONFIG; temp2 = OTG_SYSCONFIG_MIDLEMODE_SMART_STDBY | OTG_SYSCONFIG_SIDLEMODE_FORCE_IDLE | OTG_SYSCONFIG_AUTOIDLE; if (temp != temp2) { printf("OTG_SYSCONFIG: %08x - needs to be %08x\n", temp, temp2); *(unsigned int *)OTG_SYSCONFIG = temp2; } } /* * Routine: misc_init_r * Description: Init ethernet (done here so udelay works) */ int misc_init_r(void) { /* Turn on VAUX1 voltage to 3.0 volts to drive level shifters and * power 3.0v parts (tsc2004 and Product ID chip) */ twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX1_DEDICATED, TWL4030_PM_RECEIVER_VAUX1_VSEL_30, TWL4030_PM_RECEIVER_VAUX1_DEV_GRP, TWL4030_PM_RECEIVER_DEV_GRP_P1); /** Extract production data from ID chip, used to selectively * initialize portions of the system */ fetch_production_data(); #if defined(CONFIG_CMD_NET) setup_net_chip(); #endif dieid_num_r(); check_sysconfig_regs(); return 0; } /* GPMC CS1 settings for Logic SOM LV/Torpedo LAN92xx Ethernet chip */ #define LOGIC_NET_GPMC_CONFIG1 0x00001000 #define LOGIC_NET_GPMC_CONFIG2 0x00080801 #define LOGIC_NET_GPMC_CONFIG3 0x00000000 #define LOGIC_NET_GPMC_CONFIG4 0x08010801 #define LOGIC_NET_GPMC_CONFIG5 0x00080a0a #define LOGIC_NET_GPMC_CONFIG6 0x03000280 #define LOGIC_NET_GPMC_CONFIG7 0x00000848 /* * Routine: setup_net_chip * Description: Setting up the configuration GPMC registers specific to the * Ethernet hardware. */ static void setup_net_chip(void) { struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE; /* Configure GPMC registers */ writel(LOGIC_NET_GPMC_CONFIG1, &gpmc_cfg->cs[1].config1); writel(LOGIC_NET_GPMC_CONFIG2, &gpmc_cfg->cs[1].config2); writel(LOGIC_NET_GPMC_CONFIG3, &gpmc_cfg->cs[1].config3); writel(LOGIC_NET_GPMC_CONFIG4, &gpmc_cfg->cs[1].config4); writel(LOGIC_NET_GPMC_CONFIG5, &gpmc_cfg->cs[1].config5); writel(LOGIC_NET_GPMC_CONFIG6, &gpmc_cfg->cs[1].config6); writel(LOGIC_NET_GPMC_CONFIG7, &gpmc_cfg->cs[1].config7); /* Enable off mode for NWE in PADCONF_GPMC_NWE register */ writew(readw(&ctrl_base ->gpmc_nwe) | 0x0E00, &ctrl_base->gpmc_nwe); /* Enable off mode for NOE in PADCONF_GPMC_NADV_ALE register */ writew(readw(&ctrl_base->gpmc_noe) | 0x0E00, &ctrl_base->gpmc_noe); /* Enable off mode for ALE in PADCONF_GPMC_NADV_ALE register */ writew(readw(&ctrl_base->gpmc_nadv_ale) | 0x0E00, &ctrl_base->gpmc_nadv_ale); } /* GPMC CS0 settings for Logic SOM LV/Torpedo NAND settings */ #if 0 /* Following are from current DVT (2012-03-13), but don't work on T+W; * nand-small-stress-test2.sh shows differences between copied files */ #define LOGIC_NAND_GPMC_CONFIG1 0x00001800 #define LOGIC_NAND_GPMC_CONFIG2 0x00090900 #define LOGIC_NAND_GPMC_CONFIG3 0x00090900 #define LOGIC_NAND_GPMC_CONFIG4 0x06000500 #define LOGIC_NAND_GPMC_CONFIG5 0x0007080A #define LOGIC_NAND_GPMC_CONFIG6 0x000002CF #define LOGIC_NAND_GPMC_CONFIG7 0x00000C70 #else /* Timings that look to work on SOM LV/Torpedo after NAND testing; * not sure if optimal */ #define LOGIC_NAND_GPMC_CONFIG1 0x00001800 #define LOGIC_NAND_GPMC_CONFIG2 0x00090900 #define LOGIC_NAND_GPMC_CONFIG3 0x00090900 #define LOGIC_NAND_GPMC_CONFIG4 0x06000700 #define LOGIC_NAND_GPMC_CONFIG5 0x00070C0C #define LOGIC_NAND_GPMC_CONFIG6 0x00000FCF #define LOGIC_NAND_GPMC_CONFIG7 0x00000C70 #endif static void setup_nand_settings(void) { /* struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE; */ /* Configure GPMC registers */ writel(0x00000000, &gpmc_cfg->cs[0].config7); sdelay(1000); writel(LOGIC_NAND_GPMC_CONFIG1, &gpmc_cfg->cs[0].config1); writel(LOGIC_NAND_GPMC_CONFIG2, &gpmc_cfg->cs[0].config2); writel(LOGIC_NAND_GPMC_CONFIG3, &gpmc_cfg->cs[0].config3); writel(LOGIC_NAND_GPMC_CONFIG4, &gpmc_cfg->cs[0].config4); writel(LOGIC_NAND_GPMC_CONFIG5, &gpmc_cfg->cs[0].config5); writel(LOGIC_NAND_GPMC_CONFIG6, &gpmc_cfg->cs[0].config6); writel(LOGIC_NAND_GPMC_CONFIG7, &gpmc_cfg->cs[0].config7); sdelay(2000); } #define LOGIC_CF_GPMC_CONFIG1 0x00001210 #define LOGIC_CF_GPMC_CONFIG2 0x00131000 #define LOGIC_CF_GPMC_CONFIG3 0x001f1f01 #define LOGIC_CF_GPMC_CONFIG4 0x10030e03 #define LOGIC_CF_GPMC_CONFIG5 0x010f1411 #define LOGIC_CF_GPMC_CONFIG6 0x80030600 #define LOGIC_CF_GPMC_CONFIG7 0x00000f58 static void setup_compact_flash_settings(void) { /* Configure GPMC registers */ writel(0x00000000, &gpmc_cfg->cs[3].config7); sdelay(1000); writel(LOGIC_CF_GPMC_CONFIG1, &gpmc_cfg->cs[3].config1); writel(LOGIC_CF_GPMC_CONFIG2, &gpmc_cfg->cs[3].config2); writel(LOGIC_CF_GPMC_CONFIG3, &gpmc_cfg->cs[3].config3); writel(LOGIC_CF_GPMC_CONFIG4, &gpmc_cfg->cs[3].config4); writel(LOGIC_CF_GPMC_CONFIG5, &gpmc_cfg->cs[3].config5); writel(LOGIC_CF_GPMC_CONFIG6, &gpmc_cfg->cs[3].config6); writel(LOGIC_CF_GPMC_CONFIG7, &gpmc_cfg->cs[3].config7); sdelay(2000); } /* GPMC CS6 settings for Logic SOM LV/Torpedo ISP176x settings */ #define LOGIC_ISP176X_GPMC_CONFIG1 0x00001000 #define LOGIC_ISP176X_GPMC_CONFIG2 0x00090900 #define LOGIC_ISP176X_GPMC_CONFIG3 0x00000000 #define LOGIC_ISP176X_GPMC_CONFIG4 0x05000900 #define LOGIC_ISP176X_GPMC_CONFIG5 0x0007090c #define LOGIC_ISP176X_GPMC_CONFIG6 0x04010200 #define LOGIC_ISP176X_GPMC_CONFIG7 0x00000f5c static void setup_isp176x_settings(void) { /* struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE; */ /* Configure GPMC registers */ writel(0x00000000, &gpmc_cfg->cs[6].config7); sdelay(1000); writel(LOGIC_ISP176X_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); writel(LOGIC_ISP176X_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); writel(LOGIC_ISP176X_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); writel(LOGIC_ISP176X_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); writel(LOGIC_ISP176X_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); writel(LOGIC_ISP176X_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); writel(LOGIC_ISP176X_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); sdelay(2000); } #define LOGIC_STNOR_ASYNC_GPMC_CONFIG1 0x00001210 #define LOGIC_STNOR_ASYNC_GPMC_CONFIG2 0x00101001 #define LOGIC_STNOR_ASYNC_GPMC_CONFIG3 0x00020201 #define LOGIC_STNOR_ASYNC_GPMC_CONFIG4 0x0f031003 #define LOGIC_STNOR_ASYNC_GPMC_CONFIG5 0x000f1111 #define LOGIC_STNOR_ASYNC_GPMC_CONFIG6 0x0f030080 #define LOGIC_STNOR_ASYNC_GPMC_CONFIG7 0x00000c50 #define LOGIC_STNOR_DM37x_SYNC_GPMC_CONFIG1 0x6A411213 #define LOGIC_STNOR_DM37x_SYNC_GPMC_CONFIG2 0x000C1503 #define LOGIC_STNOR_DM37x_SYNC_GPMC_CONFIG3 0x00050503 #define LOGIC_STNOR_DM37x_SYNC_GPMC_CONFIG4 0x0B051506 #define LOGIC_STNOR_OMAP35x_SYNC_GPMC_CONFIG1 0x68411213 #define LOGIC_STNOR_OMAP35x_SYNC_GPMC_CONFIG2 0x000C1502 #define LOGIC_STNOR_OMAP35x_SYNC_GPMC_CONFIG3 0x00040402 #define LOGIC_STNOR_OMAP35x_SYNC_GPMC_CONFIG4 0x0B051505 #define LOGIC_STNOR_SYNC_GPMC_CONFIG5 0x020E0C15 #define LOGIC_STNOR_SYNC_GPMC_CONFIG6 0x0B0603C3 #define LOGIC_STNOR_SYNC_GPMC_CONFIG7 0x00000c50 #define LOGIC_FLASH_BASE 0x10000000 /* These are bit definitions for the RCR register of the NOR flash */ /* 28FxxxP30 device. This register sets the bus configration for reads. */ /* settings, located on address pins A[15:0]. */ #define FLASH_28FxxxP30_RCR_RM 0x8000 #define FLASH_28FxxxP30_RCR_R 0x4000 #define FLASH_28FxxxP30_RCR_LC(x) ((x & 0x7) << 11) #define FLASH_28FxxxP30_RCR_WP 0x0400 #define FLASH_28FxxxP30_RCR_DH 0x0200 #define FLASH_28FxxxP30_RCR_WD 0x0100 #define FLASH_28FxxxP30_RCR_BS 0x0080 #define FLASH_28FxxxP30_RCR_CE 0x0040 #define FLASH_28FxxxP30_RCR_BW 0x0008 #define FLASH_28FxxxP30_RCR_BL(x) ((x & 0x7) << 0) #define FLASH_28FxxxP30_BL_4 0x1 #define FLASH_28FxxxP30_BL_8 0x2 #define FLASH_28FxxxP30_BL_16 0x3 #define FLASH_28FxxxP30_BL_CONT 0x7 /* * Routine: fix_flash_sync * Description: Setting up the configuration GPMC registers specific to the * NOR flash (and place in sync mode if not done). */ static void fix_flash_sync(void) { int arch_number; u16 rcrval; /* Check the arch_number - Torpedo doesn't have NOR flash */ arch_number = gd->bd->bi_arch_number; if (!(arch_number == MACH_TYPE_DM3730_SOM_LV || arch_number == MACH_TYPE_OMAP3530_LV_SOM)) return; /* Check CS2 config, if its not in sync, or not valid, then configure it */ if ( !(readl(&gpmc_cfg->cs[2].config1) & TYPE_READTYPE) || !(readl(&gpmc_cfg->cs[2].config7) & 0x00000040) ) { /* Invalidate, in case it is set valid */ writel(0x00000000, &gpmc_cfg->cs[2].config7); /* clear WAIT1 polarity */ writel(readl(&gpmc_cfg->config) & ~0x200, &gpmc_cfg->config); /* clear GPMC_TIMEOUT */ writel(0x0, &gpmc_cfg->timeout_control); /* Configure GPMC registers for async */ writel(LOGIC_STNOR_ASYNC_GPMC_CONFIG1, &gpmc_cfg->cs[2].config1); writel(LOGIC_STNOR_ASYNC_GPMC_CONFIG2, &gpmc_cfg->cs[2].config2); writel(LOGIC_STNOR_ASYNC_GPMC_CONFIG3, &gpmc_cfg->cs[2].config3); writel(LOGIC_STNOR_ASYNC_GPMC_CONFIG4, &gpmc_cfg->cs[2].config4); writel(LOGIC_STNOR_ASYNC_GPMC_CONFIG5, &gpmc_cfg->cs[2].config5); writel(LOGIC_STNOR_ASYNC_GPMC_CONFIG6, &gpmc_cfg->cs[2].config6); writel(LOGIC_STNOR_ASYNC_GPMC_CONFIG7, &gpmc_cfg->cs[2].config7); /* Test if this NOR flash is connected */ *(volatile u16 *)LOGIC_FLASH_BASE = 0x0070; // Read status reg if (*(volatile u16 *)LOGIC_FLASH_BASE != 0x0080) { writel(0x00000000, &gpmc_cfg->cs[2].config7); /* Invalidate chip select */ puts("NOR: no flash device detected\n"); return; // fail - no NOR flash detected } *(volatile u16 *)LOGIC_FLASH_BASE = 0x0050; // Restore to read mode puts("NOR: initialize in sync mode\n"); /* 1st NOR cycle, send read config register setup 0x60 */ *(volatile u16 *)LOGIC_FLASH_BASE = 0x0060; /* 2nd NOR cycle, send 0x03 to latch in read * configuration register setttings, located on A[15:0] */ rcrval = FLASH_28FxxxP30_RCR_LC(4) | FLASH_28FxxxP30_RCR_WP | FLASH_28FxxxP30_RCR_BS | FLASH_28FxxxP30_RCR_CE | FLASH_28FxxxP30_RCR_BW | FLASH_28FxxxP30_RCR_BL(FLASH_28FxxxP30_BL_4); *(volatile u16 *)(LOGIC_FLASH_BASE | (rcrval << 1)) = 0x0003; /* Give a chance for accesses to finish... */ sdelay(2000); /* Third, set GPMC for sync. */ if (arch_number == MACH_TYPE_DM3730_SOM_LV) { /* Use DM3730 SOM LV NOR timings */ writel(LOGIC_STNOR_DM37x_SYNC_GPMC_CONFIG1, &gpmc_cfg->cs[2].config1); writel(LOGIC_STNOR_DM37x_SYNC_GPMC_CONFIG2, &gpmc_cfg->cs[2].config2); writel(LOGIC_STNOR_DM37x_SYNC_GPMC_CONFIG3, &gpmc_cfg->cs[2].config3); writel(LOGIC_STNOR_DM37x_SYNC_GPMC_CONFIG4, &gpmc_cfg->cs[2].config4); } if (arch_number == MACH_TYPE_OMAP3530_LV_SOM) { /* Use DM3730 SOM LV NOR timings */ writel(LOGIC_STNOR_OMAP35x_SYNC_GPMC_CONFIG1, &gpmc_cfg->cs[2].config1); writel(LOGIC_STNOR_OMAP35x_SYNC_GPMC_CONFIG2, &gpmc_cfg->cs[2].config2); writel(LOGIC_STNOR_OMAP35x_SYNC_GPMC_CONFIG3, &gpmc_cfg->cs[2].config3); writel(LOGIC_STNOR_OMAP35x_SYNC_GPMC_CONFIG4, &gpmc_cfg->cs[2].config4); } writel(LOGIC_STNOR_SYNC_GPMC_CONFIG5, &gpmc_cfg->cs[2].config5); writel(LOGIC_STNOR_SYNC_GPMC_CONFIG6, &gpmc_cfg->cs[2].config6); writel(LOGIC_STNOR_SYNC_GPMC_CONFIG7, &gpmc_cfg->cs[2].config7); /* And lastly, set the WAIT1 polarity high */ writel(readl(&gpmc_cfg->config) | 0x200, &gpmc_cfg->config); } else puts ("NOR: Already initialized in sync mode\n"); omap3logic_nor_exists = 1; } int board_eth_init(bd_t *bis) { int rc = 0; #ifdef CONFIG_SMC911X rc = smc911x_initialize(0, CONFIG_SMC911X_BASE); #endif return rc; } #ifdef CONFIG_CMD_GPMC_CONFIG int do_dump_gpmc(cmd_tbl_t * cmdtp, int flag, int argc, char *const argv[]) { gpmc_cfg = (struct gpmc *)GPMC_BASE; int i; printf("GPMC_SYSCONFIG: %08x\n", gpmc_cfg->sysconfig); printf("GPMC_CONFIG: %08x\n", gpmc_cfg->config); for (i=0; i<8; ++i) { struct gpmc_cs *p = &gpmc_cfg->cs[i]; if (p->config7 & (1<<6)) { printf("GPMC%d: %08x %08x %08x %08x\n", i, p->config1, p->config2, p->config3, p->config4); printf(" %08x %08x %03x\n", p->config5, p->config6, p->config7); } } return 1; } U_BOOT_CMD( gpmc_config, 1, 1, do_dump_gpmc, "gpmc_config - dump GPMC settings", "dump valid GPMC configuration" ); #endif #ifdef CONFIG_CMD_MUX_CONFIG int do_dump_mux_config(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { int i,j; u16 val; struct { u16 start; u16 stop; } mux_offsets[] = { { CONTROL_PADCONF_SDRC_D0, /* 0x0030 */ CONTROL_PADCONF_SDRC_CKE1, /* 0x0264 */ }, { CONTROL_PADCONF_SYS_32K, /* 0x0A04 */ CONTROL_PADCONF_D2D_SWAKEUP, /* 0x0A4C */ }, { CONTROL_PADCONF_ETK_CLK_ES2, /* 0x05D8 */ CONTROL_PADCONF_ETK_D15_ES2, /* 0x05FA */ }, }; for (i=0; i