sd: g12a: optimize sd & wifi TDMA
authorNan Li <nan.li@amlogic.com>
Tue, 22 May 2018 08:16:31 +0000 (16:16 +0800)
committerYixun Lan <yixun.lan@amlogic.com>
Mon, 16 Jul 2018 09:16:49 +0000 (02:16 -0700)
PD#166884: optimize sd inval irq error,
when sd insert wifi running. wifi is data1.

Change-Id: I6de4f519d3bacec7d9ab4eec4fc9b0cfc6b5d07d
Signed-off-by: Nan Li <nan.li@amlogic.com>
arch/arm64/boot/dts/amlogic/mesong12a.dtsi
drivers/amlogic/mmc/aml_sd_emmc.c
drivers/amlogic/mmc/aml_sd_emmc_v3.c
drivers/amlogic/mmc/amlsd.c
include/linux/amlogic/sd.h

index bd6c9af..907cc4a 100644 (file)
                status = "disabled";
                compatible = "amlogic, meson-mmc-g12a";
                reg = <0x0 0xffe05000 0x0 0x800>;
-               interrupts = <0 190 1>;
+               interrupts = <0 190 4>;
 
                pinctrl-names = "sd_all_pins",
                        "sd_clk_cmd_pins",
                                   "GPIOC_1",
                                   "GPIOC_2",
                                   "GPIOC_3",
-                                  "GPIOC_4",
                                   "GPIOC_5";
                        function = "gpio_periphs";
                        output-high;
                };
+               mux1 {
+                       groups = "GPIOC_4";
+                       function = "gpio_periphs";
+                       output-low;
+               };
        };
 
        sd_clr_noall_pins:sd_clr_noall_pins {
                        groups = "GPIOV_0";
                        function = "gpio_periphs";
                        bias-pull-up;
-                       output-high;
+                       output-low;
+               };
+               mux1 {
+                       groups = "GPIOX_4";
+                       function = "gpio_periphs";
+                       output-low;
                };
        };
 
index cf301b9..c276bee 100644 (file)
@@ -513,6 +513,7 @@ _cali_retry:
                ret = aml_cali_auto(mmc, &c_data);
        else
                ret = aml_cali_index(mmc, &c_data);
+       host->is_tunning = 0;
        if (ret) {
                /* Do not get a valid line delay index value! */
                if (cali_retry < MAX_CALI_RETRY) {
@@ -526,7 +527,6 @@ _cali_retry:
                        return -1;
                }
        }
-       host->is_tunning = 0;
 
        ret = aml_cali_find(mmc, &c_data);
        /* retry cali here! */
@@ -731,6 +731,7 @@ tunning:
        host->is_tunning = 1;
        ret = aml_tuning_adj(mmc, opcode,
                        tuning_data, &best_win_start, &best_win_size);
