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

SAMA5D27 bootstrap access to eMMC #137

Closed torojoel closed 2 years ago

torojoel commented 3 years ago

I see that several other people have had this issue (having the bootstrap access the eMMC). @ehristev has been very helpful in solving peoples' problems. I am hopeful someone on the discussion can help me as well.

We have a card based heavily on the Xplained eval board for the SAMA5D27. It has an SD card on SD bus 1 and the eMMC on SD bus 0.

I was using version 3.8.11 AT91 bootstrap until we got a new revision of the card. Then on some of the cards the bootstrap could not find our application on the eMMC filesystem. I looked to see if there was a solution. I first found that there was a new version of the bootstrap, so I downloaded it. I have tried 3.10.2 (commit: 5232adb1c42636e1e9cf495a6abd1a8d66475f83). That was a big improvement. It worked on most cards and the one card that wasn't working with 3.8.11, it worked on. Unfortunately that card has also stopped working.

I see that the ROMboot code can access the eMMC and find and load the bootstrap. If I boot our application off the SD card it can access the file system on the eMMC. So those two programs can access the device, it is just the bootstrap code that can not. This makes it seem like the bootstrap is not setting up the SD bus, or other parts of the system, the same way as the other two programs. This also shows me that the filesystem on the eMMC is valid.

I have applied the updates from issue #98 (change of clk_div, slower clock, and drive strength). This does not make it work.

My eMMC has been divided into 4 partitions. I don't think that matters because it does not even get to that level of access. It is failing during bus width determination. It is reading the CID register.

We are using a Kingston eMMC.

Here is the console output

RomBOOT ba_offset = 0xc ...

Dump DDRAMC Registers: @address: 0x0 0x4 0x8 0xc 0xf000c000: 0x10 0x300511 0xd0035d 0x44439436 0xf000c010: 0x3001d1b 0x74000 0x33338 0x10000 0xf000c020: 0x4 0x50008 0x0 0xc852 0xf000c030: 0x40 0x956404 0x0 0x0 0xf000c040: 0x0 0x0 0x0 0x0 0xf000c050: 0x0 0x0 0x0 0x2 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 0x3c03c02 0x0 0xf000c120: 0x0 0x0 0xb00 0xb00 0xf000c130: 0xb00 0xb00 0xc00 0xc00 0xf000c140: 0xc00 0xc00 0xf 0xf 0xf000c150: 0xf 0xf 0xe 0x0

AT91BS-TTC 3.10.2-00055-g5232adb1-dirty@eMMC (2021-07-13 13:00:06)

All interrupts redirected to AIC twi read: timeout to wait RXRDY bit on bus 0 SD/MMC: Image: Read file image_a.bin to 0x20000000 MMC: ADMA supported mmc_verify_operating_condition mmc_verify_operating_condition success OCR = 0xc0ff8080 Card type is MMC sd card identified with CID = 0x70010054 0x42323931 0x369024fa 0x800e96ff sdcard_identification success MMC: Specification Version 4.0 or higher MMC: v5.1 detected MMC: highspeed supported MMC: Dual Data Rate supported MMC: detecting buswidth... SDHC: Transfer data timeout SDHC: Transfer data timeout MMC: falling back to 1 bit bus width *** FATFS: f_open, filename: [image_a.bin]: error SD/MMC: Failed to load image RomBOOT

I would be grateful for any help on changes required to get the bootstrap to access the emmc. Regards, Joel

ehristev commented 3 years ago

Hi,

Sorry I was away for some time, but I can help with your issue now. It looks like data transfers from the eMMC to the controller completely fail. The OCR is read correctly and the CID through the CMD line, (using eMMC CMD2 ) . If the CMD / CLK lines are fine, then, I suspect that the DAT lines have a problem. Either they are badly initialized from an I/O perspective, or something is wrong with these lines. Since RomBOOT and your application works fine, then I suspect that bootstrap does not initialize these lines correctly. Could you attach snippets of code where you initialize the SDMMC0 controller and the pinout for this device, and also a snippet of your board schematic with the SDMMC0 connections ?

Eugen

torojoel commented 3 years ago

Thank you for your offer. I will collect that information you requested and post it soon.

Joel

torojoel commented 3 years ago

I have to re-clone the code because I cloned into my project's directory. That has confused git. This will slow my response a bit.

