aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChaotian Jing <chaotian.jing@mediatek.com>2016-06-29 22:01:01 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2016-07-25 04:34:32 -0400
commitae9c657e62ac1e565f66e9faed7376a7ff5806e2 (patch)
treec5b65b53faaa6287db1ff05b2ec06be1b690fb61
parentddc713878f445b68626d10aa190139908426eb91 (diff)
mmc: mediatek: perfer to use rise edge latching
in our host design, rise edge latching is more stable than fall edge latching. so that if rise edge has enough margin, no need scan fall edge. Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r--drivers/mmc/host/mtk-sd.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 91277b99f035..84e9afcb5c09 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1328,7 +1328,7 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
1328{ 1328{
1329 struct msdc_host *host = mmc_priv(mmc); 1329 struct msdc_host *host = mmc_priv(mmc);
1330 u32 rise_delay = 0, fall_delay = 0; 1330 u32 rise_delay = 0, fall_delay = 0;
1331 struct msdc_delay_phase final_rise_delay, final_fall_delay; 1331 struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
1332 u8 final_delay, final_maxlen; 1332 u8 final_delay, final_maxlen;
1333 int cmd_err; 1333 int cmd_err;
1334 int i; 1334 int i;
@@ -1341,6 +1341,11 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
1341 if (!cmd_err) 1341 if (!cmd_err)
1342 rise_delay |= (1 << i); 1342 rise_delay |= (1 << i);
1343 } 1343 }
1344 final_rise_delay = get_best_delay(host, rise_delay);
1345 /* if rising edge has enough margin, then do not scan falling edge */
1346 if (final_rise_delay.maxlen >= 10 ||
1347 (final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4))
1348 goto skip_fall;
1344 1349
1345 sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL); 1350 sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
1346 for (i = 0; i < PAD_DELAY_MAX; i++) { 1351 for (i = 0; i < PAD_DELAY_MAX; i++) {
@@ -1350,10 +1355,9 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
1350 if (!cmd_err) 1355 if (!cmd_err)
1351 fall_delay |= (1 << i); 1356 fall_delay |= (1 << i);
1352 } 1357 }
1353
1354 final_rise_delay = get_best_delay(host, rise_delay);
1355 final_fall_delay = get_best_delay(host, fall_delay); 1358 final_fall_delay = get_best_delay(host, fall_delay);
1356 1359
1360skip_fall:
1357 final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen); 1361 final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
1358 if (final_maxlen == final_rise_delay.maxlen) { 1362 if (final_maxlen == final_rise_delay.maxlen) {
1359 sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL); 1363 sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
@@ -1374,7 +1378,7 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
1374{ 1378{
1375 struct msdc_host *host = mmc_priv(mmc); 1379 struct msdc_host *host = mmc_priv(mmc);
1376 u32 rise_delay = 0, fall_delay = 0; 1380 u32 rise_delay = 0, fall_delay = 0;
1377 struct msdc_delay_phase final_rise_delay, final_fall_delay; 1381 struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
1378 u8 final_delay, final_maxlen; 1382 u8 final_delay, final_maxlen;
1379 int i, ret; 1383 int i, ret;
1380 1384
@@ -1387,6 +1391,11 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
1387 if (!ret) 1391 if (!ret)
1388 rise_delay |= (1 << i); 1392 rise_delay |= (1 << i);
1389 } 1393 }
1394 final_rise_delay = get_best_delay(host, rise_delay);
1395 /* if rising edge has enough margin, then do not scan falling edge */
1396 if (final_rise_delay.maxlen >= 10 ||
1397 (final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4))
1398 goto skip_fall;
1390 1399
1391 sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL); 1400 sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
1392 sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL); 1401 sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
@@ -1397,14 +1406,10 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
1397 if (!ret) 1406 if (!ret)
1398 fall_delay |= (1 << i); 1407 fall_delay |= (1 << i);
1399 } 1408 }
1400
1401 final_rise_delay = get_best_delay(host, rise_delay);
1402 final_fall_delay = get_best_delay(host, fall_delay); 1409 final_fall_delay = get_best_delay(host, fall_delay);
1403 1410
1411skip_fall:
1404 final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen); 1412 final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
1405 /* Rising edge is more stable, prefer to use it */
1406 if (final_rise_delay.maxlen >= 10)
1407 final_maxlen = final_rise_delay.maxlen;
1408 if (final_maxlen == final_rise_delay.maxlen) { 1413 if (final_maxlen == final_rise_delay.maxlen) {
1409 sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL); 1414 sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
1410 sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL); 1415 sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);