]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge remote-tracking branch 'remotes/origin/tx48-mmc-bugfix'
authorLothar Waßmann <LW@KARO-electronics.de>
Mon, 30 Jun 2014 13:18:34 +0000 (15:18 +0200)
committerLothar Waßmann <LW@KARO-electronics.de>
Mon, 30 Jun 2014 13:18:34 +0000 (15:18 +0200)
arch/arm/cpu/armv7/am33xx/board.c
arch/arm/cpu/armv7/am33xx/clock_am33xx.c
arch/arm/include/asm/arch-am33xx/mmc_host_def.h
board/karo/tx48/tx48.c
drivers/mmc/omap_hsmmc.c

index 5b3cefb62fb08ffcf80e558a139943eb33c7fb0f..032d28c1cb10377c8d8276c5519866ea2aff155c 100644 (file)
@@ -98,7 +98,7 @@ void enable_caches(void)
 #endif
 
 #if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
-int cpu_mmc_init(bd_t *bis)
+int __cpu_mmc_init(bd_t *bis)
 {
        int ret;
 
@@ -108,6 +108,8 @@ int cpu_mmc_init(bd_t *bis)
 
        return omap_mmc_init(1, 0, 0, -1, -1);
 }
+/* let platform code be able to override this! */
+int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__cpu_mmc_init")));
 #endif
 
 void setup_clocks_for_console(void)
index 5e37af34d627bde25685fe3223c6b4dbef487f7c..c05d115735dc978c7b6bc97f08600ef8cc1b5811 100644 (file)
@@ -154,7 +154,7 @@ static void enable_per_clocks(void)
        enable_clk(cmper->cpgmac0clkctrl, PRCM_MOD_EN);
 
        /* MMC */
-#ifndef CONFIG_OMAP_MMC_DEV_0
+#ifdef CONFIG_OMAP_MMC_DEV_0
        enable_clk(cmper->mmc0clkctrl, PRCM_MOD_EN);
 #endif
 #ifdef CONFIG_OMAP_MMC_DEV_1
index 886ca65f46fc9b7717641d007aa9419b35a2b86d..ae6e5339cf7068c0f7e0e683e453711fa841a0da 100644 (file)
@@ -21,9 +21,9 @@
 /*
  * OMAP HSMMC register definitions
  */
-#define OMAP_HSMMC1_BASE               0x48060000
-#define OMAP_HSMMC2_BASE               0x481D8000
-#define OMAP_HSMMC3_BASE               0x47810000
+#define OMAP_HSMMC1_BASE               0x48060100
+#define OMAP_HSMMC2_BASE               0x481D8100
+#define OMAP_HSMMC3_BASE               0x47810100
 
 #if defined(CONFIG_TI814X)
 #undef MMC_CLOCK_REFERENCE
index 7c39056324bfd949bfe7180e2181192444836ee4..48cb0c83da837031681307d1882482133570609b 100644 (file)
@@ -47,6 +47,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #define TX48_LCD_RST_GPIO      AM33XX_GPIO_NR(1, 19)
 #define TX48_LCD_PWR_GPIO      AM33XX_GPIO_NR(1, 22)
 #define TX48_LCD_BACKLIGHT_GPIO        AM33XX_GPIO_NR(3, 14)
+#define TX48_MMC_CD_GPIO       AM33XX_GPIO_NR(3, 15)
 
 #define GMII_SEL               (CTRL_BASE + 0x650)
 
