[U-Boot] gen_atmel_mci freeze on at91sam9g45

Hi,
I'm currently working on a custom board with an at91sam9g45 : I followed the instruction in README.atmel_mci. In U-boot, if I use the command mmcinfo, the system hang. The uSD is working correctly with at91bootstrap and linux. In U-boot everything seems fine, the card exchange a few command and response, and then freeze on the command 55 51 (the first command that will receive some data on DAT0 ) :
U-Boot> mmcinfo mci: bus_hz is 133333333, setting clock 150000 Hz, block size 512 mci: setting clock 260416 Hz, block size 512 mci: bus_hz is 133333333, setting clock 0 Hz, block size 512 mci: setting clock 260416 Hz, block size 512 mci: bus_hz is 133333333, setting clock 260416 Hz, block size 512 mci: setting clock 260416 Hz, block size 512 gen_atmel_mci: CMDR 00001000 ( 0) ARGR 00000000 (SR: 00000000) DEBUG gen_atmel_mci: CMDR 00001048 ( 8) ARGR 000001aa (SR: 00000000) DEBUG gen_atmel_mci: CMDR 00001077 (55) ARGR 00000000 (SR: 00000000) DEBUG gen_atmel_mci: CMDR 00001069 (41) ARGR 40300000 (SR: 00000000) DEBUG gen_atmel_mci: CMDR 00001077 (55) ARGR 00000000 (SR: 00000000) DEBUG gen_atmel_mci: CMDR 00001069 (41) ARGR 40300000 (SR: 00000000) DEBUG gen_atmel_mci: CMDR 00001082 ( 2) ARGR 00000000 (SR: 00000000) DEBUG gen_atmel_mci: CMDR 00001043 ( 3) ARGR 00000000 (SR: 00000000) DEBUG gen_atmel_mci: CMDR 00001089 ( 9) ARGR 88f70000 (SR: 00000000) DEBUG gen_atmel_mci: CMDR 000010c7 ( 7) ARGR 88f70000 (SR: 00000000) DEBUG gen_atmel_mci: CMDR 00001077 (55) ARGR 88f70000 (SR: 00000000) DEBUG gen_atmel_mci: CMDR 00051073 (51) ARGR 00000000 (SR: 00000000) DEBUG Read Data: 00000000: 02 25 00 00 00 00 00 00 .%...... filling rest of block...
then everything freeze ... But if I add some printf to debug , just after the mci_data_op=mci_data_read() in gen_atmel_mci, then everything is OK and I can now use the uSD without any problem. Here is where I add the printf, so uSD is correctly handled :
diff -crbN u-boot-2010.09.orig/drivers/mmc/gen_atmel_mci.c u-boot-2010.09/drivers/mmc/gen_atmel_mci.c *** u-boot-2010.09.orig/drivers/mmc/gen_atmel_mci.c 2010-09-28 23:20:55.000000000 +0200 --- u-boot-2010.09/drivers/mmc/gen_atmel_mci.c 2010-12-04 17:52:59.092770689 +0100 *************** *** 252,257 **** --- 252,258 ---- while (!status && word_count < (sys_blocksize / 4)) { status = mci_data_op(mci, &dummy, error_flags); + printf("status=%x\n",status); word_count++; } if (status) {
The result (status) from mci_data_op (=mci_data_read()) is always 0. It's a bit like if there was a timeout not correctly handled. I had the same sympton on different uSD. Actually U-boot is started by At91Bootstrap, so some HMCI register are probably not at there default value ? Any advice to investigate further ?
best regards,
Eric Cariat

Dear eric cariat,
I'm currently working on a custom board with an at91sam9g45 : I followed the instruction in README.atmel_mci. In U-boot, if I use the command mmcinfo, the system hang. The uSD is working correctly with at91bootstrap and linux. In U-boot everything seems fine, the card exchange a few command and response, and then freeze on the command 55 51 (the first command that will receive some data on DAT0 ) :
U-Boot> mmcinfo mci: bus_hz is 133333333, setting clock 150000 Hz, block size 512
"setting clock" should read "requesting clock". 150000 is the clock a MMC card should be inquired with. Unfortunately the minimum clock obtainable is 260416, but that did not cause problems with SD cards so far...
mci: setting clock 260416 Hz, block size 512
So the software sets it to the minimum-.
mci: bus_hz is 133333333, setting clock 0 Hz, block size 512 mci: setting clock 260416 Hz, block size 512 mci: bus_hz is 133333333, setting clock 260416 Hz, block size 512 mci: setting clock 260416 Hz, block size 512
First make sure the clock values are correct: Assuming the system is running at 400MHz, this would make sense if the MCI is clocked by system clock / 3. Then the minimum clock would indeed be 260416.
Is the 9G45 (H)MCI is really identical to the 9260 MCI or are there subtle differences?
But if I add some printf to debug , just after the mci_data_op=mci_data_read() in gen_atmel_mci, then everything is OK and I can now use the uSD without any problem. Here is where I add the printf, so uSD is correctly handled :
diff -crbN u-boot-2010.09.orig/drivers/mmc/gen_atmel_mci.c u-boot-2010.09/drivers/mmc/gen_atmel_mci.c *** u-boot-2010.09.orig/drivers/mmc/gen_atmel_mci.c 2010-09-28 23:20:55.000000000 +0200 --- u-boot-2010.09/drivers/mmc/gen_atmel_mci.c 2010-12-04 17:52:59.092770689 +0100
*** 252,257 **** --- 252,258 ---- while (!status && word_count < (sys_blocksize / 4)) { status = mci_data_op(mci, &dummy, error_flags);
printf("status=%x\n",status); word_count++; } if (status) {
Have you tested whether a udelay() serves the same purpose? It would seem that there is an issue when mci_data_op() is called too frequently. However, quite the same code exists a few lines above and it did not hang there.
Is your data cache on?
There are no timeouts coded in mci_data_read() and mci_data_write(), maybe it would be good to add some...
I also cannot rule out that pre-initialisation of the MCI by the bootstrap code could leave some registers with values that the gen_atmel_mci driver does not reset. But then, a printf would unlikely fix the problem.
Patches are always welcome ;)
Best Regards, Reinhard

Hi Rheinard,
2010/12/5 Reinhard Meyer u-boot@emk-elektronik.de
Dear eric cariat,
I'm currently working on a custom board with an at91sam9g45 : I followed
the
instruction in README.atmel_mci. In U-boot, if I use the command mmcinfo, the system hang. The uSD is working correctly with at91bootstrap and
linux.
In U-boot everything seems fine, the card exchange a few command and response, and then freeze on the command 55 51 (the first command that
will
receive some data on DAT0 ) :
U-Boot> mmcinfo mci: bus_hz is 133333333, setting clock 150000 Hz, block size 512
"setting clock" should read "requesting clock". 150000 is the clock a MMC card should be inquired with. Unfortunately the minimum clock obtainable is 260416, but that did not cause problems with SD cards so far...
mci: setting clock 260416 Hz, block size 512
So the software sets it to the minimum-.
mci: bus_hz is 133333333, setting clock 0 Hz, block size 512 mci: setting clock 260416 Hz, block size 512 mci: bus_hz is 133333333, setting clock 260416 Hz, block size 512 mci: setting clock 260416 Hz, block size 512
First make sure the clock values are correct: Assuming the system is running at 400MHz, this would make sense if the MCI is clocked by system clock / 3. Then the minimum clock would indeed be 260416.
Clock values are OK (running from 12 Mhz like the 9g45 eval kit), system running at 400 Mhz. 260416 Hz is exactly what I probe on the hardware.
Is the 9G45 (H)MCI is really identical to the 9260 MCI or are there subtle differences?
I checked the datasheet of the 9260, most register seems to be the same... I suppose you have been testing the gen_atmel_mci on the 9260 ?
But if I add some printf to debug , just after the mci_data_op=mci_data_read() in gen_atmel_mci, then everything is OK and I can now use the uSD without any problem. Here is where I add the printf, so uSD is correctly handled :
diff -crbN u-boot-2010.09.orig/drivers/mmc/gen_atmel_mci.c u-boot-2010.09/drivers/mmc/gen_atmel_mci.c *** u-boot-2010.09.orig/drivers/mmc/gen_atmel_mci.c 2010-09-28 23:20:55.000000000 +0200 --- u-boot-2010.09/drivers/mmc/gen_atmel_mci.c 2010-12-04 17:52:59.092770689 +0100
*** 252,257 **** --- 252,258 ---- while (!status && word_count < (sys_blocksize / 4)) { status = mci_data_op(mci, &dummy, error_flags);
printf("status=%x\n",status); word_count++; } if (status) {
Have you tested whether a udelay() serves the same purpose? It would seem that there is an issue when mci_data_op() is called too frequently. However, quite the same code exists a few lines above and it did not hang there.
I added a udelay(1) and udelay(50) -> it freeze If I put a udelay(100) -> everything is OK (same effect as printf)
Is your data cache on?
I suppose it is enabled by default, so I added #define CONFIG_SYS_NO_CP15_CACHE in my config file -> but that still freeze
There are no timeouts coded in mci_data_read() and mci_data_write(), maybe it would be good to add some...
I also cannot rule out that pre-initialisation of the MCI by the bootstrap code could leave some registers with values that the gen_atmel_mci driver does not reset. But then, a printf would unlikely fix the problem.
Patches are always welcome ;)
Best Regards, Reinhard
My observation are the following :
It seems that we are trying to read too many data byte : for ACMD 51 : the data reply is not a full 512 bytes data packet, but only 8 bytes len (checked with oscillo). Actually when in function mci_send_cmd() with ACMD 51, we first read the 8 "useful" byte ... then we try to "fill the rest of block" => we try to read 512 - 8 = 504 more bytes (which never comes on the DAT0 ) as there are no more data we should exit from mci_data_read() with a timeout error, but this never happen (I have to check error_flags about that)
Doing a pause or printf in the while change the RXRDY flag (set to 1) and so we exit from the while without any error... ( I could not understand why ? ). It seems that when we don't read the correct number of byte, the MCI controller behave incorrectly (the status register seems to be incoherent)
Actually the driver set a block len of 512 byte only once (at initialization) in the mode register (mr) in gen_atmel_mci:mci_set_mode(). So I suppose we need to change dynamically the block len for each command (most command will use the 512 byte data block reply, but some (like ACMD51) are using a specific len -> I think we don't need to change the block len in the SDCard see comment [1] below )
So I made the following change, ( just for information ) :
diff -crbN u-boot-2010.09.orig/drivers/mmc/gen_atmel_mci.c u-boot-2010.09/drivers/mmc/gen_atmel_mci.c *** u-boot-2010.09.orig/drivers/mmc/gen_atmel_mci.c 2010-09-28 23:20:55.000000000 +0200 --- u-boot-2010.09/drivers/mmc/gen_atmel_mci.c 2010-12-07 18:14:05.956116190 +0100 *************** *** 174,179 **** --- 174,180 ---- u32 cmdr; u32 error_flags = 0; u32 status; + u32 mr;
if (!initialized) { puts ("MCI not initialized!\n"); *************** *** 182,187 **** --- 183,201 ----
/* Figure out the transfer arguments */ cmdr = mci_encode_cmd(cmd, data, &error_flags); + if (data) + { + #ifdef DEBUG + printf("data->blocksize = %d\n",data->blocksize); + printf(" mmc->write_bl_len = %d\n", mmc->write_bl_len); + #endif + /* get current mr register and change block size */ + mr = readl(&mci->mr); + mr = mr & 0xffff; /* clear upper part */ + mr = mr | (data->blocksize << 16); /* set block size */ + writel( mr, &mci->mr); + } +
/* Send the command */ writel(cmd->cmdarg, &mci->argr); *************** *** 218,224 ****
if (data->flags & MMC_DATA_READ) { mci_data_op = mci_data_read; ! sys_blocksize = mmc->read_bl_len; ioptr = (u32*)data->dest; } else { mci_data_op = mci_data_write; --- 232,239 ----
if (data->flags & MMC_DATA_READ) { mci_data_op = mci_data_read; ! /* sys_blocksize = mmc->read_bl_len; */ ! sys_blocksize = data->blocksize; ioptr = (u32*)data->dest; } else { mci_data_op = mci_data_write;
But this is not correct because it must be done only for specific command (with a fixed data size reply), Here, the "filling the rest of block" is never used again -> the code is working using mmcinfo, rescan and fatls (I d'ont need the printf or udelay anymore in the while loop), but unfortunately If I remove all other debug information -> It freeze again !
So I suppose we have to modify the code for every command -> we need to know if the data reply is a fixed size or if we have to fill the rest of loop (to fill a 512 byte data packet). But the number of "data" byte reply for each command is not really clear in the specification ("Simplified_Physical_Layer_Spec.pdf") I don't know if there are some more documentation on that ...
I'm just thinking I have to check how this was done before gen_atmel_mci, in an older U-Boot, maybe I can understand a little more...
I can see the gen_atmel_mci has been working on a V1.0 SDCARD : http://www.mail-archive.com/u-boot@lists.denx.de/msg37774.html so I checked with the V2.0 : I don't see any major difference (except a few more register but SCR and ACMD51 are the same)
So I 'm not sure if I'm looking in the right direction ? am I missing something about the length on data reply ? just wanted to know what you think about all that ? any other advice ?
best regards,
Eric Cariat
For information I'm currently using an Sandisk 1 Gb uSD.
[1] In http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_S... pg 46 we can read for an other special function : The block length is predefined to 512 bits and the use of SET_BLK_LEN command is not necessary. => so we don't need to send BLK_LEN to the SDCard, but we need to inform the at91 that the number of data will be 64 bytes, so it can calculate the CRC and set it's flag according the new size.

Dear eric cariat,
First make sure the clock values are correct: Assuming the system is running at 400MHz, this would make sense if the MCI is clocked by system clock / 3. Then the minimum clock would indeed be 260416.
Clock values are OK (running from 12 Mhz like the 9g45 eval kit), system running at 400 Mhz. 260416 Hz is exactly what I probe on the hardware.
Good.
Is the 9G45 (H)MCI is really identical to the 9260 MCI or are there subtle differences?
I checked the datasheet of the 9260, most register seems to be the same... I suppose you have been testing the gen_atmel_mci on the 9260 ?
Correct, on 9xe which is like 9260
Have you tested whether a udelay() serves the same purpose? It would seem that there is an issue when mci_data_op() is called too frequently. However, quite the same code exists a few lines above and it did not hang there.
I added a udelay(1) and udelay(50) -> it freeze If I put a udelay(100) -> everything is OK (same effect as printf)
100us is a significant slowdown, that means 10kWords per second...
Is your data cache on?
I suppose it is enabled by default, so I added #define CONFIG_SYS_NO_CP15_CACHE in my config file -> but that still freeze
That define seems odd to me, it should be CONFIG_SYS_NO_DCACHE.
My observation are the following :
It seems that we are trying to read too many data byte : for ACMD 51 : the data reply is not a full 512 bytes data packet, but only 8 bytes len (checked with oscillo). Actually when in function mci_send_cmd() with ACMD 51, we first read the 8 "useful" byte ... then we try to "fill the rest of block" => we try to read 512 - 8 = 504 more bytes (which never comes on the DAT0 ) as there are no more data we should exit from mci_data_read() with a timeout error, but this never happen (I have to check error_flags about that)
That should not hurt, and even if, it should not depend on the speed at which we are trying to read the dummy data.
Doing a pause or printf in the while change the RXRDY flag (set to 1) and so we exit from the while without any error... ( I could not understand why ? ). It seems that when we don't read the correct number of byte, the MCI controller behave incorrectly (the status register seems to be incoherent)
This sounds very fishy to me.
Actually the driver set a block len of 512 byte only once (at initialization) in the mode register (mr) in gen_atmel_mci:mci_set_mode(). So I suppose we need to change dynamically the block len for each command (most command will use the 512 byte data block reply, but some (like ACMD51) are using a specific len -> I think we don't need to change the block len in the SDCard see comment [1] below )
<snip>
But this is not correct because it must be done only for specific command (with a fixed data size reply), Here, the "filling the rest of block" is never used again -> the code is working using mmcinfo, rescan and fatls (I d'ont need the printf or udelay anymore in the while loop), but unfortunately If I remove all other debug information -> It freeze again !
Which again suggests its not due to the way the Card is handled.
So I suppose we have to modify the code for every command -> we need to know if the data reply is a fixed size or if we have to fill the rest of loop (to fill a 512 byte data packet). But the number of "data" byte reply for each command is not really clear in the specification ("Simplified_Physical_Layer_Spec.pdf") I don't know if there are some more documentation on that ...
Google for SDCard and license restrictions...
So I 'm not sure if I'm looking in the right direction ? am I missing something about the length on data reply ? just wanted to know what you think about all that ? any other advice ?
I would think to look more in the hardware/memory/cache direction and less in the driver direction. The 9xe/9260 here runs at 200MHz and the MCI at 100 MHz, which is close to your 133MHz, and there are no such effects here whatsoever from old 1GB Cards to 32GB SDHC Cards.
Best regards, Reinhard
participants (2)
-
eric cariat
-
Reinhard Meyer