+       host->is_tunning = 0;
        if (ret)
                return -ENOMEM;
        if (best_win_size <= 0) {
@@ -787,7 +788,6 @@ tunning:
        gadjust->cali_enable = 0;
        gadjust->cali_rise = 0;
        writel(adjust, host->base + SD_EMMC_ADJUST);
-       host->is_tunning = 0;
 
        /* fixme, yyh for retry flow. */
        emmc_adj->adj_win_start = best_win_start;
@@ -1140,13 +1140,14 @@ void aml_sd_emmc_set_clkc(struct amlsd_platform *pdata)
 void aml_sd_emmc_save_host_val(struct mmc_host *mmc)
 {
        u32 adj, dly1, dly2, intf3;
-       u32 vconf = 0;
+       u32 vconf = 0, vclkc = 0;
        struct sd_emmc_config *pconf = (struct sd_emmc_config *)&vconf;
        struct amlsd_platform *pdata = mmc_priv(mmc);
        struct amlsd_host *host = pdata->host;
        unsigned long clk_ios;
 
        clk_ios = clk_get_rate(host->cfg_div_clk);
+       vclkc = readl(host->base + SD_EMMC_CLOCK_V3);
        vconf = readl(host->base + SD_EMMC_CFG);
        adj = readl(host->base + SD_EMMC_ADJUST_V3);
        dly1 = readl(host->base + SD_EMMC_DELAY1_V3);
@@ -1157,6 +1158,7 @@ void aml_sd_emmc_save_host_val(struct mmc_host *mmc)
                        && (pconf->bl_len == pdata->bl_len)
                        && (pconf->stop_clk == pdata->stop_clk)
                        && (mmc->actual_clock == clk_ios)
+                       && (vclkc == pdata->clkc)
                        && (adj == pdata->adj)
                        && (dly1 == pdata->dly1)
                        && (dly2 == pdata->dly2)
@@ -1169,6 +1171,7 @@ void aml_sd_emmc_save_host_val(struct mmc_host *mmc)
        pconf->bus_width = pdata->bus_width;
        pconf->bl_len = pdata->bl_len;
        pconf->stop_clk = pdata->stop_clk;
+       vclkc = pdata->clkc;
        adj = pdata->adj;
        dly1 = pdata->dly1;
        dly2 = pdata->dly2;
@@ -1176,7 +1179,9 @@ void aml_sd_emmc_save_host_val(struct mmc_host *mmc)
        if (aml_card_type_non_sdio(pdata))
                pconf->stop_clk = 0;
 
+       writel(vclkc, host->base + SD_EMMC_CLOCK_V3);
        clk_set_rate(host->cfg_div_clk, clk_ios);
+       pdata->clkc = readl(host->base + SD_EMMC_CLOCK_V3);
        writel(vconf, host->base + SD_EMMC_CFG);
        writel(adj, host->base + SD_EMMC_ADJUST_V3);
        writel(dly1, host->base + SD_EMMC_DELAY1_V3);
@@ -1858,11 +1863,72 @@ static void aml_sd_emmc_check_sdio_irq(struct amlsd_host *host)
                }
        }
 }
