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.

uboot delay function gives more delay than expected

Hello,

We have a custom board based on beaglebone black,
We have issue in uboot delay function.
Delay function gives more delay than expected.
oscillator freqency is 26MHz,

It seems timer2 is used for delay creating delay,

I had given delay of 30 seconds by using mdelay function, but actual delay observed is 34 seconds.

clock source for timer 2 is CLK_M_OSC (i think its valid clock).

what could be wrong in u-boot because of which this delay is wrong ?
Any suggestions/pointers will help me a lot.

Thank you,

Regards,
Ankur

  • Hi Ankur,

    Have you modified the V_OSCK parameter inside <u-boot>/include/configs/am335x_evm.h for your case?

    Best regards,
    Miroslav

  • Hi Miroslav,

    Thank you for reply,
    Yes board configs has V_OSCK set to 26000000.

    Best Regards,
    Ankur

  • Which version of u-boot is this? A value of 1 selects the master osc for timer2. In one version of u-boot I have, this is in arch/arm/cpu/armv7/am33xx/clock.c:

             /* Select the Master osc 24 MHZ as Timer2 clock source */
             writel(0x1, &cmdpll->clktimer2clk);

    In your case, the comment should change to 26 instead of 24 since your master osc is 26MHz. Just make sure you are writing 1 to this register.

    Steve K.

  • Hi Steve,

    Thank you for reply,
    SPL/U-boot version is "U-Boot 2013.07.004"(from timesys_factory)
    Yes that register contains the value 1.
    I read it to confirm it and its value is 1.

    Thank you,

    Best regards,
    Ankur

  • Hi,

    After some testing and code reading i think found the problem,
    extra delay is caused by function hw_watchdog_reset() in driver/watchdog/omap_wdt.c

    Now let me eloborate the issue,

    mdelay() function is implmentation is as follows, (inside file<ubootcode dir>lib/time.c)

    void udelay(unsigned long usec)
    {
            ulong kv;
    
            do {
                    WATCHDOG_RESET();
                    kv = usec > CONFIG_WD_PERIOD ? CONFIG_WD_PERIOD : usec;
                    __udelay (kv);
                    usec -= kv;
            } while(usec);
    }               
    
    void mdelay(unsigned long msec)
    {
            while (msec--)
                    udelay(1000);
    }



    every milisecond WATCHDOG_RESET is done by udelay() function.

    And watchdog reset function is defined as follows (inside driver/watchdog/omap_wdt.c)

    void hw_watchdog_reset(void)
    {
            struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
    
            /* wait for posted write to complete */
            while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WTGR)
                    ;
    
            wdt_trgr_pattern = ~wdt_trgr_pattern;
            writel(wdt_trgr_pattern, &wdt->wdtwtgr);
    
            /* wait for posted write to complete */
            while ((readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WTGR))
                    ;
    }


    Second while loop is the culprit and takes more time than first while loop and adds some delay everytime
    hw_watchdog_reset() function is called.


    We thought of three solutions:

    1. Comment the second while loop in function hw_watchdog_reset.
       PROs:
           1.With this fix 30seconds delay was ~30seconds delay.
       CONS:
           2.Still there is delay added by first while loop.
       Note: I tested with both the while loops commented, in general it works
             but if some write is pending that gets missed out.

    2. Instead of doing watchdog reset at 1 milisecond it can be done at 1 seconds
       because generally watchdog timeout will be more than 1 seconds atlest.(i am assuming it)
       PROs:
        1. With this we do less WATCHDOG_RESET and avoid delay also
       CONs:
        2. But still problem would exist if we give large delay using udelay() function.
    3. We can optimize hw_watchdog_reset() function so that it will take less time.
       PROS:
        1. This would be a better solution which would avoid changing u-boot's common code.
       CONS:
        2. I dont know what optimization can be done :D :)


    I am working on solution and post it once i find better solution among above three solutions.

    meanwhile if you have any suggestions please write it.

    Thank you,

    Best regards,
    Ankur