]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00176366: MX6-Switch ARM_CLK to PLL2_400MHz when ARM freq is below 400MHz.
authorRanjani Vaidyanathan <ra5478@freescale.com>
Wed, 7 Mar 2012 18:48:21 +0000 (12:48 -0600)
committerOliver Wendt <ow@karo-electronics.de>
Mon, 30 Sep 2013 12:11:24 +0000 (14:11 +0200)
PLL1 can be disabled whenever ARM_CLK is below 400MHz since
ARM_CLK can be sourced from PLL2_PFD_400MHz.

Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
arch/arm/mach-mx6/clock.c
arch/arm/mach-mx6/cpu_op-mx6.c

index d48856be60cf831455b8330f6deb680abed28a44..fa99bb6015e056bffb9e5c9407844d035ab56b3f 100644 (file)
@@ -29,6 +29,8 @@
 #include <mach/common.h>
 #include <mach/clock.h>
 #include <mach/mxc_dvfs.h>
+#include <mach/ahci_sata.h>
+#include <mach/mxc_hdmi.h>
 #include "crm_regs.h"
 #include "cpu_op-mx6.h"
 #include "regs-anadig.h"
@@ -51,6 +53,9 @@ void __iomem *apll_base;
 static struct clk pll1_sys_main_clk;
 static struct clk pll2_528_bus_main_clk;
 static struct clk pll2_pfd_400M;
+static struct clk pll2_pfd_352M;
+static struct clk pll3_pfd_540M;
+static struct clk pll2_pfd_594M;
 static struct clk pll3_usb_otg_main_clk;
 static struct clk pll4_audio_main_clk;
 static struct clk pll5_video_main_clk;
@@ -64,11 +69,14 @@ static struct clk usdhc3_clk;
 
 static struct cpu_op *cpu_op_tbl;
 static int cpu_op_nr;
+static bool pll1_enabled;
+static bool arm_needs_pll2_400;
 
 #define SPIN_DELAY     1200000 /* in nanoseconds */
 
 #define AUDIO_VIDEO_MIN_CLK_FREQ       650000000
 #define AUDIO_VIDEO_MAX_CLK_FREQ       1300000000
+DEFINE_SPINLOCK(clk_lock);
 
 /* We need to check the exp status again after timer expiration,
  * as there might be interrupt coming between the first time exp
@@ -192,6 +200,7 @@ static void _clk_disable_inwait(struct clk *clk)
        __raw_writel(reg, clk->enable_reg);
 }
 
+
 /*
  * For the 4-to-1 muxed input clock
  */
@@ -512,13 +521,25 @@ static int _clk_pll1_main_set_rate(struct clk *clk, unsigned long rate)
        return 0;
 }
 
+static void _clk_pll1_disable(struct clk *clk)
+{
+       pll1_enabled = false;
+       _clk_pll_disable(clk);
+}
+
+static int _clk_pll1_enable(struct clk *clk)
+{
+       _clk_pll_enable(clk);
+       pll1_enabled = true;
+}
+
 static struct clk pll1_sys_main_clk = {
        __INIT_CLK_DEBUG(pll1_sys_main_clk)
        .parent = &osc_clk,
        .get_rate = _clk_pll1_main_get_rate,
        .set_rate = _clk_pll1_main_set_rate,
-       .enable = _clk_pll_enable,
-       .disable = _clk_pll_disable,
+       .enable = _clk_pll1_enable,
+       .disable = _clk_pll1_disable,
 };
 
 static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
@@ -545,7 +566,6 @@ static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
                        reg = __raw_readl(MXC_CCM_CCSR);
                        reg |= MXC_CCM_CCSR_STEP_SEL;
                        __raw_writel(reg, MXC_CCM_CCSR);
-
                }
                reg = __raw_readl(MXC_CCM_CCSR);
                reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
@@ -610,13 +630,19 @@ static struct clk pll2_528_bus_main_clk = {
        .disable = _clk_pll_disable,
 };
 
