diff options
Diffstat (limited to 'arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c')
-rw-r--r-- | arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c | 66 |
1 files changed, 58 insertions, 8 deletions
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c index 311599405bfa..ad658fc6baef 100644 --- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c +++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * OMAP2xxx DVFS virtual clock functions | 2 | * OMAP2xxx DVFS virtual clock functions |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2008 Texas Instruments, Inc. | 4 | * Copyright (C) 2005-2008, 2012 Texas Instruments, Inc. |
5 | * Copyright (C) 2004-2010 Nokia Corporation | 5 | * Copyright (C) 2004-2010 Nokia Corporation |
6 | * | 6 | * |
7 | * Contacts: | 7 | * Contacts: |
@@ -46,6 +46,13 @@ | |||
46 | const struct prcm_config *curr_prcm_set; | 46 | const struct prcm_config *curr_prcm_set; |
47 | const struct prcm_config *rate_table; | 47 | const struct prcm_config *rate_table; |
48 | 48 | ||
49 | /* | ||
50 | * sys_ck_rate: the rate of the external high-frequency clock | ||
51 | * oscillator on the board. Set by the SoC-specific clock init code. | ||
52 | * Once set during a boot, will not change. | ||
53 | */ | ||
54 | static unsigned long sys_ck_rate; | ||
55 | |||
49 | /** | 56 | /** |
50 | * omap2_table_mpu_recalc - just return the MPU speed | 57 | * omap2_table_mpu_recalc - just return the MPU speed |
51 | * @clk: virt_prcm_set struct clk | 58 | * @clk: virt_prcm_set struct clk |
@@ -67,15 +74,14 @@ unsigned long omap2_table_mpu_recalc(struct clk *clk) | |||
67 | long omap2_round_to_table_rate(struct clk *clk, unsigned long rate) | 74 | long omap2_round_to_table_rate(struct clk *clk, unsigned long rate) |
68 | { | 75 | { |
69 | const struct prcm_config *ptr; | 76 | const struct prcm_config *ptr; |
70 | long highest_rate, sys_clk_rate; | 77 | long highest_rate; |
71 | 78 | ||
72 | highest_rate = -EINVAL; | 79 | highest_rate = -EINVAL; |
73 | sys_clk_rate = __clk_get_rate(sclk); | ||
74 | 80 | ||
75 | for (ptr = rate_table; ptr->mpu_speed; ptr++) { | 81 | for (ptr = rate_table; ptr->mpu_speed; ptr++) { |
76 | if (!(ptr->flags & cpu_mask)) | 82 | if (!(ptr->flags & cpu_mask)) |
77 | continue; | 83 | continue; |
78 | if (ptr->xtal_speed != sys_clk_rate) | 84 | if (ptr->xtal_speed != sys_ck_rate) |
79 | continue; | 85 | continue; |
80 | 86 | ||
81 | highest_rate = ptr->mpu_speed; | 87 | highest_rate = ptr->mpu_speed; |
@@ -94,15 +100,12 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate) | |||
94 | const struct prcm_config *prcm; | 100 | const struct prcm_config *prcm; |
95 | unsigned long found_speed = 0; | 101 | unsigned long found_speed = 0; |
96 | unsigned long flags; | 102 | unsigned long flags; |
97 | long sys_clk_rate; | ||
98 | |||
99 | sys_clk_rate = __clk_get_rate(sclk); | ||
100 | 103 | ||
101 | for (prcm = rate_table; prcm->mpu_speed; prcm++) { | 104 | for (prcm = rate_table; prcm->mpu_speed; prcm++) { |
102 | if (!(prcm->flags & cpu_mask)) | 105 | if (!(prcm->flags & cpu_mask)) |
103 | continue; | 106 | continue; |
104 | 107 | ||
105 | if (prcm->xtal_speed != sys_clk_rate) | 108 | if (prcm->xtal_speed != sys_ck_rate) |
106 | continue; | 109 | continue; |
107 | 110 | ||
108 | if (prcm->mpu_speed <= rate) { | 111 | if (prcm->mpu_speed <= rate) { |
@@ -168,3 +171,50 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate) | |||
168 | 171 | ||
169 | return 0; | 172 | return 0; |
170 | } | 173 | } |
174 | |||
175 | /** | ||
176 | * omap2xxx_clkt_vps_check_bootloader_rate - determine which of the rate | ||
177 | * table sets matches the current CORE DPLL hardware rate | ||
178 | * | ||
179 | * Check the MPU rate set by bootloader. Sets the 'curr_prcm_set' | ||
180 | * global to point to the active rate set when found; otherwise, sets | ||
181 | * it to NULL. No return value; | ||
182 | */ | ||
183 | void omap2xxx_clkt_vps_check_bootloader_rates(void) | ||
184 | { | ||
185 | const struct prcm_config *prcm = NULL; | ||
186 | unsigned long rate; | ||
187 | |||
188 | rate = omap2xxx_clk_get_core_rate(); | ||
189 | for (prcm = rate_table; prcm->mpu_speed; prcm++) { | ||
190 | if (!(prcm->flags & cpu_mask)) | ||
191 | continue; | ||
192 | if (prcm->xtal_speed != sys_ck_rate) | ||
193 | continue; | ||
194 | if (prcm->dpll_speed <= rate) | ||
195 | break; | ||
196 | } | ||
197 | curr_prcm_set = prcm; | ||
198 | } | ||
199 | |||
200 | /** | ||
201 | * omap2xxx_clkt_vps_late_init - store a copy of the sys_ck rate | ||
202 | * | ||
203 | * Store a copy of the sys_ck rate for later use by the OMAP2xxx DVFS | ||
204 | * code. (The sys_ck rate does not -- or rather, must not -- change | ||
205 | * during kernel runtime.) Must be called after we have a valid | ||
206 | * sys_ck rate, but before the virt_prcm_set clock rate is | ||
207 | * recalculated. No return value. | ||
208 | */ | ||
209 | void omap2xxx_clkt_vps_late_init(void) | ||
210 | { | ||
211 | struct clk *c; | ||
212 | |||
213 | c = clk_get(NULL, "sys_ck"); | ||
214 | if (IS_ERR(c)) { | ||
215 | WARN(1, "could not locate sys_ck\n"); | ||
216 | } else { | ||
217 | sys_ck_rate = clk_get_rate(c); | ||
218 | clk_put(c); | ||
219 | } | ||
220 | } | ||