+
+static void aml_sd_emmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+       struct amlsd_platform *pdata = mmc_priv(mmc);
+       struct amlsd_host *host = pdata->host;
+       unsigned long flags;
+       /* u32 vstat = 0; */
+       u32 vclkc = 0;
+       struct sd_emmc_clock *pclock = NULL;
+       struct sd_emmc_clock_v3 *pclock_v3 = NULL;
+       u32 vconf = 0;
+       struct sd_emmc_config *pconf = (struct sd_emmc_config *)&vconf;
+       u32 virqc = 0;
+       struct sd_emmc_irq_en *irqc = (struct sd_emmc_irq_en *)&virqc;
+
+       host->sdio_irqen = enable;
+       if (host->xfer_step == XFER_START)
+               return;
+
+       if (enable)
+       spin_lock_irqsave(&host->mrq_lock, flags);
+       vconf = readl(host->base + SD_EMMC_CFG);
+       virqc = readl(host->base + SD_EMMC_IRQ_EN);
+
+       pconf->irq_ds = 0;
+
+       /* vstat = sd_emmc_regs->gstatus&SD_EMMC_IRQ_ALL; */
+       if (enable)
+               irqc->irq_sdio = 1;
+       else
+               irqc->irq_sdio = 0;
+
+       writel(virqc, host->base + SD_EMMC_IRQ_EN);
+       writel(vconf, host->base + SD_EMMC_CFG);
+
+       if (host->ctrl_ver >= 3) {
+               pclock_v3 = (struct sd_emmc_clock_v3 *)&vclkc;
+               vclkc = readl(host->base + SD_EMMC_CLOCK_V3);
+               pclock_v3->irq_sdio_sleep = 1;
+               pclock_v3->irq_sdio_sleep_ds = 0;
+               writel(vclkc, host->base + SD_EMMC_CLOCK_V3);
+       } else {
+               pclock = (struct sd_emmc_clock *)&vclkc;
+               vclkc = readl(host->base + SD_EMMC_CLOCK);
+               pclock->irq_sdio_sleep = 1;
+               pclock->irq_sdio_sleep_ds = 0;
+               writel(vclkc, host->base + SD_EMMC_CLOCK);
+       }
+       pdata->clkc = vclkc;
+
+       if (enable)
+       spin_unlock_irqrestore(&host->mrq_lock, flags);
+
+       /* check if irq already occurred */
+       aml_sd_emmc_check_sdio_irq(host);
+}
+
 int meson_mmc_request_done(struct mmc_host *mmc, struct mmc_request *mrq)
 {
        struct amlsd_platform *pdata = NULL;
        struct amlsd_host *host = NULL;
        unsigned long flags;
+#ifdef AML_MMC_TDMA
+       u32 virqc = 0;
+       struct sd_emmc_irq_en *irqc = (struct sd_emmc_irq_en *)&virqc;
+#endif
 
        pdata = mmc_priv(mmc);
        host = pdata->host;
@@ -1878,11 +1944,26 @@ int meson_mmc_request_done(struct mmc_host *mmc, struct mmc_request *mrq)
        if (pdata->xfer_post)
                pdata->xfer_post(pdata);
 
+#ifdef AML_MMC_TDMA
+       if ((host->mem->start == host->data->port_b_base)
+                       && (host->data->chip_type == MMC_CHIP_G12A)
+                       && strcmp(host->pinctrl_name, "sdio_")) {
+               if (sdio_host) {
+                       if (pdata->xfer_pre)
+                               pdata->xfer_pre(mmc_priv(sdio_host));
+                       virqc = readl(host->base + SD_EMMC_IRQ_EN);
+                       if (irqc->irq_sdio != host->sdio_irqen)
+                               aml_sd_emmc_enable_sdio_irq(sdio_host,
+                                               host->sdio_irqen);
+               }
+       }
+#endif
        aml_sd_emmc_check_sdio_irq(host);
        mmc_request_done(host->mmc, mrq);
 #ifdef AML_MMC_TDMA
        if ((host->mem->start == host->data->port_b_base)
                        && (host->data->chip_type == MMC_CHIP_G12A)
+                       && (host->init_volt == 0)
                        && (host->is_tunning == 0))
                complete(&host->drv_completion);
 #endif
@@ -1982,6 +2063,11 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_request *mrq)
                conf_flag |= 1 << 0;
                pconf->auto_clk = 0;
                host->sd_sdio_switch_volat_done = 0;
