summaryrefslogtreecommitdiff
path: root/arch/arm/mach-mx37
diff options
context:
space:
mode:
authorRanjani Vaidyanathan-RA5478 <Ranjani.Vaidyanathan@freescale.com>2009-11-29 10:09:37 -0600
committerAlejandro Gonzalez <alex.gonzalez@digi.com>2010-02-12 17:19:41 +0100
commit66569dabd047718edd6ec5e02e6624e9d258cd40 (patch)
treea08e99afc9e416d4bbc0d505d9f27f9ce60bfcc4 /arch/arm/mach-mx37
parent8acdd3ce83b6f6817eff256a3fbe75f2413af6d5 (diff)
ENGR00088305: Add DVFS-PER support
Added support for DVFS-PER for both MX37 and MX51. Signed-off-by: Ranjani Vaidyanathan-RA5478 <Ranjani.Vaidyanathan@freescale.com>
Diffstat (limited to 'arch/arm/mach-mx37')
-rw-r--r--arch/arm/mach-mx37/board-mx37_3stack.h1
-rw-r--r--arch/arm/mach-mx37/bus_freq.c17
-rw-r--r--arch/arm/mach-mx37/clock.c16
-rw-r--r--arch/arm/mach-mx37/crm_regs.h7
-rw-r--r--arch/arm/mach-mx37/devices.c62
-rw-r--r--arch/arm/mach-mx37/mx37_3stack.c8
6 files changed, 96 insertions, 15 deletions
diff --git a/arch/arm/mach-mx37/board-mx37_3stack.h b/arch/arm/mach-mx37/board-mx37_3stack.h
index 82eee4d47476..ba7eaa51a5c2 100644
--- a/arch/arm/mach-mx37/board-mx37_3stack.h
+++ b/arch/arm/mach-mx37/board-mx37_3stack.h
@@ -110,6 +110,7 @@ extern struct tve_platform_data tve_data;
extern struct mxc_dptc_data dptc_lp_data;
extern struct mxc_dptc_data dptc_gp_data;
extern struct mxc_dvfs_platform_data dvfs_core_data;
+extern struct mxc_dvfsper_data dvfs_per_data;
extern char *gp_reg_id;
extern char *lp_reg_id;
diff --git a/arch/arm/mach-mx37/bus_freq.c b/arch/arm/mach-mx37/bus_freq.c
index 302f59a17881..465055fb5cdf 100644
--- a/arch/arm/mach-mx37/bus_freq.c
+++ b/arch/arm/mach-mx37/bus_freq.c
@@ -70,6 +70,8 @@ char *gp_reg_id = "SW1";
char *lp_reg_id = "SW2";
static struct cpu_wp *cpu_wp_tbl;
static int busfreq_suspended;
+/* True if bus_frequency is scaled not using DVFS-PER */
+int bus_freq_scaling_is_active;
struct dvfs_wp dvfs_core_setpoint[] = {
{33, 8, 33, 10, 10, 0x08},
@@ -81,25 +83,22 @@ int set_low_bus_freq(void)
{
int ret = 0;
unsigned long flags;
- int reg;
unsigned long lp_lpm_clk;
if (busfreq_suspended)
return ret;
- spin_lock_irqsave(&bus_freq_lock, flags);
-
if (low_bus_freq_mode || (clk_get_rate(cpu_clk) != GP_LPAPM_FREQ)) {
- spin_unlock_irqrestore(&bus_freq_lock, flags);
return ret;
}
- if (clk_get_rate(cpu_clk) != GP_LPAPM_FREQ)
- return ret;
+ stop_dvfs_per();
+
+ spin_lock_irqsave(&bus_freq_lock, flags);
lp_lpm_clk = clk_get_rate(periph_apm_clk) / 8;
- /* Set the parent of peripheral_apm_clk to be lpapm */
+ /* Set the parent of peripheral_apm_clk to be pll1 */
clk_set_parent(periph_apm_clk, pll1);
/* Set the LP clocks */
clk_set_parent(main_bus_clk, periph_apm_clk);
@@ -137,6 +136,9 @@ int set_high_bus_freq(int high_bus_freq)
if (!low_bus_freq_mode)
return ret;
+ if (dvfs_per_active())
+ return ret;
+
/* Set the voltage to 1.25V for the LP domain. */
ret = regulator_set_voltage(lp_regulator, 1250000, 1250000);
udelay(100);
@@ -166,6 +168,7 @@ int set_high_bus_freq(int high_bus_freq)
spin_unlock_irqrestore(&bus_freq_lock, flags);
+ start_dvfs_per();
return ret;
}
diff --git a/arch/arm/mach-mx37/clock.c b/arch/arm/mach-mx37/clock.c
index b39b3c09e37c..014f268f2259 100644
--- a/arch/arm/mach-mx37/clock.c
+++ b/arch/arm/mach-mx37/clock.c
@@ -24,6 +24,7 @@
#include <mach/mxc_dptc.h>
#include <mach/spba.h>
#include <mach/mxc_uart.h>
+#include <mach/mxc_dvfs.h>
#include "crm_regs.h"
#include "iomux.h"
@@ -474,14 +475,25 @@ static struct clk periph_apm_clk = {
static void _clk_main_bus_recalc(struct clk *clk)
{
- clk->rate = clk->parent->rate;
+ u32 div;
+
+ if (dvfs_per_divider_active()) {
+ div = __raw_readl(MXC_CCM_CDCR)
+ & MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK;
+ clk->rate = clk->parent->rate/(div + 1);
+ } else
+ clk->rate = clk->parent->rate;
}
static int _clk_main_bus_set_rate(struct clk *clk, unsigned long rate)
{
u32 div = 0;
-
+ if (dvfs_per_divider_active()) {
+ div = __raw_readl(MXC_CCM_CDCR)
+ & MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK;
+ }
clk->rate = clk->parent->rate/(div + 1);
+
return 0;
}
static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
diff --git a/arch/arm/mach-mx37/crm_regs.h b/arch/arm/mach-mx37/crm_regs.h
index 345746a789f9..a03bc4e103f5 100644
--- a/arch/arm/mach-mx37/crm_regs.h
+++ b/arch/arm/mach-mx37/crm_regs.h
@@ -506,7 +506,7 @@
#define MXC_DPTC_LP_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x80)
#define MXC_DPTC_GP_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x100)
#define MXC_DVFS_CORE_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x180)
-#define MXC_DPTC_PER_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x1C0)
+#define MXC_DVFS_PER_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x1C4)
#define MXC_PGC_IPU_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x220)
#define MXC_PGC_VPU_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x240)
#define MXC_SRPGC_EMI_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x280)
@@ -527,7 +527,7 @@
/* GPC */
#define MXC_GPC_CNTR (MXC_GPC_BASE + 0x0)
#define MXC_GPC_PGR (MXC_GPC_BASE + 0x4)
-#define MXC_GPC_VCR (MXC_GPC_BASE + 0x8)
+#define MXC_GPC_VCR (MXC_GPC_BASE + 0x8)
/* DVFS CORE */
#define MXC_DVFSTHRS (MXC_DVFS_CORE_BASE + 0x00)
@@ -580,10 +580,9 @@
#define MXC_DPTCCR_VAI_MASK 0x00000006
#define MXC_DPTCCR_DEN 0x00000001
-#define MXC_GPCCNTR_GPCIRQ 0x00100000
#define MXC_GPCCNTR_DPTC0CR 0x00040000
#define MXC_GPCCNTR_DPTC1CR 0x00080000
-#define MXC_GPCCNTR_ADU 0x00008000
+#define MXC_GPCCNTR_GPCIRQ 0x00100000
/* SRPG */
#define MXC_SRPGC_EMI_SRPGCR (MXC_SRPGC_EMI_BASE + 0x0)
diff --git a/arch/arm/mach-mx37/devices.c b/arch/arm/mach-mx37/devices.c
index 596777d0bc6b..63cfeb21344b 100644
--- a/arch/arm/mach-mx37/devices.c
+++ b/arch/arm/mach-mx37/devices.c
@@ -646,7 +646,7 @@ static struct platform_device mxc_dvfs_core_device = {
.resource = dvfs_core_resources,
};
-static inline void mxc_init_dvfs(void)
+static inline void mxc_init_dvfs_core(void)
{
if (platform_device_register(&mxc_dvfs_core_device) < 0)
dev_err(&mxc_dvfs_core_device.dev,
@@ -919,6 +919,63 @@ static inline void mxc_init_busfreq(void)
(void)platform_device_register(&busfreq_device);
}
+/*!
+ * Resource definition for the DVFS PER
+ */
+static struct resource dvfs_per_resources[] = {
+ [0] = {
+ .start = DVFSPER_BASE_ADDR,
+ .end = DVFSPER_BASE_ADDR + 2 * SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_GPC1,
+ .end = MXC_INT_GPC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC DVFS Peripheral */
+struct mxc_dvfsper_data dvfs_per_data = {
+ .reg_id = "SW2",
+ .clk_id = "gpc_dvfs_clk",
+ .gpc_cntr_reg_addr = MXC_GPC_CNTR,
+ .gpc_vcr_reg_addr = MXC_GPC_VCR,
+ .gpc_adu = 0x0,
+ .vai_mask = MXC_DVFSPMCR0_FSVAI_MASK,
+ .vai_offset = MXC_DVFSPMCR0_FSVAI_OFFSET,
+ .dvfs_enable_bit = MXC_DVFSPMCR0_DVFEN,
+ .irq_mask = MXC_DVFSPMCR0_FSVAIM,
+ .div3_offset = 1,
+ .div3_mask = 0x3,
+ .div3_div = 3,
+ .lp_high = 1200000,
+ .lp_low = 1050000,
+};
+
+/*! Device Definition for MXC DVFS Peripheral */
+static struct platform_device mxc_dvfs_per_device = {
+ .name = "mxc_dvfsper",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &dvfs_per_data,
+ },
+ .num_resources = ARRAY_SIZE(dvfs_per_resources),
+ .resource = dvfs_per_resources,
+};
+
+static inline void mxc_init_dvfs_per(void)
+{
+ if (platform_device_register(&mxc_dvfs_per_device) < 0) {
+ dev_err(&mxc_dvfs_per_device.dev,
+ "Unable to register DVFS Peripheral device\n");
+ } else {
+ printk(KERN_INFO "mxc_init_dvfs_per initialised\n");
+ }
+ return;
+}
+
#if defined(CONFIG_HW_RANDOM_FSL_RNGC) || \
defined(CONFIG_HW_RANDOM_FSL_RNGC_MODULE)
static struct resource rngc_resources[] = {
@@ -1016,7 +1073,8 @@ int __init mxc_init_devices(void)
mxc_init_tve();
mx37_init_lpmode();
mxc_init_busfreq();
- mxc_init_dvfs();
+ mxc_init_dvfs_core();
+ mxc_init_dvfs_per();
mxc_init_dptc();
mxc_init_rngc();
mxc_init_iim();
diff --git a/arch/arm/mach-mx37/mx37_3stack.c b/arch/arm/mach-mx37/mx37_3stack.c
index acd36bc2cd9e..ce2ff2b47f8d 100644
--- a/arch/arm/mach-mx37/mx37_3stack.c
+++ b/arch/arm/mach-mx37/mx37_3stack.c
@@ -48,6 +48,7 @@
#include <mach/memory.h>
#include <mach/gpio.h>
#include <mach/mmc.h>
+#include <mach/mxc_dvfs.h>
#include "board-mx37_3stack.h"
#include "iomux.h"
#include "crm_regs.h"
@@ -867,6 +868,7 @@ static void mx37_3stack_fixup_for_board_v1(void)
lcd_data.core_reg = "LDO1";
lcd_data.io_reg = "DCDC6";
dvfs_core_data.reg_id = "DCDC1";
+ dvfs_per_data.reg_id = "DCDC4";
ls_data.vdd_reg = "DCDC3";
mxc_bt_data.bt_vdd = "DCDC3";
mxc_bt_data.bt_vusb = "DCDC6";
@@ -874,6 +876,12 @@ static void mx37_3stack_fixup_for_board_v1(void)
unifi_data.reg_1v5_ana_bb = NULL; /* VMAIN is used on v1 board */
unifi_data.reg_vdd_vpa = NULL;
unifi_data.reg_1v5_dd = NULL;
+ /*Set the CPU voltage to be higher for the lower setpoint
+ * When set to 0.85V, under certain situations, the voltage drops
+ * below 0.85V and the system hangs.
+ */
+ cpu_wp_auto[1].cpu_voltage = 925000;
+
#if defined(CONFIG_KEYBOARD_MPR084) || defined(CONFIG_KEYBOARD_MPR084_MODULE)
keypad_data.vdd_reg = "DCDC3";
#endif