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.

TPS65921 with AM37xx I2C1 lockup

Other Parts Discussed in Thread: TPS65921, TPS65950, AM3703

Hi all,

 

a customer is using the TPS65921 with the AM3703 and they are running into an I2C1 lockup issue when an external hosts resets (PWRONRESET) the AM3703 during an ongoing I2C1 transaction. The I2C1 from then on stays locked and cannot be used until the board is power cycled. This seems to be very similar failure mode as has been seen with the TPS65950. I was made aware of the following changes to the board.c file in order to fix this problem for the '950 in Linux.

 

static struct twl4030_ins wrst_seq[] __initdata = {

/*

 * Reset twl4030.

 * Reset VDD1 regulator.

 * Reset VDD2 regulator.

 * Reset VPLL1 regulator.

 * Enable sysclk output.

 * Reenable twl4030.

 */

                {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_OFF), 2},     //added

                {MSG_SINGULAR(DEV_GRP_P1, RES_VDD1, RES_STATE_WRST), 15},

                {MSG_SINGULAR(DEV_GRP_P1, RES_VDD2, RES_STATE_WRST), 15},

                {MSG_SINGULAR(DEV_GRP_P1, RES_VPLL1, RES_STATE_WRST), 0x60},

                {MSG_SINGULAR(DEV_GRP_P1, RES_HFCLKOUT, RES_STATE_ACTIVE), 2},

                {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_ACTIVE), 2},   //added

};

static struct twl4030_script wrst_script __initdata = {

                .script = wrst_seq,

                .size   = ARRAY_SIZE(wrst_seq),

                .flags  = TRITON_WRST_SCRIPT,

};

 

Questions:

(1) Is this the correct (complete) workaround, or are there other things to consider?

(2) Does this TPS65950 workaround also apply to the TPS65921?

(3) How does the above sequence apply for the AM37xx PWRONRST, i.e. in the customer case an external host asserts the PWRONRST on the AM37xx to cause a reset. I want to make sure that the additional PMIC initialization is part of this reset sequence.

 

Thanks,

