summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinyu Chen <xinyu.chen@freescale.com>2012-08-13 10:55:02 +0800
committerXinyu Chen <xinyu.chen@freescale.com>2012-08-13 10:55:02 +0800
commit67c5fc0f0214faea7186138245303a832ed825d5 (patch)
tree0df6922959ff8072edaca7876910b990aa953426
parent14839768c2e0f5448f1767729a7fe5791cd4f3dd (diff)
parent1f4aead453351d7d9658f6ebb31f6deaea3262b6 (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.c85
-rw-r--r--arch/arm/mach-mx6/system.c60
-rwxr-xr-xarch/arm/plat-mxc/clock.c68
-rwxr-xr-xarch/arm/plat-mxc/cpufreq.c5
-rwxr-xr-xarch/arm/plat-mxc/dvfs_core.c16
-rw-r--r--drivers/crypto/caam/ctrl.c10
-rw-r--r--drivers/crypto/caam/intern.h3
-rw-r--r--drivers/crypto/caam/regs.h1
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 */