+#ifdef AML_MMC_TDMA
+               if ((host->mem->start == host->data->port_b_base)
+                               && (host->data->chip_type == MMC_CHIP_G12A))
+                       host->init_volt = 1;
+#endif
        }
        if ((pconf->auto_clk) && (pdata->auto_clk_close)) {
                conf_flag |= 1 << 1;
@@ -2254,10 +2340,9 @@ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
                pdata->xfer_pre(pdata);
 
 #ifdef AML_MMC_TDMA
-               if ((host->mem->start == host->data->port_b_base)
-                       && (host->data->chip_type == MMC_CHIP_G12A)) {
-                       aml_sd_emmc_save_host_val(mmc);
-       }
+       if ((host->mem->start == host->data->port_b_base)
+                       && (host->data->chip_type == MMC_CHIP_G12A))
+               aml_sd_emmc_save_host_val(mmc);
 #endif
 
        spin_lock_irqsave(&host->mrq_lock, flags);
@@ -2391,6 +2476,9 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
        if (WARN_ON(!host))
                return IRQ_NONE;
 
+#ifdef AML_MMC_TDMA
+       spin_lock_irqsave(&host->mrq_lock, flags);
+#endif
        virqc = readl(host->base + SD_EMMC_IRQ_EN) & 0xffff;
        vstat = readl(host->base + SD_EMMC_STATUS) & 0xffffffff;
        host->ista = vstat;
@@ -2399,16 +2487,46 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
                        __func__, __LINE__, vstat);
 
        if (irqc->irq_sdio && ista->irq_sdio) {
-               if ((host->mmc->sdio_irq_thread)
-                       && (!atomic_read(&host->mmc->sdio_irq_thread_abort))) {
-                       mmc_signal_sdio_irq(host->mmc);
-                       if (!(vstat & 0x3fff))
-                               return IRQ_HANDLED;
+#ifdef AML_MMC_TDMA
+               if (strcmp(mmc_hostname(host->mmc), "sdio")
+                               && sdio_host) {
+                       if ((sdio_host->sdio_irq_thread)
+                               && (!atomic_read(
+                                       &sdio_host->sdio_irq_thread_abort))) {
+                               mmc_signal_sdio_irq(sdio_host);
+                               if (!(vstat & 0x3fff)) {
+                                       spin_unlock_irqrestore(&host->mrq_lock,
+                                                       flags);
+                                       return IRQ_HANDLED;
+                               }
+                       }
+               } else {
+#endif
+                       if ((host->mmc->sdio_irq_thread)
+                               && (!atomic_read(
+                                       &host->mmc->sdio_irq_thread_abort))) {
+                               mmc_signal_sdio_irq(host->mmc);
+                               if (!(vstat & 0x3fff)) {
+#ifdef AML_MMC_TDMA
+                                       spin_unlock_irqrestore(&host->mrq_lock,
+                                                       flags);
+#endif
+                                       return IRQ_HANDLED;
+                               }
+                       }
+#ifdef AML_MMC_TDMA
                }
-       } else if (!(vstat & 0x3fff))
+#endif
+       } else if (!(vstat & 0x3fff)) {
+#ifdef AML_MMC_TDMA
+               spin_unlock_irqrestore(&host->mrq_lock, flags);
+#endif
                return IRQ_HANDLED;
+       }
 
+#ifndef AML_MMC_TDMA
        spin_lock_irqsave(&host->mrq_lock, flags);
+#endif
        mrq = host->mrq;
        mmc = host->mmc;
        pdata = mmc_priv(mmc);
@@ -2816,56 +2934,6 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static void aml_sd_emmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
-{
-       struct amlsd_platform *pdata = mmc_priv(mmc);
-       struct amlsd_host *host = pdata->host;
-       unsigned long flags;
-       /* u32 vstat = 0; */
-       u32 vclkc = 0;
-       struct sd_emmc_clock *pclock = NULL;
-       struct sd_emmc_clock_v3 *pclock_v3 = NULL;
-       u32 vconf = 0;
-       struct sd_emmc_config *pconf = (struct sd_emmc_config *)&vconf;
-       u32 virqc = 0;
-       struct sd_emmc_irq_en *irqc = (struct sd_emmc_irq_en *)&virqc;
-
-       host->sdio_irqen = enable;
-       spin_lock_irqsave(&host->mrq_lock, flags);
-       vconf = readl(host->base + SD_EMMC_CFG);
-       virqc = readl(host->base + SD_EMMC_IRQ_EN);
-
-       pconf->irq_ds = 0;
-
-       /* vstat = sd_emmc_regs->gstatus&SD_EMMC_IRQ_ALL; */
-       if (enable)
-               irqc->irq_sdio = 1;
-       else
-               irqc->irq_sdio = 0;
-
-       writel(virqc, host->base + SD_EMMC_IRQ_EN);
-       writel(vconf, host->base + SD_EMMC_CFG);
-       if (host->ctrl_ver >= 3) {
-               pclock_v3 = (struct sd_emmc_clock_v3 *)&vclkc;
-               vclkc = readl(host->base + SD_EMMC_CLOCK_V3);
-               pclock_v3->irq_sdio_sleep = 1;
-               pclock_v3->irq_sdio_sleep_ds = 0;
-               writel(vclkc, host->base + SD_EMMC_CLOCK_V3);
-       } else {
-               pclock = (struct sd_emmc_clock *)&vclkc;
-               vclkc = readl(host->base + SD_EMMC_CLOCK);
-               pclock->irq_sdio_sleep = 1;
-               pclock->irq_sdio_sleep_ds = 0;
-               writel(vclkc, host->base + SD_EMMC_CLOCK);
-       }
-       pdata->clkc = vclkc;
-
-       spin_unlock_irqrestore(&host->mrq_lock, flags);
-
-       /* check if irq already occurred */
-       aml_sd_emmc_check_sdio_irq(host);
-}
-
 /*get readonly: 0 for rw, 1 for ro*/
 static int aml_sd_emmc_get_ro(struct mmc_host *mmc)
 {
@@ -2905,6 +2973,12 @@ static int aml_sd_emmc_card_busy(struct mmc_host *mmc)
        u32 vconf;
        struct sd_emmc_config *pconf = (struct sd_emmc_config *)&vconf;
 
+#ifdef AML_MMC_TDMA
+       if ((host->mem->start == host->data->port_b_base)
+                       && (host->data->chip_type == MMC_CHIP_G12A)
+                       && (host->init_volt == 0))
+               wait_for_completion(&host->drv_completion);
+#endif
        vstat = readl(host->base + SD_EMMC_STATUS);
        status = ista->dat_i & 0xf;
 
@@ -2914,7 +2988,18 @@ static int aml_sd_emmc_card_busy(struct mmc_host *mmc)
                vconf = readl(host->base + SD_EMMC_CFG);
                pconf->auto_clk = 1;
                writel(vconf, host->base + SD_EMMC_CFG);
+#ifdef AML_MMC_TDMA
+               if ((host->mem->start == host->data->port_b_base)
+                               && (host->data->chip_type == MMC_CHIP_G12A))
+                       host->init_volt = 0;
+#endif
        }
