sd: sd & wifi TDMA crash.
authorNan Li <nan.li@amlogic.com>
Fri, 20 Apr 2018 10:10:33 +0000 (18:10 +0800)
committerYixun Lan <yixun.lan@amlogic.com>
Tue, 8 May 2018 07:50:49 +0000 (00:50 -0700)
PD#164804: when system run with SD card in,
system will be crashed. rm post_dma() crash error.

Change-Id: I99c10fcbf151a4c349bf6b0584056cd9080349e8
Signed-off-by: Nan Li <nan.li@amlogic.com>
drivers/amlogic/mmc/aml_sd_emmc.c
drivers/amlogic/mmc/aml_sd_emmc_v3.c
include/linux/amlogic/sd.h

index 43d5e03..9facd41 100644 (file)
@@ -1059,6 +1059,7 @@ static void aml_mmc_clk_switch_off(struct amlsd_platform *pdata)
        vcfg = readl(host->base + SD_EMMC_CFG);
        conf->stop_clk = 1;
        writel(vcfg, host->base + SD_EMMC_CFG);
+       pdata->stop_clk = 1;
 
        host->is_gated = true;
 }
@@ -1133,9 +1134,6 @@ void aml_sd_emmc_save_host_val(struct mmc_host *mmc)
        struct amlsd_host *host = pdata->host;
        unsigned long clk_ios;
 
-       strcpy(host->cur_dev, pdata->pinname);
-       host->val_f = 0;
-
        clk_ios = clk_get_rate(host->cfg_div_clk);
        vconf = readl(host->base + SD_EMMC_CFG);
        adj = readl(host->base + SD_EMMC_ADJUST_V3);
@@ -1145,6 +1143,7 @@ void aml_sd_emmc_save_host_val(struct mmc_host *mmc)
 
        if ((pconf->bus_width == pdata->bus_width)
                        && (pconf->bl_len == pdata->bl_len)
+                       && (pconf->stop_clk == pdata->stop_clk)
                        && (mmc->actual_clock == clk_ios)
                        && (adj == pdata->adj)
                        && (dly1 == pdata->dly1)
@@ -1152,9 +1151,12 @@ void aml_sd_emmc_save_host_val(struct mmc_host *mmc)
                        && (intf3 == pdata->intf3))
                return;
 
+       if (aml_card_type_non_sdio(pdata))
+               vconf = pdata->ctrl;
        clk_ios = mmc->actual_clock;
        pconf->bus_width = pdata->bus_width;
        pconf->bl_len = pdata->bl_len;
+       pconf->stop_clk = pdata->stop_clk;
        adj = pdata->adj;
        dly1 = pdata->dly1;
        dly2 = pdata->dly2;
@@ -1868,7 +1870,8 @@ int meson_mmc_request_done(struct mmc_host *mmc, struct mmc_request *mrq)
        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->data->chip_type == MMC_CHIP_G12A)
+                       && (host->is_tunning == 0))
                complete(&host->drv_completion);
 #endif
 
@@ -2208,14 +2211,16 @@ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
        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)
+                       && (mrq->cmd->opcode != MMC_SEND_TUNING_BLOCK))
                wait_for_completion(&host->drv_completion);
 #endif
 
        if (aml_check_unsupport_cmd(mmc, mrq)) {
 #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)
+                       && (mrq->cmd->opcode != MMC_SEND_TUNING_BLOCK))
                        complete(&host->drv_completion);
 #endif
                return;
@@ -2237,10 +2242,8 @@ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
                pdata->xfer_pre(pdata);
 
 #ifdef AML_MMC_TDMA
-       if ((aml_card_type_sdio(pdata)
-                               || aml_card_type_non_sdio(pdata))
+               if ((host->mem->start == host->data->port_b_base)
                        && (host->data->chip_type == MMC_CHIP_G12A)) {
-               if (strcmp(host->cur_dev, pdata->pinname) || host->val_f)
                        aml_sd_emmc_save_host_val(mmc);
        }
 #endif
@@ -2995,11 +2998,17 @@ static int meson_mmc_probe(struct platform_device *pdev)
                goto fail_init_host;
        }
 
