summaryrefslogtreecommitdiff
path: root/arch/arm/mach-mx3/dvfs.c
diff options
context:
space:
mode:
authorQuinn Jensen <quinn.jensen@freescale.com>2007-05-24 18:04:50 -0600
committerQuinn Jensen <quinn.jensen@freescale.com>2007-05-24 18:04:50 -0600
commit6280b6d6d53c4c12298a322be64586fb62257240 (patch)
treebc9d02e93219dc1e993c64a429bbb34403e3477a /arch/arm/mach-mx3/dvfs.c
parentabcf741d99ebdf68cd8eb1903e1bf8aa9d81c691 (diff)
CR TLSbo91040: Add 4 step DVFS support for MX31 Rev 2
http://www.bitshrine.org/gpp/linux-2.6.19.2-mx-mx31_4_step_dvfs_support.patch
Diffstat (limited to 'arch/arm/mach-mx3/dvfs.c')
-rw-r--r--arch/arm/mach-mx3/dvfs.c62
1 files changed, 50 insertions, 12 deletions
diff --git a/arch/arm/mach-mx3/dvfs.c b/arch/arm/mach-mx3/dvfs.c
index de3aa50e8498..ad8d95c5490a 100644
--- a/arch/arm/mach-mx3/dvfs.c
+++ b/arch/arm/mach-mx3/dvfs.c
@@ -45,6 +45,8 @@
#include <asm/semaphore.h>
#include <linux/jiffies.h>
#include <linux/device.h>
+#include <linux/delay.h>
+#include <asm/arch/clock.h>
#include <asm/arch/gpio.h>
#include <asm/arch/sdma.h>
#include <linux/dma-mapping.h>
@@ -97,6 +99,21 @@ pmcr0 = ((pmcr0 & ~MXC_CCM_PMCR0_DFSUP1) | x << MXC_CCM_PMCR0_DFSUP1_OFFSET)
#define SET_VSCNT(pmcr0, x) \
pmcr0 = ((pmcr0 & ~MXC_CCM_PMCR0_VSCNT_MASK) | x << MXC_CCM_PMCR0_VSCNT_OFFSET)
+/*
+ * Clear DPVCR bit
+ */
+#define CLEAR_DPVCR(pmcr0) pmcr0 &= ~MXC_CCM_PMCR0_DPVCR
+
+/*
+ * Set DPVCR bit
+ */
+#define SET_DPVCR(pmcr0) pmcr0 |= MXC_CCM_PMCR0_DPVCR
+
+/*
+ * Set DPVCR bit
+ */
+#define SET_DPVV(pmcr0) pmcr0 |= MXC_CCM_PMCR0_DPVV
+
dvfs_states_table *dvfs_states_tbl;
/*!
@@ -500,6 +517,21 @@ int __init init_dvfs_controller(dvfs_dptc_params_s * params)
dvfs_dptc_params = params;
+ if (system_rev >= CHIP_REV_2_0) {
+ /* Rev2.0 changes */
+
+ /* Disable PLL restart on DVFS switch */
+ mxc_ccm_modify_reg(MXC_CCM_PMCR1, MXC_CCM_PMCR1_PLLRDIS,
+ MXC_CCM_PMCR1_PLLRDIS);
+
+ /* Enable automatic EMI handshake */
+ mxc_ccm_modify_reg(MXC_CCM_PMCR1, MXC_CCM_PMCR1_EMIRQ_EN,
+ MXC_CCM_PMCR1_EMIRQ_EN);
+
+ /* Init SR PLL for 399MHz */
+ mxc_ccm_modify_reg(MXC_CCM_SRPCTL, 0xffffffff, 0x00331c23);
+ }
+
if (res == 0) {
printk(KERN_INFO "DVFS controller initialized\n");
}
@@ -536,21 +568,17 @@ void dvfs_update_freqs_table(dvfs_dptc_tables_s * dvfs_dptc_tables_ptr)
pll = table[0].pll_up;
pdr0 = table[0].pdr0_up;
freq = dvfs_get_clock(table[0].pll_up, table[0].pdr0_up);
- dvfs_states_tbl->freqs[0] = 1000000 * (freq / 1000000);
+ dvfs_states_tbl->freqs[0] = freq;
for (i = 0; i < dvfs_dptc_tables_ptr->dvfs_state_num - 1; i++) {
+
if (table[i].pll_sw_down == 1) {
pll = table[i].pll_down;
}
pdr0 = table[i].pdr0_down;
freq = dvfs_get_clock(pll, pdr0);
- dvfs_states_tbl->freqs[i + 1] = 1000000 * (freq / 1000000);
- }
-
- for (i = 0; i < dvfs_dptc_tables_ptr->dvfs_state_num; i++) {
- printk(KERN_INFO "DVFS frequency #%d: %d\n", i,
- dvfs_states_tbl->freqs[i]);
+ dvfs_states_tbl->freqs[i + 1] = freq;
}
}
@@ -642,8 +670,10 @@ void set_freq(dvfs_dptc_params_s * params, int fsvai)
int dfsup0, dfsup1;
dvfs_state *table;
unsigned long pmcr0;
+ int dptc_enable = 0;
pmcr0 = mxc_ccm_get_reg(MXC_CCM_PMCR0);
+ dptc_enable = pmcr0 & MXC_CCM_PMCR0_DPTEN;
/* Read DVSUP - current frequency index */
dvsup = dvfs_get_dvsup();
@@ -655,16 +685,15 @@ void set_freq(dvfs_dptc_params_s * params, int fsvai)
table = sdma_phys_to_virt((unsigned long)table);
#endif
+ if (dptc_enable) {
+ CLEAR_DPVCR(pmcr0);
+ }
if (fsvai == DVFS_DECREASE) {
/* On DVFS_DECREASE event the frequency will be changed according
* to the next state setting
*/
CLEAR_UDSC(pmcr0);
- if (params->dvfs_dptc_tables_ptr->use_four_freq) {
- dvsup++;
- } else {
- dvsup = 0x3;
- }
+ dvsup++;
SET_VSCNT(pmcr0, 1);
pll_switch = table[curr_freq_index].pll_sw_down;
pdr0 = table[curr_freq_index].pdr0_down;
@@ -706,6 +735,8 @@ void set_freq(dvfs_dptc_params_s * params, int fsvai)
SET_DFSUP1(pmcr0, dfsup1);
mxc_ccm_modify_reg(MXC_CCM_PMCR0, 0xffffffff, pmcr0);
+ /* software wait for voltage ramp-up */
+ udelay(100);
mxc_ccm_modify_reg(MXC_CCM_PDR0, 0xffffffff, pdr0);
if (pll_switch == 1) {
@@ -718,6 +749,13 @@ void set_freq(dvfs_dptc_params_s * params, int fsvai)
}
}
+ if (dptc_enable) {
+ pmcr0 = mxc_ccm_get_reg(MXC_CCM_PMCR0);
+ SET_DPVCR(pmcr0);
+ SET_DPVV(pmcr0);
+ mxc_ccm_modify_reg(MXC_CCM_PMCR0, 0xffffffff, pmcr0);
+ }
+
pr_debug(KERN_INFO "ARM frequency: %dMHz CKIH frequency: %dMHz(%d)\n",
(int)mxc_get_clocks(CPU_CLK) / 1000000,
(int)mxc_get_clocks(CKIH_CLK) / 1000000, (int)jiffies);