+#ifdef AML_MMC_TDMA
+               if ((host->mem->start == host->data->port_b_base)
+                               && (host->data->chip_type == MMC_CHIP_G12A)
+                               && (host->init_volt == 0))
+                       complete(&host->drv_completion);
+#endif
        return !status;
 }
 
@@ -3021,12 +3106,14 @@ static int meson_mmc_probe(struct platform_device *pdev)
        }
 
        if (host->ctrl_ver >= 3) {
+#ifdef AML_MMC_TDMA
                if ((host->mem->start == host->data->port_b_base)
                                && (host->data->chip_type == MMC_CHIP_G12A))
                        ret = devm_request_threaded_irq(&pdev->dev, host->irq,
                                        meson_mmc_irq, meson_mmc_irq_thread_v3,
                                        IRQF_ONESHOT, "meson-aml-mmc", host);
                else
+#endif
                        ret = devm_request_threaded_irq(&pdev->dev, host->irq,
                                        meson_mmc_irq, meson_mmc_irq_thread_v3,
                                        IRQF_SHARED, "meson-aml-mmc", host);
index d397f25..5241cd4 100644 (file)
@@ -62,6 +62,9 @@ int meson_mmc_clk_init_v3(struct amlsd_host *host)
        pclkc->div = 60;         /* 400KHz */
        pclkc->src = 0;   /* 0: Crystal 24MHz */
        pclkc->core_phase = init->core_phase;     /* 2: 180 phase */
+       if ((host->mem->start == host->data->port_b_base)
+                       && (host->data->chip_type == MMC_CHIP_G12A))
+               pclkc->core_phase = 2;
        pclkc->rx_phase = init->rx_phase;
        pclkc->tx_phase = init->tx_phase;
        pclkc->always_on = 1;     /* Keep clock always on */
@@ -307,17 +310,19 @@ void meson_mmc_set_ios_v3(struct mmc_host *mmc,
                                struct mmc_ios *ios)
 {
        struct amlsd_platform *pdata = mmc_priv(mmc);
+#ifdef AML_MMC_TDMA
        struct amlsd_host *host = pdata->host;
 
-#ifdef AML_MMC_TDMA
        if ((host->mem->start == host->data->port_b_base)
-                       && (host->data->chip_type == MMC_CHIP_G12A))
+                       && (host->data->chip_type == MMC_CHIP_G12A)
+                       && (host->init_volt == 0))
                wait_for_completion(&host->drv_completion);
 #endif
        if (!pdata->is_in) {
 #ifdef AML_MMC_TDMA
                if ((host->mem->start == host->data->port_b_base)
-                               && (host->data->chip_type == MMC_CHIP_G12A))
+                               && (host->data->chip_type == MMC_CHIP_G12A)
+                               && (host->init_volt == 0))
                        complete(&host->drv_completion);
 #endif
                return;
@@ -341,7 +346,8 @@ void meson_mmc_set_ios_v3(struct mmc_host *mmc,
                aml_cs_dont_care(mmc);
 #ifdef AML_MMC_TDMA
        if ((host->mem->start == host->data->port_b_base)
-                       && (host->data->chip_type == MMC_CHIP_G12A))
+                       && (host->data->chip_type == MMC_CHIP_G12A)
+                       && (host->init_volt == 0))
                complete(&host->drv_completion);
 #endif
 }