-       if (host->ctrl_ver >= 3)
-               ret = devm_request_threaded_irq(&pdev->dev, host->irq,
-                       meson_mmc_irq, meson_mmc_irq_thread_v3,
-                       IRQF_SHARED, "meson-aml-mmc", host);
-       else
+       if (host->ctrl_ver >= 3) {
+               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
+                       ret = devm_request_threaded_irq(&pdev->dev, host->irq,
+                                       meson_mmc_irq, meson_mmc_irq_thread_v3,
+                                       IRQF_SHARED, "meson-aml-mmc", host);
+       } else
                ret = devm_request_threaded_irq(&pdev->dev, host->irq,
                        meson_mmc_irq, meson_mmc_irq_thread,
                        IRQF_SHARED, "meson-aml-mmc", host);
@@ -3081,6 +3090,7 @@ static int meson_mmc_probe(struct platform_device *pdev)
        /* save def clk & cfg */
        pdata->clkc = clk;
        pdata->ctrl = cfg;
+       pdata->bl_len = (cfg >> 4) & 0xf;
 
        if (pdata->caps & MMC_CAP_NONREMOVABLE)
                pdata->is_in = 1;
index 5691e70..82c1288 100644 (file)
@@ -155,6 +155,7 @@ static int meson_mmc_clk_set_rate_v3(struct mmc_host *mmc,
        if (!conf->stop_clk) {
                conf->stop_clk = 1;
                writel(vcfg, host->base + SD_EMMC_CFG);
+               pdata->stop_clk = 1;
        }
 
        if (aml_card_type_mmc(pdata)) {
@@ -192,6 +193,7 @@ static int meson_mmc_clk_set_rate_v3(struct mmc_host *mmc,
                conf->stop_clk = 0;
                writel(vcfg, host->base + SD_EMMC_CFG);
                pdata->clkc = readl(host->base + SD_EMMC_CLOCK_V3);
+               pdata->stop_clk = 0;
        }
 #endif
        pr_debug("actual_clock :%u, HHI_nand: 0x%x\n",
@@ -321,11 +323,6 @@ void meson_mmc_set_ios_v3(struct mmc_host *mmc,
                return;
        }
 
-       if ((aml_card_type_sdio(pdata)
-                               || aml_card_type_non_sdio(pdata))
-                       && (host->data->chip_type == MMC_CHIP_G12A))
-               host->val_f = 1;
-
        /*Set Power*/
        aml_sd_emmc_set_power_v3(pdata, ios->power_mode);
 
@@ -990,6 +987,11 @@ static int _aml_sd_emmc_execute_tuning(struct mmc_host *mmc, u32 opcode,
        int curr_win_start, curr_win_size;
        u32 rxdly[3] = {0xA28A28A, 0x15500514, 0x1FF8079E};
 
+#ifdef AML_MMC_TDMA
+       if ((host->mem->start == host->data->port_b_base)
+                       && (host->data->chip_type == MMC_CHIP_G12A))
+               wait_for_completion(&host->drv_completion);
+#endif
        writel(0, host->base + SD_EMMC_ADJUST_V3);
 
 tunning:
@@ -1076,6 +1078,12 @@ tunning:
                        || (clkc->div >= 10)) {
                        pr_info("%s: final result of tuning failed\n",
                                 mmc_hostname(host->mmc));
+#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;
@@ -1112,6 +1120,11 @@ tunning:
        writel(adjust, host->base + SD_EMMC_ADJUST_V3);
        pdata->adj = adjust;
        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
 
        pr_info("%s: sd_emmc_regs->gclock=0x%x,sd_emmc_regs->gadjust=0x%x\n",
                        mmc_hostname(host->mmc),
index ac0d884..6bd9af6 100644 (file)
@@ -262,6 +262,7 @@ struct amlsd_platform {
        unsigned char signal_voltage;
        int     bus_width;
        int     bl_len;
+       int     stop_clk;
 
        unsigned int low_burst;
        struct mutex in_out_lock;
@@ -412,8 +413,6 @@ struct amlsd_host {
        char is_tunning;
        char is_timming;
        char tuning_mode;
-       char cur_dev[32];
-       unsigned int val_f;
        unsigned int irq;
        unsigned int irq_in;
        unsigned int irq_out;