Skip to content

Commit ef20553

Browse files
committed
Merge pull request #159 from derolf/rpi-3.2.27
Lazy CRC quirk: Implemented retrying mechanisms for SD SSR and SCR, disa...
2 parents 00c4bfd + 22e8df6 commit ef20553

File tree

2 files changed

+109
-19
lines changed

2 files changed

+109
-19
lines changed

drivers/mmc/core/sd.c

Lines changed: 99 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include <linux/err.h>
1414
#include <linux/slab.h>
1515
#include <linux/stat.h>
16+
#include <linux/jiffies.h>
17+
#include <linux/nmi.h>
1618

1719
#include <linux/mmc/host.h>
1820
#include <linux/mmc/card.h>
@@ -58,6 +60,15 @@ static const unsigned int tacc_mant[] = {
5860
__res & __mask; \
5961
})
6062

63+
// timeout for tries
64+
static const unsigned long retry_timeout_ms= 10*1000;
65+
66+
// try at least 10 times, even if timeout is reached
67+
static const int retry_min_tries= 10;
68+
69+
// delay between tries
70+
static const unsigned long retry_delay_ms= 10;
71+
6172
/*
6273
* Given the decoded CSD structure, decode the raw CID to our CID structure.
6374
*/
@@ -210,12 +221,62 @@ static int mmc_decode_scr(struct mmc_card *card)
210221
}
211222

