summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShen Yong <b00984@freescale.com>2010-06-28 13:14:22 +0800
committerJustin Waters <justin.waters@timesys.com>2010-12-17 12:10:50 -0500
commit529cc4441f785e43baa72e41634e6f3e21ac1c1d (patch)
treef42b91d3f7139dc605ab794bf771a8a1227f0488
parent3879e4dc9d7034c37ea17331f74fc14d94da0a08 (diff)
ENGR00124132 MX53: busfreq driver support
1. adjust lp_clk, ddr_clk MX53 and MX51 uses different one 2. adjust cpu rate in cpu_wp_table 3. enable clock divider handshaking when ddr clock changing 4. add AHB_MED_SET_POINT to ldb_di_clk 5. adjust the bit define about CCDR register Signed-off-by: Shen Yong <b00984@freescale.com>
-rw-r--r--arch/arm/mach-mx5/bus_freq.c75
-rw-r--r--arch/arm/mach-mx5/clock.c16
-rw-r--r--arch/arm/mach-mx5/mx53_evk.c3
3 files changed, 69 insertions, 25 deletions
diff --git a/arch/arm/mach-mx5/bus_freq.c b/arch/arm/mach-mx5/bus_freq.c
index ce5faad029e2..4fcaf95e3019 100644
--- a/arch/arm/mach-mx5/bus_freq.c
+++ b/arch/arm/mach-mx5/bus_freq.c
@@ -33,12 +33,8 @@
#include <mach/sdram_autogating.h>
#include "crm_regs.h"
-#define LP_NORMAL_CLK 133000000
-#define LP_MED_CLK 83125000
#define LP_APM_CLK 24000000
#define NAND_LP_APM_CLK 12000000
-#define DDR_LOW_FREQ_CLK 133000000
-#define DDR_NORMAL_CLK 200000000
#define AXI_A_NORMAL_CLK 166250000
#define AXI_A_CLK_NORMAL_DIV 4
#define AXI_B_CLK_NORMAL_DIV 5
@@ -46,7 +42,13 @@
#define EMI_SLOW_CLK_NORMAL_DIV AXI_B_CLK_NORMAL_DIV
#define NFC_CLK_NORMAL_DIV 4
+static unsigned long lp_normal_rate;
+static unsigned long lp_med_rate;
+static unsigned long ddr_normal_rate;
+static unsigned long ddr_low_rate;
+
static struct clk *ddr_clk;
+static struct clk *pll1_sw_clk;
static struct clk *pll2;
static struct clk *pll3;
static struct clk *main_bus_clk;
@@ -93,7 +95,6 @@ struct dvfs_wp dvfs_core_setpoint[] = {
{28, 8, 33, 20, 30, 0x08},
{29, 0, 33, 20, 10, 0x08},};
-
int set_low_bus_freq(void)
{
u32 reg;
@@ -102,15 +103,20 @@ int set_low_bus_freq(void)
return 0;
if (bus_freq_scaling_initialized) {
+ /* can not enter low bus freq, when cpu is in highest freq */
if (clk_get_rate(cpu_clk) != cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate)
return 0;
+ /* currently not support on mx53 */
+ if (cpu_is_mx53())
+ return 0;
+
stop_dvfs_per();
stop_sdram_autogating();
/*Change the DDR freq to 133Mhz. */
clk_set_rate(ddr_hf_clk,
- clk_round_rate(ddr_hf_clk, DDR_LOW_FREQ_CLK));
+ clk_round_rate(ddr_hf_clk, ddr_low_rate));
/* Set PLL3 to 133Mhz if no-one is using it. */
if (clk_get_usecount(pll3) == 0) {
@@ -163,6 +169,7 @@ int set_high_bus_freq(int high_bus_freq)
u32 reg;
if (bus_freq_scaling_initialized) {
+
stop_sdram_autogating();
if (low_bus_freq_mode) {
@@ -207,7 +214,8 @@ int set_high_bus_freq(int high_bus_freq)
/*Change the DDR freq to 200MHz*/
clk_set_rate(ddr_hf_clk,
- clk_round_rate(ddr_hf_clk, DDR_NORMAL_CLK));
+ clk_round_rate(ddr_hf_clk, ddr_normal_rate));
+
start_dvfs_per();
}
if (bus_freq_scaling_is_active) {
@@ -219,24 +227,28 @@ int set_high_bus_freq(int high_bus_freq)
cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate)
high_bus_freq = 1;
- if (((clk_get_rate(ahb_clk) == LP_MED_CLK)
+ if (((clk_get_rate(ahb_clk) == lp_med_rate)
&& lp_high_freq) || high_bus_freq) {
/* Set to the high setpoint. */
high_bus_freq_mode = 1;
+
clk_set_rate(ahb_clk,
- clk_round_rate(ahb_clk, LP_NORMAL_CLK));
+ clk_round_rate(ahb_clk, lp_normal_rate));
+
clk_set_rate(ddr_hf_clk,
- clk_round_rate(ddr_hf_clk, DDR_NORMAL_CLK));
+ clk_round_rate(ddr_hf_clk, ddr_normal_rate));
}
+
if (!lp_high_freq && !high_bus_freq) {
/* Set to the medium setpoint. */
high_bus_freq_mode = 0;
low_bus_freq_mode = 0;
+
clk_set_rate(ddr_hf_clk,
- clk_round_rate(ddr_hf_clk,
- DDR_LOW_FREQ_CLK));
+ clk_round_rate(ddr_hf_clk, ddr_low_rate));
+
clk_set_rate(ahb_clk,
- clk_round_rate(ahb_clk, LP_MED_CLK));
+ clk_round_rate(ahb_clk, lp_med_rate));
}
}
start_sdram_autogating();
@@ -289,6 +301,7 @@ static ssize_t bus_freq_scaling_enable_store(struct device *dev,
clk_set_parent(main_bus_clk, pll2);
bus_freq_scaling_is_active = 1;
+ set_high_bus_freq(0);
}
else if (strstr(buf, "0") != NULL) {
if (bus_freq_scaling_is_active)
@@ -326,6 +339,7 @@ static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show,
static int __devinit busfreq_probe(struct platform_device *pdev)
{
int err = 0;
+ unsigned long pll2_rate, pll1_rate;
busfreq_dev = &pdev->dev;
@@ -336,12 +350,41 @@ static int __devinit busfreq_probe(struct platform_device *pdev)
return PTR_ERR(main_bus_clk);
}
+ pll1_sw_clk = clk_get(NULL, "pll1_sw_clk");
+ if (IS_ERR(pll1_sw_clk)) {
+ printk(KERN_DEBUG "%s: failed to get pll1_sw_clk\n", __func__);
+ return PTR_ERR(pll1_sw_clk);
+ }
+
pll2 = clk_get(NULL, "pll2");
if (IS_ERR(pll2)) {
printk(KERN_DEBUG "%s: failed to get pll2\n", __func__);
return PTR_ERR(pll2);
}
+ pll1_rate = clk_get_rate(pll1_sw_clk);
+ pll2_rate = clk_get_rate(pll2);
+
+ if (pll2_rate == 665000000) {
+ /* for mx51 */
+ lp_normal_rate = pll2_rate / 5;
+ lp_med_rate = pll2_rate / 8;
+ ddr_normal_rate = pll1_rate / 4; /* 200M */
+ ddr_low_rate = pll1_rate / 6; /* 133M */
+ } else if (pll2_rate == 600000000) {
+ /* for mx53 evk rev.A */
+ lp_normal_rate = pll2_rate / 5;
+ lp_med_rate = pll2_rate / 8;
+ ddr_normal_rate = pll2_rate / 2;
+ ddr_low_rate = pll2_rate / 2;
+ } else if (pll2_rate == 400000000) {
+ /* for mx53 evk rev.B */
+ lp_normal_rate = pll2_rate / 3;
+ lp_med_rate = pll2_rate / 5;
+ ddr_normal_rate = pll2_rate / 1;
+ ddr_low_rate = pll2_rate / 3;
+ }
+
pll3 = clk_get(NULL, "pll3");
if (IS_ERR(pll3)) {
printk(KERN_DEBUG "%s: failed to get pll3\n", __func__);
@@ -362,7 +405,11 @@ static int __devinit busfreq_probe(struct platform_device *pdev)
return PTR_ERR(axi_b_clk);
}
- ddr_hf_clk = clk_get(NULL, "ddr_hf_clk");
+ if (cpu_is_mx51())
+ ddr_hf_clk = clk_get(NULL, "ddr_hf_clk");
+ else
+ ddr_hf_clk = clk_get(NULL, "axi_a_clk");
+
if (IS_ERR(ddr_hf_clk)) {
printk(KERN_DEBUG "%s: failed to get ddr_hf_clk\n",
__func__);
diff --git a/arch/arm/mach-mx5/clock.c b/arch/arm/mach-mx5/clock.c
index b1b2d5818f0a..bded58677bed 100644
--- a/arch/arm/mach-mx5/clock.c
+++ b/arch/arm/mach-mx5/clock.c
@@ -1411,7 +1411,10 @@ static int _clk_ipu_enable(struct clk *clk)
_clk_enable(clk);
/* Handshake with IPU when certain clock rates are changed. */
reg = __raw_readl(MXC_CCM_CCDR);
- reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
+ if (cpu_is_mx51())
+ reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
+ else
+ reg &= ~MXC_CCM_CCDR_IPU_HS_MX53_MASK;
__raw_writel(reg, MXC_CCM_CCDR);
/* Handshake with IPU when LPM is entered as its enabled. */
@@ -1717,7 +1720,7 @@ static struct clk ldb_di_clk[] = {
.set_rate = _clk_ldb_di_set_rate,
.enable = _clk_ldb_di_enable,
.disable = _clk_ldb_di_disable,
- .flags = RATE_PROPAGATES,
+ .flags = RATE_PROPAGATES | AHB_MED_SET_POINT,
},
{
.name = "ldb_di1_clk",
@@ -1731,7 +1734,7 @@ static struct clk ldb_di_clk[] = {
.set_rate = _clk_ldb_di_set_rate,
.enable = _clk_ldb_di_enable,
.disable = _clk_ldb_di_disable,
- .flags = RATE_PROPAGATES,
+ .flags = RATE_PROPAGATES | AHB_MED_SET_POINT,
},
};
@@ -4829,13 +4832,6 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, unsigned long
__raw_writel(reg, MXC_CCM_CLPCR);
#endif
- /* Disable the handshake with HSC block as its not
- * initialised right now.
- */
- reg = __raw_readl(MXC_CCM_CCDR);
- reg |= MXC_CCM_CCDR_EMI_HS_MASK;
- __raw_writel(reg, MXC_CCM_CCDR);
-
/* This will propagate to all children and init all the clock rates */
propagate_rate(&osc_clk);
propagate_rate(&ckih_clk);
diff --git a/arch/arm/mach-mx5/mx53_evk.c b/arch/arm/mach-mx5/mx53_evk.c
index cb0de8cfbbfc..e7bf88805d5f 100644
--- a/arch/arm/mach-mx5/mx53_evk.c
+++ b/arch/arm/mach-mx5/mx53_evk.c
@@ -98,7 +98,7 @@ static struct cpu_wp cpu_wp_auto[] = {
.cpu_voltage = 1050000,},
{
.pll_rate = 800000000,
- .cpu_rate = 166250000,
+ .cpu_rate = 160000000,
.pdf = 4,
.mfi = 8,
.mfd = 2,
@@ -974,6 +974,7 @@ static void __init mxc_board_init(void)
mxc_register_device(&sdram_autogating_device, NULL);
*/
mxc_register_device(&mxc_dvfs_core_device, &dvfs_core_data);
+ mxc_register_device(&busfreq_device, NULL);
/*
mxc_register_device(&mxc_dvfs_per_device, &dvfs_per_data);