summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorXinyu Chen <xinyu.chen@freescale.com>2012-05-10 16:28:20 +0800
committerXinyu Chen <xinyu.chen@freescale.com>2012-05-10 17:14:29 +0800
commite1dfe672764f5cdf6ed37a178aa62ffd042e6d62 (patch)
tree5574e107beba3a56eb20324072277463054c502e /arch
parent5a3f94f9b90aa263c9b3d2b745d7971a8b62788a (diff)
ENGR00182646-1 Merge "ARM_CLK to PLL2_400 when ARM freq is below 400MHz."
This reverts commit b49928de9c47839a681eae67513f37bc936372ea. Conflicts: arch/arm/mach-mx6/clock.c arch/arm/mach-mx6/cpu_op-mx6.c Signed-off-by: Xinyu Chen <xinyu.chen@freescale.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-mx6/clock.c108
-rw-r--r--arch/arm/mach-mx6/cpu_op-mx6.c54
2 files changed, 105 insertions, 57 deletions
diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c
index 12a8fcf8464c..76ad46a6dea6 100644
--- a/arch/arm/mach-mx6/clock.c
+++ b/arch/arm/mach-mx6/clock.c
@@ -53,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;
@@ -66,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
@@ -184,6 +190,7 @@ static void _clk_disable_inwait(struct clk *clk)
__raw_writel(reg, clk->enable_reg);
}
+
/*
* For the 4-to-1 muxed input clock
*/
@@ -509,8 +516,8 @@ static struct clk 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)
@@ -537,7 +544,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;
@@ -602,13 +608,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,
@@ -1144,8 +1156,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)
@@ -1154,30 +1166,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;
}
@@ -1863,7 +1912,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)
@@ -1999,6 +2047,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],
@@ -2008,7 +2057,6 @@ static struct clk vpu_clk[] = {
.parent = &mx6fast1_clk,
.secondary = &ocram_clk,
},
-
};
static int _clk_ipu1_set_parent(struct clk *clk, struct clk *parent)
@@ -2089,7 +2137,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)
@@ -2150,7 +2198,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 = {
@@ -2723,7 +2771,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)
@@ -2794,7 +2842,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,
};
@@ -2987,7 +3035,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)
@@ -3001,7 +3049,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,
},
};
@@ -3164,7 +3212,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)
@@ -3178,7 +3226,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,
},
};
@@ -4252,9 +4300,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,
@@ -4650,7 +4698,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],
@@ -5203,9 +5251,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 |
diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c
index 88d1d960c0f2..ac65b27888eb 100644
--- a/arch/arm/mach-mx6/cpu_op-mx6.c
+++ b/arch/arm/mach-mx6/cpu_op-mx6.c
@@ -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 = 1125000,},
{
- .pll_rate = 792000000,
+ .pll_rate = 396000000,
.cpu_rate = 396000000,
- .cpu_podf = 1,
+ .cpu_podf = 0,
.cpu_voltage = 1025000,},
{
- .pll_rate = 792000000,
+ .pll_rate = 396000000,
.cpu_rate = 198000000,
- .cpu_podf = 3,
+ .cpu_podf = 1,
.cpu_voltage = 1025000,},
};
@@ -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)
{