summaryrefslogtreecommitdiff
path: root/arch/arm/mach-mx6/clock.c
diff options
context:
space:
mode:
authorRanjani Vaidyanathan <ra5478@freescale.com>2012-02-07 14:34:13 -0600
committerJason Liu <r64343@freescale.com>2012-07-20 13:36:15 +0800
commite49e91034281133c9871a9fe6a1ed2864a947765 (patch)
tree3dab4075e6c6807d9cc2d03307ad4e77cf2d30d9 /arch/arm/mach-mx6/clock.c
parent6079ec044048b2f50f53a22c48df84e123d24535 (diff)
ENGR00179574: MX6- Add bus frequency scaling support
Add support for scaling the bus frequency (both DDR and ahb_clk). The DDR and AHB_CLK are dropped to 24MHz when all devices that need high AHB frequency are disabled and the CORE frequency is at the lowest setpoint. The DDR is dropped to 400MHz for the video playback usecase. In this mode the GPU, FEC, SATA etc are disabled. To scale the bus frequency, its necessary that all cores except the core that is executing the DDR frequency change are in WFE. This is achieved by generating interrupts on un-used interrupts (Int no 139, 144, 145 and 146). Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
Diffstat (limited to 'arch/arm/mach-mx6/clock.c')
-rw-r--r--arch/arm/mach-mx6/clock.c48
1 files changed, 30 insertions, 18 deletions
diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c
index 5372dace4d44..bd90ba897518 100644
--- a/arch/arm/mach-mx6/clock.c
+++ b/arch/arm/mach-mx6/clock.c
@@ -170,11 +170,6 @@ static int _clk_enable(struct clk *clk)
reg |= MXC_CCM_CCGRx_CG_MASK << clk->enable_shift;
__raw_writel(reg, clk->enable_reg);
- if (clk->flags & AHB_HIGH_SET_POINT)
- lp_high_freq++;
- else if (clk->flags & AHB_MED_SET_POINT)
- lp_med_freq++;
-
return 0;
}
@@ -184,11 +179,6 @@ static void _clk_disable(struct clk *clk)
reg = __raw_readl(clk->enable_reg);
reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
__raw_writel(reg, clk->enable_reg);
-
- if (clk->flags & AHB_HIGH_SET_POINT)
- lp_high_freq--;
- else if (clk->flags & AHB_MED_SET_POINT)
- lp_med_freq--;
}
static void _clk_disable_inwait(struct clk *clk)
@@ -2228,7 +2218,6 @@ static struct clk ipu2_clk = {
static struct clk usdhc_dep_clk = {
.parent = &mmdc_ch0_axi_clk[0],
.secondary = &mx6per1_clk,
- .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
};
static unsigned long _clk_usdhc_round_rate(struct clk *clk,
@@ -2306,7 +2295,6 @@ static struct clk usdhc1_clk = {
.round_rate = _clk_usdhc_round_rate,
.set_rate = _clk_usdhc1_set_rate,
.get_rate = _clk_usdhc1_get_rate,
- .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
};
static int _clk_usdhc2_set_parent(struct clk *clk, struct clk *parent)
@@ -2364,7 +2352,6 @@ static struct clk usdhc2_clk = {
.round_rate = _clk_usdhc_round_rate,
.set_rate = _clk_usdhc2_set_rate,
.get_rate = _clk_usdhc2_get_rate,
- .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
};
static int _clk_usdhc3_set_parent(struct clk *clk, struct clk *parent)
@@ -2423,7 +2410,6 @@ static struct clk usdhc3_clk = {
.round_rate = _clk_usdhc_round_rate,
.set_rate = _clk_usdhc3_set_rate,
.get_rate = _clk_usdhc3_get_rate,
- .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
};
static int _clk_usdhc4_set_parent(struct clk *clk, struct clk *parent)
@@ -2482,7 +2468,6 @@ static struct clk usdhc4_clk = {
.round_rate = _clk_usdhc_round_rate,
.set_rate = _clk_usdhc4_set_rate,
.get_rate = _clk_usdhc4_get_rate,
- .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
};
static unsigned long _clk_ssi_round_rate(struct clk *clk,
@@ -5144,7 +5129,7 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
unsigned long ckih1, unsigned long ckih2)
{
__iomem void *base;
- int i;
+ int i, reg;
external_low_reference = ckil;
external_high_reference = ckih1;
@@ -5278,8 +5263,8 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
__raw_writel(0, MXC_CCM_CCGR6);
- /* Lower the ipg_perclk frequency to 8.25MHz. */
- clk_set_rate(&ipg_perclk, 8250000);
+ /* Lower the ipg_perclk frequency to 6MHz. */
+ clk_set_rate(&ipg_perclk, 6000000);
/* S/PDIF */
clk_set_parent(&spdif0_clk[0], &pll3_pfd_454M);
@@ -5310,6 +5295,33 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
lp_high_freq = 0;
lp_med_freq = 0;
+ /* Turn OFF all unnecessary PHYs. */
+ /* Turn off SATA PHY. */
+ base = ioremap(MX6Q_SATA_BASE_ADDR, SZ_8K);
+ reg = __raw_readl(base + PORT_PHY_CTL);
+ __raw_writel(reg | PORT_PHY_CTL_PDDQ_LOC, base + PORT_PHY_CTL);
+
+ /* Turn off HDMI PHY. */
+ base = ioremap(MX6Q_HDMI_ARB_BASE_ADDR, SZ_128K);
+ reg = __raw_readb(base + HDMI_PHY_CONF0);
+ __raw_writeb(reg | HDMI_PHY_CONF0_GEN2_PDDQ_MASK, base + HDMI_PHY_CONF0);
+
+ reg = __raw_readb(base + HDMI_MC_PHYRSTZ);
+ __raw_writeb(reg | HDMI_MC_PHYRSTZ_DEASSERT, base + HDMI_MC_PHYRSTZ);
+
+ iounmap(base);
+
+ base = ioremap(MX6Q_IOMUXC_BASE_ADDR, SZ_4K);
+ /* Close PLL inside SATA PHY. */
+ reg = __raw_readl(base + 0x34);
+ __raw_writel(reg | (1 << 1), base + 0x34);
+
+ /* Close PCIE PHY. */
+ reg = __raw_readl(base + 0x04);
+ reg |= (1 << 18);
+ __raw_writel(reg, base + 0x04);
+ iounmap(base);
+
return 0;
}