author | xiaojing.huang <xiaojing.huang@amlogic.com> | 2018-08-09 05:33:25 (GMT) |
---|---|---|
committer | Xindong Xu <xindong.xu@amlogic.com> | 2018-08-16 07:36:32 (GMT) |
commit | 28dfbc5048e7e6942c7337cb2c12f7cadf778e57 (patch) | |
tree | f9be65bedfb865ddf474b2365d4d0b9753870109 | |
parent | ea0ab54e12dfc7e40b7a1634ebb364f22f80c1b1 (diff) | |
download | common-28dfbc5048e7e6942c7337cb2c12f7cadf778e57.zip common-28dfbc5048e7e6942c7337cb2c12f7cadf778e57.tar.gz common-28dfbc5048e7e6942c7337cb2c12f7cadf778e57.tar.bz2 |
emmc: get emmc cmd-window for HS400 busmode
PD#169808: emmc: get emmc cmd-window for HS400 busmode
Change-Id: Ica198c0ad73808d697c3aedb43c1c9565092b8ff
-rw-r--r-- | drivers/amlogic/mmc/aml_sd_emmc_v3.c | 90 |
1 files changed, 71 insertions, 19 deletions
diff --git a/drivers/amlogic/mmc/aml_sd_emmc_v3.c b/drivers/amlogic/mmc/aml_sd_emmc_v3.c index cdce99b..6d0cb1d 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc_v3.c +++ b/drivers/amlogic/mmc/aml_sd_emmc_v3.c @@ -762,6 +762,66 @@ static void update_all_line_eyetest(struct mmc_host *mmc) emmc_eyetest_log(mmc, line_x); } } + +static unsigned int get_emmc_cmd_win(struct mmc_host *mmc) +{ + struct amlsd_platform *pdata = mmc_priv(mmc); + struct amlsd_host *host = pdata->host; + u32 delay2 = readl(host->base + SD_EMMC_DELAY2_V3); + u32 max = 0, i, temp; + u32 str[64] = {0}; + int best_start = -1, best_size = -1; + int cur_start = -1, cur_size = 0; + + for (i = 0; i < 64; i++) { + delay2 &= ~(0x3f << 24); + delay2 |= (i << 24); + writel(delay2, host->base + SD_EMMC_DELAY2_V3); + emmc_eyetest_log(mmc, 9); + temp = fbinary(pdata->align[9]); + str[i] = temp; + if (max < temp) + max = temp; + } + for (i = 0; i < 64; i++) { + if (str[i] >= 4) { + if (cur_start < 0) + cur_start = i; + cur_size++; + } else { + if (cur_start >= 0) { + if (best_start < 0) { + best_start = cur_start; + best_size = cur_size; + } else { + if (best_size < cur_size) { + best_start = cur_start; + best_size = cur_size; + } + } + cur_start = -1; + cur_size = 0; + } + } + } + if (cur_start >= 0) { + if (best_start < 0) { + best_start = cur_start; + best_size = cur_size; + } else if (best_size < cur_size) { + best_start = cur_start; + best_size = cur_size; + } + cur_start = -1; + cur_size = -1; + } + delay2 &= ~(0x3f << 24); + delay2 |= ((best_start + best_size / 2) << 24); + writel(delay2, host->base + SD_EMMC_DELAY2_V3); + emmc_eyetest_log(mmc, 9); + return max; +} + /* first step*/ static int emmc_ds_core_align(struct mmc_host *mmc) { @@ -770,8 +830,7 @@ static int emmc_ds_core_align(struct mmc_host *mmc) u32 delay1 = readl(host->base + SD_EMMC_DELAY1_V3); u32 delay2 = readl(host->base + SD_EMMC_DELAY2_V3); u32 delay2_bak = delay2; - u32 count = 0; - u32 ds_count = 0, cmd_count = 0; + u32 count = 0, ds_count = 0, cmd_count = 0; ds_count = fbinary(pdata->align[8]); if (ds_count == 0) @@ -798,26 +857,19 @@ static int emmc_ds_core_align(struct mmc_host *mmc) count = ((delay2>>18) & 0x3f) - ((delay2_bak>>18) & 0x3f); delay1 += (count<<0)|(count<<6)|(count<<12)|(count<<18)|(count<<24); delay2 += (count<<0)|(count<<6)|(count<<12); + writel(delay1, host->base + SD_EMMC_DELAY1_V3); + writel(delay2, host->base + SD_EMMC_DELAY2_V3); out_cmd: - cmd_count = fbinary(pdata->align[9]); - if (cmd_count <= (pdata->count/3)) - cmd_count = (pdata->count/3)-cmd_count; - else if (cmd_count <= 2*pdata->count/3) - cmd_count = 0; - else if (cmd_count <= pdata->count) - cmd_count = (pdata->count-cmd_count)+pdata->count/3; - else - cmd_count = pdata->count/3; - delay2 += (cmd_count<<24); - writel(delay1, host->base + SD_EMMC_DELAY1_V3); - writel(delay2, host->base + SD_EMMC_DELAY2_V3); - pdata->dly1 = delay1; - pdata->dly2 = delay2; - pr_info("cmd_count:%d,delay1:0x%x,delay2:0x%x,count: %u\n", - cmd_count, readl(host->base + SD_EMMC_DELAY1_V3), - readl(host->base + SD_EMMC_DELAY2_V3), count); + cmd_count = get_emmc_cmd_win(mmc); + pdata->dly1 = readl(host->base + SD_EMMC_DELAY1_V3); + pdata->dly2 = readl(host->base + SD_EMMC_DELAY2_V3); + pr_info("ds_count:%u,count:%d, cmd_count:%u\n", + ds_count, count, cmd_count); + pr_info("delay1:0x%x,delay2:0x%x\n", + readl(host->base + SD_EMMC_DELAY1_V3), + readl(host->base + SD_EMMC_DELAY2_V3)); return 0; } |