brcm2708: update against latest rpi-3.10.y branch
[openwrt.git] / target / linux / brcm2708 / patches-3.10 / 0038-Lazy-CRC-quirk-Implemented-retrying-mechanisms-for-S.patch
1 From d6442f505a7bf1bebe9bd4689d021f007a269cd6 Mon Sep 17 00:00:00 2001
2 From: dero <de@ro>
3 Date: Mon, 19 Nov 2012 12:46:06 +0100
4 Subject: [PATCH 038/174] Lazy CRC quirk: Implemented retrying mechanisms for
5  SD SSR and SCR, disabled missing_status and spurious CRC ACMD51 quirks by
6  default (should be fixed by the retrying-mechanishm)
7
8 ---
9  drivers/mmc/core/sd.c            | 115 +++++++++++++++++++++++++++++++++------
10  drivers/mmc/host/sdhci-bcm2708.c |  11 +++-
11  2 files changed, 108 insertions(+), 18 deletions(-)
12
13 --- a/drivers/mmc/core/sd.c
14 +++ b/drivers/mmc/core/sd.c
15 @@ -13,6 +13,8 @@
16  #include <linux/err.h>
17  #include <linux/slab.h>
18  #include <linux/stat.h>
19 +#include <linux/jiffies.h>
20 +#include <linux/nmi.h>
21  
22  #include <linux/mmc/host.h>
23  #include <linux/mmc/card.h>
24 @@ -58,6 +60,15 @@ static const unsigned int tacc_mant[] =
25                 __res & __mask;                                         \
26         })
27  
28 +// timeout for tries
29 +static const unsigned long retry_timeout_ms= 10*1000;
30 +
31 +// try at least 10 times, even if timeout is reached
32 +static const int retry_min_tries= 10;
33 +
34 +// delay between tries
35 +static const unsigned long retry_delay_ms= 10;
36 +
37  /*
38   * Given the decoded CSD structure, decode the raw CID to our CID structure.
39   */
40 @@ -210,12 +221,62 @@ static int mmc_decode_scr(struct mmc_car
41  }
42  
43  /*
44 - * Fetch and process SD Status register.
45 + * Fetch and process SD Configuration Register.
46 + */
47 +static int mmc_read_scr(struct mmc_card *card)
48 +{
49 +       unsigned long timeout_at;
50 +       int err, tries;
51 +
52 +       timeout_at= jiffies + msecs_to_jiffies( retry_timeout_ms );
53 +       tries=          0;
54 +
55 +       while( tries < retry_min_tries || time_before( jiffies, timeout_at ) )
56 +       {
57 +               unsigned long delay_at;
58 +               tries++;
59 +
60 +               err = mmc_app_send_scr(card, card->raw_scr);
61 +               if( !err )
62 +                       break; // sucess!!!
63 +
64 +               touch_nmi_watchdog();     // we are still alive!
65 +
66 +               // delay
67 +               delay_at= jiffies + msecs_to_jiffies( retry_delay_ms );
68 +               while( time_before( jiffies, delay_at ) )
69 +               {
70 +                       mdelay( 1 );
71 +                       touch_nmi_watchdog();     // we are still alive!
72 +               }
73 +       }
74 +       
75 +       if( err)
76 +       {
77 +               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 );
78 +               return err;
79 +       }
80 +
81 +       if( tries > 1 )
82 +       {
83 +               pr_info("%s: could read SD Configuration register (SCR) at the %dth attempt\n", mmc_hostname(card->host), tries );
84 +       }
85 +
86 +       err = mmc_decode_scr(card);
87 +       if (err)
88 +               return err;
89 +       
90 +       return err;
91 +}
92 +
93 +/*
94 + * Fetch and process SD Status Register.
95   */
96  static int mmc_read_ssr(struct mmc_card *card)
97  {
98 +       unsigned long timeout_at;
99         unsigned int au, es, et, eo;
100 -       int err, i;
101 +       int err, i, tries;
102         u32 *ssr;
103  
104         if (!(card->csd.cmdclass & CCC_APP_SPEC)) {
105 @@ -227,15 +288,41 @@ static int mmc_read_ssr(struct mmc_card
106         ssr = kmalloc(64, GFP_KERNEL);
107         if (!ssr)
108                 return -ENOMEM;
109 -
110 -       err = mmc_app_sd_status(card, ssr);
111 -       if (err) {
112 -               pr_warning("%s: problem reading SD Status "
113 -                       "register.\n", mmc_hostname(card->host));
114 -               err = 0;
115 +       
116 +       timeout_at= jiffies + msecs_to_jiffies( retry_timeout_ms );
117 +       tries=          0;
118 +       
119 +       while( tries < retry_min_tries || time_before( jiffies, timeout_at ) )
120 +       {
121 +               unsigned long delay_at;
122 +               tries++;
123 +               
124 +               err= mmc_app_sd_status(card, ssr);
125 +               if( !err )
126 +                       break; // sucess!!!
127 +       
128 +               touch_nmi_watchdog();     // we are still alive!
129 +       
130 +               // delay
131 +               delay_at= jiffies + msecs_to_jiffies( retry_delay_ms );
132 +               while( time_before( jiffies, delay_at ) )
133 +               {
134 +                       mdelay( 1 );
135 +                       touch_nmi_watchdog();     // we are still alive!
136 +               }                       
137 +       }
138 +       
139 +       if( err) 
140 +       {
141 +               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 );
142                 goto out;
143         }
144  
145 +       if( tries > 1 )
146 +       {
147 +               pr_info("%s: could read SD Status register (SSR) at the %dth attempt\n", mmc_hostname(card->host), tries );
148 +       }
149 +
150         for (i = 0; i < 16; i++)
151                 ssr[i] = be32_to_cpu(ssr[i]);
152  
153 @@ -808,15 +895,11 @@ int mmc_sd_setup_card(struct mmc_host *h
154  
155         if (!reinit) {
156                 /*
157 -                * Fetch SCR from card.
158 +                * Fetch and decode SD Configuration register.
159                  */
160 -               err = mmc_app_send_scr(card, card->raw_scr);
161 -               if (err)
162 -                       return err;
163 -
164 -               err = mmc_decode_scr(card);
165 -               if (err)
166 -                       return err;
167 +               err = mmc_read_scr(card);
168 +               if( err )
169 +                       return err;
170  
171                 /*
172                  * Fetch and process SD Status register.
173 --- a/drivers/mmc/host/sdhci-bcm2708.c
174 +++ b/drivers/mmc/host/sdhci-bcm2708.c
175 @@ -137,6 +137,7 @@ static bool allow_highspeed = 1;
176  static int emmc_clock_freq = BCM2708_EMMC_CLOCK_FREQ;
177  static bool sync_after_dma = 1;
178  static bool missing_status = 1;
179 +static bool spurious_crc_acmd51 = 0;
180  bool enable_llm = 1;
181  
182  #if 0
183 @@ -1103,7 +1104,7 @@ static unsigned int sdhci_bcm2708_quirk_
184          return 1;
185  }
186  
187 -static unsigned int sdhci_bcm2708_quirk_spurious_crc(struct sdhci_host *host)
188 +static unsigned int sdhci_bcm2708_quirk_spurious_crc_acmd51(struct sdhci_host *host)
189  {
190          return 1;
191  }
192 @@ -1149,7 +1150,6 @@ static struct sdhci_ops sdhci_bcm2708_op
193         .pdma_reset = sdhci_bcm2708_platdma_reset,
194  #endif
195         .extra_ints = sdhci_bcm2708_quirk_extra_ints,
196 -       .spurious_crc_acmd51 = sdhci_bcm2708_quirk_spurious_crc,
197         .voltage_broken = sdhci_bcm2708_quirk_voltage_broken,
198         .uhs_broken = sdhci_bcm2708_uhs_broken,
199  };
200 @@ -1194,6 +1194,11 @@ static int sdhci_bcm2708_probe(struct pl
201                 sdhci_bcm2708_ops.missing_status = sdhci_bcm2708_missing_status;
202         }
203  
204 +       if( spurious_crc_acmd51 ) {
205 +               sdhci_bcm2708_ops.spurious_crc_acmd51 = sdhci_bcm2708_quirk_spurious_crc_acmd51;
206 +       }
207 +
208 +
209         printk("sdhci: %s low-latency mode\n",enable_llm?"Enable":"Disable");
210  
211         host->hw_name = "BCM2708_Arasan";
212 @@ -1389,6 +1394,7 @@ module_param(allow_highspeed, bool, 0444
213  module_param(emmc_clock_freq, int, 0444);
214  module_param(sync_after_dma, bool, 0444);
215  module_param(missing_status, bool, 0444);
216 +module_param(spurious_crc_acmd51, bool, 0444);
217  module_param(enable_llm, bool, 0444);
218  module_param(cycle_delay, int, 0444);
219  
220 @@ -1401,6 +1407,7 @@ MODULE_PARM_DESC(allow_highspeed, "Allow
221  MODULE_PARM_DESC(emmc_clock_freq, "Specify the speed of emmc clock");
222  MODULE_PARM_DESC(sync_after_dma, "Block in driver until dma complete");
223  MODULE_PARM_DESC(missing_status, "Use the missing status quirk");
224 +MODULE_PARM_DESC(spurious_crc_acmd51, "Use the spurious crc quirk for reading SCR (ACMD51)");
225  MODULE_PARM_DESC(enable_llm, "Enable low-latency mode");
226  
227