212223
/*
213-
* Fetch and process SD Status register.
224+
* Fetch and process SD Configuration Register.
225+
*/
226+
static int mmc_read_scr(struct mmc_card *card)
227+
{
228+
unsigned long timeout_at;
229+
int err, tries;
230+
231+
timeout_at= jiffies + msecs_to_jiffies( retry_timeout_ms );
232+
tries= 0;
233+
234+
while( tries < retry_min_tries || time_before( jiffies, timeout_at ) )
235+
{
236+
unsigned long delay_at;
237+
tries++;
238+
239+
err = mmc_app_send_scr(card, card->raw_scr);
240+
if( !err )
241+
break; // sucess!!!
242+
243+
touch_nmi_watchdog(); // we are still alive!
244+
245+
// delay
246+
delay_at= jiffies + msecs_to_jiffies( retry_delay_ms );
247+
while( time_before( jiffies, delay_at ) )
248+
{
249+
mdelay( 1 );
250+
touch_nmi_watchdog(); // we are still alive!
251+
}
252+
}
253+
254+
if( err)
255+
{
256+
pr_err("%s: failed to read SD Configuration register (SCR) after %d tries during %lu ms, error %d\n", mmc_hostname(card->host), tries, retry_timeout_ms, err );
257+
return err;
258+
}
259+
260+
if( tries > 1 )
261+
{
262+
pr_info("%s: could read SD Configuration register (SCR) at the %dth attempt\n", mmc_hostname(card->host), tries );
263+
}
264+
265+
err = mmc_decode_scr(card);
266+
if (err)
267+
return err;
268+
269+
return err;
270+
}
271+
272+
/*
273+
* Fetch and process SD Status Register.
214274
*/
215275
static int mmc_read_ssr(struct mmc_card *card)
216276
{
277+
unsigned long timeout_at;
217278
unsigned int au, es, et, eo;
218-
int err, i;
279+
int err, i, tries;
219280
u32 *ssr;
220281

221282
if (!(card->csd.cmdclass & CCC_APP_SPEC)) {
@@ -227,15 +288,41 @@ static int mmc_read_ssr(struct mmc_card *card)
227288
ssr = kmalloc(64, GFP_KERNEL);
228289
if (!ssr)
229290
return -ENOMEM;
230-
231-
err = mmc_app_sd_status(card, ssr);
232-
if (err) {
233-
pr_warning("%s: problem reading SD Status "
234-
"register.\n", mmc_hostname(card->host));
235-
err = 0;
291+
292+
timeout_at= jiffies + msecs_to_jiffies( retry_timeout_ms );
293+
tries= 0;
294+
295+
while( tries < retry_min_tries || time_before( jiffies, timeout_at ) )
296+
{
297+
unsigned long delay_at;
298+
tries++;
299+
300+
err= mmc_app_sd_status(card, ssr);
301+
if( !err )
302+
break; // sucess!!!
303+
304+
touch_nmi_watchdog(); // we are still alive!
305+
306+
// delay
307+
delay_at= jiffies + msecs_to_jiffies( retry_delay_ms );
308+
while( time_before( jiffies, delay_at ) )
309+
{
310+
mdelay( 1 );
311+
touch_nmi_watchdog(); // we are still alive!
312+
}
313+
}
314+
315+
if( err)
316+
{
317+
pr_err("%s: failed to read SD Status register (SSR) after %d tries during %lu ms, error %d\n", mmc_hostname(card->host), tries, retry_timeout_ms, err );
236318
goto out;
237319
}
238320

321+
if( tries > 1 )
322+
{
323+
pr_info("%s: could read SD Status register (SSR) at the %dth attempt\n", mmc_hostname(card->host), tries );
324+
}
325+
239326
for (i = 0; i < 16; i++)
240327
ssr[i] = be32_to_cpu(ssr[i]);
241328

@@ -803,15 +890,11 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
803890

804891
if (!reinit) {
805892
/*
806-
* Fetch SCR from card.
893+
* Fetch and decode SD Configuration register.
807894
*/
808-
err = mmc_app_send_scr(card, card->raw_scr);
809-
if (err)
810-
return err;
811-
812-
err = mmc_decode_scr(card);
813-
if (err)
814-
return err;
895+
err = mmc_read_scr(card);
896+
if( err )
897+
return err;
815898

816899
/*
817900
* Fetch and process SD Status register.

drivers/mmc/host/sdhci-bcm2708.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ static inline unsigned long int since_ns(hptime_t t)
141141
static bool allow_highspeed = 1;
142142
static int emmc_clock_freq = BCM2708_EMMC_CLOCK_FREQ;
143143
static bool sync_after_dma = 1;
144-
static bool missing_status = 1;
144+
static bool missing_status = 0;
145+
static bool spurious_crc_acmd51 = 0;
145146
bool enable_llm = 1;
146147

147148
#if 0
@@ -1220,7 +1221,7 @@ static unsigned int sdhci_bcm2708_quirk_extra_ints(struct sdhci_host *host)
12201221
return 1;
12211222
}
12221223

1223-
static unsigned int sdhci_bcm2708_quirk_spurious_crc(struct sdhci_host *host)
1224+
static unsigned int sdhci_bcm2708_quirk_spurious_crc_acmd51(struct sdhci_host *host)
12241225
{
12251226
return 1;
12261227
}
@@ -1270,7 +1271,6 @@ static struct sdhci_ops sdhci_bcm2708_ops = {
12701271
.pdma_reset = sdhci_bcm2708_platdma_reset,
12711272
#endif
12721273
.extra_ints = sdhci_bcm2708_quirk_extra_ints,
1273-
.spurious_crc_acmd51 = sdhci_bcm2708_quirk_spurious_crc,
12741274
.voltage_broken = sdhci_bcm2708_quirk_voltage_broken,
12751275
.uhs_broken = sdhci_bcm2708_uhs_broken,
12761276
};
@@ -1315,6 +1315,11 @@ static int __devinit sdhci_bcm2708_probe(struct platform_device *pdev)
13151315
sdhci_bcm2708_ops.missing_status = sdhci_bcm2708_missing_status;
13161316
}
13171317

1318+
if( spurious_crc_acmd51 ) {
1319+
sdhci_bcm2708_ops.spurious_crc_acmd51 = sdhci_bcm2708_quirk_spurious_crc_acmd51;
1320+
}
1321+
1322+
13181323
printk("sdhci: %s low-latency mode\n",enable_llm?"Enable":"Disable");
13191324

13201325
host->hw_name = "BCM2708_Arasan";
@@ -1518,6 +1523,7 @@ module_param(allow_highspeed, bool, 0444);
15181523
module_param(emmc_clock_freq, int, 0444);
15191524
module_param(sync_after_dma, bool, 0444);
15201525
module_param(missing_status, bool, 0444);
1526+
module_param(spurious_crc_acmd51, bool, 0444);
15211527
module_param(enable_llm, bool, 0444);
15221528
module_param(cycle_delay, int, 0444);
15231529

@@ -1530,6 +1536,7 @@ MODULE_PARM_DESC(allow_highspeed, "Allow high speed transfers modes");
15301536
MODULE_PARM_DESC(emmc_clock_freq, "Specify the speed of emmc clock");
15311537
MODULE_PARM_DESC(sync_after_dma, "Block in driver until dma complete");
15321538
MODULE_PARM_DESC(missing_status, "Use the missing status quirk");
1539+
MODULE_PARM_DESC(spurious_crc_acmd51, "Use the spurious crc quirk for reading SCR (ACMD51)");
15331540
MODULE_PARM_DESC(enable_llm, "Enable low-latency mode");
15341541

15351542

0 commit comments

Comments
 (0)