]> git.sur5r.net Git - u-boot/blobdiff - board/davinci/da8xxevm/da850evm.c
da8xx/hawkboard: Add support for ohci host controller
[u-boot] / board / davinci / da8xxevm / da850evm.c
index 34ef53df2bca699c375852d0504bbd5750ad0322..0c7aabb13492843a25d6f52260fb0f2b3217e1dc 100644 (file)
 #include <i2c.h>
 #include <net.h>
 #include <netdev.h>
+#include <spi.h>
+#include <spi_flash.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/emif_defs.h>
 #include <asm/arch/emac_defs.h>
 #include <asm/arch/pinmux_defs.h>
 #include <asm/io.h>
 #include <asm/arch/davinci_misc.h>
+#include <asm/errno.h>
 #include <hwconfig.h>
 
+#ifdef CONFIG_DAVINCI_MMC
+#include <mmc.h>
+#include <asm/arch/sdmmc_defs.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef CONFIG_DRIVER_TI_EMAC
@@ -43,6 +51,36 @@ DECLARE_GLOBAL_DATA_PTR;
 #endif
 #endif /* CONFIG_DRIVER_TI_EMAC */
 
+#define CFG_MAC_ADDR_SPI_BUS   0
+#define CFG_MAC_ADDR_SPI_CS    0
+#define CFG_MAC_ADDR_SPI_MAX_HZ        CONFIG_SF_DEFAULT_SPEED
+#define CFG_MAC_ADDR_SPI_MODE  SPI_MODE_3
+
+#define CFG_MAC_ADDR_OFFSET    (flash->size - SZ_64K)
+
+#ifdef CONFIG_MAC_ADDR_IN_SPIFLASH
+static int get_mac_addr(u8 *addr)
+{
+       struct spi_flash *flash;
+       int ret;
+
+       flash = spi_flash_probe(CFG_MAC_ADDR_SPI_BUS, CFG_MAC_ADDR_SPI_CS,
+                       CFG_MAC_ADDR_SPI_MAX_HZ, CFG_MAC_ADDR_SPI_MODE);
+       if (!flash) {
+               printf("Error - unable to probe SPI flash.\n");
+               return -1;
+       }
+
+       ret = spi_flash_read(flash, CFG_MAC_ADDR_OFFSET, 6, addr);
+       if (ret) {
+               printf("Error - unable to read MAC address from SPI flash.\n");
+               return -1;
+       }
+
+       return ret;
+}
+#endif
+
 void dsp_lpsc_on(unsigned domain, unsigned int id)
 {
        dv_reg_p mdstat, mdctl, ptstat, ptcmd;
@@ -98,14 +136,105 @@ static void dspwake(void)
 int misc_init_r(void)
 {
        dspwake();
+
+#if defined(CONFIG_MAC_ADDR_IN_SPIFLASH) || defined(CONFIG_MAC_ADDR_IN_EEPROM)
+
+       uchar env_enetaddr[6];
+       int enetaddr_found;
+
+       enetaddr_found = eth_getenv_enetaddr("ethaddr", env_enetaddr);
+
+#ifdef CONFIG_MAC_ADDR_IN_SPIFLASH
+       int spi_mac_read;
+       uchar buff[6];
+
+       spi_mac_read = get_mac_addr(buff);
+
+       /*
+        * MAC address not present in the environment
+        * try and read the MAC address from SPI flash
+        * and set it.
+        */
+       if (!enetaddr_found) {
+               if (!spi_mac_read) {
+                       if (is_valid_ether_addr(buff)) {
+                               if (eth_setenv_enetaddr("ethaddr", buff)) {
+                                       printf("Warning: Failed to "
+                                       "set MAC address from SPI flash\n");
+                               }
+                       } else {
+                                       printf("Warning: Invalid "
+                                       "MAC address read from SPI flash\n");
+                       }
+               }
+       } else {
+               /*
+                * MAC address present in environment compare it with
+                * the MAC address in SPI flash and warn on mismatch
+                */
+               if (!spi_mac_read && is_valid_ether_addr(buff) &&
+                                               memcmp(env_enetaddr, buff, 6))
+                       printf("Warning: MAC address in SPI flash don't match "
+                                       "with the MAC address in the environment\n");
+                       printf("Default using MAC address from environment\n");
+       }
+#endif
+       uint8_t enetaddr[8];
+       int eeprom_mac_read;
+
+       /* Read Ethernet MAC address from EEPROM */
+       eeprom_mac_read = dvevm_read_mac_address(enetaddr);
+
+       /*
+        * MAC address not present in the environment
+        * try and read the MAC address from EEPROM flash
+        * and set it.
+        */
+       if (!enetaddr_found) {
+               if (eeprom_mac_read)
+                       /* Set Ethernet MAC address from EEPROM */
+                       davinci_sync_env_enetaddr(enetaddr);
+       } else {
+               /*
+                * MAC address present in environment compare it with
+                * the MAC address in EEPROM and warn on mismatch
+                */
+               if (eeprom_mac_read && memcmp(enetaddr, env_enetaddr, 6))
+                       printf("Warning: MAC address in EEPROM don't match "
+                                       "with the MAC address in the environment\n");
+                       printf("Default using MAC address from environment\n");
+       }
+
+#endif
        return 0;
 }
 
+#ifdef CONFIG_DAVINCI_MMC
+static struct davinci_mmc mmc_sd0 = {
+       .reg_base = (struct davinci_mmc_regs *)DAVINCI_MMC_SD0_BASE,
+       .host_caps = MMC_MODE_4BIT,     /* DA850 supports only 4-bit SD/MMC */
+       .voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
+       .version = MMC_CTLR_VERSION_2,
+};
+
+int board_mmc_init(bd_t *bis)
+{
+       mmc_sd0.input_clk = clk_get(DAVINCI_MMCSD_CLKID);
+
+       /* Add slot-0 to mmc subsystem */
+       return davinci_mmc_init(bis, &mmc_sd0);
+}
+#endif
+
 static const struct pinmux_config gpio_pins[] = {
 #ifdef CONFIG_USE_NOR
        /* GP0[11] is required for NOR to work on Rev 3 EVMs */
        { pinmux(0), 8, 4 },    /* GP0[11] */
 #endif
+#ifdef CONFIG_DAVINCI_MMC
+       /* GP0[11] is required for SD to work on Rev 3 EVMs */
+       { pinmux(0),  8, 4 },   /* GP0[11] */
+#endif
 };
 
 const struct pinmux_resource pinmuxes[] = {
@@ -133,6 +262,9 @@ const struct pinmux_resource pinmuxes[] = {
        PINMUX_ITEM(emifa_pins_nor),
 #endif
        PINMUX_ITEM(gpio_pins),
+#ifdef CONFIG_DAVINCI_MMC
+       PINMUX_ITEM(mmc0_pins),
+#endif
 };
 
 const int pinmuxes_size = ARRAY_SIZE(pinmuxes);
@@ -143,6 +275,9 @@ const struct lpsc_resource lpsc[] = {
        { DAVINCI_LPSC_EMAC },  /* image download */
        { DAVINCI_LPSC_UART2 }, /* console */
        { DAVINCI_LPSC_GPIO },
+#ifdef CONFIG_DAVINCI_MMC
+       { DAVINCI_LPSC_MMC_SD },
+#endif
 };
 
 const int lpsc_size = ARRAY_SIZE(lpsc);
@@ -200,7 +335,7 @@ int board_early_init_f(void)
 
 int board_init(void)
 {
-#ifdef CONFIG_USE_NOR
+#if defined(CONFIG_USE_NOR) || defined(CONFIG_DAVINCI_MMC)
        u32 val;
 #endif
 
@@ -213,11 +348,11 @@ int board_init(void)
         * NAND CS setup - cycle counts based on da850evm NAND timings in the
         * Linux kernel @ 25MHz EMIFA
         */
-       writel((DAVINCI_ABCR_WSETUP(0) |
-               DAVINCI_ABCR_WSTROBE(1) |
-               DAVINCI_ABCR_WHOLD(0) |
-               DAVINCI_ABCR_RSETUP(0) |
-               DAVINCI_ABCR_RSTROBE(1) |
+       writel((DAVINCI_ABCR_WSETUP(2) |
+               DAVINCI_ABCR_WSTROBE(2) |
+               DAVINCI_ABCR_WHOLD(1) |
+               DAVINCI_ABCR_RSETUP(1) |
+               DAVINCI_ABCR_RSTROBE(4) |
                DAVINCI_ABCR_RHOLD(0) |
                DAVINCI_ABCR_TA(1) |
                DAVINCI_ABCR_ASIZE_8BIT),
@@ -251,6 +386,16 @@ int board_init(void)
        writel(val, GPIO_BANK0_REG_CLR_ADDR);
 #endif
 
+#ifdef CONFIG_DAVINCI_MMC
+       /* Set the GPIO direction as output */
+       clrbits_le32((u32 *)GPIO_BANK0_REG_DIR_ADDR, (0x01 << 11));
+
+       /* Set the output as high */
+       val = readl(GPIO_BANK0_REG_SET_ADDR);
+       val |= (0x01 << 11);
+       writel(val, GPIO_BANK0_REG_SET_ADDR);
+#endif
+
 #ifdef CONFIG_DRIVER_TI_EMAC
        davinci_emac_mii_mode_sel(HAS_RMII);
 #endif /* CONFIG_DRIVER_TI_EMAC */