cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Adventurer
Adventurer
11,900 Views
Registered: ‎09-30-2014

U-Boot SD card support breaks with certain CPU frequencies

Jump to solution

I am stumped by a problem we ran into.  Using 2014.4 tools and Petalinux.  Running a custom board using a 7020 -3E variant.   Upper end theoretical CPU frequency is 867 MHz according to datasheet.  We create a very minimal project in Vivado and intitially set the CPU frequency to 650 MHz (Input Frequency is 33.333 MHz).  The project builds successfully, and we export the HDF.  Then we go into petalinux and create a project and use the exported HDF from Vivado to configure the petalinux project.  When we build and load the project on a Micro SD card, the project boots to U-Boot and the mmc info reports correctly.

 

We then tried to go back to Vivado and boost the CPU frequency to 867 MHz.  We exported and created a new project with petalinux for this build using the new HDF.  The board boots, U-Boot comes up, but when running "mmc info", errors are reported by the sdhci driver. 

 

We finally backed the CPU frequency down until the SD interface worked in U-Boot ("mmc info" reports correctly).  The magic frequency seemed to be around 783.33 MHz.  At this frequency the CPU 1X frequency drop to 130.555 versus 133.33344. 

 

I don't understand what is so magical about this frequency point, but it is frustrating that the CPU frequency needs to be limited.  Shouldn't U-Boot handle the upper frequency range?  Any help would be appreciated.  This appears to be a U-boot related issue since the FSBL is successfully loading from the SD card and the U-Boot elf loads and executes from the SD card as well.

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Adventurer
Adventurer
21,085 Views
Registered: ‎09-30-2014

Re: U-Boot SD card support breaks with certain CPU frequencies

Jump to solution

After multiple days of debugging....it turns out there is an apparent bug in the sdhci driver in U-Boot.  In the sdhci.c file for U-Boot, there is a retry loop (in sdhci_send_command) that waits for specific status to set in the Normal_Interrupt_Status register.  The retry loop simply uses a decrementing counter instead of a wait based on system timing.  The retry attempts is set too low so that when running the Zynq ARM CPU frequency above 783 MHz resulting in an internal bus frequency (CPU_1X) above 133 MHz, there are conditions / configurations of U-Boot which won't allow enough time for the SD card to finish before exiting the routine in error.

 

Solution was to increase the "retry" variable greater than the default 10000.

View solution in original post

0 Kudos
9 Replies
Highlighted
Scholar
Scholar
11,873 Views
Registered: ‎05-28-2012

Re: U-Boot SD card support breaks with certain CPU frequencies

Jump to solution

The u-boot appears to assume an input clock to the SD controller of 52MHz. See drivers/mmc/zynq_sdhci.c. It sounds like you have an input clock ranging from 130.5MHz to 133.3Mhz. The driver code will try to set the clock to 50Mhz. I am guessing the SDHCI divider calc is something like 52/50=1.04, rounds to 2. An input clock of 130.5MHz to 133.3Mhz should result in an output clock of 65.25MHz to 66.65Mhz. Not much of a difference. I am guessing your specific SD card tolerates the lower of the overclock frequencies but not the higher. Can you measure the actual SD CLK at the card? Try a different card?

0 Kudos
Highlighted
Adventurer
Adventurer
11,861 Views
Registered: ‎09-30-2014

Re: U-Boot SD card support breaks with certain CPU frequencies

Jump to solution

Actually, I ddn't choose the frequency.  The 130 and 133 is just the observation of what Vivado is reporting the CPU_1X clock is.  The SDHCI, according to Vivado output is setup for 50 MHz utilizing the IO PLL clock source.  When looking at U-Boot, it looks like it should be inheriting the IO PLL clock source and computing the divisor based off of that.  That is why I am asking the question.   I don't understand why only changing the CPU operating frequency in Vivado and using the hardware export file out of Vivado to create the BSP for U-Boot using Petalinux is causing a problem.  I am not choosing a clock source other than changing the CPU frequency (I am not touching the other clock source in Vivado, or U-Boot for that matter).

0 Kudos
Highlighted
Scholar
Scholar
11,831 Views
Registered: ‎05-28-2012

Re: U-Boot SD card support breaks with certain CPU frequencies

Jump to solution

I agree that changes to the ARM PLL should not effect the IO PLL. All the PLLs and divisors are setup in the FSBL ps2_init.c/.h code. I would suggest checking the code to see what Vivado generated. Check the xparameters.h in the BSP as well.

On a related note, I've had the FSBL fail to read the SD Card. That means the ROM bootloader was fine with the SD Card. When booted from NAND, the same ROM Bootloader, FSBL, U-Boot and Linux are all read fine from SD Card. There are definitely quirks in the Zynq. In my case, the SD input clock was changed from 125Mhz to 100Mhz in an attempt to optimize the SD CLK. Never found a solution.

