mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-25 12:10:53 +07:00
[Blackfin] arch: Support for CPU_FREQ and NOHZ
Singed-off-by: Vitja Makarov <vitja.makarov@gmail.com>
This commit is contained in:
parent
14b03204c8
commit
1bfb4b21c7
@ -60,7 +60,7 @@ static inline unsigned long long cycles_2_ns(cycle_t cyc)
|
|||||||
|
|
||||||
static cycle_t read_cycles(void)
|
static cycle_t read_cycles(void)
|
||||||
{
|
{
|
||||||
return get_cycles();
|
return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long long sched_clock(void)
|
unsigned long long sched_clock(void)
|
||||||
@ -117,7 +117,7 @@ static void bfin_timer_set_mode(enum clock_event_mode mode,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CLOCK_EVT_MODE_ONESHOT:
|
case CLOCK_EVT_MODE_ONESHOT:
|
||||||
bfin_write_TSCALE(0);
|
bfin_write_TSCALE(TIME_SCALE - 1);
|
||||||
bfin_write_TCOUNT(0);
|
bfin_write_TCOUNT(0);
|
||||||
bfin_write_TCNTL(TMPWR | TMREN);
|
bfin_write_TCNTL(TMPWR | TMREN);
|
||||||
CSYNC();
|
CSYNC();
|
||||||
@ -183,10 +183,14 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
|
|||||||
|
|
||||||
static int __init bfin_clockevent_init(void)
|
static int __init bfin_clockevent_init(void)
|
||||||
{
|
{
|
||||||
|
unsigned long timer_clk;
|
||||||
|
|
||||||
|
timer_clk = get_cclk() / TIME_SCALE;
|
||||||
|
|
||||||
setup_irq(IRQ_CORETMR, &bfin_timer_irq);
|
setup_irq(IRQ_CORETMR, &bfin_timer_irq);
|
||||||
bfin_timer_init();
|
bfin_timer_init();
|
||||||
|
|
||||||
clockevent_bfin.mult = div_sc(get_cclk(), NSEC_PER_SEC, clockevent_bfin.shift);
|
clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift);
|
||||||
clockevent_bfin.max_delta_ns = clockevent_delta2ns(-1, &clockevent_bfin);
|
clockevent_bfin.max_delta_ns = clockevent_delta2ns(-1, &clockevent_bfin);
|
||||||
clockevent_bfin.min_delta_ns = clockevent_delta2ns(100, &clockevent_bfin);
|
clockevent_bfin.min_delta_ns = clockevent_delta2ns(100, &clockevent_bfin);
|
||||||
clockevents_register_device(&clockevent_bfin);
|
clockevents_register_device(&clockevent_bfin);
|
||||||
|
@ -62,6 +62,14 @@ static struct bfin_dpm_state {
|
|||||||
unsigned int tscale; /* change the divider on the core timer interrupt */
|
unsigned int tscale; /* change the divider on the core timer interrupt */
|
||||||
} dpm_state_table[3];
|
} dpm_state_table[3];
|
||||||
|
|
||||||
|
/*
|
||||||
|
normalized to maximum frequncy offset for CYCLES,
|
||||||
|
used in time-ts cycles clock source, but could be used
|
||||||
|
somewhere also.
|
||||||
|
*/
|
||||||
|
unsigned long long __bfin_cycles_off;
|
||||||
|
unsigned int __bfin_cycles_mod;
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
static unsigned int bfin_getfreq(unsigned int cpu)
|
static unsigned int bfin_getfreq(unsigned int cpu)
|
||||||
@ -80,6 +88,7 @@ static int bfin_target(struct cpufreq_policy *policy,
|
|||||||
unsigned int index, plldiv, tscale;
|
unsigned int index, plldiv, tscale;
|
||||||
unsigned long flags, cclk_hz;
|
unsigned long flags, cclk_hz;
|
||||||
struct cpufreq_freqs freqs;
|
struct cpufreq_freqs freqs;
|
||||||
|
cycles_t cycles;
|
||||||
|
|
||||||
if (cpufreq_frequency_table_target(policy, bfin_freq_table,
|
if (cpufreq_frequency_table_target(policy, bfin_freq_table,
|
||||||
target_freq, relation, &index))
|
target_freq, relation, &index))
|
||||||
@ -101,8 +110,14 @@ static int bfin_target(struct cpufreq_policy *policy,
|
|||||||
bfin_write_PLL_DIV(plldiv);
|
bfin_write_PLL_DIV(plldiv);
|
||||||
/* we have to adjust the core timer, because it is using cclk */
|
/* we have to adjust the core timer, because it is using cclk */
|
||||||
bfin_write_TSCALE(tscale);
|
bfin_write_TSCALE(tscale);
|
||||||
|
cycles = get_cycles();
|
||||||
SSYNC();
|
SSYNC();
|
||||||
|
cycles += 10; /* ~10 cycles we loose after get_cycles() */
|
||||||
|
__bfin_cycles_off += (cycles << __bfin_cycles_mod) - (cycles << index);
|
||||||
|
__bfin_cycles_mod = index;
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
/* TODO: just test case for cycles clock source, remove later */
|
||||||
|
pr_debug("cpufreq: done\n");
|
||||||
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -119,15 +134,6 @@ static int __init __bfin_cpu_init(struct cpufreq_policy *policy)
|
|||||||
unsigned long cclk, sclk, csel, min_cclk;
|
unsigned long cclk, sclk, csel, min_cclk;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
#ifdef CONFIG_CYCLES_CLOCKSOURCE
|
|
||||||
/*
|
|
||||||
* Clocksource CYCLES is still CONTINUOUS but not longer with a constant tick rate in case we enable
|
|
||||||
* CPU frequency scaling, since CYCLES runs off Core Clock.
|
|
||||||
*/
|
|
||||||
printk(KERN_WARNING "CPU frequency scaling not supported: Clocksource not suitable\n"
|
|
||||||
return -ENODEV;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (policy->cpu != 0)
|
if (policy->cpu != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
#ifndef CONFIG_CPU_FREQ
|
#ifndef CONFIG_CPU_FREQ
|
||||||
#define TIME_SCALE 1
|
#define TIME_SCALE 1
|
||||||
|
#define __bfin_cycles_off (0)
|
||||||
|
#define __bfin_cycles_mod (0)
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* Blackfin CPU frequency scaling supports max Core Clock 1, 1/2 and 1/4 .
|
* Blackfin CPU frequency scaling supports max Core Clock 1, 1/2 and 1/4 .
|
||||||
@ -31,6 +33,8 @@
|
|||||||
* adjust the Core Timer Presale Register. This way we don't lose time.
|
* adjust the Core Timer Presale Register. This way we don't lose time.
|
||||||
*/
|
*/
|
||||||
#define TIME_SCALE 4
|
#define TIME_SCALE 4
|
||||||
|
extern unsigned long long __bfin_cycles_off;
|
||||||
|
extern unsigned int __bfin_cycles_mod;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user