@@ -333,10 +334,13 @@ static const struct pin_mux stk5_pads[] = {
        { OFFSET(gpmc_a6), MODE(7) | PULLUDEN, },
        /* LCD Backlight (PWM) */
        { OFFSET(mcasp0_aclkx), MODE(7) | PULLUDEN, },
+       /* MMC CD */
+       { OFFSET(mcasp0_fsx), MODE(7) | PULLUDEN | PULLUP_EN, },
 };
 
 static const struct gpio stk5_gpios[] = {
-       { AM33XX_GPIO_NR(1, 26), GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
+       { TX48_LED_GPIO, GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
+       { TX48_MMC_CD_GPIO, GPIOF_INPUT, "HEARTBEAT LED", },
 };
 
 static const struct pin_mux stk5_lcd_pads[] = {
@@ -1015,6 +1019,13 @@ int board_eth_init(bd_t *bis)
 }
 #endif /* CONFIG_DRIVER_TI_CPSW */
 
+#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
+int cpu_mmc_init(bd_t *bis)
+{
+       return omap_mmc_init(1, 0, 0, TX48_MMC_CD_GPIO, -1);
+}
+#endif
+
 void tx48_disable_watchdog(void)
 {
        struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
index 67d6b6862554c8150aea1b3c3786a58e5b0c424a..20893217df99649104492c6ebbb72aab99bec896 100644 (file)
@@ -131,7 +131,7 @@ static void omap5_pbias_config(struct mmc *mmc)
 }
 #endif
 
-unsigned char mmc_board_init(struct mmc *mmc)
+static void mmc_board_init(struct mmc *mmc)
 {
 #if defined(CONFIG_OMAP34XX)
        t2_t *t2_base = (t2_t *)T2_BASE;
@@ -180,8 +180,6 @@ unsigned char mmc_board_init(struct mmc *mmc)
        if (mmc->block_dev.dev == 0)
                omap5_pbias_config(mmc);
 #endif
-
-       return 0;
 }
 
 void mmc_init_stream(struct hsmmc *mmc_base)
@@ -193,26 +191,29 @@ void mmc_init_stream(struct hsmmc *mmc_base)
        writel(MMC_CMD0, &mmc_base->cmd);
        start = get_timer(0);
        while (!(readl(&mmc_base->stat) & CC_MASK)) {
-               if (get_timer(start) > MAX_RETRY_MS) {
-                       printf("%s: timeout waiting for cc!\n", __func__);
-                       return;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if (!(readl(&mmc_base->stat) & CC_MASK)) {
+               printf("%s: timeout waiting for cc!\n", __func__);
+               return;
        }
-       writel(CC_MASK, &mmc_base->stat)
-               ;
-       writel(MMC_CMD0, &mmc_base->cmd)
-               ;
+
+       writel(CC_MASK, &mmc_base->stat);
+       writel(MMC_CMD0, &mmc_base->cmd);
+
        start = get_timer(0);
        while (!(readl(&mmc_base->stat) & CC_MASK)) {
-               if (get_timer(start) > MAX_RETRY_MS) {
-                       printf("%s: timeout waiting for cc2!\n", __func__);
-                       return;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if (!(readl(&mmc_base->stat) & CC_MASK)) {
+               printf("%s: timeout waiting for cc2!\n", __func__);
+               return;
        }
        writel(readl(&mmc_base->con) & ~INIT_INITSTREAM, &mmc_base->con);
 }
 
-
 static int mmc_init_setup(struct mmc *mmc)
 {
        struct omap_hsmmc_data *priv_data = mmc->priv;
@@ -227,19 +228,23 @@ static int mmc_init_setup(struct mmc *mmc)
                &mmc_base->sysconfig);
        start = get_timer(0);
        while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) {
-               if (get_timer(start) > MAX_RETRY_MS) {
-                       printf("%s: timeout waiting for cc2!\n", __func__);
-                       return TIMEOUT;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) {
+               printf("%s: timeout %08x waiting for softreset done!\n", __func__,
+                       readl(&mmc_base->sysstatus));
+               return TIMEOUT;
        }
        writel(readl(&mmc_base->sysctl) | SOFTRESETALL, &mmc_base->sysctl);
        start = get_timer(0);
-       while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0x0) {
-               if (get_timer(start) > MAX_RETRY_MS) {
-                       printf("%s: timeout waiting for softresetall!\n",
-                               __func__);
-                       return TIMEOUT;
-               }
+       while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0) {
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0) {
+               printf("%s: timeout waiting for softresetall!\n", __func__);
+               return TIMEOUT;
        }
        writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl);
        writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,
@@ -258,10 +263,12 @@ static int mmc_init_setup(struct mmc *mmc)
                (dsor << CLKD_OFFSET) | ICE_OSCILLATE);
        start = get_timer(0);
        while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
-               if (get_timer(start) > MAX_RETRY_MS) {
-                       printf("%s: timeout waiting for ics!\n", __func__);
-                       return TIMEOUT;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
+               printf("%s: timeout waiting for ics!\n", __func__);
+               return TIMEOUT;
        }
        writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
 
@@ -290,11 +297,12 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit)
 
        start = get_timer(0);
        while ((readl(&mmc_base->sysctl) & bit) != 0) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for sysctl %x to clear\n",
-                               __func__, bit);
-                       return;
-               }
+               if (get_timer(0) - start > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysctl) & bit) != 0) {
+               printf("%s: timedout waiting for sysctl %x to clear\n", __func__, bit);
+               return;
        }
 }
 
