aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorArindam Nath <arindam.nath@amd.com>2011-05-05 02:48:58 -0400
committerChris Ball <cjb@laptop.org>2011-05-24 21:04:40 -0400
commit013909c4ffd16ded4895528b856fd8782df04dc6 (patch)
treeb74fe0c34dfd3c2348497b1aa3a34f5132ca4822 /drivers/mmc
parentf2119df6b764609af4baceb68caf1e848c1c8aa7 (diff)
mmc: sd: query function modes for uhs cards
SD cards which conform to Physical Layer Spec v3.01 can support additional Bus Speed Modes, Driver Strength, and Current Limit other than the default values. We use CMD6 mode 0 to read these additional card functions. The values read here will be used during UHS-I initialization steps. Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath <arindam.nath@amd.com> Reviewed-by: Philip Rakity <prakity@marvell.com> Tested-by: Philip Rakity <prakity@marvell.com> Acked-by: Zhangfei Gao <zhangfei.gao@marvell.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/sd.c68
1 files changed, 58 insertions, 10 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index b0cd285d272a..8285842f19e9 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -189,6 +189,9 @@ static int mmc_decode_scr(struct mmc_card *card)
189 189
190 scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); 190 scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4);
191 scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); 191 scr->bus_widths = UNSTUFF_BITS(resp, 48, 4);
192 if (scr->sda_vsn == SCR_SPEC_VER_2)
193 /* Check if Physical Layer Spec v3.0 is supported */
194 scr->sda_spec3 = UNSTUFF_BITS(resp, 47, 1);
192 195
193 if (UNSTUFF_BITS(resp, 55, 1)) 196 if (UNSTUFF_BITS(resp, 55, 1))
194 card->erased_byte = 0xFF; 197 card->erased_byte = 0xFF;
@@ -274,29 +277,74 @@ static int mmc_read_switch(struct mmc_card *card)
274 status = kmalloc(64, GFP_KERNEL); 277 status = kmalloc(64, GFP_KERNEL);
275 if (!status) { 278 if (!status) {
276 printk(KERN_ERR "%s: could not allocate a buffer for " 279 printk(KERN_ERR "%s: could not allocate a buffer for "
277 "switch capabilities.\n", mmc_hostname(card->host)); 280 "switch capabilities.\n",
281 mmc_hostname(card->host));
278 return -ENOMEM; 282 return -ENOMEM;
279 } 283 }
280 284
285 /* Find out the supported Bus Speed Modes. */
281 err = mmc_sd_switch(card, 0, 0, 1, status); 286 err = mmc_sd_switch(card, 0, 0, 1, status);
282 if (err) { 287 if (err) {
283 /* If the host or the card can't do the switch, 288 /*
284 * fail more gracefully. */ 289 * If the host or the card can't do the switch,
285 if ((err != -EINVAL) 290 * fail more gracefully.
286 && (err != -ENOSYS) 291 */
287 && (err != -EFAULT)) 292 if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)
288 goto out; 293 goto out;
289 294
290 printk(KERN_WARNING "%s: problem reading switch " 295 printk(KERN_WARNING "%s: problem reading Bus Speed modes.\n",
291 "capabilities, performance might suffer.\n",
292 mmc_hostname(card->host)); 296 mmc_hostname(card->host));
293 err = 0; 297 err = 0;
294 298
295 goto out; 299 goto out;
296 } 300 }
297 301
298 if (status[13] & 0x02) 302 if (card->scr.sda_spec3) {
299 card->sw_caps.hs_max_dtr = 50000000; 303 card->sw_caps.sd3_bus_mode = status[13];
304
305 /* Find out Driver Strengths supported by the card */
306 err = mmc_sd_switch(card, 0, 2, 1, status);
307 if (err) {
308 /*
309 * If the host or the card can't do the switch,
310 * fail more gracefully.
311 */
312 if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)
313 goto out;
314
315 printk(KERN_WARNING "%s: problem reading "
316 "Driver Strength.\n",
317 mmc_hostname(card->host));
318 err = 0;
319
320 goto out;
321 }
322
323 card->sw_caps.sd3_drv_type = status[9];
324
325 /* Find out Current Limits supported by the card */
326 err = mmc_sd_switch(card, 0, 3, 1, status);
327 if (err) {
328 /*
329 * If the host or the card can't do the switch,
330 * fail more gracefully.
331 */
332 if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)
333 goto out;
334
335 printk(KERN_WARNING "%s: problem reading "
336 "Current Limit.\n",
337 mmc_hostname(card->host));
338 err = 0;
339
340 goto out;
341 }
342
343 card->sw_caps.sd3_curr_limit = status[7];
344 } else {
345 if (status[13] & 0x02)
346 card->sw_caps.hs_max_dtr = 50000000;
347 }
300 348
301out: 349out:
302 kfree(status); 350 kfree(status);