@@ -581,7 +587,6 @@ static int emmc_eyetest_log(struct mmc_host *mmc, u32 line_x)
        u64 tmp = 0;
        u32 blksz = 512;
 
-       host->is_tunning = 1;
        pr_debug("delay1: 0x%x , delay2: 0x%x, line_x: %d\n",
                        readl(host->base + SD_EMMC_DELAY1_V3),
                        readl(host->base + SD_EMMC_DELAY2_V3), line_x);
@@ -601,12 +606,14 @@ RETRY:
 
        /*****test start*************/
        udelay(5);
+       host->is_tunning = 1;
        if (line_x < 9)
                aml_sd_emmc_cali_v3(mmc,
                        MMC_READ_MULTIPLE_BLOCK,
                        host->blk_test, blksz, 40);
        else
                aml_sd_emmc_cmd_v3(mmc);
+       host->is_tunning = 0;
        udelay(1);
        eyetest_log = readl(host->base + SD_EMMC_EYETEST_LOG);
 
@@ -635,7 +642,6 @@ RETRY:
                        readl(host->base + SD_EMMC_DELAY1_V3),
                        readl(host->base + SD_EMMC_DELAY2_V3),
                        pdata->align[line_x], line_x);
-       host->is_tunning = 0;
        return 0;
 }
 
@@ -1075,12 +1081,12 @@ tunning:
                        || (clkc->div >= 10)) {
                        pr_info("%s: final result of tuning failed\n",
                                 mmc_hostname(host->mmc));
+                       host->is_tunning = 0;
 #ifdef AML_MMC_TDMA
        if ((host->mem->start == host->data->port_b_base)
                        && (host->data->chip_type == MMC_CHIP_G12A))
                complete(&host->drv_completion);
 #endif
-
                        return -1;
                }
                clkc->div += 1;
@@ -1093,6 +1099,12 @@ tunning:
                if (++tuning_num > MAX_TUNING_RETRY) {
                        pr_err("%s: tuning failed\n",
                                mmc_hostname(host->mmc));
+                       host->is_tunning = 0;
+#ifdef AML_MMC_TDMA
+       if ((host->mem->start == host->data->port_b_base)
+                       && (host->data->chip_type == MMC_CHIP_G12A))
+               complete(&host->drv_completion);
+#endif
                        return -1;
                }
                pr_warn("wave is not sharp, again\n");
@@ -1116,6 +1128,11 @@ tunning:
        gadjust->cali_rise = 0;
        writel(adjust, host->base + SD_EMMC_ADJUST_V3);
        pdata->adj = adjust;