+static void _clk_pll2_pfd_400M_disable(struct clk *clk)
+{
+       if (!arm_needs_pll2_400)
+               _clk_pfd_disable(clk);
+}
+
 static struct clk pll2_pfd_400M = {
        __INIT_CLK_DEBUG(pll2_pfd_400M)
        .parent = &pll2_528_bus_main_clk,
        .enable_reg = (void *)PFD_528_BASE_ADDR,
        .enable_shift = ANADIG_PFD2_FRAC_OFFSET,
        .enable = _clk_pfd_enable,
-       .disable = _clk_pfd_disable,
+       .disable = _clk_pll2_pfd_400M_disable,
        .get_rate = pfd_get_rate,
        .set_rate = pfd_set_rate,
        .get_rate = pfd_get_rate,
@@ -1152,8 +1178,8 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
 {
        int i;
        u32 div;
-       u32 parent_rate;
-
+       unsigned long parent_rate;
+       unsigned long flags;
 
        for (i = 0; i < cpu_op_nr; i++) {
                if (rate == cpu_op_tbl[i].cpu_rate)
@@ -1162,30 +1188,67 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
        if (i >= cpu_op_nr)
                return -EINVAL;
 
-       if (cpu_op_tbl[i].pll_rate != clk_get_rate(&pll1_sys_main_clk)) {
-               /* Change the PLL1 rate. */
-               if (pll2_pfd_400M.usecount != 0)
+       spin_lock_irqsave(&clk_lock, flags);
+
+       if (rate <= clk_get_rate(&pll2_pfd_400M)) {
+               /* Source pll1_sw_clk from step_clk which is sourced from
+                 * PLL2_PFD_400M.
+                 */
+               if (pll1_sw_clk.parent != &pll2_pfd_400M) {
+                       pll2_pfd_400M.enable(&pll2_pfd_400M);
+                       arm_needs_pll2_400 = true;
                        pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd_400M);
-               else
-                       pll1_sw_clk.set_parent(&pll1_sw_clk, &osc_clk);
-               pll1_sys_main_clk.set_rate(&pll1_sys_main_clk, cpu_op_tbl[i].pll_rate);
-               pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk);
+                       pll1_sw_clk.parent = &pll2_pfd_400M;
+               }
+       } else {
+               if (pll1_sw_clk.parent != &pll1_sys_main_clk) {
+                       /* pll1_sw_clk was being sourced from pll2_400M. */
+                       /* Enable PLL1 and set pll1_sw_clk parent as PLL1 */
+                       if (!pll1_enabled)
+                               pll1_sys_main_clk.enable(&pll1_sys_main_clk);
+                       pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk);
+                       pll1_sw_clk.parent = &pll1_sys_main_clk;
+                       arm_needs_pll2_400 = false;
+                       if (pll2_pfd_400M.usecount == 0)
+                               pll2_pfd_400M.disable(&pll2_pfd_400M);
+               }
+               if (cpu_op_tbl[i].pll_rate != clk_get_rate(&pll1_sys_main_clk)) {
+                       /* Change the PLL1 rate. */
+                       if (pll2_pfd_400M.usecount != 0)
+                               pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd_400M);
+                       else
+                               pll1_sw_clk.set_parent(&pll1_sw_clk, &osc_clk);
+                       pll1_sys_main_clk.set_rate(&pll1_sys_main_clk, cpu_op_tbl[i].pll_rate);
+                       pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk);
+               }
        }
-
        parent_rate = clk_get_rate(clk->parent);
        div = parent_rate / rate;
-
        if (div == 0)
                div = 1;
 
        if ((parent_rate / div) > rate)
                div++;
 
-       if (div > 8)
+       if (div > 8) {
+               spin_unlock_irqrestore(&clk_lock, flags);
                return -1;
+       }
+
+       /* Need PLL1-MAIN to be ON to write to ARM-PODF bit. */
+       if (!pll1_enabled)
+               pll1_sys_main_clk.enable(&pll1_sys_main_clk);
 
        __raw_writel(div - 1, MXC_CCM_CACRR);
 
