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.

Linux/AM3358: Setting MPU PLL M2 Divider

Part Number: AM3358

Tool/software: Linux

MPU PLL M2 Divider seems to be not maintained by the kernel. Our customer sees that the MPU clock is always set to half frequency by the kernel if M2 Divider is set to 2 when initializing the PLL by U-Boot.

I have tested using EVM with the latest SDK (v05.02.00.10) prebuilt image to reproduce it. The terminal logs that the M2 divider is 1 or 2 are attached here:

MPU PLL M2 Divider = 1.txt

MPU PLL M2 Divider = 2.txt

Note that if M2 Divider is 2, the corresponding register was set by the U-Boot command at booting.

Note that the outputs by omapconf shows the correct results, but the outputs by cpuinfo_cur_freq shows the incorrect results that disregards M2.

Best regards,

Daisuke

  • Hello Daisuke,

    I am wondering if you have tried running the command "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" to see if it matches the omapconf results. Also, please refer to the following TI document.

    Regards,

    Krunal

  • Hi Krunal-san,

    Thank you for your reply.

    Please check the outputs by omapconf. Comparing the both results shows that the MPU clock is always set to half frequency by the kernel if M2 Divider is set to 2 when initializing the PLL by U-Boot. For the clock speed of M2 output, it changes in the range from 300MHz to 1000MHz when the M2 divider is 1, but it changes in the range from 300MHz to 500MHz when the M2 divider is 2.

    Best regards,

    Daisuke

  • Hi Krunal-san,

    Is it correct that tha kernel changes the clock speed of M2 output in the range from 300MHz to 500MHz when the M2 divider is 2?

    Tha kernel should change the clock speed of M2 output in the range from 300MHz to 1000MHz by changing the M2 divider value which is set by U-Boot.

    Best regards,

    Daisuke

  • Daisuke,

    Linux is clearly not expecting M2 divider to be 2.

    Regards,
    Ahmad

  • Hi Ahmad-san,

    Thank you for your reply.

    This issue will be avoided by setting the M2 divider to 1 by U-Boot. Is my guess correct?

    However, our customer expects that the kernel can set the clock speed correctly even if the M2 divider is set to a value other than 1. They want to make changes to the kernel to implement that.

    In which source code does the kernel change the PLL configuration to change the clock speed?

    Best regards,

    Daisuke

  • Hi Ahmad-san,

    Could you answer my questions?

    Daisuke Maeda said:

    This issue will be avoided by setting the M2 divider to 1 by U-Boot. Is my guess correct?

    However, our customer expects that the kernel can set the clock speed correctly even if the M2 divider is set to a value other than 1. They want to make changes to the kernel to implement that.

    In which source code does the kernel change the PLL configuration to change the clock speed?

    I have additional questions.

    Has this issue been identified as a bug by TI?

    If so, is there a plan to fix the bug?

    Best regards,

    Daisuke

  • Hi Krunal-san,

    I checked the MPU clock speed by the command "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq".

    If the M2 divider is set to 2, the clock speed that output by scaling_cur_freq shows the double of the clock speed of the M2 output that output by omapconf. The terminal log is attached here:3683.MPU PLL M2 Divider = 2.txt

    I used EVM with the pre-built image of latest SDK (v05.03.00.07) and reproduced it in the steps below.

    To modify and check the M2 divider value in the U-Boot:

      md 44E004A8 1
      mw 44E004A8 00000202
      md 44E004A8 1
      boot

    To change and check the clock speed in the Kernel:

      echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
      cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
      
      echo 300000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
      cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
      
      omapconf show dpll
      omapconf dump dpll
      
      echo 600000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
      cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
      
      omapconf show dpll
      omapconf dump dpll
      
      echo 720000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
      cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
      
      omapconf show dpll
      omapconf dump dpll
      
      echo 800000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
      cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
      
      omapconf show dpll
      omapconf dump dpll
      
      echo 1000000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
      cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
      
      omapconf show dpll
      omapconf dump dpll

    Could you answer my questions which posted above?

    Best regards,

    Daisuke

  • Hello Daisuke,

    The Processor SDK is tested with Linux and U-boot together so Linux is expecting the M2 drivier = 1 at all times. As you are making adjustments in u-boot you must also make these adjustments in Linux. Unfortunately Linux does not handle the MPU frequency using a look-up table of multiplier and divider values. It is calculated at run time / dynamically with the common dpll driver. You would need to hack this driver to achieve your needs.

    Really, you should keep M2 = 1. 

  • Hi Ahmad-san,

    Thank you for your reply.

    This issue will reproduce when a 300MHz device is used. U-Boot seems to refer to the lookup table to configure the DPLL. By default, the M2 divider for OPP50 (300MHz) is set to 2.

    "arch/arm/mach-omap2/am33xx/clock_am33xx.c"

      const struct dpll_params dpll_mpu_opp[NUM_CRYSTAL_FREQ][NUM_OPPS] = {
       { /* 19.2 MHz */
        {125, 3, 2, -1, -1, -1, -1}, /* OPP 50 */
        {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
        {125, 3, 1, -1, -1, -1, -1}, /* OPP 100 */
        {150, 3, 1, -1, -1, -1, -1}, /* OPP 120 */
        {125, 2, 1, -1, -1, -1, -1}, /* OPP TB */
        {625, 11, 1, -1, -1, -1, -1} /* OPP NT */
       },
       { /* 24 MHz */
        {25, 0, 2, -1, -1, -1, -1}, /* OPP 50 */
        {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
        {25, 0, 1, -1, -1, -1, -1}, /* OPP 100 */
        {30, 0, 1, -1, -1, -1, -1}, /* OPP 120 */
        {100, 3, 1, -1, -1, -1, -1}, /* OPP TB */
        {125, 2, 1, -1, -1, -1, -1} /* OPP NT */
       },
       { /* 25 MHz */
        {24, 0, 2, -1, -1, -1, -1}, /* OPP 50 */
        {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
        {24, 0, 1, -1, -1, -1, -1}, /* OPP 100 */
        {144, 4, 1, -1, -1, -1, -1}, /* OPP 120 */
        {32, 0, 1, -1, -1, -1, -1}, /* OPP TB */
        {40, 0, 1, -1, -1, -1, -1} /* OPP NT */
       },
       { /* 26 MHz */
        {300, 12, 2, -1, -1, -1, -1}, /* OPP 50 */
        {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
        {300, 12, 1, -1, -1, -1, -1}, /* OPP 100 */
        {360, 12, 1, -1, -1, -1, -1}, /* OPP 120 */
        {400, 12, 1, -1, -1, -1, -1}, /* OPP TB */
        {500, 12, 1, -1, -1, -1, -1} /* OPP NT */
       },
      };

    I can not reproduce it because I do not have a board with a 300MHz device. Could you try to reproduce it?

    To hack the dpll driver for linux kernel, please tell me which source code to configure the DPLL.

    Best regards,

    Daisuke

  • If a 300 MHz device was used then cpufreq should not be involved. The Arm freq would be fixed at 300 MHz.