提交 6f546bc3 编写于 作者: G Graf Yang 提交者: Mike Frysinger

Blackfin: SMP: implement cpu_freq support

Re-use some of the existing cpu hotplugging code in the process.
Signed-off-by: NGraf Yang <graf.yang@analog.com>
Signed-off-by: NMike Frysinger <vapier@gentoo.org>
上级 820b127d
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -125,6 +125,9 @@ void unset_dram_srfs(void);
#define VRPAIR(vlev, freq) (((vlev) << 16) | ((freq) >> 16))
#ifdef CONFIG_CPU_FREQ
#define CPUFREQ_CPU 0
#endif
struct bfin_dpmc_platform_data {
const unsigned int *tuple_tab;
unsigned short tabsize;
......
......@@ -34,7 +34,7 @@ extern unsigned long dcache_invld_count[NR_CPUS];
void smp_icache_flush_range_others(unsigned long start,
unsigned long end);
#ifdef CONFIG_HOTPLUG_CPU
void coreb_sleep(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
void coreb_die(void);
void cpu_die(void);
void platform_cpu_die(void);
int __cpu_disable(void);
......
......@@ -5,30 +5,27 @@
* Licensed under the GPL-2 or later.
*/
#include <linux/smp.h>
#include <asm/blackfin.h>
#include <asm/irq.h>
#include <asm/smp.h>
#define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1))
#include <mach/pll.h>
int hotplug_coreb;
void platform_cpu_die(void)
{
unsigned long iwr[2] = {0, 0};
unsigned long bank = SIC_SYSIRQ(IRQ_SUPPLE_0) / 32;
unsigned long bit = 1 << (SIC_SYSIRQ(IRQ_SUPPLE_0) % 32);
unsigned long iwr;
hotplug_coreb = 1;
iwr[bank] = bit;
/* disable core timer */
bfin_write_TCNTL(0);
/* clear ipi interrupt IRQ_SUPPLE_0 */
/* clear ipi interrupt IRQ_SUPPLE_0 of CoreB */
bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (10 + 1)));
SSYNC();
coreb_sleep(iwr[0], iwr[1], 0);
/* set CoreB wakeup by ipi0, iwr will be discarded */
bfin_iwr_set_sup0(&iwr, &iwr, &iwr);
SSYNC();
coreb_die();
}
......@@ -162,39 +162,31 @@ ENTRY(_coreb_trampoline_start)
ENDPROC(_coreb_trampoline_start)
ENTRY(_coreb_trampoline_end)
#ifdef CONFIG_HOTPLUG_CPU
.section ".text"
ENTRY(_set_sicb_iwr)
P0.H = hi(SICB_IWR0);
P0.L = lo(SICB_IWR0);
P1.H = hi(SICB_IWR1);
P1.L = lo(SICB_IWR1);
[P0] = R0;
[P1] = R1;
SSYNC;
RTS;
ENDPROC(_set_sicb_iwr)
ENTRY(_coreb_sleep)
ENTRY(_coreb_die)
sp.l = lo(INITIAL_STACK);
sp.h = hi(INITIAL_STACK);
fp = sp;
usp = sp;
call _set_sicb_iwr;
CLI R2;
SSYNC;
IDLE;
STI R2;
R0 = IWR_DISABLE_ALL;
R1 = IWR_DISABLE_ALL;
call _set_sicb_iwr;
P0.H = hi(SYSMMR_BASE);
P0.L = lo(SYSMMR_BASE);
[P0 + (SICB_IWR0 - SYSMMR_BASE)] = R0;
[P0 + (SICB_IWR1 - SYSMMR_BASE)] = R0;
SSYNC;
p0.h = hi(COREB_L1_CODE_START);
p0.l = lo(COREB_L1_CODE_START);
jump (p0);
ENDPROC(_coreb_sleep)
ENDPROC(_coreb_die)
#endif
__INIT
ENTRY(_coreb_start)
......
......@@ -16,8 +16,6 @@
#include <asm/time.h>
#include <asm/dpmc.h>
#define CPUFREQ_CPU 0
/* this is the table of CCLK frequencies, in Hz */
/* .index is the entry in the auxillary dpm_state_table[] */
static struct cpufreq_frequency_table bfin_freq_table[] = {
......
......@@ -61,17 +61,63 @@ static unsigned int bfin_get_vlev(unsigned int freq)
}
#ifdef CONFIG_CPU_FREQ
# ifdef CONFIG_SMP
static void bfin_idle_this_cpu(void *info)
{
unsigned long flags = 0;
unsigned long iwr0, iwr1, iwr2;
unsigned int cpu = smp_processor_id();
local_irq_save_hw(flags);
bfin_iwr_set_sup0(&iwr0, &iwr1, &iwr2);
platform_clear_ipi(cpu, IRQ_SUPPLE_0);
SSYNC();
asm("IDLE;");
bfin_iwr_restore(iwr0, iwr1, iwr2);
local_irq_restore_hw(flags);
}
static void bfin_idle_cpu(void)
{
smp_call_function(bfin_idle_this_cpu, NULL, 0);
}
static void bfin_wakeup_cpu(void)
{
unsigned int cpu;
unsigned int this_cpu = smp_processor_id();
cpumask_t mask = cpu_online_map;
cpu_clear(this_cpu, mask);
for_each_cpu_mask(cpu, mask)
platform_send_ipi_cpu(cpu, IRQ_SUPPLE_0);
}
# else
static void bfin_idle_cpu(void) {}
static void bfin_wakeup_cpu(void) {}
# endif
static int
vreg_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
{
struct cpufreq_freqs *freq = data;
if (freq->cpu != CPUFREQ_CPU)
return 0;
if (val == CPUFREQ_PRECHANGE && freq->old < freq->new) {
bfin_idle_cpu();
bfin_set_vlev(bfin_get_vlev(freq->new));
udelay(pdata->vr_settling_time); /* Wait until Volatge settled */
} else if (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)
bfin_wakeup_cpu();
} else if (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) {
bfin_idle_cpu();
bfin_set_vlev(bfin_get_vlev(freq->new));
bfin_wakeup_cpu();
}
return 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部