+       while (__raw_readl(MXC_CCM_CDHIPR))
+               ;
+
+       if (pll1_sys_main_clk.usecount == 1 && arm_needs_pll2_400)
+               pll1_sys_main_clk.disable(&pll1_sys_main_clk);
+
+       spin_unlock_irqrestore(&clk_lock, flags);
+
        return 0;
 }
 
@@ -1871,7 +1934,6 @@ static struct clk gpt_clk[] = {
         .enable = _clk_enable,
         .disable = _clk_disable,
         .get_rate = _clk_gpt_get_rate,
-        .secondary = &gpt_clk[1],
         },
        {
        __INIT_CLK_DEBUG(gpt_serial_clk)
@@ -2007,6 +2069,7 @@ static struct clk vpu_clk[] = {
        .set_rate = _clk_vpu_axi_set_rate,
        .get_rate = _clk_vpu_axi_get_rate,
        .secondary = &vpu_clk[1],
+       .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
        },
        {
        .parent =  &mmdc_ch0_axi_clk[0],
@@ -2016,7 +2079,6 @@ static struct clk vpu_clk[] = {
        .parent =  &mx6fast1_clk,
        .secondary = &ocram_clk,
        },
-
 };
 
 static int _clk_ipu1_set_parent(struct clk *clk, struct clk *parent)
@@ -2097,7 +2159,7 @@ static struct clk ipu1_clk = {
        .round_rate = _clk_ipu_round_rate,
        .set_rate = _clk_ipu1_set_rate,
        .get_rate = _clk_ipu1_get_rate,
-       .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+       .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
 };
 
 static int _clk_ipu2_set_parent(struct clk *clk, struct clk *parent)
@@ -2158,7 +2220,7 @@ static struct clk ipu2_clk = {
        .round_rate = _clk_ipu_round_rate,
        .set_rate = _clk_ipu2_set_rate,
        .get_rate = _clk_ipu2_get_rate,
-       .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+       .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
 };
 
 static struct clk usdhc_dep_clk = {
@@ -2729,7 +2791,7 @@ static struct clk ldb_di0_clk = {
        .set_rate = _clk_ldb_di0_set_rate,
        .round_rate = _clk_ldb_di_round_rate,
        .get_rate = _clk_ldb_di0_get_rate,
-       .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+       .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
 };
 
 static unsigned long _clk_ldb_di1_get_rate(struct clk *clk)
@@ -2796,7 +2858,7 @@ static struct clk ldb_di1_clk = {
        .set_rate = _clk_ldb_di1_set_rate,
        .round_rate = _clk_ldb_di_round_rate,
        .get_rate = _clk_ldb_di1_get_rate,
-       .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+       .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
 };
 
 
@@ -2989,7 +3051,7 @@ static struct clk ipu1_di_clk[] = {
        .set_rate = _clk_ipu1_di0_set_rate,
        .round_rate = _clk_ipu_di_round_rate,
        .get_rate = _clk_ipu1_di0_get_rate,
-       .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+       .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
        },
        {
         __INIT_CLK_DEBUG(ipu1_di_clk_1)
@@ -3003,7 +3065,7 @@ static struct clk ipu1_di_clk[] = {
        .set_rate = _clk_ipu1_di1_set_rate,
        .round_rate = _clk_ipu_di_round_rate,
        .get_rate = _clk_ipu1_di1_get_rate,
-       .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+       .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
        },
 };
 
@@ -3166,7 +3228,7 @@ static struct clk ipu2_di_clk[] = {
        .set_rate = _clk_ipu2_di0_set_rate,
        .round_rate = _clk_ipu_di_round_rate,
        .get_rate = _clk_ipu2_di0_get_rate,
-       .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+       .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
        },
        {
         __INIT_CLK_DEBUG(ipu2_di_clk_1)
@@ -3180,7 +3242,7 @@ static struct clk ipu2_di_clk[] = {
        .set_rate = _clk_ipu2_di1_set_rate,
        .round_rate = _clk_ipu_di_round_rate,
        .get_rate = _clk_ipu2_di1_get_rate,
-       .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+       .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
        },
 };
 
@@ -4254,9 +4316,9 @@ static struct clk gpu3d_core_clk[] = {
        __INIT_CLK_DEBUG(gpu3d_core_clk)
        .parent = &pll2_pfd_594M,
        .enable = _clk_enable,
+       .disable = _clk_disable,
        .enable_reg = MXC_CCM_CCGR1,
        .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
-       .disable = _clk_disable,
        .set_parent = _clk_gpu3d_core_set_parent,
        .set_rate = _clk_gpu3d_core_set_rate,
        .get_rate = _clk_gpu3d_core_get_rate,
@@ -4656,7 +4718,7 @@ static struct clk usboh3_clk[] = {
        .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
        .disable = _clk_disable,
        .secondary = &usboh3_clk[1],
-       .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+       .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
        },
        {
        .parent = &mmdc_ch0_axi_clk[0],
@@ -5084,6 +5146,7 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
        unsigned long ckih1, unsigned long ckih2)
 {
        __iomem void *base;
+       unsigned int reg;
        int i;
 
        external_low_reference = ckil;
@@ -5201,9 +5264,9 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
                     3 << MXC_CCM_CCGRx_CG9_OFFSET |
                     3 << MXC_CCM_CCGRx_CG8_OFFSET, MXC_CCM_CCGR2);
        __raw_writel(1 << MXC_CCM_CCGRx_CG14_OFFSET |
-                    3 << MXC_CCM_CCGRx_CG13_OFFSET |
+                    1 << MXC_CCM_CCGRx_CG13_OFFSET |
                     3 << MXC_CCM_CCGRx_CG12_OFFSET |
-                    3 << MXC_CCM_CCGRx_CG11_OFFSET |
+                    1 << MXC_CCM_CCGRx_CG11_OFFSET |
                     3 << MXC_CCM_CCGRx_CG10_OFFSET, MXC_CCM_CCGR3);
        __raw_writel(3 << MXC_CCM_CCGRx_CG7_OFFSET |
                        1 << MXC_CCM_CCGRx_CG6_OFFSET |
index 4fe3086dd7ccc50471ddd21290daf818669a060e..80b5e055d0898b0234fd6e0c65306c70993aaa27 100644 (file)
@@ -40,14 +40,14 @@ static struct cpu_op mx6_cpu_op_1_2G[] = {
         .cpu_rate = 672000000,
         .cpu_voltage = 1100000,},
         {
-         .pll_rate = 792000000,
+         .pll_rate = 396000000,
          .cpu_rate = 396000000,
-         .cpu_podf = 1,
+         .cpu_podf = 0,
          .cpu_voltage = 950000,},
        {
-        .pll_rate = 792000000,
+        .pll_rate = 396000000,
         .cpu_rate = 198000000,
-        .cpu_podf = 3,
+        .cpu_podf = 1,
         .cpu_voltage = 850000,},
 };
 
@@ -68,14 +68,14 @@ static struct cpu_op mx6_cpu_op_1G[] = {
         .cpu_rate = 672000000,
         .cpu_voltage = 1100000,},
         {
-         .pll_rate = 792000000,
+         .pll_rate = 396000000,
          .cpu_rate = 396000000,
-         .cpu_podf = 1,
+         .cpu_podf = 0,
          .cpu_voltage = 950000,},
        {
-        .pll_rate = 792000000,
+        .pll_rate = 396000000,
         .cpu_rate = 198000000,
-        .cpu_podf = 3,
+        .cpu_podf = 1,
         .cpu_voltage = 850000,},
 };
 
@@ -86,14 +86,14 @@ static struct cpu_op mx6_cpu_op[] = {
         .cpu_podf = 0,
         .cpu_voltage = 1100000,},
         {
-         .pll_rate = 792000000,
+         .pll_rate = 396000000,
          .cpu_rate = 396000000,
-         .cpu_podf = 1,
+         .cpu_podf = 0,
          .cpu_voltage = 950000,},
        {
-        .pll_rate = 792000000,
+        .pll_rate = 396000000,
         .cpu_rate = 198000000,
-        .cpu_podf = 3,
+        .cpu_podf = 1,
         .cpu_voltage = 850000,},
 };
 
@@ -110,14 +110,14 @@ static struct cpu_op mx6dl_cpu_op_1_2G[] = {
         .cpu_podf = 0,
         .cpu_voltage = 1100000,},
         {
-         .pll_rate = 792000000,
+         .pll_rate = 396000000,
          .cpu_rate = 396000000,
-         .cpu_podf = 1,
+         .cpu_podf = 0,
          .cpu_voltage = 1000000,},
        {
-        .pll_rate = 792000000,
+        .pll_rate = 396000000,
         .cpu_rate = 198000000,
-        .cpu_podf = 3,
+        .cpu_podf = 1,
         .cpu_voltage = 1000000,},
 };
 /* working point(wp): 0 - 1GHz; 1 - 800MHz, 2 - 400MHz, 3  - 200MHz */
