diff options
author | Xinyu Chen <xinyu.chen@freescale.com> | 2012-08-13 10:55:02 +0800 |
---|---|---|
committer | Xinyu Chen <xinyu.chen@freescale.com> | 2012-08-13 10:55:02 +0800 |
commit | 67c5fc0f0214faea7186138245303a832ed825d5 (patch) | |
tree | 0df6922959ff8072edaca7876910b990aa953426 | |
parent | 14839768c2e0f5448f1767729a7fe5791cd4f3dd (diff) | |
parent | 1f4aead453351d7d9658f6ebb31f6deaea3262b6 (diff) |
Merge remote branch 'fsl-linux-sdk/imx_3.0.35' into imx_3.0.35_android
-rw-r--r-- | arch/arm/mach-mx6/bus_freq.c | 85 | ||||
-rw-r--r-- | arch/arm/mach-mx6/system.c | 60 | ||||
-rwxr-xr-x | arch/arm/plat-mxc/clock.c | 68 | ||||
-rwxr-xr-x | arch/arm/plat-mxc/cpufreq.c | 5 | ||||
-rwxr-xr-x | arch/arm/plat-mxc/dvfs_core.c | 16 | ||||
-rw-r--r-- | drivers/crypto/caam/ctrl.c | 10 | ||||
-rw-r--r-- | drivers/crypto/caam/intern.h | 3 | ||||
-rw-r--r-- | drivers/crypto/caam/regs.h | 1 |
8 files changed, 138 insertions, 110 deletions
diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index 5e9b6513992f..e147bc4068a4 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -81,7 +81,7 @@ extern int update_ddr_freq(int ddr_rate); extern int chip_rev; extern bool arm_mem_clked_in_wait; -struct mutex bus_freq_mutex; +DEFINE_MUTEX(bus_freq_mutex); struct timeval start_time; struct timeval end_time; @@ -113,21 +113,6 @@ static void reduce_bus_freq_handler(struct work_struct *work) if (audio_bus_freq_mode && lp_audio_freq) return; - while (!mutex_trylock(&bus_freq_mutex)) - msleep(1); - - /* PLL3 is used in the DDR freq change process, enable it. */ - - if (low_bus_freq_mode || !low_freq_bus_used()) { - mutex_unlock(&bus_freq_mutex); - return; - } - - if (audio_bus_freq_mode && lp_audio_freq) { - mutex_unlock(&bus_freq_mutex); - return; - } - if (!cpu_is_mx6sl()) { clk_enable(pll3); if (lp_audio_freq) { @@ -188,8 +173,6 @@ static void reduce_bus_freq_handler(struct work_struct *work) high_bus_freq_mode = 0; med_bus_freq_mode = 0; - - mutex_unlock(&bus_freq_mutex); } /* Set the DDR, AHB to 24MHz. * This mode will be activated only when none of the modules that @@ -235,15 +218,10 @@ int set_high_bus_freq(int high_bus_freq) if (cpu_is_mx6dl() && med_bus_freq_mode) return 0; - while (!mutex_trylock(&bus_freq_mutex)) - msleep(1); - if ((high_bus_freq_mode && (high_bus_freq || lp_high_freq)) || (med_bus_freq_mode && !high_bus_freq && lp_med_freq && - !lp_high_freq)) { - mutex_unlock(&bus_freq_mutex); + !lp_high_freq)) return 0; - } if (cpu_is_mx6sl()) { /* Set the voltage of VDDSOC to 1.2V as in normal mode. */ @@ -315,8 +293,6 @@ int set_high_bus_freq(int high_bus_freq) if (cpu_is_mx6sl()) arm_mem_clked_in_wait = false; - mutex_unlock(&bus_freq_mutex); - return 0; } @@ -341,6 +317,61 @@ int low_freq_bus_used(void) return 0; } +void bus_freq_update(struct clk *clk, bool flag) +{ + mutex_lock(&bus_freq_mutex); + if (flag) { + /* Update count */ + if (clk->flags & AHB_HIGH_SET_POINT) + lp_high_freq++; + else if (clk->flags & AHB_MED_SET_POINT) + lp_med_freq++; + else if (clk->flags & AHB_AUDIO_SET_POINT) + lp_audio_freq++; + /* Update bus freq */ + if ((clk->flags & CPU_FREQ_TRIG_UPDATE) + && (clk_get_usecount(clk) == 0)) { + if (!(clk->flags & + (AHB_HIGH_SET_POINT | AHB_MED_SET_POINT))) { + if (low_freq_bus_used()) { + if ((clk->flags & AHB_AUDIO_SET_POINT) & !audio_bus_freq_mode) + set_low_bus_freq(); + else if (!low_bus_freq_mode) + set_low_bus_freq(); + } + } else { + if ((clk->flags & AHB_MED_SET_POINT) + && !med_bus_freq_mode) + /* Set to Medium setpoint */ + set_high_bus_freq(0); + else if ((clk->flags & AHB_HIGH_SET_POINT) + && !high_bus_freq_mode) + /* Currently at low or medium set point, + * need to set to high setpoint + */ + set_high_bus_freq(1); + } + } + } else { + /* Update count */ + if (clk->flags & AHB_HIGH_SET_POINT) + lp_high_freq--; + else if (clk->flags & AHB_MED_SET_POINT) + lp_med_freq--; + else if (clk->flags & AHB_AUDIO_SET_POINT) + lp_audio_freq--; + /* Update bus freq */ + if ((clk->flags & CPU_FREQ_TRIG_UPDATE) + && (clk_get_usecount(clk) == 0)) { + if (low_freq_bus_used() && !low_bus_freq_mode) + set_low_bus_freq(); + else + /* Set to either high or medium setpoint. */ + set_high_bus_freq(0); + } + } + mutex_unlock(&bus_freq_mutex); +} void setup_pll(void) { } @@ -521,8 +552,6 @@ static int __devinit busfreq_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler); - mutex_init(&bus_freq_mutex); - if (!cpu_is_mx6sl()) init_mmdc_settings(); diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c index ebc1ca1ee3cc..57dee5f4c4c0 100644 --- a/arch/arm/mach-mx6/system.c +++ b/arch/arm/mach-mx6/system.c @@ -30,6 +30,7 @@ #include <mach/clock.h> #include <asm/proc-fns.h> #include <asm/system.h> +#include <asm/hardware/gic.h> #include "crm_regs.h" #include "regs-anadig.h" @@ -144,19 +145,22 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode) /* Power down and power up sequence */ __raw_writel(0xFFFFFFFF, gpc_base + GPC_PGC_CPU_PUPSCR_OFFSET); __raw_writel(0xFFFFFFFF, gpc_base + GPC_PGC_CPU_PDNSCR_OFFSET); - - /* dormant mode, need to power off the arm core */ if (stop_mode == 2) { + /* dormant mode, need to power off the arm core */ __raw_writel(0x1, gpc_base + GPC_PGC_CPU_PDN_OFFSET); - __raw_writel(0x1, gpc_base + GPC_PGC_GPU_PGCR_OFFSET); - __raw_writel(0x1, gpc_base + GPC_CNTR_OFFSET); if (cpu_is_mx6q() || cpu_is_mx6dl()) { - /* Enable weak 2P5 linear regulator */ - anatop_val = __raw_readl(anatop_base + - HW_ANADIG_REG_2P5); - anatop_val |= BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG; - __raw_writel(anatop_val, anatop_base + - HW_ANADIG_REG_2P5); + /* If stop_mode_config is clear, then 2P5 will be off, + need to enable weak 2P5, as DDR IO need 2P5 as + pre-driver */ + if ((__raw_readl(anatop_base + HW_ANADIG_ANA_MISC0) + & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) { + /* Enable weak 2P5 linear regulator */ + anatop_val = __raw_readl(anatop_base + + HW_ANADIG_REG_2P5); + anatop_val |= BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG; + __raw_writel(anatop_val, anatop_base + + HW_ANADIG_REG_2P5); + } if (mx6q_revision() != IMX_CHIP_REVISION_1_0) { /* Enable fet_odrive */ anatop_val = __raw_readl(anatop_base + @@ -181,16 +185,22 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode) reg |= MXC_CCM_CGPR_MEM_IPG_STOP_MASK; __raw_writel(reg, MXC_CCM_CGPR); } - - if (!cpu_is_mx6dl()) + /* DL's TO1.0 can't support DSM mode due to ipg glitch */ + if (mx6dl_revision() != IMX_CHIP_REVISION_1_0) __raw_writel(__raw_readl(MXC_CCM_CCR) | MXC_CCM_CCR_RBC_EN, MXC_CCM_CCR); + /* Make sure we clear WB_COUNT and re-config it */ __raw_writel(__raw_readl(MXC_CCM_CCR) & - (~MXC_CCM_CCR_WB_COUNT_MASK), MXC_CCM_CCR); - udelay(50); - __raw_writel(__raw_readl(MXC_CCM_CCR) | (0x1 << - MXC_CCM_CCR_WB_COUNT_OFFSET), MXC_CCM_CCR); + (~MXC_CCM_CCR_WB_COUNT_MASK) & + (~MXC_CCM_CCR_REG_BYPASS_CNT_MASK), MXC_CCM_CCR); + udelay(60); + /* Reconfigurate WB and RBC counter */ + __raw_writel(__raw_readl(MXC_CCM_CCR) | + (0x1 << MXC_CCM_CCR_WB_COUNT_OFFSET) | + (0x20 << MXC_CCM_CCR_REG_BYPASS_CNT_OFFSET), MXC_CCM_CCR); + + /* Set WB_PER enable */ ccm_clpcr |= MXC_CCM_CLPCR_WB_PER_AT_LPM; } if (cpu_is_mx6sl() || @@ -219,6 +229,13 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode) extern int tick_broadcast_oneshot_active(void); +void ca9_do_idle(void) +{ + do { + cpu_do_idle(); + } while (__raw_readl(gic_cpu_base_addr + GIC_CPU_HIGHPRI) == 1023); +} + void arch_idle_single_core(void) { u32 reg; @@ -232,7 +249,7 @@ void arch_idle_single_core(void) reg |= MXC_CCM_CGPR_WAIT_MODE_FIX; __raw_writel(reg, MXC_CCM_CGPR); - cpu_do_idle(); + ca9_do_idle(); } else { /* * Implement the 12:5 ARM:IPG_CLK ratio @@ -250,7 +267,7 @@ void arch_idle_single_core(void) __raw_writel(wait_mode_arm_podf, MXC_CCM_CACRR); while (__raw_readl(MXC_CCM_CDHIPR)) ; - cpu_do_idle(); + ca9_do_idle(); __raw_writel(cur_arm_podf - 1, MXC_CCM_CACRR); } @@ -258,7 +275,6 @@ void arch_idle_single_core(void) void arch_idle_with_workaround(cpu) { - u32 reg; u32 podf = wait_mode_arm_podf; *((char *)(&num_cpu_idle_lock) + (char)cpu) = 0x0; @@ -302,7 +318,7 @@ void arch_idle_multi_core(void) reg |= MXC_CCM_CGPR_WAIT_MODE_FIX; __raw_writel(reg, MXC_CCM_CGPR); - cpu_do_idle(); + ca9_do_idle(); } else arch_idle_with_workaround(cpu); #ifdef CONFIG_LOCAL_TIMERS @@ -329,7 +345,7 @@ void arch_idle(void) reg &= ~MXC_CCM_CGPR_MEM_IPG_STOP_MASK; __raw_writel(reg, MXC_CCM_CGPR); - cpu_do_idle(); + ca9_do_idle(); } else if (num_possible_cpus() == 1) /* iMX6SL or iMX6DLS */ arch_idle_single_core(); @@ -337,7 +353,7 @@ void arch_idle(void) arch_idle_multi_core(); } else { mxc_cpu_lp_set(WAIT_CLOCKED); - cpu_do_idle(); + ca9_do_idle(); } } diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c index 43d33376b52d..ee4ea63d9fdc 100755 --- a/arch/arm/plat-mxc/clock.c +++ b/arch/arm/plat-mxc/clock.c @@ -45,16 +45,7 @@ #include <mach/hardware.h> extern int dvfs_core_is_active; -extern int lp_high_freq; -extern int lp_med_freq; -extern int lp_audio_freq; -extern int audio_bus_freq_mode; -extern int low_bus_freq_mode; -extern int high_bus_freq_mode; -extern int med_bus_freq_mode; -extern int set_high_bus_freq(int high_freq); -extern int set_low_bus_freq(void); -extern int low_freq_bus_used(void); +extern void bus_freq_update(struct clk *clk, bool flag); static LIST_HEAD(clocks); static DEFINE_MUTEX(clocks_mutex); @@ -113,36 +104,12 @@ int clk_enable(struct clk *clk) if (clk == NULL || IS_ERR(clk)) return -EINVAL; - if (clk->flags & AHB_HIGH_SET_POINT) - lp_high_freq++; - else if (clk->flags & AHB_MED_SET_POINT) - lp_med_freq++; - else if (clk->flags & AHB_AUDIO_SET_POINT) - lp_audio_freq++; - - if ((clk->flags & CPU_FREQ_TRIG_UPDATE) - && (clk_get_usecount(clk) == 0)) { - if (!(clk->flags & - (AHB_HIGH_SET_POINT | AHB_MED_SET_POINT))) { - if (low_freq_bus_used()) { - if ((clk->flags & AHB_AUDIO_SET_POINT) & !audio_bus_freq_mode) - set_low_bus_freq(); - else if (!low_bus_freq_mode) - set_low_bus_freq(); - } - } else { - if ((clk->flags & AHB_MED_SET_POINT) - && !med_bus_freq_mode) - /* Set to Medium setpoint */ - set_high_bus_freq(0); - else if ((clk->flags & AHB_HIGH_SET_POINT) - && !high_bus_freq_mode) - /* Currently at low or medium set point, - * need to set to high setpoint - */ - set_high_bus_freq(1); - } - } + if ((clk->flags & AHB_HIGH_SET_POINT) || + (clk->flags & AHB_MED_SET_POINT) || + (clk->flags & AHB_AUDIO_SET_POINT) || + (clk->flags & CPU_FREQ_TRIG_UPDATE)) + bus_freq_update(clk, true); + mutex_lock(&clocks_mutex); ret = __clk_enable(clk); mutex_unlock(&clocks_mutex); @@ -168,24 +135,15 @@ void clk_disable(struct clk *clk) if (clk == NULL || IS_ERR(clk)) return; - if (clk->flags & AHB_HIGH_SET_POINT) - lp_high_freq--; - else if (clk->flags & AHB_MED_SET_POINT) - lp_med_freq--; - else if (clk->flags & AHB_AUDIO_SET_POINT) - lp_audio_freq--; - mutex_lock(&clocks_mutex); __clk_disable(clk); mutex_unlock(&clocks_mutex); - if ((clk->flags & CPU_FREQ_TRIG_UPDATE) - && (clk_get_usecount(clk) == 0)) { - if (low_freq_bus_used() && !low_bus_freq_mode) - set_low_bus_freq(); - else - /* Set to either high or medium setpoint. */ - set_high_bus_freq(0); - } + + if ((clk->flags & AHB_HIGH_SET_POINT) || + (clk->flags & AHB_MED_SET_POINT) || + (clk->flags & AHB_AUDIO_SET_POINT) || + (clk->flags & CPU_FREQ_TRIG_UPDATE)) + bus_freq_update(clk, false); } EXPORT_SYMBOL(clk_disable); diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c index 765f05e23712..935570707e6b 100755 --- a/arch/arm/plat-mxc/cpufreq.c +++ b/arch/arm/plat-mxc/cpufreq.c @@ -61,6 +61,7 @@ extern int high_bus_freq_mode; extern int set_low_bus_freq(void); extern int set_high_bus_freq(int high_bus_speed); extern int low_freq_bus_used(void); +extern struct mutex bus_freq_mutex; int set_cpu_freq(int freq) { @@ -86,8 +87,10 @@ int set_cpu_freq(int freq) #endif /*Set the voltage for the GP domain. */ if (freq > org_cpu_rate) { + mutex_lock(&bus_freq_mutex); if (low_bus_freq_mode || audio_bus_freq_mode) set_high_bus_freq(0); + mutex_unlock(&bus_freq_mutex); ret = regulator_set_voltage(cpu_regulator, gp_volt, gp_volt); if (ret < 0) { @@ -109,9 +112,11 @@ int set_cpu_freq(int freq) printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!\n"); return ret; } + mutex_lock(&bus_freq_mutex); if (low_freq_bus_used() && !(low_bus_freq_mode || audio_bus_freq_mode)) set_low_bus_freq(); + mutex_unlock(&bus_freq_mutex); } return ret; diff --git a/arch/arm/plat-mxc/dvfs_core.c b/arch/arm/plat-mxc/dvfs_core.c index a31ee9a71940..9018b49511cc 100755 --- a/arch/arm/plat-mxc/dvfs_core.c +++ b/arch/arm/plat-mxc/dvfs_core.c @@ -154,6 +154,7 @@ extern int high_bus_freq_mode; extern int set_low_bus_freq(void); extern int set_high_bus_freq(int high_bus_speed); extern int low_freq_bus_used(void); +extern struct mutex bus_freq_mutex; DEFINE_SPINLOCK(mxc_dvfs_core_lock); @@ -603,8 +604,12 @@ static void dvfs_core_work_handler(struct work_struct *work) if (fsvai == FSVAI_FREQ_DECREASE) { if (curr_cpu <= cpu_op_tbl[cpu_op_nr - 1].cpu_rate) { minf = 1; - if (low_bus_freq_mode) + mutex_lock(&bus_freq_mutex); + if (low_bus_freq_mode) { + mutex_unlock(&bus_freq_mutex); goto END; + } else + mutex_unlock(&bus_freq_mutex); } else { /* freq down */ curr_op++; @@ -621,6 +626,7 @@ static void dvfs_core_work_handler(struct work_struct *work) maxf = 1; goto END; } else { + mutex_lock(&bus_freq_mutex); if (!high_bus_freq_mode && dvfs_config_setpoint == (cpu_op_nr + 1)) { /* bump up LP freq first. */ @@ -633,24 +639,30 @@ static void dvfs_core_work_handler(struct work_struct *work) minf = 0; dvfs_load_config(0); } + mutex_unlock(&bus_freq_mutex); } } low_freq_bus_ready = low_freq_bus_used(); + mutex_lock(&bus_freq_mutex); if ((curr_op == cpu_op_nr - 1) && (!low_bus_freq_mode) && (low_freq_bus_ready) && !bus_incr) { + mutex_unlock(&bus_freq_mutex); if (!minf) set_cpu_freq(curr_op); /* If dvfs_core_op is greater than cpu_op_nr, it implies * we support LPAPM mode for this platform. */ if (dvfs_core_op > cpu_op_nr) { + mutex_lock(&bus_freq_mutex); set_low_bus_freq(); + mutex_unlock(&bus_freq_mutex); dvfs_load_config(cpu_op_nr + 1); } } else { if (!high_bus_freq_mode) set_high_bus_freq(1); + mutex_unlock(&bus_freq_mutex); if (!bus_incr) ret = set_cpu_freq(curr_op); bus_incr = 0; @@ -722,8 +734,10 @@ void stop_dvfs(void) + MXC_DVFSCORE_CNTR); curr_op = 0; + mutex_lock(&bus_freq_mutex); if (!high_bus_freq_mode) set_high_bus_freq(1); + mutex_unlock(&bus_freq_mutex); curr_cpu = clk_get_rate(cpu_clk); if (curr_cpu != cpu_op_tbl[curr_op].cpu_rate) { diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index f2c8595ccb9b..c47e25eee926 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -163,14 +163,16 @@ static void kick_trng(struct platform_device *pdev) /* put RNG4 into program mode */ setbits32(&r4tst->rtmctl, RTMCTL_PRGM); - /* 1600 clocks per sample */ + /* Set clocks per sample to the default, and divider to zero */ val = rd_reg32(&r4tst->rtsdctl); - val = (val & ~RTSDCTL_ENT_DLY_MASK) | (1600 << RTSDCTL_ENT_DLY_SHIFT); + val = ((val & ~RTSDCTL_ENT_DLY_MASK) | + (RNG4_ENT_CLOCKS_SAMPLE << RTSDCTL_ENT_DLY_SHIFT)) & + ~RTMCTL_OSC_DIV_MASK; wr_reg32(&r4tst->rtsdctl, val); /* min. freq. count */ - wr_reg32(&r4tst->rtfrqmin, 400); + wr_reg32(&r4tst->rtfrqmin, RNG4_ENT_CLOCKS_SAMPLE / 4); /* max. freq. count */ - wr_reg32(&r4tst->rtfrqmax, 6400); + wr_reg32(&r4tst->rtfrqmax, RNG4_ENT_CLOCKS_SAMPLE * 8); /* put RNG4 into run mode */ clrbits32(&r4tst->rtmctl, RTMCTL_PRGM); } diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h index 18e7385fb2d8..1f818ffb831a 100644 --- a/drivers/crypto/caam/intern.h +++ b/drivers/crypto/caam/intern.h @@ -12,6 +12,9 @@ #define JOBR_UNASSIGNED 0 #define JOBR_ASSIGNED 1 +/* Default clock/sample settings for an RNG4 entropy source */ +#define RNG4_ENT_CLOCKS_SAMPLE 1600 + /* Currently comes from Kconfig param as a ^2 (driver-required) */ #define JOBR_DEPTH (1 << CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE) diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h index fd8a2a251b8a..04ae9d4167b0 100644 --- a/drivers/crypto/caam/regs.h +++ b/drivers/crypto/caam/regs.h @@ -297,6 +297,7 @@ struct rngtst { /* RNG4 TRNG test registers */ struct rng4tst { #define RTMCTL_PRGM 0x00010000 /* 1 -> program mode, 0 -> run mode */ +#define RTMCTL_OSC_DIV_MASK 0xc /* select oscillator divider value */ u32 rtmctl; /* misc. control register */ u32 rtscmisc; /* statistical check misc. register */ u32 rtpkrrng; /* poker range register */ |