From 784b259a54086b633add7a76d587654fabfd67ba Mon Sep 17 00:00:00 2001 From: Yonghui Yu Date: Wed, 8 Aug 2018 15:51:02 +0800 Subject: [PATCH] sdemmc: update fix adj tuning method PD#172367: sdemmc: update fix adj tuning method All adj delay are avalible is not fair when fix adj mode were used for tuning. We had tried to add all data with rx delay to find out the unstable adj delay point. This method can not cover all scene. For example: All adj delay are available as below. ADJ 0 1 2 3 4 0 1 Src --__--__--__--__--__--__-- D0 __________________-------- D1 __________________-------- D2 __________________-------- D3 __________________-------- when same rx delay were added to all data line. All adj delay are still avalible as below. ADJ 0 1 2 3 4 0 1 Src --__--__--__--__--__--__-- D0 ----__________________---- D1 ----__________________---- D2 ----__________________---- D3 ----__________________---- So, a new method to find out the unstable adj point were designed for better compatibility. Rx delay were added on only 1 data line, such as D1. When rx delay were added on D1 only. Adj delay 1 is not available anymore as below. ADJ 0 1 2 3 4 0 1 Src --__--__--__--__--__--__-- D0 __________________-------- D1 ----__________________---- D2 __________________-------- D3 __________________-------- In this way, the unsatble adj delay could be distinguished. Change-Id: I0488dec001a55f6b50b431ee4d691c872947f0f3 Signed-off-by: Yonghui Yu --- drivers/amlogic/mmc/aml_sd_emmc.c | 32 +++++++++++++++++----------- drivers/amlogic/mmc/aml_sd_emmc_v3.c | 27 +++++++++++++---------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/drivers/amlogic/mmc/aml_sd_emmc.c b/drivers/amlogic/mmc/aml_sd_emmc.c index 146b3e012bcf..015a1205b254 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc.c +++ b/drivers/amlogic/mmc/aml_sd_emmc.c @@ -716,8 +716,11 @@ int aml_sd_emmc_execute_tuning_(struct mmc_host *mmc, u32 opcode, u32 clock, clk_div; u32 adj_delay_find; int best_win_start = -1, best_win_size = 0; - u32 rxdly[4] = {0, 0x55555555, 0xAAAAAAAA, 0xFFFFFFFF}; + u32 old_dly, d1_dly, dly; + old_dly = readl(host->base + SD_EMMC_DELAY); + d1_dly = (old_dly >> 4) & 0xF; + pr_info("Data 1 aligned delay is %d\n", d1_dly); writel(0, host->base + SD_EMMC_ADJUST); tunning: @@ -748,17 +751,21 @@ tunning: pr_err("%s: tuning failed, reduce freq and retuning\n", mmc_hostname(host->mmc)); goto tunning; + /* fixme, debug code for sharping delay cell */ } else if (best_win_size == clk_div) { - if (++tuning_num > MAX_TUNING_RETRY) { - pr_err("%s: tuning failed\n", - mmc_hostname(host->mmc)); - return -1; - } - pr_warn("wave is not sharp, again\n"); - /* add basic data rx delay */ - writel(rxdly[tuning_num-1], host->base + SD_EMMC_DELAY); - pr_warn("rxdly @ %d is %x\n", tuning_num, rxdly[tuning_num-1]); - goto tunning; + pr_debug("%s(), d1_dly %d, window start %d, size %d\n", + __func__, d1_dly, best_win_start, best_win_size); + dly = readl(host->base + SD_EMMC_DELAY); + d1_dly = (dly >> 4) & 0xF; + if (d1_dly < 16) { + d1_dly++; + dly &= ~(0xF << 4); + dly |= d1_dly << 4; + writel(dly, host->base + SD_EMMC_DELAY); + pr_info("%s(), window is not sharp\n", __func__); + goto tunning; + } else + pr_err("%s(), all adj used out!\n", __func__); } else { pr_info("%s: best_win_start =%d, best_win_size =%d\n", mmc_hostname(host->mmc), best_win_start, best_win_size); @@ -788,7 +795,8 @@ tunning: gadjust->cali_enable = 0; gadjust->cali_rise = 0; writel(adjust, host->base + SD_EMMC_ADJUST); - + /* restore aligned data */ + writel(old_dly, host->base + SD_EMMC_DELAY); /* fixme, yyh for retry flow. */ emmc_adj->adj_win_start = best_win_start; emmc_adj->adj_win_len = best_win_size; diff --git a/drivers/amlogic/mmc/aml_sd_emmc_v3.c b/drivers/amlogic/mmc/aml_sd_emmc_v3.c index 627b7079aaac..7e79f8710bb0 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc_v3.c +++ b/drivers/amlogic/mmc/aml_sd_emmc_v3.c @@ -960,7 +960,6 @@ static int _aml_sd_emmc_execute_tuning(struct mmc_host *mmc, u32 opcode, struct aml_tuning_data *tuning_data, u32 adj_win_start) { -#if 1 /* need finish later */ struct amlsd_platform *pdata = mmc_priv(mmc); struct amlsd_host *host = pdata->host; u32 vclk; @@ -980,11 +979,15 @@ static int _aml_sd_emmc_execute_tuning(struct mmc_host *mmc, u32 opcode, int wrap_win_start, wrap_win_size; int best_win_start, best_win_size; int curr_win_start, curr_win_size; - u32 rxdly[3] = {0xA28A28A, 0x15500514, 0x1FF8079E}; + u32 old_dly, d1_dly, dly; if ((host->mem->start == host->data->port_b_base) && host->data->tdma_f) wait_for_completion(&host->drv_completion); + + old_dly = readl(host->base + SD_EMMC_DELAY1_V3); + d1_dly = (old_dly >> 0x6) & 0x3F; + pr_info("Data 1 aligned delay is %d\n", d1_dly); writel(0, host->base + SD_EMMC_ADJUST_V3); tunning: @@ -1045,7 +1048,6 @@ tunning: curr_win_size = 0; } } - } /* last point is ok! */ if (curr_win_start >= 0) { @@ -1084,7 +1086,11 @@ tunning: mmc_hostname(host->mmc)); goto tunning; } else if (best_win_size == clk_div) { - if (++tuning_num > MAX_TUNING_RETRY) { + dly = readl(host->base + SD_EMMC_DELAY1_V3); + d1_dly = (dly >> 0x6) & 0x3F; + pr_warn("%s() d1_dly %d, window start %d, size %d\n", + __func__, d1_dly, best_win_start, best_win_size); + if (++d1_dly > 0x3F) { pr_err("%s: tuning failed\n", mmc_hostname(host->mmc)); host->is_tunning = 0; @@ -1093,11 +1099,10 @@ tunning: complete(&host->drv_completion); return -1; } - pr_warn("wave is not sharp, again\n"); - /* add basic data rx delay */ - writel(rxdly[tuning_num-1], host->base + SD_EMMC_DELAY1_V3); - writel(rxdly[tuning_num-1], host->base + SD_EMMC_DELAY2_V3); - pr_warn("rxdly @ %x\n", rxdly[tuning_num-1]); + dly &= ~(0x3F << 6); + dly |= d1_dly << 6; + pdata->dly1 = dly; + writel(dly, host->base + SD_EMMC_DELAY1_V3); goto tunning; } else pr_info("%s: best_win_start =%d, best_win_size =%d\n", @@ -1114,6 +1119,8 @@ tunning: gadjust->cali_rise = 0; writel(adjust, host->base + SD_EMMC_ADJUST_V3); pdata->adj = adjust; + pdata->dly1 = old_dly; + writel(old_dly, host->base + SD_EMMC_DELAY1_V3); pr_info("%s: sd_emmc_regs->gclock=0x%x,sd_emmc_regs->gadjust=0x%x\n", mmc_hostname(host->mmc), @@ -1125,8 +1132,6 @@ tunning: complete(&host->drv_completion); return ret; -#endif - return 0; } int aml_get_data_eyetest(struct mmc_host *mmc)