@@ -133,14 +133,14 @@ static struct cpu_op mx6dl_cpu_op_1G[] = {
         .cpu_podf = 0,
         .cpu_voltage = 1100000,},
         {
-         .pll_rate = 792000000,
+         .pll_rate = 396000000,
          .cpu_rate = 396000000,
-         .cpu_podf = 1,
+         .cpu_podf = 0,
          .cpu_voltage = 1000000,},
        {
-        .pll_rate = 792000000,
+        .pll_rate = 396000000,
         .cpu_rate = 198000000,
-        .cpu_podf = 3,
+        .cpu_podf = 1,
         .cpu_voltage = 1000000,},
 };
 
@@ -151,35 +151,35 @@ static struct cpu_op mx6dl_cpu_op[] = {
         .cpu_podf = 0,
         .cpu_voltage = 1100000,},
         {
-         .pll_rate = 792000000,
+         .pll_rate = 396000000,
          .cpu_rate = 396000000,
-         .cpu_podf = 1,
+         .cpu_podf = 0,
          .cpu_voltage = 1000000,},
        {
-        .pll_rate = 792000000,
+        .pll_rate = 396000000,
         .cpu_rate = 198000000,
-        .cpu_podf = 3,
+        .cpu_podf = 1,
         .cpu_voltage = 1000000,},
 };
 
 static struct dvfs_op dvfs_core_setpoint_1_2G[] = {
        {33, 14, 33, 10, 128, 0x10},     /* 1.2GHz*/
        {30, 12, 33, 100, 200, 0x10},   /* 800MHz */
-       {28, 12, 33, 100, 200, 0x10},   /* 624MHz */
+       {28, 12, 33, 100, 200, 0x10},   /* 672MHz */
        {26, 8, 33, 100, 200, 0x10},   /* 400MHz */
        {20, 0, 33, 20, 10, 0x10} };   /* 200MHz*/
 
 static struct dvfs_op dvfs_core_setpoint_1G[] = {
        {33, 14, 33, 10, 128, 0x10}, /* 1GHz*/
        {30, 12, 33, 100, 200, 0x10},   /* 800MHz */
-       {28, 12, 33, 100, 200, 0x10},   /* 624MHz */
+       {28, 12, 33, 100, 200, 0x10},   /* 672MHz */
        {26, 8, 33, 100, 200, 0x10},   /* 400MHz */
        {20, 0, 33, 20, 10, 0x10} };   /* 200MHz*/
 
 static struct dvfs_op dvfs_core_setpoint[] = {
        {33, 14, 33, 10, 128, 0x08},   /* 800MHz */
        {26, 8, 33, 100, 200, 0x08},   /* 400MHz */
-       {20, 0, 33, 20, 10, 0x08} };   /* 200MHz*/
+       {20, 0, 33, 100, 10, 0x08} };   /* 200MHz*/
 
 static struct dvfs_op *mx6_get_dvfs_core_table(int *wp)
 {