This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Beaglebone: SD Card performance issues

Hi,

I'm using linux kernel 3.2.14+ (from yocto project) on my Beaglebone. I'm experiencing bad SD Card performance in my application where I have to write a lot of data to SD card. (Certain amount of data is generated every second)

When I write to the SD Card (class 10 Samsung) at the rate of 1.5 MB/s, then writing is fine. But when I write @ 3.0 MB/s (double) the performance is severely affected.
I thought I'm writing excessive data and Beaglebone at 720 MHz (and class 10 SD) is not good enough.

I did the same test on another ARM9 (400 MHz) and it did pretty well for both 1.5 MB/s & 3.0 MB/s, with the same SD card.

This points to me possibility of bad kernel driver or silicon issues on AM335x. No silicon errata is mentioned by TI for SD/MMC on AM335x.

Can anyone recollect any such issue reported earlier? Any inputs can give me some leads to look into the problem.

-PJ

  • Below link will give you performance figures for MMC module on am335x

    http://processors.wiki.ti.com/index.php/AM335x-PSP_04.06.00.08_Features_and_Performance_Guide#MMC.2FSD_Driver

  • Hi Gururaja,

    Thanks for pointing that link to me. I'm using FAT32 & in your test case, the size of buffer is large. I will try with larger buffer size for test, but I'm not sure if I can actually use larger buffer.

    Secondly, I saw your patch regarding HSPE bit enable on AM33xx processors. I thought that could solve my SD problem when I use class 10 UHS-1 SD Card. In your patch this part of code confuses me:

    +    /*
    +     * Enable High-Speed Support
    +     * Pre-Requisites
    +     *    - Controller should support High-Speed-Enable Bit
    +     *    - Controller should not be using DDR Mode
    +     *    - Controller should advertise that it supports High Speed
    +     *      in capabilities register
    +     *    - MMC/SD clock coming out of controller > 25MHz
    +     */
    +    if ((mmc_slot(host).features & HSMMC_HAS_HSPE_SUPPORT) &&
    +        (ios->timing != MMC_TIMING_UHS_DDR50) &&
    +        ((OMAP_HSMMC_READ(host->base, CAPA) & HSS) == HSS)) {
    +        regval = OMAP_HSMMC_READ(host->base, HCTL);
    +        if (clkdiv && (clk_get_rate(host->fclk)/clkdiv) > 25000000)
    +            regval |= HSPE;
    +        else
    +            regval &= ~HSPE;
    +
    +        OMAP_HSMMC_WRITE(host->base, HCTL, regval);
    +    }

    In the above code, check the line: if (clkdiv && (clk_get_rate(host->fclk)/clkdiv) > 25000000)

    What if clkdiv is 0 & clk_get_rate(host->fclk) is > 25000000, then should the HSPE be enabled??  That the case in my setup. Can you please confirm?

    I was trying your patch, since my kernel is different I had to manually apply it. Not sure whether the above patch will be sufficient for UHS.

    -PJ

  • well clkdiv being zero is wrong condition (since anythini/zero is infinity).

    also,

    /* Calculate divisor for the given clock frequency */
    static u16 calc_divisor(struct omap_hsmmc_host *host, struct mmc_ios *ios)
    {
        u16 dsor = 0;

        if (ios->clock) {
            dsor = DIV_ROUND_UP(clk_get_rate(host->fclk), ios->clock);
            if (dsor > 250)
                dsor = 250;
        }

        return dsor;
    }

    static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
    {
        struct mmc_ios *ios = &host->mmc->ios;
        unsigned long regval;
        unsigned long timeout;
        unsigned long clkdiv;

        dev_dbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock);

        clkdiv = calc_divisor(host, ios);

    ....

    clkdiv is updated depending on ios->clock. we need to update clk registers only when there is a clock/frequency changes

  • Hi Gururaja,

    In my case ios->clock is 0, so clkdiv is also 0.
    clk_get_rate(host->fclk) gives 76800000.
    Does this indicate any problem?

    Regarding my app test with larger buffer: did not solve the problem. You have tested the Write performance of SD without the memory usage statistics. (I forgot to add that keeping memory usage low is also one of my requirements).
    Your test only gave good SD write results, but in turn your memory usage was very high (because of buffer caching).

    I need to write larger data to SD keeping the memory usage low, or reasonable (say only few MBs).

    -PJ

  • Hi gururaja,

    just to elaborate:

    Case 1: Your test type (the results of which are published by TI)

         ^
         |
         |
         |    ----------
       ^ |    |        |
       | |    |        |
    MB | |    |        |
       | |    |        |
         |    |        |
         |    |        |
         |    |        |
         |    |        |
         |    |        |
         |-----        -------------------------------
       --+-------------------------------------------->
                    time ->

    Case 2: My test

         ^
         |
       ^ |
       | |
    MB | |
       | |
         | ---  ---  ---  ---  ---  ---  ---
         | | |  | |  | |  | |  | |  | |  | |
         | | |  | |  | |  | |  | |  | |  | |
         |-- ---- ---- ---- ---- ---- ---- -------
       --+------------------------------------------>
                    time ->

    In case 1, you will get good write speeds but if the same test is done for longer time period, the system may choke.

    In case 2 (that I need), the write speed may be less, but the system is required to be running for infinite time.

    Now, with same test application, I'm able to achieve amazing results with an Atmels ARM9 (400 MHz) processor, but Cortex-a8 (720 MHz) is not able to give me the same result, so the obvious culprit seems to be the MMC driver.

    And what I want to know, if any one has had any experience which may suggest something.


    -PJ