--Gunter

 

  • Hi all,

     

    One side question: Would a simultaneous NRESWARM (to the PMIC) simultaneous to the AM37xx PWRONRST clear up the I2C lock also? The customer system allows for that with right resistor population.

     

    Thanks,

    --Gunter

  • Hi all,

     

    do you have an update on the above?

     

    Thanks,

    --Gunter

  • I'd like to try the
    patch you referenced:

    http://e2e.ti.com/support/power_management/pmu/f/43/t/182798.aspx

      for the I2C lockup issue.  This patch seems to be for a Nokia
      product and doesn't really apply to the Beagleboard.  I could lift
      the whole 4030 script structure and put it in the Beagleboard board
      file:

    arch/arm/mach-omap2/board-omap3beagle.c

      Do you recommend this?

      I'm not sure whether I need to use all four members in:

    -------------------------------------------------
    static struct twl4030_script *twl4030_scripts[] __initdata = {
        /* wakeup12 script should be loaded before sleep script, otherwise a
           board might hit retention before loading of wakeup script is
           completed. This can cause boot failures depending on timing issues.
        */
        &wakeup_script,
        &sleep_on_script,
        &wakeup_p3_script,
        &wrst_script,
    };
    -------------------------------------------------

      Seems like we just need &wrst_script but I'm not sure...

     Any help is greatly appreciated.

  • I put the code in and it's telling me:

    [    0.158020] TWL4030: Bad order of scripts (sleep script before wakeup) Leads to bootfailure on some boards



  •   Looks like there may have been a fix for this:

    http://www.mail-archive.com/linux-omap@vger.kernel.org/msg45509.html

  • Still getting errors with this addition:

    Starting vsftpd: OK
     Enabling hot-plug: [   11.566680] omap_i2c omap_i2c.1: Arbitration lost
    [   11.597564] omap_i2c omap_i2c.1: omap_i2c_bus_clear stat = 0x0, was 0x0 systest = 0x1e0
    [   11.606018] twl: i2c_read failed to transfer all messages
    [   12.621185] omap_i2c omap_i2c.1: timeout waiting for bus ready
    [   12.636871] omap_i2c omap_i2c.1: omap_i2c_bus_clear stat = 0x0, was 0x1000 systest = 0x1e0
    [   12.645568] twl: i2c_write failed to transfer all messages
    [   12.651306] ------------[ cut here ]------------
    [   12.656188] WARNING: at drivers/usb/otg/twl4030-usb.c:331 twl4030_i2c_access+0x58/0x110()
    [   12.664733] Modules linked in: g_ether(+)
    [   12.669006] [<c0040d1c>] (unwind_backtrace+0x0/0xec) from [<c0067bac>] (warn_slowpath_common+0x4c/0x64)
    [   12.678863] [<c0067bac>] (warn_slowpath_common+0x4c/0x64) from [<c0067bdc>] (warn_slowpath_null+0x18/0x1c)
    [   12.688964] [<c0067bdc>] (warn_slowpath_null+0x18/0x1c) from [<c02f92e8>] (twl4030_i2c_access+0x58/0x110)
    [   12.699005] [<c02f92e8>] (twl4030_i2c_access+0x58/0x110) from [<c02f93bc>] (__twl4030_phy_resume+0x1c/0x44)
    [   12.709228] [<c02f93bc>] (__twl4030_phy_resume+0x1c/0x44) from [<c02f93fc>] (twl4030_phy_resume+0x18/0x24)
    [   12.719329] [<c02f93fc>] (twl4030_phy_resume+0x18/0x24) from [<c02f9488>] (twl4030_set_suspend+0x1c/0x24)
    [   12.729370] [<c02f9488>] (twl4030_set_suspend+0x1c/0x24) from [<c032e310>] (omap2430_runtime_resume+0x3c/0x44)
    [   12.739868] [<c032e310>] (omap2430_runtime_resume+0x3c/0x44) from [<c02b59bc>] (pm_generic_runtime_resume+0x2c/0x38)
    [   12.750915] [<c02b59bc>] (pm_generic_runtime_resume+0x2c/0x38) from [<c02b7a58>] (rpm_callback+0x38/0x44)
    [   12.760925] [<c02b7a58>] (rpm_callback+0x38/0x44) from [<c02b86b0>] (rpm_resume+0x2a0/0x364)
    [   12.769775] [<c02b86b0>] (rpm_resume+0x2a0/0x364) from [<c02b8610>] (rpm_resume+0x200/0x364)
    [   12.778625] [<c02b8610>] (rpm_resume+0x200/0x364) from [<c02b898c>] (__pm_runtime_resume+0x30/0x48)
    [   12.788116] [<c02b898c>] (__pm_runtime_resume+0x30/0x48) from [<c032a0b8>] (usb_gadget_probe_driver+0x58/0x1b4)
    [   12.798706] [<c032a0b8>] (usb_gadget_probe_driver+0x58/0x1b4) from [<c00373a4>] (do_one_initcall+0x90/0x160)
    [   12.809020] [<c00373a4>] (do_one_initcall+0x90/0x160) from [<c00911e0>] (sys_init_module+0x1398/0x1538)
    [   12.818847] [<c00911e0>] (sys_init_module+0x1398/0x1538) from [<c003c700>] (ret_fast_syscall+0x0/0x30)
    [   12.828613] ---[ end trace 3f066241ed6d15fc ]---
    [   12.887817] twl: i2c_read failed to transfer all messages
    [   12.893676] twl4030_usb twl4030_usb: Timeout setting T2 HSUSB PHY DPLL clock


  • Sorry, the team is 100% hardware and I cannot go in such details.

    Root cause of the issue is when an I2C transfer is interrupted at Master side the PMIC I2C is still waiting for the rest of the transaction for a while.

    There are two solutions,

    1/ the master is abble to complete the transfer
    2/ knowning that in normal application mode the transaction is interrupted by a warm reset. Program the PMIC to reset itself when it receives a warm reset. This is the purpose of the requested sequence which is just the normal way to use the device. 

    When sequence is filled in don't forget to enable the warm reset (P1_SW_EVENTS, P2_SW_EVENTS, P3_SW_EVENTS registers)

    If the I2C transfer interrupt is initated by something else it should also generate a warm reset to the PMIC.

    Regards,

    Philippe

     

  • Hi Philippe,

      I've installed the patch for the script and have added a feature in the i2c driver that clocks out 16 clocks when it detects a stuck data line in the hope of freeing a stuck peripheral that is waiting for a i2c transaction and has control of the SDA line.  When I installed the "16 clock" feature, the frequency of hangs went way down so I believe it is working.  Now when I test by continually resetting the OMAP it takes about an hour for a hang.  I have brought out the SDA and SCL lines and the hang I see now is that the SCL line is stuck low.  It would seem that the PMIC is holding it low since I can take the OMAP through a complete reset, load software and it's still low.  There is a feature in the i2c peripheral to output a square wave on the SCL line but when I try this in the stuck mode, nothing happens, the line is still stuck low.

      Questions for you:

    1. Do you know about this problem?

    2. How do I know the script is working?  Is there a way I can read it out and verify that it really got loaded?

      Thanks much.

     Rick Bronson

  • It looks surprising to me. I propose to dump the sequencer to crosscheck the code.

    SEQ_ADD_W2P
    SEQ_ADD_P2A
    SEQ_ADD_A2W
    SEQ_ADD_A2S
    SEQ_ADD_S2A12
    SEQ_ADD_S2A3
    SEQ_ADD_WARM

    Regards,

    Philippe

  • Hi Philippe,

      I ran this same kernel on the BeagleBoardXM and it works fine. The
    SEQ is being programmed correctly.  So it seems to have something to
    do with the different PMIC chip we are using.  Just for your info the
    IDCODE of the BBXM is:

    [    0.099517] idcode addr = 0x00 = 0x2f
    [    0.099578] idcode addr = 0x01 = 0x00
    [    0.099670] idcode addr = 0x02 = 0x09
    [    0.099731] idcode addr = 0x03 = 0x30

      Our IDCODE is:

    [    0.119171] idcode addr = 0x00 = 0x2f
    [    0.119232] idcode addr = 0x01 = 0x80
    [    0.119323] idcode addr = 0x02 = 0x77
    [    0.119384] idcode addr = 0x03 = 0x1b

      The problem seems to be the PROTECT_KEY register.  When the BBXM
    sets this register to unlock, it reads back a 0x02:

    [    0.098052] unprotect_pm_master addr = 0x0e = 0x02

      Which from the manual:

    Read 10 when access to Power Configuration Registers is
    enabled

      When we set it we read back 0x00 which means we have no access.

      Any ideas?

      Rick

  • Hi all,

     

    was there any more resolution to the problem of unlocking the PMIC register and appropriately writing the warm reset script correctly for this PMIC?

     

    Thanks,

    --Gunter