mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
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 <nan.li@amlogic.com>
This commit is contained in:
@@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user