linux4sam / at91bootstrap

Second level bootloader for Microchip SoC (aka AT91)
https://www.linux4sam.org/linux4sam/bin/view/Linux4SAM/AT91Bootstrap4
112 stars 232 forks source link

eMMC init issue #107

Closed arahowerya closed 4 years ago

arahowerya commented 4 years ago

Hi all,

I hope this is the right forum for this, if not please point me in the right direction.

We have a custom board, using a SAMA5D27 D1G CU, and a Micron MTFC2GMDEA-0M WT 2GB eMMC.

Schematic has been verified and board layout: image

image

I can't get it to be recognised by u-boot, but at91 bootstrap does show some interesting data, however it returns an error (-10) when running mmc_cmd_switch_fun() on line 791 of mci_media.c

CONFIG_DEBUG_VERY_LOUD is set.

 ba_offset = 0xb ...

Dump DDRAMC Registers:
@address: 0x0 0x4 0x8 0xc
0xf000c000: 0x10 0x3004ff 0xd00139 0x22239337
0xf000c010: 0x2c81716 0x82482 0x33338 0x10000
0xf000c020: 0x16 0x50008 0x0 0x0
0xf000c030: 0x6 0x76504 0x0 0x0
0xf000c040: 0x0 0x0 0x0 0x0
0xf000c050: 0x0 0x0 0x0 0x1
0xf000c060: 0x0 0x0 0x0 0x0
0xf000c070: 0x0 0x0 0x0 0x0
0xf000c080: 0x0 0x0 0x0 0x0
0xf000c090: 0x0 0x0 0x0 0x0
0xf000c0a0: 0x0 0x0 0x0 0x0
0xf000c0b0: 0x0 0x0 0x1 0x0
0xf000c0c0: 0x0 0x0 0x0 0x0
0xf000c0d0: 0x0 0x0 0x0 0x0
0xf000c0e0: 0x0 0x0 0x0 0x4000
0xf000c0f0: 0x484d5044 0x44524320 0x0 0x20301
0xf000c100: 0x0 0x0 0x4040404 0x3030303
0xf000c110: 0x0 0x1 0x3f03f02 0x0
0xf000c120: 0x0 0x0 0xc00 0xc00
0xf000c130: 0xc00 0xc00 0xd00 0xd00
0xf000c140: 0xd00 0xd00 0x10 0x10
0xf000c150: 0x10 0x10 0xf 0x0
Applying VDDSDMMC errata to ID: 0x33

AT91Bootstrap 3.9.1-00011-g5a3157e (Mon Mar  9 10:50:35 GMT 2020)

All interrupts redirected to AIC
SDHC: fix in place for SAMA5D2 SoM VDDSDMMC over-consumption errata
SD/MMC: Image: Read file u-boot.bin to 0x23f00000
MMC: ADMA supported
mmc_verify_operating_condition
mmc_verify_operating_condition success OCR = 0x80ff8080
Card type is MMC
sd card identified with CID = 0xfe014e4d 0x4d433032 0x4742f707 0xf43c95ff
sdcard_identification success
MMC: Specification Version 4.0 or higher
MMC: v4.41 detected
MMC: highspeed supported
MMC: Dual Data Rate supported
MMC: detecting buswidth...
SDHC: Timeout waiting for command complete
SDHC: Timeout waiting for command complete
SDHC: Timeout waiting for command complete
SDHC: Timeout waiting for command complete
MMC: falling back to 1 bit bus width
SDHC: Timeout waiting for command complete
SDHC: Timeout waiting for command complete
MMC: DDR mode could not be enabled: -10
SDHC: Timeout waiting for command complete
*** FATFS: f_open, filename: [u-boot.bin]: error
SD/MMC: Failed to load image

The CID looks correct, and it detects the right version, but that's all I can get out of it. I've been banging my head off this for a week or so now so any help would be greatly appreciated.

Thanks

ehristev commented 4 years ago

As it looks to me, your data lines have some errors... like no valid data could be received on the data lines when the bus is tested. If the CID is correctly read, it should mean that the CMD line works fine. The Extended CID is received as a data block of 512 bytes from what I remember (please correct me if I am wrong) So I would assume that the data lines are fine (at least DAT0) Can you try to hack the code to use just 1 data line and see if you can make it work ?

