0134-bcm2835-sdhost-Add-workaround-for-odd-behaviour-on-s.patch 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. From 3162c03da716f865fb9b766c8bd7d1dac0386f88 Mon Sep 17 00:00:00 2001
  2. From: Phil Elwell <phil@raspberrypi.org>
  3. Date: Tue, 19 Jan 2016 17:16:38 +0000
  4. Subject: [PATCH 134/381] bcm2835-sdhost: Add workaround for odd behaviour on
  5. some cards
  6. For reasons not understood, the sdhost driver fails when reading
  7. sectors very near the end of some SD cards. The problem could
  8. be related to the similar issue that reading the final sector
  9. of any card as part of a multiple read never completes, and the
  10. workaround is an extension of the mechanism introduced to solve
  11. that problem which ensures those sectors are always read singly.
  12. ---
  13. drivers/mmc/host/bcm2835-sdhost.c | 61 +++++++++++++++++++++++++++++++++------
  14. 1 file changed, 52 insertions(+), 9 deletions(-)
  15. --- a/drivers/mmc/host/bcm2835-sdhost.c
  16. +++ b/drivers/mmc/host/bcm2835-sdhost.c
  17. @@ -173,6 +173,9 @@ struct bcm2835_host {
  18. u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */
  19. u32 overclock; /* Current frequency if overclocked, else zero */
  20. u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */
  21. +
  22. + u32 sectors; /* Cached card size in sectors */
  23. + u32 single_read_sectors[8];
  24. };
  25. @@ -277,6 +280,9 @@ static void bcm2835_sdhost_reset_interna
  26. {
  27. u32 temp;
  28. + if (host->debug)
  29. + pr_info("%s: reset\n", mmc_hostname(host->mmc));
  30. +
  31. bcm2835_sdhost_set_power(host, false);
  32. bcm2835_sdhost_write(host, 0, SDCMD);
  33. @@ -299,6 +305,8 @@ static void bcm2835_sdhost_reset_interna
  34. bcm2835_sdhost_set_power(host, true);
  35. mdelay(10);
  36. host->clock = 0;
  37. + host->sectors = 0;
  38. + host->single_read_sectors[0] = ~0;
  39. bcm2835_sdhost_write(host, host->hcfg, SDHCFG);
  40. bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
  41. mmiowb();
  42. @@ -309,8 +317,6 @@ static void bcm2835_sdhost_reset(struct
  43. {
  44. struct bcm2835_host *host = mmc_priv(mmc);
  45. unsigned long flags;
  46. - if (host->debug)
  47. - pr_info("%s: reset\n", mmc_hostname(mmc));
  48. spin_lock_irqsave(&host->lock, flags);
  49. bcm2835_sdhost_reset_internal(host);
  50. @@ -676,6 +682,32 @@ static void bcm2835_sdhost_prepare_data(
  51. host->flush_fifo = 0;
  52. host->data->bytes_xfered = 0;
  53. + if (!host->sectors && host->mmc->card)
  54. + {
  55. + struct mmc_card *card = host->mmc->card;
  56. + if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) {
  57. + /*
  58. + * The EXT_CSD sector count is in number of 512 byte
  59. + * sectors.
  60. + */
  61. + host->sectors = card->ext_csd.sectors;
  62. + pr_err("%s: using ext_csd!\n", mmc_hostname(host->mmc));
  63. + } else {
  64. + /*
  65. + * The CSD capacity field is in units of read_blkbits.
  66. + * set_capacity takes units of 512 bytes.
  67. + */
  68. + host->sectors = card->csd.capacity <<
  69. + (card->csd.read_blkbits - 9);
  70. + }
  71. + host->single_read_sectors[0] = host->sectors - 65;
  72. + host->single_read_sectors[1] = host->sectors - 64;
  73. + host->single_read_sectors[2] = host->sectors - 33;
  74. + host->single_read_sectors[3] = host->sectors - 32;
  75. + host->single_read_sectors[4] = host->sectors - 1;
  76. + host->single_read_sectors[5] = ~0; /* Safety net */
  77. + }
  78. +
  79. host->use_dma = host->have_dma && (data->blocks > host->pio_limit);
  80. if (!host->use_dma) {
  81. int flags;
  82. @@ -1246,6 +1278,10 @@ static u32 bcm2835_sdhost_block_irq(stru
  83. bcm2835_sdhost_finish_data(host);
  84. } else {
  85. + /* Reset the timer */
  86. + mod_timer(&host->pio_timer,
  87. + jiffies + host->pio_timeout);
  88. +
  89. bcm2835_sdhost_transfer_pio(host);
  90. /* Reset the timer */
  91. @@ -1450,8 +1486,8 @@ void bcm2835_sdhost_set_clock(struct bcm
  92. host->cdiv = div;
  93. bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
  94. - /* Set the timeout to 500ms */
  95. - bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT);
  96. + /* Set the timeout to 250ms */
  97. + bcm2835_sdhost_write(host, host->mmc->actual_clock/4, SDTOUT);
  98. if (host->debug)
  99. pr_info("%s: clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n",
  100. @@ -1566,13 +1602,20 @@ static int bcm2835_sdhost_multi_io_quirk
  101. reading the final sector of the card as part of a multiple read
  102. problematic. Detect that case and shorten the read accordingly.
  103. */
  104. - /* csd.capacity is in weird units - convert to sectors */
  105. - u32 card_sectors = (card->csd.capacity << (card->csd.read_blkbits - 9));
  106. + struct bcm2835_host *host;
  107. +
  108. + host = mmc_priv(card->host);
  109. - if ((direction == MMC_DATA_READ) &&
  110. - ((blk_pos + blk_size) == card_sectors))
  111. - blk_size--;
  112. + if (direction == MMC_DATA_READ)
  113. + {
  114. + int i;
  115. + int sector;
  116. + for (i = 0; blk_pos > (sector = host->single_read_sectors[i]); i++)
  117. + continue;
  118. + if ((blk_pos + blk_size) > sector)
  119. + blk_size = (blk_pos == sector) ? 1 : (sector - blk_pos);
  120. + }
  121. return blk_size;
  122. }