diff options
Diffstat (limited to 'arch/blackfin/mach-common/cpufreq.c')
-rw-r--r-- | arch/blackfin/mach-common/cpufreq.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c index ed81e00d20e1..75cdad291e88 100644 --- a/arch/blackfin/mach-common/cpufreq.c +++ b/arch/blackfin/mach-common/cpufreq.c | |||
@@ -62,6 +62,14 @@ static struct bfin_dpm_state { | |||
62 | unsigned int tscale; /* change the divider on the core timer interrupt */ | 62 | unsigned int tscale; /* change the divider on the core timer interrupt */ |
63 | } dpm_state_table[3]; | 63 | } dpm_state_table[3]; |
64 | 64 | ||
65 | /* | ||
66 | normalized to maximum frequncy offset for CYCLES, | ||
67 | used in time-ts cycles clock source, but could be used | ||
68 | somewhere also. | ||
69 | */ | ||
70 | unsigned long long __bfin_cycles_off; | ||
71 | unsigned int __bfin_cycles_mod; | ||
72 | |||
65 | /**************************************************************************/ | 73 | /**************************************************************************/ |
66 | 74 | ||
67 | static unsigned int bfin_getfreq(unsigned int cpu) | 75 | static unsigned int bfin_getfreq(unsigned int cpu) |
@@ -80,6 +88,7 @@ static int bfin_target(struct cpufreq_policy *policy, | |||
80 | unsigned int index, plldiv, tscale; | 88 | unsigned int index, plldiv, tscale; |
81 | unsigned long flags, cclk_hz; | 89 | unsigned long flags, cclk_hz; |
82 | struct cpufreq_freqs freqs; | 90 | struct cpufreq_freqs freqs; |
91 | cycles_t cycles; | ||
83 | 92 | ||
84 | if (cpufreq_frequency_table_target(policy, bfin_freq_table, | 93 | if (cpufreq_frequency_table_target(policy, bfin_freq_table, |
85 | target_freq, relation, &index)) | 94 | target_freq, relation, &index)) |
@@ -101,8 +110,14 @@ static int bfin_target(struct cpufreq_policy *policy, | |||
101 | bfin_write_PLL_DIV(plldiv); | 110 | bfin_write_PLL_DIV(plldiv); |
102 | /* we have to adjust the core timer, because it is using cclk */ | 111 | /* we have to adjust the core timer, because it is using cclk */ |
103 | bfin_write_TSCALE(tscale); | 112 | bfin_write_TSCALE(tscale); |
113 | cycles = get_cycles(); | ||
104 | SSYNC(); | 114 | SSYNC(); |
115 | cycles += 10; /* ~10 cycles we loose after get_cycles() */ | ||
116 | __bfin_cycles_off += (cycles << __bfin_cycles_mod) - (cycles << index); | ||
117 | __bfin_cycles_mod = index; | ||
105 | local_irq_restore(flags); | 118 | local_irq_restore(flags); |
119 | /* TODO: just test case for cycles clock source, remove later */ | ||
120 | pr_debug("cpufreq: done\n"); | ||
106 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 121 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); |
107 | 122 | ||
108 | return 0; | 123 | return 0; |
@@ -119,22 +134,13 @@ static int __init __bfin_cpu_init(struct cpufreq_policy *policy) | |||
119 | unsigned long cclk, sclk, csel, min_cclk; | 134 | unsigned long cclk, sclk, csel, min_cclk; |
120 | int index; | 135 | int index; |
121 | 136 | ||
122 | #ifdef CONFIG_CYCLES_CLOCKSOURCE | ||
123 | /* | ||
124 | * Clocksource CYCLES is still CONTINUOUS but not longer MONOTONIC in case we enable | ||
125 | * CPU frequency scaling, since CYCLES runs off Core Clock. | ||
126 | */ | ||
127 | printk(KERN_WARNING "CPU frequency scaling not supported: Clocksource not suitable\n" | ||
128 | return -ENODEV; | ||
129 | #endif | ||
130 | |||
131 | if (policy->cpu != 0) | 137 | if (policy->cpu != 0) |
132 | return -EINVAL; | 138 | return -EINVAL; |
133 | 139 | ||
134 | cclk = get_cclk(); | 140 | cclk = get_cclk(); |
135 | sclk = get_sclk(); | 141 | sclk = get_sclk(); |
136 | 142 | ||
137 | #if ANOMALY_05000273 | 143 | #if ANOMALY_05000273 || (!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_DCACHE)) |
138 | min_cclk = sclk * 2; | 144 | min_cclk = sclk * 2; |
139 | #else | 145 | #else |
140 | min_cclk = sclk; | 146 | min_cclk = sclk; |