diff options
author | Ranjani Vaidyanathan-RA5478 <Ranjani.Vaidyanathan@freescale.com> | 2009-11-29 10:09:37 -0600 |
---|---|---|
committer | Alejandro Gonzalez <alex.gonzalez@digi.com> | 2010-02-12 17:19:41 +0100 |
commit | 66569dabd047718edd6ec5e02e6624e9d258cd40 (patch) | |
tree | a08e99afc9e416d4bbc0d505d9f27f9ce60bfcc4 /arch/arm/mach-mx37 | |
parent | 8acdd3ce83b6f6817eff256a3fbe75f2413af6d5 (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.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-mx37/bus_freq.c | 17 | ||||
-rw-r--r-- | arch/arm/mach-mx37/clock.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-mx37/crm_regs.h | 7 | ||||
-rw-r--r-- | arch/arm/mach-mx37/devices.c | 62 | ||||
-rw-r--r-- | arch/arm/mach-mx37/mx37_3stack.c | 8 |
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 |