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.

OMAP-L138 reset hang using cpu_arm926_reset linux macro

Other Parts Discussed in Thread: OMAP-L138

I’ve been trying to get the OMAP-L138 to do a software reset for some time now in our Linux environment.  Some quick background:  The design uses the ROM bootloaders to first initate the system, then the OMAP-L138 UBL bootloader loads UBOOT, which UBOOT then loads Linux.  This is the path I'd like to mimic for my software reset by jumping to the ARM ROM bootloader.

However, due to hardware restrictions in our design (where I can't use the watchdog or PLL registers to kick off the reset) the only remaining option that is available to use is the cpu_arm926_reset macro in our linux distribution.

Sometimes the reset works, but the majority of the time, it hangs.  Here’s a forum post very similar to my situation.

http://lists.infradead.org/pipermail/linux-arm-kernel/2009-November/003952.html

 I’ve used CCSv5 to verify that the jump is being made to the ARM ROM bootloader address where it starts executing.  However, the system gets stuck in a loop at address 0xFFFD3978. 

Here’s the disassembly from CCSv5:

0xfffd3978:   E1A00000  MOV   R0, R0

                          EAFFFFFD  B          0xfffd3978

1.)    What is this is or where it’s stuck and why it would get here?

2.)    Is jumping to the ARM ROM bootloader the best way to do the software reset considering my limitations?  Is it possible to jump to the DSP one which I believe then jumps to the ARM bootloader?  Maybe there’s a setup issue that the DSP does during a cold boot to the ARM? 

3.)    If I can’t use the DSP ROM bootloader, could another issue be the state of external RAM, internal RAM (e.g. junk data?)  Would internal/external RAM need to be cleared out prior to jumping to the ROM bootloaders?

4.)   Is there an easy way set all the registers to defaults so the OMAP behaves like it's coming out of a cold reset?

------------------

Below is the code I'm using to do the resets now (which is currently inconsistent).

-------------------

  // disable interrupts

    __asm__ __volatile__(
        "mrs r0, cpsr\n\t"
        "orr r0, r0, #0xc0\n\t"
        "msr cpsr_c, r0"
    );

   // flush all cache then jump to the ROM bootloader

    cpu_arm926_proc_fin();

    cpu_arm926_reset(0xFFFD0000);

-------------------

These are the macro definitions in my Linux distrbution.

*/
/* cpu_arm926_proc_fin()
 */
ENTRY(cpu_arm926_proc_fin)
         mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
         bic     r0, r0, #0x1000                 @ ...i............
         bic     r0, r0, #0x000e                 @ ............wca.
         mcr     p15, 0, r0, c1, c0, 0           @ disable caches
         mov     pc, lr

-------------------

/*
 * cpu_arm926_reset(loc)
 *
 * Perform a soft reset of the system.  Put the CPU into the
 * same state as it would be if it had been reset, and branch
 * to what would be the reset vector.
 *
 * loc: location to jump to for soft reset
 */
    .align    5
        .pushsection    .idmap.text, "ax"
ENTRY(cpu_arm926_reset)
    mov    ip, #0
    mcr    p15, 0, ip, c7, c7, 0        @ invalidate I,D caches
    mcr    p15, 0, ip, c7, c10, 4        @ drain WB
#ifdef CONFIG_MMU
    mcr    p15, 0, ip, c8, c7, 0        @ invalidate I & D TLBs
#endif
    mrc    p15, 0, ip, c1, c0, 0        @ ctrl register
    bic    ip, ip, #0x000f            @ ............wcam
    bic    ip, ip, #0x1100            @ ...i...s........
    mcr    p15, 0, ip, c1, c0, 0        @ ctrl register
    mov    pc, r0