+
+       pr_info("%s: sd_emmc_regs->gclock=0x%x,sd_emmc_regs->gadjust=0x%x\n",
+                       mmc_hostname(host->mmc),
+                       readl(host->base + SD_EMMC_CLOCK_V3),
+                       readl(host->base + SD_EMMC_ADJUST_V3));
        host->is_tunning = 0;
 #ifdef AML_MMC_TDMA
        if ((host->mem->start == host->data->port_b_base)
@@ -1123,10 +1140,6 @@ tunning:
                complete(&host->drv_completion);
 #endif
 
-       pr_info("%s: sd_emmc_regs->gclock=0x%x,sd_emmc_regs->gadjust=0x%x\n",
-                       mmc_hostname(host->mmc),
-                       readl(host->base + SD_EMMC_CLOCK_V3),
-                       readl(host->base + SD_EMMC_ADJUST_V3));
        return ret;
 #endif
        return 0;
@@ -1253,7 +1266,6 @@ static int sdio_eyetest_log(struct mmc_host *mmc, u32 line_x, u32 opcode,
        const u8 *blk_pattern = tuning_data->blk_pattern;
        unsigned int blksz = tuning_data->blksz;
 
-       host->is_tunning = 1;
        /****** calculate  line_x ***************************/
        /******* init eyetest register ************************/
        pr_debug("delay1: 0x%x , delay2: 0x%x, line_x: %d\n",
@@ -1271,9 +1283,11 @@ RETRY:
        pdata->intf3 = intf3;
        udelay(5);
 
+       host->is_tunning = 1;
        for (i = 0; i < 40; i++)
                aml_sd_emmc_tuning_transfer(mmc, opcode,
                                blk_pattern, host->blk_test, blksz);
+       host->is_tunning = 0;
        udelay(1);
        eyetest_log = readl(host->base + SD_EMMC_EYETEST_LOG);
        eyetest_out0 = readl(host->base + SD_EMMC_EYETEST_OUT0);
@@ -1302,7 +1316,6 @@ RETRY:
        pdata->intf3 = intf3;
        pdata->align[line_x] = ((tmp | eyetest_out1) << 32) | eyetest_out0;
        pr_debug("u64 eyetestout 0x%llx\n", pdata->align[line_x]);
-       host->is_tunning = 0;
        return 0;
 }
 
@@ -1315,7 +1328,6 @@ static int aml_sdio_timing(struct mmc_host *mmc, u32 opcode,
        u32 line_x = 0, delay1 = 0, retry = 1, temp;
        int ret;
 
-       host->is_tunning = 1;
        delay1 = 0;
        for (line_x = 0; line_x < 4; line_x++) {
                writel(0, host->base + SD_EMMC_DELAY1_V3);
@@ -1356,7 +1368,6 @@ RETRY:
        writel(delay1, host->base + SD_EMMC_DELAY1_V3);
        pdata->dly1 = delay1;
 
-       host->is_tunning = 0;
        pr_info("%s: gadjust=0x%x, gdelay1=0x%x, gclock=0x%x\n",
                        mmc_hostname(host->mmc),
                        readl(host->base + SD_EMMC_ADJUST_V3),
index c7e05dc..ee080da 100644 (file)
@@ -867,6 +867,8 @@ int aml_sd_uart_detect(struct amlsd_platform *pdata)
                        pr_info("normal card in\n");
                        aml_uart_switch(pdata, 0);
                        aml_jtag_switch_ao(pdata);
+                       if (host->data->chip_type == MMC_CHIP_G12A)
+                               host->is_sduart = 0;
                        if (pdata->caps & MMC_CAP_4_BIT_DATA)
                                mmc->caps |= MMC_CAP_4_BIT_DATA;
                }
@@ -882,6 +884,8 @@ int aml_sd_uart_detect(struct amlsd_platform *pdata)
                        pr_info("card out\n");
 
                pdata->is_tuned = false;
+               if (host->data->chip_type == MMC_CHIP_G12A)
+                       host->is_sduart = 0;
                if (mmc && mmc->card)
                        mmc_card_set_removed(mmc->card);
                aml_uart_switch(pdata, 0);
index ab9c04b..47954f1 100644 (file)
@@ -470,6 +470,7 @@ struct amlsd_host {
 
        int      status; /* host status: xx_error/ok */
        int init_flag;
+       int init_volt;
 
        char    *msg_buf;
 #define MESSAGE_BUF_SIZE                       512