0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/io.h>
0014 #include <linux/kernel.h>
0015 #include <linux/time.h>
0016 #include <asm/machdep.h>
0017 #include <asm/hw_irq.h>
0018 #include <asm/cell-regs.h>
0019
0020 #include "ppc_cbe_cpufreq.h"
0021
0022
0023 static u64 MIC_Slow_Fast_Timer_table[] = {
0024 [0 ... 7] = 0x007fc00000000000ull,
0025 };
0026
0027
0028 static u64 MIC_Slow_Next_Timer_table[] = {
0029 0x0000240000000000ull,
0030 0x0000268000000000ull,
0031 0x000029C000000000ull,
0032 0x00002D0000000000ull,
0033 0x0000300000000000ull,
0034 0x0000334000000000ull,
0035 0x000039C000000000ull,
0036 0x00003FC000000000ull,
0037 };
0038
0039
0040 int cbe_cpufreq_set_pmode(int cpu, unsigned int pmode)
0041 {
0042 struct cbe_pmd_regs __iomem *pmd_regs;
0043 struct cbe_mic_tm_regs __iomem *mic_tm_regs;
0044 unsigned long flags;
0045 u64 value;
0046 #ifdef DEBUG
0047 long time;
0048 #endif
0049
0050 local_irq_save(flags);
0051
0052 mic_tm_regs = cbe_get_cpu_mic_tm_regs(cpu);
0053 pmd_regs = cbe_get_cpu_pmd_regs(cpu);
0054
0055 #ifdef DEBUG
0056 time = jiffies;
0057 #endif
0058
0059 out_be64(&mic_tm_regs->slow_fast_timer_0, MIC_Slow_Fast_Timer_table[pmode]);
0060 out_be64(&mic_tm_regs->slow_fast_timer_1, MIC_Slow_Fast_Timer_table[pmode]);
0061
0062 out_be64(&mic_tm_regs->slow_next_timer_0, MIC_Slow_Next_Timer_table[pmode]);
0063 out_be64(&mic_tm_regs->slow_next_timer_1, MIC_Slow_Next_Timer_table[pmode]);
0064
0065 value = in_be64(&pmd_regs->pmcr);
0066
0067 value &= 0xFFFFFFFFFFFFFFF8ull;
0068
0069 value |= pmode;
0070
0071 out_be64(&pmd_regs->pmcr, value);
0072
0073 #ifdef DEBUG
0074
0075 value = in_be64(&pmd_regs->pmsr) & 0x07;
0076 while (value != pmode) {
0077 cpu_relax();
0078 value = in_be64(&pmd_regs->pmsr) & 0x07;
0079 }
0080
0081 time = jiffies - time;
0082 time = jiffies_to_msecs(time);
0083 pr_debug("had to wait %lu ms for a transition using " \
0084 "pervasive unit\n", time);
0085 #endif
0086 local_irq_restore(flags);
0087
0088 return 0;
0089 }
0090
0091
0092 int cbe_cpufreq_get_pmode(int cpu)
0093 {
0094 int ret;
0095 struct cbe_pmd_regs __iomem *pmd_regs;
0096
0097 pmd_regs = cbe_get_cpu_pmd_regs(cpu);
0098 ret = in_be64(&pmd_regs->pmsr) & 0x07;
0099
0100 return ret;
0101 }
0102