From dd857260209bd5610173cf0e17728f75772d7310 Mon Sep 17 00:00:00 2001 From: Nan Li Date: Fri, 20 Apr 2018 18:10:33 +0800 Subject: [PATCH] sd: sd & wifi TDMA crash. 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 --- drivers/amlogic/mmc/aml_sd_emmc.c | 38 +++++++++++++++++++++++------------- drivers/amlogic/mmc/aml_sd_emmc_v3.c | 23 +++++++++++++++++----- include/linux/amlogic/sd.h | 3 +-- 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/drivers/amlogic/mmc/aml_sd_emmc.c b/drivers/amlogic/mmc/aml_sd_emmc.c index 43d5e03..9facd41 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc.c +++ b/drivers/amlogic/mmc/aml_sd_emmc.c @@ -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; diff --git a/drivers/amlogic/mmc/aml_sd_emmc_v3.c b/drivers/amlogic/mmc/aml_sd_emmc_v3.c index 5691e70..82c1288 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc_v3.c +++ b/drivers/amlogic/mmc/aml_sd_emmc_v3.c @@ -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), diff --git a/include/linux/amlogic/sd.h b/include/linux/amlogic/sd.h index ac0d884..6bd9af6 100644 --- a/include/linux/amlogic/sd.h +++ b/include/linux/amlogic/sd.h @@ -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; -- 2.7.4