Some backports from FSL tree: lost the ENGR numbers but in summary:

* fix bus frequency driver check for frequency (> instead of !=)
* fix VPU lockup due to misassigning a clock
* stop dvfs before reboots (otherwise it might not reboot)
* small cleanups in DVFS code for frequency changing and added spinlock
This commit is contained in:
Matt Sealey
2011-01-20 10:23:28 -06:00
parent 62cc8b2320
commit 8d61b989fb
5 changed files with 30 additions and 17 deletions

View File

@@ -104,7 +104,7 @@ int set_low_bus_freq(void)
if (bus_freq_scaling_initialized) {
/* can not enter low bus freq, when cpu is in highest freq */
if (clk_get_rate(cpu_clk) != cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate)
if (clk_get_rate(cpu_clk) > cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate)
return 0;
/* currently not support on mx53 */
@@ -223,7 +223,7 @@ int set_high_bus_freq(int high_bus_freq)
* If the CPU freq is 800MHz, set the bus to the high
* setpoint (133MHz) and DDR to 200MHz.
*/
if (clk_get_rate(cpu_clk) !=
if (clk_get_rate(cpu_clk) >
cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate)
high_bus_freq = 1;

View File

@@ -4790,9 +4790,6 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, unsigned long
esdhc3_clk[0].recalc = _clk_esdhc3_recalc;
esdhc3_clk[0].set_rate = _clk_sdhc3_set_rate;
#ifdef CONFIG_MXC_VPU_IRAM
vpu_clk[2].secondary = &emi_intr_clk[1];
#endif
#if defined(CONFIG_USB_STATIC_IRAM) \
|| defined(CONFIG_USB_STATIC_IRAM_PPH)
usboh3_clk[1].secondary = &emi_intr_clk[1];

View File

@@ -38,6 +38,8 @@
extern int mxc_jtag_enabled;
extern int iram_ready;
extern int dvfs_core_is_active;
extern void stop_dvfs(void);
static struct clk *gpc_dvfs_clk;
extern void cpu_cortexa8_do_idle(void *addr);
@@ -71,6 +73,7 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
if (mode == WAIT_UNCLOCKED_POWER_OFF) {
ccm_clpcr |= (0x1 << MXC_CCM_CLPCR_LPM_OFFSET);
ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY;
ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
stop_mode = 0;
} else {
ccm_clpcr |= (0x2 << MXC_CCM_CLPCR_LPM_OFFSET);
@@ -179,6 +182,9 @@ void arch_reset(char mode)
if (cpu_is_mx51() || cpu_is_mx53())
__raw_writel(0x20600, IO_ADDRESS(NFC_BASE_ADDR) + 0x28);
if (dvfs_core_is_active)
stop_dvfs();
/* Assert SRS signal */
mxc_wd_reset();
#if defined(CONFIG_MACH_MX51_EFIKAMX)

View File

@@ -89,6 +89,7 @@ extern int cpufreq_trig_needed;
struct timeval core_prev_intr;
void dump_dvfs_core_regs(void);
void stop_dvfs(void);
static struct delayed_work dvfs_core_handler;
/*
@@ -268,6 +269,7 @@ static int set_cpu_freq(int wp)
/* Set ARM_PODF */
reg &= 0xFFFFFFF8;
reg |= arm_podf;
spin_lock_irqsave(&mxc_dvfs_core_lock, flags);
reg1 = __raw_readl(dvfs_data->ccm_cdhipr_reg_addr);
if ((reg1 & 0x00010000) == 0)
@@ -277,12 +279,6 @@ static int set_cpu_freq(int wp)
return 0;
}
/* START the GPC main control FSM */
reg = __raw_readl(dvfs_data->gpc_cntr_reg_addr);
reg |= MXC_GPCCNTR_FUPD;
/* ADU=1, select ARM domain */
reg |= MXC_GPCCNTR_ADU;
__raw_writel(reg, dvfs_data->gpc_cntr_reg_addr);
/* set VINC */
reg = __raw_readl(dvfs_data->gpc_vcr_reg_addr);
reg &=
@@ -294,8 +290,13 @@ static int set_cpu_freq(int wp)
__raw_writel(reg, dvfs_data->gpc_vcr_reg_addr);
reg = __raw_readl(dvfs_data->gpc_cntr_reg_addr);
reg &= (~(MXC_GPCCNTR_ADU | MXC_GPCCNTR_FUPD));
reg |= MXC_GPCCNTR_ADU | MXC_GPCCNTR_FUPD | MXC_GPCCNTR_STRT;
reg &= (~(MXC_GPCCNTR_ADU | MXC_GPCCNTR_FUPD | MXC_GPCCNTR_STRT));
__raw_writel(reg, dvfs_data->gpc_cntr_reg_addr);
reg = __raw_readl(dvfs_data->gpc_cntr_reg_addr);
reg |= MXC_GPCCNTR_ADU | MXC_GPCCNTR_FUPD;
__raw_writel(reg, dvfs_data->gpc_cntr_reg_addr);
reg = __raw_readl(dvfs_data->gpc_cntr_reg_addr);
reg |= MXC_GPCCNTR_STRT;
__raw_writel(reg, dvfs_data->gpc_cntr_reg_addr);
/* Wait for arm podf Enable */
@@ -305,6 +306,8 @@ static int set_cpu_freq(int wp)
udelay(10);
}
spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags);
if (vinc == 0) {
ret = regulator_set_voltage(core_regulator,
gp_volt, gp_volt);
@@ -485,7 +488,7 @@ static void dvfs_core_work_handler(struct work_struct *work)
maxf = 1;
goto END;
} else {
if (low_bus_freq_mode) {
if (!high_bus_freq_mode) {
/* bump up LP freq first. */
bus_incr = 1;
dvfs_load_config(2);
@@ -511,8 +514,8 @@ static void dvfs_core_work_handler(struct work_struct *work)
cpu_dcr = 0;
}
} else {
if (low_bus_freq_mode)
set_high_bus_freq(0);
if (!high_bus_freq_mode)
set_high_bus_freq(1);
if (!bus_incr)
ret = set_cpu_freq(curr_wp);
@@ -551,7 +554,7 @@ END: /* Set MAXF, MINF */
/*!
* This function disables the DVFS module.
*/
static void stop_dvfs(void)
void stop_dvfs(void)
{
u32 reg = 0;
unsigned long flags;

View File

@@ -38,6 +38,10 @@
#define WDOG_WCR_ENABLE (1 << 2)
#endif
extern int dvfs_core_is_active;
extern void stop_dvfs(void);
/*
* Reset the system. It is called by machine_restart().
*/
@@ -51,6 +55,9 @@ void arch_reset(char mode, const char *cmd)
clk_enable(clk);
}
if (dvfs_core_is_active)
stop_dvfs();
/* Assert SRS signal */
__raw_writew(WDOG_WCR_ENABLE, WDOG_WCR_REG);