|
@@ -1328,7 +1328,7 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
|
|
{
|
|
{
|
|
struct msdc_host *host = mmc_priv(mmc);
|
|
struct msdc_host *host = mmc_priv(mmc);
|
|
u32 rise_delay = 0, fall_delay = 0;
|
|
u32 rise_delay = 0, fall_delay = 0;
|
|
- struct msdc_delay_phase final_rise_delay, final_fall_delay;
|
|
|
|
|
|
+ struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
|
|
u8 final_delay, final_maxlen;
|
|
u8 final_delay, final_maxlen;
|
|
int cmd_err;
|
|
int cmd_err;
|
|
int i;
|
|
int i;
|
|
@@ -1341,6 +1341,11 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
|
|
if (!cmd_err)
|
|
if (!cmd_err)
|
|
rise_delay |= (1 << i);
|
|
rise_delay |= (1 << i);
|
|
}
|
|
}
|
|
|
|
+ final_rise_delay = get_best_delay(host, rise_delay);
|
|
|
|
+ /* if rising edge has enough margin, then do not scan falling edge */
|
|
|
|
+ if (final_rise_delay.maxlen >= 10 ||
|
|
|
|
+ (final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4))
|
|
|
|
+ goto skip_fall;
|
|
|
|
|
|
sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
|
|
sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
|
|
for (i = 0; i < PAD_DELAY_MAX; i++) {
|
|
for (i = 0; i < PAD_DELAY_MAX; i++) {
|
|
@@ -1350,10 +1355,9 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
|
|
if (!cmd_err)
|
|
if (!cmd_err)
|
|
fall_delay |= (1 << i);
|
|
fall_delay |= (1 << i);
|
|
}
|
|
}
|
|
-
|
|
|
|
- final_rise_delay = get_best_delay(host, rise_delay);
|
|
|
|
final_fall_delay = get_best_delay(host, fall_delay);
|
|
final_fall_delay = get_best_delay(host, fall_delay);
|
|
|
|
|
|
|
|
+skip_fall:
|
|
final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
|
|
final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
|
|
if (final_maxlen == final_rise_delay.maxlen) {
|
|
if (final_maxlen == final_rise_delay.maxlen) {
|
|
sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
|
|
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)
|
|
{
|
|
{
|
|
struct msdc_host *host = mmc_priv(mmc);
|
|
struct msdc_host *host = mmc_priv(mmc);
|
|
u32 rise_delay = 0, fall_delay = 0;
|
|
u32 rise_delay = 0, fall_delay = 0;
|
|
- struct msdc_delay_phase final_rise_delay, final_fall_delay;
|
|
|
|
|
|
+ struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
|
|
u8 final_delay, final_maxlen;
|
|
u8 final_delay, final_maxlen;
|
|
int i, ret;
|
|
int i, ret;
|
|
|
|
|
|
@@ -1387,6 +1391,11 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
|
|
if (!ret)
|
|
if (!ret)
|
|
rise_delay |= (1 << i);
|
|
rise_delay |= (1 << i);
|
|
}
|
|
}
|
|
|
|
+ final_rise_delay = get_best_delay(host, rise_delay);
|
|
|
|
+ /* if rising edge has enough margin, then do not scan falling edge */
|
|
|
|
+ if (final_rise_delay.maxlen >= 10 ||
|
|
|
|
+ (final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4))
|
|
|
|
+ goto skip_fall;
|
|
|
|
|
|
sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
|
|
sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
|
|
sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
|
|
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)
|
|
if (!ret)
|
|
if (!ret)
|
|
fall_delay |= (1 << i);
|
|
fall_delay |= (1 << i);
|
|
}
|
|
}
|
|
-
|
|
|
|
- final_rise_delay = get_best_delay(host, rise_delay);
|
|
|
|
final_fall_delay = get_best_delay(host, fall_delay);
|
|
final_fall_delay = get_best_delay(host, fall_delay);
|
|
|
|
|
|
|
|
+skip_fall:
|
|
final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
|
|
final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
|
|
- /* Rising edge is more stable, prefer to use it */
|
|
|
|
- if (final_rise_delay.maxlen >= 10)
|
|
|
|
- final_maxlen = final_rise_delay.maxlen;
|
|
|
|
if (final_maxlen == final_rise_delay.maxlen) {
|
|
if (final_maxlen == final_rise_delay.maxlen) {
|
|
sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
|
|
sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
|
|
sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
|
|
sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
|