0 Kudos
Highlighted
Adventurer
Adventurer
11,785 Views
Registered: ‎09-30-2014

Re: U-Boot SD card support breaks with certain CPU frequencies

Jump to solution

I have rechecked the IO PLL control register and the SD controller clock register.  Both are reasonable and valid while examining them in U-boot.   I am back to wondering about the CPU_1X that feeds some of the logic in the SD Controller.

0 Kudos
Highlighted
Adventurer
Adventurer
11,773 Views
Registered: ‎09-30-2014

Re: U-Boot SD card support breaks with certain CPU frequencies

Jump to solution

Another interesting observation I found is that the output frequency from the SD controller to the card seems to be correct in both cases.   When I run at the lower CPU / CPU_1X frequency (less that 783 MHz / 130 MHz respectively), the SD controller is properly set to the lowest frequency (196 kHz) for discovery, then gets boosted up by U-Boot to 25 MHz.  However in the higher frequency (anything above 783 MHz for the CPU), the SD controller still puts out the 196 kHz to start, but never transitions over because of the error reported by the SD controller.

 

Any thoughts?

0 Kudos
Highlighted
Scholar
Scholar
11,755 Views
Registered: ‎10-26-2012

Re: U-Boot SD card support breaks with certain CPU frequencies

Jump to solution

Manually check the register contents for the clock dividers in u-boot using the "md.l" command for example.

 

Be aware that vivado does not set the clocks in the bitstream, it generates the "ps7_init.*" files that contain that information. You have to compile bootloaders using these files.

 

There's a fair chance that Vivado just generated the wrong settings for the clocks.

 

And 25MHz is wrong - it should have been 50MHz.

 

0 Kudos
Highlighted
Adventurer
Adventurer
11,742 Views
Registered: ‎09-30-2014

Re: U-Boot SD card support breaks with certain CPU frequencies

Jump to solution
With all do respect. I have already checked at the register that pertain.

0xf8000108
0xf8000110
0xf8000150

These pertain to setup of the IO PLL and the setup of the SDIO clock source. These all appear to be setup correctly. The IO PLL is setup exactly the same way whether the CPU frequency is above or below 783 MHZ.
0 Kudos
Highlighted
Adventurer
Adventurer
21,086 Views
Registered: ‎09-30-2014

Re: U-Boot SD card support breaks with certain CPU frequencies

Jump to solution

After multiple days of debugging....it turns out there is an apparent bug in the sdhci driver in U-Boot.  In the sdhci.c file for U-Boot, there is a retry loop (in sdhci_send_command) that waits for specific status to set in the Normal_Interrupt_Status register.  The retry loop simply uses a decrementing counter instead of a wait based on system timing.  The retry attempts is set too low so that when running the Zynq ARM CPU frequency above 783 MHz resulting in an internal bus frequency (CPU_1X) above 133 MHz, there are conditions / configurations of U-Boot which won't allow enough time for the SD card to finish before exiting the routine in error.

 

Solution was to increase the "retry" variable greater than the default 10000.

View solution in original post

0 Kudos
Highlighted
Scholar
Scholar
11,698 Views
Registered: ‎05-28-2012

Re: U-Boot SD card support breaks with certain CPU frequencies

Jump to solution

Thanks for posting the solution. The change from 650MHz to 783.33 MHz is about 20% faster. At 650MHz, a retry of 10000 seems already too low for comfort. An order of magnitude higher would be better.

The u-boot code would suggest that broken R1B quirk has something to do with it. It certainly hides the timeout error.

 

drivers/mmc/zynq_sdhci.c

int zynq_sdhci_init(phys_addr_t regbase)
{
  ...
  host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
                 SDHCI_QUIRK_BROKEN_R1B;
  ...
}

drivers/mmc/sdhci.c

static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
           struct mmc_data *data)
{
  ...
  unsigned int retry = 10000;
  ...
  sdhci_writew(host, SDHCI_MAKE_CMD(cmd->cmdidx, flags), SDHCI_COMMAND);
  do {
    stat = sdhci_readl(host, SDHCI_INT_STATUS);
    if (stat & SDHCI_INT_ERROR)
      break;
    if (--retry == 0)
      break;
  } while ((stat & mask) != mask);

  if (retry == 0) {
    if (host->quirks & SDHCI_QUIRK_BROKEN_R1B)
      return 0;
    else {
      printf("%s: Timeout for status update!\n", __func__);
      return TIMEOUT;
    }
  }
  ...
  if (host->quirks & SDHCI_QUIRK_WAIT_SEND_CMD)
    udelay(1000);

...
}

What amount of retry remained at the highest CPU frequency? Does different cards affect the timing?

 

0 Kudos