Re: [PATCH 1/7] mmc: at91_mci: support for block size not modulo 4



Hi Nicolas!

On Friday 30 May 2008, Nicolas Ferre wrote:
From: Marc Pignat <marc.pignat@xxxxxxx>

Implement transfer with size not modulo 4 for at91sam9*. Please note that the
at91rm9200 simply can't handle this.

Signed-off-by: Marc Pignat <marc.pignat@xxxxxxx>
Signed-off-by: Nicolas Ferre <nicolas.ferre@xxxxxxxxx>
---

I just want we don't forget that at91sam9260 errata, pointed by someone when I
posted this patch...

44.2.4.4 Data Write Operation and number of bytes
                     The Data Write operation with a number of bytes less than 12 is impossible.
                     Problem Fix/Workaround
                     The PDC counters must always be equal to 12 bytes for data transfers lower than 12 bytes. The
                     BLKLEN or BCNT field are used to specify the real count number.

We should probably fix that thing in the next release and verify if other
chips are affected!



 drivers/mmc/host/at91_mci.c |   15 ++++++++++-----
 1 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 8979ad3..543b64b 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -233,11 +233,11 @@ static void at91_mci_pre_dma_read(struct at91mci_host *host)
 
              if (i == 0) {
                      at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address);
-                     at91_mci_write(host, ATMEL_PDC_RCR, sg->length / 4);
+                     at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
              }
              else {
                      at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address);
-                     at91_mci_write(host, ATMEL_PDC_RNCR, sg->length / 4);
+                     at91_mci_write(host, ATMEL_PDC_RNCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
              }
      }
 
@@ -430,7 +430,7 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
 
      if (data) {
 
-             if ( data->blksz & 0x3 ) {
+             if ( cpu_is_at91rm9200() && (data->blksz & 0x3) ) {
                      pr_debug("Unsupported block size\n");
                      cmd->error = -EINVAL;
                      mmc_request_done(host->mmc, host->request);
@@ -482,7 +482,10 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
      } else {
              /* zero block length and PDC mode */
              mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff;
-             at91_mci_write(host, AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE);
here, we should do something like
{
        /* blocks smaller than 16 will be rounded up to 16 at91sam9260, and 16 is modulo 4 :) */
        if (!(cpu_is_at91sam9260() && size < 16))
                mr |= (data->blksz & 0x3) ? AT91_MCI_PDCFBYTE : 0;
}
+             mr |= (block_length << 16);
+             mr |= AT91_MCI_PDCMODE;
+             at91_mci_write(host, AT91_MCI_MR, mr);
 
              /*
               * Disable the PDC controller
@@ -517,7 +520,9 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
                              pr_debug("Transmitting %d bytes\n", host->total_length);
 
                              at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
-                             at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4);
+                             at91_mci_write(host, ATMEL_PDC_TCR, (data->blksz & 0x3) ?
+                                             host->total_length : host->total_length / 4);
here, we should add something like
{
        unsigned long size = data->blksz;
        if (cpu_is_at91sam9260() && size < 16 )
                size = 16;
        at91_mci_write(host, ATMEL_PDC_TCR, (size & 0x3) ? size : size / 4);
}
+
                              ier = AT91_MCI_CMDRDY;
                      }
              }

Best regards

Marc
N?§²æìr¸?yúè?Øb²X¬¶Ç§vØ^?)Þº{.nÇ+?·¥?{±?êçzX§¶?¡Ü¨}©?²Æ zÚ&j:+v?¨¾«?êçzZ+?Ê+zf£¢·h??§~?­?Ûiÿûàz¹®w¥¢¸??¨è­Ú&¢)ߢf?ù^jÇ«y§m?á@A«a¶Úÿ 0¶ìh®å?i

Relevant Pages

  • Re: [PATCH 2/6] Unified AVR32/AT91 MCI Platform Driver
    ... There is some indentation errors in this patch (blank instead of tabs). ... Best regards, ... Nicolas Ferre ...
    (Linux-Kernel)
  • Re: Les Hatton on Fortran, C, and C++
    ... >Organization: Comcast Online ... I always found (modulo my bad C syntax) ... under the asumption that the value in b is suitable. ... >Best Regards, ...
    (comp.lang.fortran)
  • Re: Fastcode IsPrime B&V 3.1
    ... congruent to q modulo m" More on this can be found here: ... Regards, ... > Weak Probable Prime Base test. ...
    (borland.public.delphi.language.basm)
  • Re: find the first Monday in June
    ... MODis superfluous for the same reason I gave to Norman: ... a kind of modulo. ... Regards, ... Daniel M. ...
    (microsoft.public.excel.worksheet.functions)
  • Re: problem of arithmetic modulo
    ... Draw your conclusions. ... where a_i are the digits of the numbre 3^1000? ... It does'nt seem as straightforward as with c modulo 3. ... Regards ...
    (sci.math)

Loading