aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c')
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c70
1 files changed, 60 insertions, 10 deletions
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
index a38ebb209721..1c2041fbd718 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:
@@ -37,7 +37,7 @@
37#include "clock.h" 37#include "clock.h"
38#include "clock2xxx.h" 38#include "clock2xxx.h"
39#include "opp2xxx.h" 39#include "opp2xxx.h"
40#include "cm2xxx_3xxx.h" 40#include "cm2xxx.h"
41#include "cm-regbits-24xx.h" 41#include "cm-regbits-24xx.h"
42#include "sdrc.h" 42#include "sdrc.h"
43#include "sram.h" 43#include "sram.h"
@@ -45,6 +45,13 @@
45const struct prcm_config *curr_prcm_set; 45const struct prcm_config *curr_prcm_set;
46const struct prcm_config *rate_table; 46const struct prcm_config *rate_table;
47 47
48/*
49 * sys_ck_rate: the rate of the external high-frequency clock
50 * oscillator on the board. Set by the SoC-specific clock init code.
51 * Once set during a boot, will not change.
52 */
53static unsigned long sys_ck_rate;
54
48/** 55/**
49 * omap2_table_mpu_recalc - just return the MPU speed 56 * omap2_table_mpu_recalc - just return the MPU speed
50 * @clk: virt_prcm_set struct clk 57 * @clk: virt_prcm_set struct clk
@@ -66,15 +73,14 @@ unsigned long omap2_table_mpu_recalc(struct clk *clk)
66long omap2_round_to_table_rate(struct clk *clk, unsigned long rate) 73long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
67{ 74{
68 const struct prcm_config *ptr; 75 const struct prcm_config *ptr;
69 long highest_rate, sys_clk_rate; 76 long highest_rate;
70 77
71 highest_rate = -EINVAL; 78 highest_rate = -EINVAL;
72 sys_clk_rate = __clk_get_rate(sclk);
73 79
74 for (ptr = rate_table; ptr->mpu_speed; ptr++) { 80 for (ptr = rate_table; ptr->mpu_speed; ptr++) {
75 if (!(ptr->flags & cpu_mask)) 81 if (!(ptr->flags & cpu_mask))
76 continue; 82 continue;
77 if (ptr->xtal_speed != sys_clk_rate) 83 if (ptr->xtal_speed != sys_ck_rate)
78 continue; 84 continue;
79 85
80 highest_rate = ptr->mpu_speed; 86 highest_rate = ptr->mpu_speed;
@@ -93,15 +99,12 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
93 const struct prcm_config *prcm; 99 const struct prcm_config *prcm;
94 unsigned long found_speed = 0; 100 unsigned long found_speed = 0;
95 unsigned long flags; 101 unsigned long flags;
96 long sys_clk_rate;
97
98 sys_clk_rate = __clk_get_rate(sclk);
99 102
100 for (prcm = rate_table; prcm->mpu_speed; prcm++) { 103 for (prcm = rate_table; prcm->mpu_speed; prcm++) {
101 if (!(prcm->flags & cpu_mask)) 104 if (!(prcm->flags & cpu_mask))
102 continue; 105 continue;
103 106
104 if (prcm->xtal_speed != sys_clk_rate) 107 if (prcm->xtal_speed != sys_ck_rate)
105 continue; 108 continue;
106 109
107 if (prcm->mpu_speed <= rate) { 110 if (prcm->mpu_speed <= rate) {
@@ -117,7 +120,7 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
117 } 120 }
118 121
119 curr_prcm_set = prcm; 122 curr_prcm_set = prcm;
120 cur_rate = omap2xxx_clk_get_core_rate(dclk); 123 cur_rate = omap2xxx_clk_get_core_rate();
121 124
122 if (prcm->dpll_speed == cur_rate / 2) { 125 if (prcm->dpll_speed == cur_rate / 2) {
123 omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1); 126 omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
@@ -167,3 +170,50 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
167 170
168 return 0; 171 return 0;
169} 172}
173
174/**
175 * omap2xxx_clkt_vps_check_bootloader_rate - determine which of the rate
176 * table sets matches the current CORE DPLL hardware rate
177 *
178 * Check the MPU rate set by bootloader. Sets the 'curr_prcm_set'
179 * global to point to the active rate set when found; otherwise, sets
180 * it to NULL. No return value;
181 */
182void omap2xxx_clkt_vps_check_bootloader_rates(void)
183{
184 const struct prcm_config *prcm = NULL;
185 unsigned long rate;
186
187 rate = omap2xxx_clk_get_core_rate();
188 for (prcm = rate_table; prcm->mpu_speed; prcm++) {
189 if (!(prcm->flags & cpu_mask))
190 continue;
191 if (prcm->xtal_speed != sys_ck_rate)
192 continue;
193 if (prcm->dpll_speed <= rate)
194 break;
195 }
196 curr_prcm_set = prcm;
197}
198
199/**
200 * omap2xxx_clkt_vps_late_init - store a copy of the sys_ck rate
201 *
202 * Store a copy of the sys_ck rate for later use by the OMAP2xxx DVFS
203 * code. (The sys_ck rate does not -- or rather, must not -- change
204 * during kernel runtime.) Must be called after we have a valid
205 * sys_ck rate, but before the virt_prcm_set clock rate is
206 * recalculated. No return value.
207 */
208void omap2xxx_clkt_vps_late_init(void)
209{
210 struct clk *c;
211
212 c = clk_get(NULL, "sys_ck");
213 if (IS_ERR(c)) {
214 WARN(1, "could not locate sys_ck\n");
215 } else {
216 sys_ck_rate = clk_get_rate(c);
217 clk_put(c);
218 }
219}