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 4430 DPLL_MPU Locking issue

Other Parts Discussed in Thread: 4430

Hi,

Im working with an OMAP 4430. During the initialization Im able to set the dpll_mpu with the correspoding frequency and Im able to lock it with no problem. In  the code, I have a condition that when met I need to change the dpll_mpu frequency from 300MHZ to 600MHz. I follow the "DPLL Output-Frequency Change" flow chart: I unlock the dpll, change the parameters, and then lock it again. The problem is when I try to lock it everything freezes. 

Questions:

1) Can I change the frequency of the dpll_mpu whenever I want?

2) Am I following the correct flow: unlock, change M N M2, then lock the dpll?

3) Will the change take immediate effect?

  • Hello Christian,

    At first, could you specify what is your OS and board with OMAP4430?

    About your questions:

    #Q: 1) Can I change the frequency of the dpll_mpu whenever I want?

    - Yes, you can change dpll_mpu at any time. However you must observe some requirements, see the note:

    Automatic recalibration of the DPLL can start at any time. While relocking, the DPLL switches to bypass mode, which introduces a frequency change. For modules that are sensitive to frequency change while operating, this can introduce operational instability. For example, a module is sensitive to a frequency change on the DPLL because its embedded DLL relocks on a frequency change.

    MPU can random hang can happen during MHz OPP changes. Hang are due to MPU clock glitch or shrink pulses created at DPLL MPU enable/disable with DCC (Duty Cycle Correction) used.

    I suggest you to check and disable:

    CM_CLKSEL_DPLL_MPU[22] DCC_EN bit - 0x0: DCC disabled

    CM_AUTOIDLE_DPLL_MPU[2:0] AUTO_DPLL_MODE - 0x0: DPLL auto control disabled

    #Q: 2) Am I following the correct flow: unlock, change M N M2, then lock the dpll?

    Yes you are right.

    Do you change CM_CLKMODE_DPLL_MPU - register and Configure output clocks parameters ?

    See section Table 3-355. Subprocess Call Summary for Sequence – DPLL Output Frequency Change in TRM.

    #Q: 3) Will the change take immediate effect?

    Yes the change must be have immediate effect.

    You can use following command to View and Change Frequency (OPP):
    First, set cpufreq governor to userspace
    View current frequency:
    root@XXXXXX-evm# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq

    Change Frequency to 600MHz:

    root@XXXXXX-evm# echo 600000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed

    Best regards,

    Yanko

     

  • Hi Yanko,

    Thank you for taking time to responde to my question.

    We are using a custom board with QNX qnx650sp1 as the OS.

    The following are the registers we change:

    CM_CLKMODE_DPLL_MPU[2:0] = 0x4

    wait for CM_IDLEST_DPLL_MPU[0] = 0x0

    CM_AUTOIDLE_DPLL_MPU[2:0] = 0x0

    CM_CLKSEL_DPLL_MPU[18:8] = 0x7d

    CM_CLKSEL_DPLL_MPU[6:0] = 0x03

    CM_DIV_M2_DPLL_MPU[4:0] = 0x01

    CM_DIV_M2_DPLL_MPU[8] = 0x1

    CM_CLKMODE_DPLL_MPU[2:0] = 0x7   <-- this is where it hangs.

    wait for CM_IDLEST_DPLL_MPU[0] = 0x1     

    Thanks,

    Christian Archilla

  • Hello Christian,

    Could you check the clock configurations files in QNX.

    See the following functions used for DPLL settings in Linux:

    static inline void do_lock_dpll(const struct dpll_regs *dpll_regs)
    {
    clrsetbits_le32(dpll_regs->cm_clkmode_dpll, CM_CLKMODE_DPLL_DPLL_EN_MASK,
    DPLL_EN_LOCK << CM_CLKMODE_DPLL_EN_SHIFT);
    }


    static inline void wait_for_lock(const struct dpll_regs *dpll_regs)
    {
    if (!wait_on_value(ST_DPLL_CLK_MASK, ST_DPLL_CLK_MASK,
    (void *)dpll_regs->cm_idlest_dpll, LDELAY)) {
    printf("DPLL locking failed for 0x%x\n",
    dpll_regs->cm_clkmode_dpll);
    hang();
    }
    }
    static inline void do_bypass_dpll(const struct dpll_regs *dpll_regs)
    {
    clrsetbits_le32(dpll_regs->cm_clkmode_dpll,
    CM_CLKMODE_DPLL_DPLL_EN_MASK,
    DPLL_EN_MN_BYPASS << CM_CLKMODE_DPLL_EN_SHIFT);
    }
    static inline void wait_for_bypass(const struct dpll_regs *dpll_regs)
    {
    if (!wait_on_value(ST_DPLL_CLK_MASK, 0,
    (void *)dpll_regs->cm_idlest_dpll, LDELAY)) {
    printf("Bypassing DPLL failed 0x%x\n",
    dpll_regs->cm_clkmode_dpll);
    }
    }
    static void bypass_dpll(const struct dpll_regs *dpll_regs)
    {
    do_bypass_dpll(dpll_regs);
    wait_for_bypass(dpll_regs);
    }

    Best regards,

    Yanko