ENDPROC(cpu_arm926_reset)
        .popsection

  • adamk said:
    However, due to hardware restrictions in our design (where I can't use the watchdog or PLL registers to kick off the reset) the only remaining option that is available to use is the cpu_arm926_reset macro in our linux distribution.

    Can you elaborate on what hardware restrictions you're referring to?  I think that these options are by FAR the best so before we dismiss them I would like to make sure they truly cannot be used.  If you elaborate on why they cannot be used perhaps I can think of a workaround to that issue so that you can use them.

    adamk said:

    I’ve used CCSv5 to verify that the jump is being made to the ARM ROM bootloader address where it starts executing.  However, the system gets stuck in a loop at address 0xFFFD3978. 

    Here’s the disassembly from CCSv5:

    0xfffd3978:   E1A00000  MOV   R0, R0

                              EAFFFFFD  B          0xfffd3978

    What silicon revision are you using?  The silicon revision also determines the ROM code revision which will be needed in order for us to give you any indication as to what's happening.

    adamk said:
    4.)   Is there an easy way set all the registers to defaults so the OMAP behaves like it's coming out of a cold reset?

    Well, normally this is where I would say the watchdog is the easy way!!!

  • Thanks Brian.

    The hardware restrictions stem from a PMIC that we have in front of the OMAP.  It uses the OMAP's GPIO to control the PMIC, which determines whether to release RESET on the processor.  If the OMAP GPIO aren't at the thresholds the PMIC needs to keep the processor alive, then the system goes down.  So, if the GPIO go tri-state during a normal reset (e.g. issuing #/ reboot), then the PMIC takes over and holds reset low. 

    We are using silicon rev 2.1 of the OMAP-L138.

    Any other thoughts are welcome.

  • For clarification:

    1.  The distribution is TI Arago version 03.20.00.13, Linux kernel version 2.6.33-rc4
    2.  The design is based on the OMAP-L138 SoM from Logic
    3.  There have been changes made to Uboot to support the hardware design

    These may play into the analysis of the issue.

  • If you're going to go with a pure software reset method then you would need to make sure the ARM core is in the expected state when branching to the ROM entry point.  I just pulled out a board, connected with an emulator, enabled "halt on reset", and then did a system reset.  Looking at the status at the bottom I see the following:

    • ARM mode (not thumb)
    • Supervisor
    • MMU Off

    You must make sure to handle all of the above conditions or else the ROM code probably won't execute properly.

    One other thing I recommend doing prior to the software reset would be to set the various PSC domains to their reset states.  I ran this gel file to see the state of the various domains when I get to the ROM entry point.  Here it is:

    ARM9_0: GEL Output: ---------------------------------------------
    ARM9_0: GEL Output: |              PSC0 Information             |
    ARM9_0: GEL Output: ---------------------------------------------
    ARM9_0: GEL Output:
    ARM9_0: GEL Output: State Decoder:
    ARM9_0: GEL Output:  0 = SwRstDisable (reset asserted, clock off)
    ARM9_0: GEL Output:  1 = SyncReset (reset assered, clock on)
    ARM9_0: GEL Output:  2 = Disable (reset de-asserted, clock off)
    ARM9_0: GEL Output:  3 = Enable (reset de-asserted, clock on)
    ARM9_0: GEL Output: >3 = Transition in progress
    ARM9_0: GEL Output:
    ARM9_0: GEL Output: Module 0:    EDMA3CC (0)        STATE = 0
    ARM9_0: GEL Output: Module 1:    EDMA3 TC0          STATE = 0
    ARM9_0: GEL Output: Module 2:    EDMA3 TC1          STATE = 0
    ARM9_0: GEL Output: Module 3:    EMIFA (BR7)        STATE = 0
    ARM9_0: GEL Output: Module 4:    SPI 0              STATE = 0
    ARM9_0: GEL Output: Module 5:    MMC/SD 0           STATE = 0
    ARM9_0: GEL Output: Module 6:    AINTC              STATE = 3
    ARM9_0: GEL Output: Module 7:    ARM RAM/ROM        STATE = 3
    ARM9_0: GEL Output: Module 9:    UART 0             STATE = 0
    ARM9_0: GEL Output: Module 10:    SCR 0 (BR0/1/2/8)  STATE = 3
    ARM9_0: GEL Output: Module 11:    SCR 1 (BR4)        STATE = 3
    ARM9_0: GEL Output: Module 12:    SCR 2 (BR3/5/6)    STATE = 3
    ARM9_0: GEL Output: Module 13:    PRUSS              STATE = 0
    ARM9_0: GEL Output: Module 14:    ARM                STATE = 3
    ARM9_0: GEL Output: Module 15:    DSP                STATE = 3
    ARM9_0: GEL Output:
    ARM9_0: GEL Output: ---------------------------------------------
    ARM9_0: GEL Output: |              PSC1 Information             |
    ARM9_0: GEL Output: ---------------------------------------------
    ARM9_0: GEL Output:
    ARM9_0: GEL Output: State Decoder:
    ARM9_0: GEL Output:  0 = SwRstDisable (reset asserted, clock off)
    ARM9_0: GEL Output:  1 = SyncReset (reset assered, clock on)
    ARM9_0: GEL Output:  2 = Disable (reset de-asserted, clock off)
    ARM9_0: GEL Output:  3 = Enable (reset de-asserted, clock on)
    ARM9_0: GEL Output: >3 = Transition in progress
    ARM9_0: GEL Output:
    ARM9_0: GEL Output: Module 0:    EDMA3CC (1)        STATE = 0
    ARM9_0: GEL Output: Module 1:    USB0 (2.0)         STATE = 0
    ARM9_0: GEL Output: Module 2:    USB1 (1.1)         STATE = 0
    ARM9_0: GEL Output: Module 3:    GPIO               STATE = 0
    ARM9_0: GEL Output: Module 4:    UHPI               STATE = 0
    ARM9_0: GEL Output: Module 5:    EMAC               STATE = 0
    ARM9_0: GEL Output: Module 6:    DDR2 and SCR F3    STATE = 0
    ARM9_0: GEL Output: Module 7:    MCASP0 + FIFO      STATE = 0
    ARM9_0: GEL Output: Module 8:    SATA               STATE = 0
    ARM9_0: GEL Output: Module 9:    VPIF               STATE = 0
    ARM9_0: GEL Output: Module 10:    SPI 1              STATE = 0
    ARM9_0: GEL Output: Module 11:    I2C 1              STATE = 0
    ARM9_0: GEL Output: Module 12:    UART 1             STATE = 0
    ARM9_0: GEL Output: Module 13:    UART 2             STATE = 0
    ARM9_0: GEL Output: Module 14:    MCBSP0 + FIFO      STATE = 0
    ARM9_0: GEL Output: Module 15:    MCBSP1 + FIFO      STATE = 0
    ARM9_0: GEL Output: Module 16:    LCDC               STATE = 0
    ARM9_0: GEL Output: Module 17:    eHRPWM (all)       STATE = 0
    ARM9_0: GEL Output: Module 18:    MMC/SD 1           STATE = 0
    ARM9_0: GEL Output: Module 19:    UPP                STATE = 0
    ARM9_0: GEL Output: Module 20:    eCAP (all)         STATE = 0
    ARM9_0: GEL Output: Module 21:    EDMA3 TC2          STATE = 0
    ARM9_0: GEL Output: Module 24:    SCR-F0 Br-F0       STATE = 3
    ARM9_0: GEL Output: Module 25:    SCR-F1 Br-F1       STATE = 3
    ARM9_0: GEL Output: Module 26:    SCR-F2 Br-F2       STATE = 3
    ARM9_0: GEL Output: Module 27:    SCR-F6 Br-F3       STATE = 3
    ARM9_0: GEL Output: Module 28:    SCR-F7 Br-F4       STATE = 3
    ARM9_0: GEL Output: Module 29:    SCR-F8 Br-F5       STATE = 3
    ARM9_0: GEL Output: Module 30:    Br-F7 (DDR Contr)  STATE = 3
    ARM9_0: GEL Output: Module 31:    L3 RAM, SCR-F4, Br-F6 STATE = 3

    You'll obviously need to be careful when turning off various clocks.  A slightly different approach with the PSC would be to make sure the individual drivers first disable the peripheral through PSC and then re-enable them (as opposed to assuming it's disabled by reset and only doing the enable step).  If you always do the disable/enable then you will successfully reset the various peripherals before you use them in the code.

  • adamk said:

    Here’s the disassembly from CCSv5:

    0xfffd3978:   E1A00000  MOV   R0, R0

                              EAFFFFFD  B          0xfffd3978

    FYI, that's Rev 2.0 silicon, not Rev 2.1 like you mentioned previously.  This particular loop is the ROM code's abort loop.  Just before it enters the loop it should log the error reason.  You can use this gel file to help you interpret the ROM status code and understand what went wrong.

  • Hi All,

    Can any boby tell me how can i enable the watchdog timer from U-Boot prior to booting the kernel, in case the kernel fails to load/hangs, it should reset the system.

    Any pointer would be great help

    Thanks

    ~Sumit gemini