You are using SDMMC1 IP block right ?

All is left to do is to put a scope on the data lines and see what is happening, how the data is transmitted... if the switch function fails, then the card cannot go to a different mode. The switch function is the CMD6 that changes the condition of the card. Probably your fail is when it tries to go to 8 bit bus mode, then fallback to 4 bit, and then fallback to 1 bit. Try with 1bit from the starters see if that helps in any way

Also eMMCs are designed to operate at signaling/power at either 3v3, 1v8 or 1v2, it should not be changed during the operations. So 1V8sel does not have any point in your schematic. eMMC should not voltage switch. Are you using 3v3 for all voltage references for this eMMC ?

arahowerya commented 4 years ago

Thanks for your quick reply!

Looks to be 128 bits wide, and it matches what's in the datasheet. Is this the same as the extended CID? image

I'll try and set it to use just 1 data line. I'm using SDMMC0.

We had a previous revision of the board that didn't have the 1v8 selection so we added it to this board to see if this was the issue. I can bridge it however to constantly select 1v8 or 3v3 so I'll try that too

arahowerya commented 4 years ago

I removed the switching voltage from 1v8 to 3v3 and tied all comms and pullups to 3v3.

I scoped the clock and DAT0 and got this. When it fails there are weird voltages present, goes into some odd impedance state, 1.3 1.4v?

The yellow trace is the clock, pink is DAT0

DS1Z_QuickPrint1

arahowerya commented 4 years ago

I added this debug code:

