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.

OPP selection issue on AM335x Starter Kit

Other Parts Discussed in Thread: TPS65217, TPS65910

Just a heads-up to those working with the AM335x Starter Kit and the WEC 7.0 BSP from Adeneo.

There seems to be an issue where selecting the highest OPP (OPP4, MPU @ 720 MHz), will actually make the MPU run at OPP2, at 500 MHz. I believe there is also a problem with configuring Vdd1 and Vdd2 on the CPU in XLDR, related to the OPP issue.

To confirm this, boot the binary WEC 7.0 images supplied by Adeneo on a Starter Kit. Then look at the output from IOCTL_HAL_GET_CPUSPEED (this returns the current CPU speed in MHz). This is what I am seeing, after selecting each OPP in the bootloader menu:

  • OPP1: 275 MHz (OK, as expected)
  • OPP2: 500 MHz (OK)
  • OPP3: 600 MHz (OK)
  • OPP4: 500 MHz (problem - expected 720 MHz)

The troubles start in XLDR, platform.c file, board_init function.

Since g_dwBoardId on a Starter Kit doesn't match the BeagleBone ID, we end up in the else branch, where the following lines can be found:

        if (TWLSetOPVoltage(kVdd1,opp_setting->VDD1Init))
        {
            mpu_pll_config(opp_setting);   
        }

The TWLSetOPVoltage call fails, which means that XLDR does not configure the OPP, but leaves it as is.

The CE OAL would normally set up the OPP again, but the SetOpp function (opp_map.c) assumes that XLDR succeeded in initially setting the OPP to whatever was selected at compile time, so if OPP4 was selected (by means of BSP_OPM_SELECT=4 in am33x_sk_bsp.bat), and a request comes in to change to OPP4, SetOpp ignores it, believing that the platform is already running at OPP4.

So the root of the problem is the failing TWLSetOPVoltage call in XLDR.

To fix it, change the following:

  • In bsp_def.h, the I2C address of the power management device is incorrect.
    • Change the definition of TPS65217_I2C_SLAVE_ADDRESS from 0x24 to 0x2d
    • While you are at it, you might want to rename TPS65217_I2C_SLAVE_ADDRESS to TPS65910_I2C_SLAVE_ADDRESS, since the Starter Kit uses a TPS65910; same with TPS65217_I2C_BUS_ID
  • In platform.c, the writes to the Vdd1/Vdd2 registers in the TPS65910 fail; specifically, the writes appear to succeed, but when the code reads back the values they don't match what was written. The Vdd1/Vdd2 registers are by default only accessible from the SmartReflex I2C interface, but this interface is not connected on the Starter Kit; only the "Control I2C" interface is. To make the registers accessible through the Control I2C interface, add a new branch to the if/else statement in board_init as shown:

    else if (g_dwBoardId == AM33X_BOARDID_SK_BOARD)
    {
        // Need to configure TPS65910 to access voltage setup registers
        // through the control I2C interface rather than the SmartReflex
        // I2C interface, since the latter is not connected on the AM335x
        // Starter Kit.
        // We do this by setting the SR_CTL_I2C_SEL bit in the
        // DEVCTRL_REG register in the TPS65910.
        hTwl = TWLOpen();
        if(hTwl)
        {
            if(TWLReadRegs(hTwl, PMIC_DEVCTRL_REG, &twlDevCtrlValue, sizeof(twlDevCtrlValue)))
            {
                twlDevCtrlValue |=  PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C;
                TWLWriteRegs(hTwl, PMIC_DEVCTRL_REG, &twlDevCtrlValue, sizeof(twlDevCtrlValue));
            }

            TWLClose(hTwl);
            hTwl = NULL;
        }

        TWLSetOPVoltage(kVdd2,VDD2_INIT);

        if(TWLSetOPVoltage(kVdd1,opp_setting->VDD1Init))
        {
            mpu_pll_config(opp_setting);
        }
    }

This appears to fix the issues with setting up Vdd1/Vdd2 voltages and selecting OPP4 in XLDR.

Finally, to minimize confusion, you might want to also modify the debug message in opp_map.c, SetOpp so that the Opp index printed matches the Eboot entry (the 'opp' index is 0-based, Eboot entries are 1-based):
    OALMSG(1, (L"SetOpp to %d\r\n", opp + 1));

  • I found this post very interesting and I confirmed your observations.

    Even with the correct I2C controller (I2C0 instead of I2C1) and the correct slave addresses I found the reason the TWLSetOPVoltage() routine fails and returns false is the read back check is failing: 

     

    if( (UINT32)(buf & PMIC_OP_REG_SEL_MASK ) != mv)

     goto cleanup;

     

    I noticed this register always returns 00 for reads no matter what I write.

    I can read and write other registers on the 65910 so I know its not an addressing or read/write issue.

    I have not actually check if the voltage is actually changing but I will do that next.

     

     

     

  • The voltage seems to always stay at ~1.1v no matter what I write to the VDD1_OP_REG or what I set the OPP at.

     

    There was a note in the BSP that the DVFS is not working. Don't know if this is a software, hardware or PMIC problem.

  • David,

    That was my observation as well; reading back from the register returns 0 instead of 0x38 as expected for 1.26 V, for example.

    The reason is that there's a few registers in the TPS65910 that are not accessible by default on the "Control I2C" interface - the only interface that is connected on the Starter Kit. To access these registers, you'll need to flip a bit in a control register - the 65910 datasheet says this under the DEVCTRL_REG (0x3f) description:

    SR_CTL_I2C_SEL: Smartreflex registers access control bit: RW 0

    when 0: access to smartreflex registers by smartreflex I2C
    when 1: access to smartreflex registers by control I2C

    The smartreflex
    registers are: VDD1_OP_REG, VDD1_SR_REG, VDD2_OP_REG and
    VDD2_SR_REG.

    The rather large code snippet I included above does just that, and I have confirmed that reading back from the 65910 does return the right values then.

  • Totally missed that bit. Thank you for pointing that out. Working as expected now.