From 59bc6ce4ed9feee26e903134d77a675ebab75de4 Mon Sep 17 00:00:00 2001 From: Nan Li Date: Tue, 22 May 2018 16:16:31 +0800 Subject: [PATCH] sd: g12a: optimize sd & wifi TDMA PD#166884: optimize sd inval irq error, when sd insert wifi running. wifi is data1. Change-Id: I6de4f519d3bacec7d9ab4eec4fc9b0cfc6b5d07d Signed-off-by: Nan Li --- arch/arm64/boot/dts/amlogic/mesong12a.dtsi | 15 +- drivers/amlogic/mmc/aml_sd_emmc.c | 213 +++++++++++++++------ drivers/amlogic/mmc/aml_sd_emmc_v3.c | 41 ++-- drivers/amlogic/mmc/amlsd.c | 4 + include/linux/amlogic/sd.h | 1 + 5 files changed, 193 insertions(+), 81 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi index bd6c9afc6561..907cc4a36bcd 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi @@ -1425,7 +1425,7 @@ 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", @@ -2058,11 +2058,15 @@ "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 { @@ -2165,7 +2169,12 @@ groups = "GPIOV_0"; function = "gpio_periphs"; bias-pull-up; - output-high; + output-low; + }; + mux1 { + groups = "GPIOX_4"; + function = "gpio_periphs"; + output-low; }; }; diff --git a/drivers/amlogic/mmc/aml_sd_emmc.c b/drivers/amlogic/mmc/aml_sd_emmc.c index cf301b971fca..c276beefaff9 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc.c +++ b/drivers/amlogic/mmc/aml_sd_emmc.c @@ -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); diff --git a/drivers/amlogic/mmc/aml_sd_emmc_v3.c b/drivers/amlogic/mmc/aml_sd_emmc_v3.c index d397f25e4aea..5241cd4a1671 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc_v3.c +++ b/drivers/amlogic/mmc/aml_sd_emmc_v3.c @@ -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), diff --git a/drivers/amlogic/mmc/amlsd.c b/drivers/amlogic/mmc/amlsd.c index c7e05dc96432..ee080da81a88 100644 --- a/drivers/amlogic/mmc/amlsd.c +++ b/drivers/amlogic/mmc/amlsd.c @@ -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); diff --git a/include/linux/amlogic/sd.h b/include/linux/amlogic/sd.h index ab9c04bf898e..47954f18354e 100644 --- a/include/linux/amlogic/sd.h +++ b/include/linux/amlogic/sd.h @@ -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