+++ b/driver/mci_media.c
@@ -591,6 +591,7 @@ static int mmc_cmd_switch_fun(struct sd_card *sdcard,

        ret = host->ops->send_command(command, 0);

+       console_printf("mmc_cmd_switch_fun(access_mode = %d index = %d, value = %d) = %d\n", access_mode, index, value, ret);
        sd_cmd_send_status(sdcard, retries);
        if (ret)
                return ret;

And got:

sd card identified with CID = 0xfe014e4d 0x4d433032 0x4742f707 0xf43c95ff
sdcard_identification success
MMC: Specification Version 4.0 or higher
MMC: v4.41 detected
MMC: highspeed supported
MMC: Dual Data Rate supported
mmc_cmd_switch_fun(access_mode = 3 index = 185, value = 1) = 0
MMC: detecting buswidth...
SDHC: Timeout waiting for command complete
mmc_cmd_switch_fun(access_mode = 3 index = 183, value = 2) = -10
SDHC: Timeout waiting for command complete
SDHC: Timeout waiting for command complete
mmc_cmd_switch_fun(access_mode = 3 index = 183, value = 1) = -10
SDHC: Timeout waiting for command complete
MMC: falling back to 1 bit bus width
SDHC: Timeout waiting for command complete
mmc_cmd_switch_fun(access_mode = 3 index = 183, value = 5) = -10
SDHC: Timeout waiting for command complete
MMC: DDR mode could not be enabled: -10
SDHC: Timeout waiting for command complete
*** FATFS: f_open, filename: [u-boot.bin]: error
SD/MMC: Failed to load image

So the function runs correctly once, and fails every other time?

ehristev commented 4 years ago

switch_fun is used for various things throughout the initialization procedure. to switch to highspeed, to change bus width, etc. So it's normal that it's called multiple times. It looks like it starts failing that's true

ehristev commented 4 years ago

Try to hack through mmc_detect_buswidth and see if that helps, skipping that detection should leave the emmc in 1 bit bus mode

ehristev commented 4 years ago

Also, try to enable HIGH DRIVE STRENGTH for your eMMC pins... here is a wiki page that shows an example how to do that https://www.linux4sam.org/bin/view/Linux4SAM/SOM1EKeMMCSupport

arahowerya commented 4 years ago

Thanks for that. I hacked through mmc_detect_buswidth and got:

SDHC: Timeout waiting for command complete
mmc_cmd_switch_fun(access_mode = 3 index = 183, value = 5) = -1
SDHC: Timeout waiting for CMD and DAT Inhibit bits
SDHC: Timeout waiting for command complete
MMC: DDR mode could not be enabled: -1
SDHC: Timeout waiting for CMD and DAT Inhibit bits
SDHC: Timeout waiting for command complete

Changing the drive strength made no change. This is also like this on multiple boards.

ehristev commented 4 years ago

remove the enabling of the DDR also. DDR only works with at least 4 bits so it will try to enable 4 bits again

ehristev commented 4 years ago

basically you need mode 0 : 1 bit bus and no DDR

define MMC_BUS_WIDTH_8_DDR 6

define MMC_BUS_WIDTH_4_DDR 5

define MMC_BUS_WIDTH_8 2

define MMC_BUS_WIDTH_4 1

define MMC_BUS_WIDTH_1 0

arahowerya commented 4 years ago

OK, did that and the errors disappeared! Thanks... However I cannot probe it in u-boot, nor can I write anything to it via sam-ba so I can't test if it's working. Apologies that this is vague! Should I concentrate on uboot?

ehristev commented 4 years ago

So, did at91bootstrap succeed in copying u-boot from EMMC ??

arahowerya commented 4 years ago

I can't write anything to emmc to begin with. at91bootstrap is the only bit of software that vaguely recognizes its existence. I was hoping to find the problem in at91bootstrap

ehristev commented 4 years ago

I can't write anything to emmc to begin with. at91bootstrap is the only bit of software that vaguely recognizes its existence. I was hoping to find the problem in at91bootstrap

I understand but it's very important if at91bootstrap managed to read on 1 bit or not. If 1 bit works, then, it's clear that the other 7 lines are messed up . maybe you have them mixed up in the schematics ?

arahowerya commented 4 years ago

Sure, I'll see if I can find a way of testing that, thanks

ehristev commented 4 years ago

for testing the bus, the emmc sends a test pattern and the software must validate if the pattern was correctly received. If you mixed up some lines in hardware then bit 1 will arrive as bit 4, etc. so it will always fail but it looks like bit 0 is correctly set ? this is the test pattern in at91bootstrap unsigned char data_8bits[8] = {0x55, 0xaa, 0, 0, 0, 0, 0, 0};
unsigned char data_4bits[4] = {0x5a, 0, 0, 0}; you can print the actual data that is received from the emmc there, and compare.. see how wrong it is. I am still unsure if the switch function fails or there is an actual bus test error.

arahowerya commented 4 years ago

It seems to fail on mmc_bus_width_select which is the command before the data is sent. the response code on that one is -10

arahowerya commented 4 years ago

fails, even when I force it to be MMC_BUS_WIDTH_1

ehristev commented 4 years ago

Okay so we need to go back... the extended CSD is received correctly ? Try to print it out (mmc_card_identify). This extended CSD should be received through the DAT lines.. if I remember correctly

ehristev commented 4 years ago

You can also try to comment the switch_fun call which moves to HIGH speed mode (EXT_CSD byte 185 ). Then proceed normal with the initialization. Some memories do not like the signals after moving to high speed mode.

arahowerya commented 4 years ago

here is extended CSD:

0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xca 0x1 0x0 
0x3 0x0 0x0 0x0 0x0 0x0 0x5 0x0 0x1 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x5 0x0 0x2 0x0 0x7 0x0 0x2 0x1 0x0 0x0 0x0 0x0 0x0 0x8 0x8 0x8 
0x8 0x8 0x8 0x0 0x0 0x0 0x0 0x0 0x0 0x10 0x0 0x8 0x8 0x0 0x1 0x1 
0x0 0x5 0x8 0x0 0x7 0x3 0x2 0x15 0x6 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x7a 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x1 0x3 0x1 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
arahowerya commented 4 years ago

Tried that, kept it in low speed mode, verified on oscilloscope, 400kHz clock speed

arahowerya commented 4 years ago

I was able to get Linux to recognise it and mount it if I set the Linux device tree to bus width 1, with a slower clock.

For now I'm happy that it's somewhat working and I'll take up further issues with the manufacturer. Thanks @ehristev for your help debugging, much appreciated! 🤺