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.

DM8148 DDR3 533 MHz and OPP

Hi,

We have a custom board with the DM8148 CYE2 and we want to run the DDR3 @ 533 MHz.

As far as I get it from the datasheet DDR3 @ 533 MHz requires to run the core domain at OPP166, which in turn requires CVDD to be 1.35V.

As changing the DDR PLL cannot be done while the DDR is in use the setting of the DDR PLL for 533 MHz needs to be done in the early steps of U-Boot (stage1), before it is relocated to DDR memory.

The PMIC (TPS659113) runs CVDD at 1.2 V by default, but 1.35V is required for OPP166. This can be changed via I2C, but I2C for the DM814x cannot be used before U-Boot has been moved to DDR as the driver uses some global variables.

So this looks like a chicken and egg problem, to run the DDR @ 533 MHz we need to raise CVDD via I2C but to do that we need to be using the DDR, but then we cannot change the DDR PLL as DDR is in use.

How is this supposed to be done in U-Boot then? I could not find any indication of it in the DM81xx U-Boot user guide on the wiki.

I guess one could initialize the DDR PLL for 533 MHz regardless of CVDD being at 1.2V and then raise it to 1.35V as soon as U-Boot is relocated to DDR, but this does not seem very reliable as the datasheet says that for 533 MHz OPP166 is needed and for OPP166 CVDD must be 1.35V. It works on my test bench, but I would not be comfortable to do it on a product.

  • We simply enabled CONFIG_I2C in the first stage u-boot, and then used i2c_write() to set PMIC regs ...

  • Diego,

    Another approach can be to use the below u-boot command:

    TI8148_EVM#i2c mw 0x2D 0x22 0x3C

    This method works with Power Management chip TPS659113, attached to I2C0 at address 0x2D.

    Regards,

    Pavel

  • Thanks for this suggestion and the one above.

    I had already done this and yes it works on my test system, but my impression is that this is not 100% reliable across all working conditions. To be able to use an OPP one needs to first raise the voltage to the required minimum and then raise the frequency. But this is doing the inverse, it is first setting the DDR to 533 MHz (OPP166), using the DDR and only then raising the voltage to the required level. This usually works but I would be afraid that it would break under some circumstances as it is working out of spec for a brief period.

    How did people at TI test this reliably with CYE1 and CYE2 silicon? I find it surprising that the software in the PSP does not support this configuration.

  • Diego,

    Diego Santa Cruz said:
    This usually works but I would be afraid that it would break under some circumstances as it is working out of spec for a brief period.


    I understand your concern now. I have never seen someone to report any kind of "brake" when doing this (first raise the DDR3 to 533MHz, then raise the voltage to 1.35V). Note that we have the same approach when raising the CPU to 1GHz.

    I will check with the HW team and let you know if/when I have something about that.

    BR
    Pavel

  • Daniel,

    Daniel70334 said:
    We simply enabled CONFIG_I2C in the first stage u-boot, and then used i2c_write() to set PMIC regs ...

    Do you mean that by this way you increase the voltage to 1.35V (OPP166) from the first stage u-boot (MLO, x-loader)?

    BR
    Pavel

  • Yes - my understanding is that the MLO (or single stage NAND boot loader) runs from SRAM, and that all DDR controller and PLL setup must be done from the program running from SRAM, before DDR is used.  So I added the CONFIG_I2C to the MLO uboot profile, and added the additional I2C writes to set up PMIC.  I imagine that PLL registers are still written before the voltage is increased, but at least both PLL setting and PMIC update occurs before a program is loaded into DDR.

  • Hi Pavel and Daniel,

    Sorry to correct, but the first stage of U-Boot does not run from SRAM, it runs from DDR. It is loaded to SRAM by the ROM boot code, but then it is moved to DDR by the low level initialization code. So it starts running from SRAM but only up until the cpu_init_crit assembly function returns. It is then moved to DDR by relocate and copy_loop in arch/arm/cpu/arm_cortexa8/start.S. BTW, stage 1 is compiled with TEXT_BASE = 0x80700000, which is an address in DDR.

    The cpu_init_crit assembly function calls lowlevel_init, s_init_start and finally s_init in evm.c and all PLLs and DDR is initialized from s_init().

    So it is not enough to write the PMIC registers in stage1, it must be done from s_init() before the PLLs are set up by prcm_init().

    I managed to do the I2C calls before the PLLs are set up by doing the following:

    • Remove the global variables from the I2C driver (drivers/i2c/omap24xx_i2c.c), they are not needed. They were intended for I2C multi bus configurations bus I2C multi bus is only partially implemented and totally broken.
    • Enable I2C in stage 1 by defining CONFIG_I2C in the minimal configuration
    • Move the initialization of DMTIMER1 out of per_clocks_enable() into a function that is called earlier, be it basic_timer_init(). It selects OSC0 as source for DMTIMER1, resets it and starts it with auto-reload enabled (auto-reload was not enabled in the original code). This makes it possible to use udelay(), which is called by the I2C driver, so it must be done before I2C can be used.
    • As the start of prcm_init() call basic_timer_init(), enable the I2C module (CM_ALWON_I2C_0_CLKCTRL), the I2C0 SDA and SCL pins, call i2c_init() and then write the PMIC registers as necessary to raise the voltages to 1.35V as required for OPP166. Note that the I2C module gets its clock from SYSCLK10, but this is already set up by the ROM boot code to be 48 MHz as expected by the I2C driver.

    It works like a charm, and the voltages are raised to the required level before initializing the PLLs.

    Just a remark: none of the functions called by s_init() can use static arrays, because the compiler generates absolute addresses to load these and absolute addresses do not work at that point, since U-Boot is not yet running from the expected address.

  • Hello :

     My system  based on DM8148 now can work at DDR 533M  DSP 700M and ARM 1G accroding the document http://processors.wiki.ti.com/index.php/TI814x-DDR3-Init-U-Boot_Wordwise_SWleveling

    and

    (1)I adjust the dsp and core and arm voltage value in the second uboot

    (2)change the parameter

    #define DDR3_PHY_RD_DQS_CS0_DEFINE     
    #define DDR3_PHY_WR_DQS_CS0_DEFINE     
    #define DDR3_PHY_RD_DQS_GATE_CS0_DEFINE    
    #define DDR3_PHY_WR_DATA_CS0_DEFINE    
    (3)Change
    arch/arm/include/asm/arch-ti81xx/clocks_ti814x.h
  • Hi Diego,

    Diego Santa Cruz said:

    So it is not enough to write the PMIC registers in stage1, it must be done from s_init() before the PLLs are set up by prcm_init().

    I managed to do the I2C calls before the PLLs are set up by doing the following:

    • Remove the global variables from the I2C driver (drivers/i2c/omap24xx_i2c.c), they are not needed. They were intended for I2C multi bus configurations bus I2C multi bus is only partially implemented and totally broken.
    • Enable I2C in stage 1 by defining CONFIG_I2C in the minimal configuration
    • Move the initialization of DMTIMER1 out of per_clocks_enable() into a function that is called earlier, be it basic_timer_init(). It selects OSC0 as source for DMTIMER1, resets it and starts it with auto-reload enabled (auto-reload was not enabled in the original code). This makes it possible to use udelay(), which is called by the I2C driver, so it must be done before I2C can be used.
    • As the start of prcm_init() call basic_timer_init(), enable the I2C module (CM_ALWON_I2C_0_CLKCTRL), the I2C0 SDA and SCL pins, call i2c_init() and then write the PMIC registers as necessary to raise the voltages to 1.35V as required for OPP166. Note that the I2C module gets its clock from SYSCLK10, but this is already set up by the ROM boot code to be 48 MHz as expected by the I2C driver.

    It works like a charm, and the voltages are raised to the required level before initializing the PLLs.

    Is it possible to get your code in order to implement it in my custom board?

    Regards