torojoel commented 3 years ago

emmc-sd0.zip In this zip file are the things you requested. I took the stock 3.10.2 build (commit 5232adb1) and applied the changes you mentioned in #98 . I thought those changes might have already be in the build, but they were not for the SAMA5D2 processor. I show the changes in the delta.txt file. I did this instead of sending you snippets of the init code. I included the .config file so you can see how I am setting things up. And a picture of our schematic. I left the VDDSEL line as an input so that the voltage select switch will not be driven. Instead the pull down resistor will select 3.3 volts. I think this is what the ROMboot code must do, because it doesn't know anything about what hardware is present. We are using an ACT8865 PMIC. I agree with what you said about the bootstrap not setting something up properly. It might not be the SD bus though. Since the ROMboot code shut down everything it started to get the bootstrap to load it could be other parts of the SOC. I wonder about the PMC, PMIC, and even the eMMC. I wonder if some eMMCs don't recover well after they have the signals pulled away after it was working. I think the bootstrap issues a reset command. I would think that that would solve the issue. I am reading the CID, but that comes from a different pin. I really appreciate your help. Since you have better knowledge of the code and the parts you might find the issue faster than I would. Joel

ehristev commented 3 years ago

The schematic is very low resolution, I cannot understand anything from it. Could you zoom it , and attach it as a photo on the thread ?

ehristev commented 3 years ago

There is one problem with your schematic. eMMCs never switch the signaling voltage. They have to have the same voltage through the entire operation, from power on to power down. If you change the voltage during operations, it might get stuck. So, first step is to modify your board a little bit, to have your VDDSDHC tied to either 3v3 or 1v8, depending on which voltage you wish to operate your eMMC under. (this depends also on the specific eMMC device, which signaling voltage it supports). Then, the VDDSEL pin of the MPU should be unused. This pin is only used for SD-Cards.

ehristev commented 3 years ago

Second, you would have to place a scope on CK , CMD and DAT0 lines. And then we have to check the waveform to see what happens in bootstrap operations (after Romcode has loaded bootstrap). Romcode will load from SD-card and then bootstrap will reinitialize the eMMC. So you have to capture the waveform on these, to see what is happening.

ehristev commented 3 years ago

Second, you would have to place a scope on CK , CMD and DAT0 lines. And then we have to check the waveform to see what happens in bootstrap operations (after Romcode has loaded bootstrap). Romcode will load from SD-card and then bootstrap will reinitialize the eMMC. So you have to capture the waveform on these, to see what is happening.

First try to remove U24 (bypass it , probably populate R321 and R322) and let's see if this works.

torojoel commented 3 years ago

We just copied what Microchip/Atmel showed in their SAMA5D27 Xplained board. It shows that the VCCOn signals can be either 3.3 or 1.8 volts. I will modify a board and see what it does. We haven't seen that we needed to run with 1.8 volts, so going with 3.3 would be fine.

torojoel commented 3 years ago

I should mention that when I boot off the SD card I load our application off of it. I do not attempt to access the emmc from the SD card's bootstrap. The application that is loaded from the SD card starts up and configures the system, including the SD buses. It then mounts the emmc and can be accessed.

ehristev commented 3 years ago

We just copied what Microchip/Atmel showed in their SAMA5D27 Xplained board. It shows that the VCCOn signals can be either 3.3 or 1.8 volts. I will modify a board and see what it does. We haven't seen that we needed to run with 1.8 volts, so going with 3.3 would be fine.

Yes. The sama5d27 xplained board has this problem, and the board is wrong in this aspect. Going to 1.8v has benefits in: power consumption, EMI , etc. And if you wish to go to higher speed grades, 1.8V is mandatory. The sama5d2 with 3.3V can go up to 'high speed DDR' mode , in 50 Mhz, 8 bit bus. HS200 mode which requires 1.8V signaling is broken at the moment.

ehristev commented 3 years ago

I should mention that when I boot off the SD card I load our application off of it. I do not attempt to access the emmc from the SD card's bootstrap. The application that is loaded from the SD card starts up and configures the system, including the SD buses. It then mounts the emmc and can be accessed.