@@ -308,19 +316,22 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 
        start = get_timer(0);
        while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {
-               if (get_timer(start) > MAX_RETRY_MS) {
-                       printf("%s: timeout waiting on cmd inhibit to clear\n",
-                                       __func__);
-                       return TIMEOUT;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {
+               printf("%s: timeout waiting on cmd inhibit to clear\n", __func__);
+               return TIMEOUT;
        }
        writel(0xFFFFFFFF, &mmc_base->stat);
        start = get_timer(0);
        while (readl(&mmc_base->stat)) {
-               if (get_timer(start) > MAX_RETRY_MS) {
-                       printf("%s: timeout waiting for stat!\n", __func__);
-                       return TIMEOUT;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if (readl(&mmc_base->stat)) {
+               printf("%s: timeout waiting for stat!\n", __func__);
+               return TIMEOUT;
        }
        /*
         * CMDREG
@@ -378,13 +389,14 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
        writel((cmd->cmdidx << 24) | flags, &mmc_base->cmd);
 
        start = get_timer(0);
-       do {
-               mmc_stat = readl(&mmc_base->stat);
-               if (get_timer(start) > MAX_RETRY_MS) {
-                       printf("%s : timeout: No status update\n", __func__);
-                       return TIMEOUT;
-               }
-       } while (!mmc_stat);
+       while (!(mmc_stat = readl(&mmc_base->stat))) {
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if (!mmc_stat) {
+               printf("%s : timeout: No status update\n", __func__);
+               return TIMEOUT;
+       }
 
        if ((mmc_stat & IE_CTO) != 0) {
                mmc_reset_controller_fsm(mmc_base, SYSCTL_SRC);
@@ -431,14 +443,15 @@ static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size)
 
        while (size) {
                ulong start = get_timer(0);
-               do {
-                       mmc_stat = readl(&mmc_base->stat);
-                       if (get_timer(start) > MAX_RETRY_MS) {
-                               printf("%s: timeout waiting for status!\n",
-                                               __func__);
-                               return TIMEOUT;
-                       }
-               } while (mmc_stat == 0);
+
+               while (!(mmc_stat = readl(&mmc_base->stat))) {
+                       if (get_timer(start) > MAX_RETRY_MS)
+                               break;
+               }
+               if (!mmc_stat) {
+                       printf("%s: timeout waiting for status!\n", __func__);
+                       return TIMEOUT;
+               }
 
                if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0)
                        mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);
@@ -486,14 +499,15 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
 
        while (size) {
                ulong start = get_timer(0);
-               do {
-                       mmc_stat = readl(&mmc_base->stat);
-                       if (get_timer(start) > MAX_RETRY_MS) {
-                               printf("%s: timeout waiting for status!\n",
-                                               __func__);
-                               return TIMEOUT;
-                       }
-               } while (mmc_stat == 0);
+
+               while (!(mmc_stat = readl(&mmc_base->stat))) {
+                       if (get_timer(start) > MAX_RETRY_MS)
+                               break;
+               }
+               if (!mmc_stat) {
+                       printf("%s: timeout waiting for status!\n", __func__);
+                       return TIMEOUT;
+               }
 
                if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0)
                        mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);
@@ -572,10 +586,12 @@ static void mmc_set_ios(struct mmc *mmc)
 
        start = get_timer(0);
        while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
-               if (get_timer(start) > MAX_RETRY_MS) {
-                       printf("%s: timeout waiting for ics!\n", __func__);
-                       return;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
+               printf("%s: timeout waiting for ics!\n", __func__);
+               return;
        }
        writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
 }
@@ -583,33 +599,39 @@ static void mmc_set_ios(struct mmc *mmc)
 int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
                int wp_gpio)
 {
-       struct mmc *mmc = &hsmmc_dev[dev_index];
-       struct omap_hsmmc_data *priv_data = &hsmmc_dev_data[dev_index];
-
-       sprintf(mmc->name, "OMAP SD/MMC");
-       mmc->send_cmd = mmc_send_cmd;
-       mmc->set_ios = mmc_set_ios;
-       mmc->init = mmc_init_setup;
-       mmc->priv = priv_data;
+       struct mmc *mmc;
+       struct omap_hsmmc_data *priv_data;
+       unsigned long base_addr;
 
        switch (dev_index) {
        case 0:
-               priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
+               base_addr = OMAP_HSMMC1_BASE;
                break;
 #ifdef OMAP_HSMMC2_BASE
        case 1:
-               priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC2_BASE;
+               base_addr = OMAP_HSMMC2_BASE;
                break;
 #endif
 #ifdef OMAP_HSMMC3_BASE
        case 2:
-               priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC3_BASE;
+               base_addr = OMAP_HSMMC3_BASE;
                break;
 #endif
        default:
-               priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
+               printf("Invalid MMC device index: %d\n", dev_index);
                return 1;
        }
+
+       mmc = &hsmmc_dev[dev_index];
+       priv_data = &hsmmc_dev_data[dev_index];
+       priv_data->base_addr = (void *)base_addr;
+
+       sprintf(mmc->name, "OMAP SD/MMC");
+       mmc->send_cmd = mmc_send_cmd;
+       mmc->set_ios = mmc_set_ios;
+       mmc->init = mmc_init_setup;
+       mmc->priv = priv_data;
+
        priv_data->cd_gpio = omap_mmc_setup_gpio_in(cd_gpio, "mmc_cd");
        if (priv_data->cd_gpio != -1)
                mmc->getcd = omap_mmc_getcd;