You could try to force the selection of VDDSEL from bootstrap to 0, such that 3v3 is always selected. (This can be done by just selecting the pin as GPIO function with output predefined value = 0). but, it's a risk that during pin operation, a glitch may affect the eMMC (for example, if the pin was floating previously...) you could also attempt to reset the eMMC device completely, with the RSTN pin, which can be controlled from a register inside the SDMMC controller (register name is MC1R )

torojoel commented 3 years ago

You have given me lots of things to try. I will go through them. I did have the VDDSEL set as output low. That wasn't working. I set it to an input because I assumed the ROMboot code would do that since it wouldn't know what the use was on the HW it was booting from. Thank you for the information the Xplained board. (a humorous pun) That explains a lot. I am going to delete the PDF of the schematic.

ehristev commented 3 years ago

out of my head, ROMboot will never touch the VDDSEL line. RomBoot will only try the card in basic 1.0 specification, Default speed 25 Mhz, I don't think it will even try to switch to high speed, because it must be backwards compatible with all kind of old sd-cards and eMMC specs.

ehristev commented 3 years ago

out of my head, ROMboot will never touch the VDDSEL line. RomBoot will only try the card in basic 1.0 specification, Default speed 25 Mhz, I don't think it will even try to switch to high speed, because it must be backwards compatible with all kind of old sd-cards and eMMC specs.

So basically if VDDSEL is floating, and your U24 reads it high, then in bootstrap you switch it to 0, then, basically, your emmc signaling is changed which is illegal for this device...

torojoel commented 3 years ago

Some new information. Our latest boards where built without the power switch (U26) so the power rail is always at 3.3. This is the board that I am having the problem with. This means that the problem with switching power is not an issue. I added code to activate and release RSTN on the bus to the eMMC before going through device initialization. I looked at the SoftPack code to see it that was done there. It is. That is why I did it early. This did not make it work. I even added some delays before and after hoping that letting things settle down would help out.

I think it is scope time. That will have to wait until tomorrow.

Thanks, Joel

[Here is the code I added for activating RSTN]

`static int sdhc_init(struct sd_card *sdcard) { unsigned int normal_status_mask, error_status_mask;

// reset the device by activating the RSTN signal
sdhc_activate_RSTN();

sdhc_software_reset();

sdhc_set_power();

sdhc_host_capability(sdcard);

if (sdhc_is_card_inserted(sdcard) <= 0) {
    dbg_info("SDHC: Error: No Card Inserted\n");
    return -1;
}

`

And the function

`static void sdhc_activate_RSTN(void) { unsigned char mc1r;

// let's wait a bit before do anything
console_printf("SDHC: pause\n");
udelay(1000);

// in the MC1R register, set the RSTN bit for 10 usec (as done by softpack)
console_printf("SDHC: Activate RSTN\n");

// read what is there, or in the RSTN bit, and write it back
mc1r = sdhc_readb(SDMMC_MC1R);
sdhc_writeb(SDMMC_MC1R, (mc1r | SDMMC_MC1R_RSTN));

// delay for 10 usec with RSTN active  
udelay(10);

// write MC1R back to what it was, with the RSTN bit clear
sdhc_writeb(SDMMC_MC1R, (mc1r & ~SDMMC_MC1R_RSTN));
console_printf("SDHC: Release RSTN\n");

// then let's wait a little longer for it to recover
udelay(1000);
console_printf("SDHC: ready\n");

} // func sdhc_activate_RSTN `

ehristev commented 3 years ago

Do you refer to U26 or U24 ? The power rail is 3v3 for all eMMCs (+3.3V), but it's about the signaling voltage (VDDSDHC) in your schematic, that has to be also 3.3v

ehristev commented 3 years ago

Hardware engineer here says that you should also give us the routing for the PCB so we can double check it. If you are uncomfortable to share files through the github interface you can open a support case on microchip.com and then refer us directly to the case number.

torojoel commented 3 years ago

You are correct the designator should be U24. I was looking on a newer schematic where they change the designator. The power select switch. You figured it out.

torojoel commented 3 years ago

I created a Microchip case: 00771305. I have attached our schematic. This is for the actual board I am using. It will be different from the page I had uploaded earlier. We are not populating the power switch. Instead we tie the power lines to 3.3V with some zero ohm resistors.

ehristev commented 2 years ago

@torojoel if you still require help you know where to find me. I am closing this for the time being.