aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2013-01-24 06:47:48 -0500
committerIngo Molnar <mingo@kernel.org>2013-01-24 06:47:48 -0500
commitbefddb21c845f8fb49e637997891ef97c6a869dc (patch)
tree0e7629123184f2dd50291ad6d477b894175f0f26 /arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
parente716efde75267eab919cdb2bef5b2cb77f305326 (diff)
parent7d1f9aeff1ee4a20b1aeb377dd0f579fe9647619 (diff)
Merge tag 'v3.8-rc4' into irq/core
Merge Linux 3.8-rc4 before pulling in new commits - we were on an old v3.7 base. Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c')
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c85
1 files changed, 68 insertions, 17 deletions
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
index 3524f0e7b6d5..ae2b35e76dc8 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:
@@ -33,27 +33,33 @@
33#include <linux/cpufreq.h> 33#include <linux/cpufreq.h>
34#include <linux/slab.h> 34#include <linux/slab.h>
35 35
36#include <plat/clock.h>
37#include <plat/sram.h>
38#include <plat/sdrc.h>
39
40#include "soc.h" 36#include "soc.h"
41#include "clock.h" 37#include "clock.h"
42#include "clock2xxx.h" 38#include "clock2xxx.h"
43#include "opp2xxx.h" 39#include "opp2xxx.h"
44#include "cm2xxx_3xxx.h" 40#include "cm2xxx.h"
45#include "cm-regbits-24xx.h" 41#include "cm-regbits-24xx.h"
42#include "sdrc.h"
43#include "sram.h"
46 44
47const struct prcm_config *curr_prcm_set; 45const struct prcm_config *curr_prcm_set;
48const struct prcm_config *rate_table; 46const struct prcm_config *rate_table;
49 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
50/** 55/**
51 * omap2_table_mpu_recalc - just return the MPU speed 56 * omap2_table_mpu_recalc - just return the MPU speed
52 * @clk: virt_prcm_set struct clk 57 * @clk: virt_prcm_set struct clk
53 * 58 *
54 * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set. 59 * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
55 */ 60 */
56unsigned long omap2_table_mpu_recalc(struct clk *clk) 61unsigned long omap2_table_mpu_recalc(struct clk_hw *clk,
62 unsigned long parent_rate)
57{ 63{
58 return curr_prcm_set->mpu_speed; 64 return curr_prcm_set->mpu_speed;
59} 65}
@@ -65,18 +71,18 @@ unsigned long omap2_table_mpu_recalc(struct clk *clk)
65 * Some might argue L3-DDR, others ARM, others IVA. This code is simple and 71 * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
66 * just uses the ARM rates. 72 * just uses the ARM rates.
67 */ 73 */
68long omap2_round_to_table_rate(struct clk *clk, unsigned long rate) 74long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate,
75 unsigned long *parent_rate)
69{ 76{
70 const struct prcm_config *ptr; 77 const struct prcm_config *ptr;
71 long highest_rate, sys_clk_rate; 78 long highest_rate;
72 79
73 highest_rate = -EINVAL; 80 highest_rate = -EINVAL;
74 sys_clk_rate = __clk_get_rate(sclk);
75 81
76 for (ptr = rate_table; ptr->mpu_speed; ptr++) { 82 for (ptr = rate_table; ptr->mpu_speed; ptr++) {
77 if (!(ptr->flags & cpu_mask)) 83 if (!(ptr->flags & cpu_mask))
78 continue; 84 continue;
79 if (ptr->xtal_speed != sys_clk_rate) 85 if (ptr->xtal_speed != sys_ck_rate)
80 continue; 86 continue;
81 87
82 highest_rate = ptr->mpu_speed; 88 highest_rate = ptr->mpu_speed;
@@ -89,21 +95,19 @@ long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
89} 95}
90 96
91/* Sets basic clocks based on the specified rate */ 97/* Sets basic clocks based on the specified rate */
92int omap2_select_table_rate(struct clk *clk, unsigned long rate) 98int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate,
99 unsigned long parent_rate)
93{ 100{
94 u32 cur_rate, done_rate, bypass = 0, tmp; 101 u32 cur_rate, done_rate, bypass = 0, tmp;
95 const struct prcm_config *prcm; 102 const struct prcm_config *prcm;
96 unsigned long found_speed = 0; 103 unsigned long found_speed = 0;
97 unsigned long flags; 104 unsigned long flags;
98 long sys_clk_rate;
99
100 sys_clk_rate = __clk_get_rate(sclk);
101 105
102 for (prcm = rate_table; prcm->mpu_speed; prcm++) { 106 for (prcm = rate_table; prcm->mpu_speed; prcm++) {
103 if (!(prcm->flags & cpu_mask)) 107 if (!(prcm->flags & cpu_mask))
104 continue; 108 continue;
105 109
106 if (prcm->xtal_speed != sys_clk_rate) 110 if (prcm->xtal_speed != sys_ck_rate)
107 continue; 111 continue;
108 112
109 if (prcm->mpu_speed <= rate) { 113 if (prcm->mpu_speed <= rate) {
@@ -119,7 +123,7 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
119 } 123 }
120 124
121 curr_prcm_set = prcm; 125 curr_prcm_set = prcm;
122 cur_rate = omap2xxx_clk_get_core_rate(dclk); 126 cur_rate = omap2xxx_clk_get_core_rate();
123 127
124 if (prcm->dpll_speed == cur_rate / 2) { 128 if (prcm->dpll_speed == cur_rate / 2) {
125 omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1); 129 omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
@@ -169,3 +173,50 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
169 173
170 return 0; 174 return 0;
171} 175}
176
177/**
178 * omap2xxx_clkt_vps_check_bootloader_rate - determine which of the rate
179 * table sets matches the current CORE DPLL hardware rate
180 *
181 * Check the MPU rate set by bootloader. Sets the 'curr_prcm_set'
182 * global to point to the active rate set when found; otherwise, sets
183 * it to NULL. No return value;
184 */
185void omap2xxx_clkt_vps_check_bootloader_rates(void)
186{
187 const struct prcm_config *prcm = NULL;
188 unsigned long rate;
189
190 rate = omap2xxx_clk_get_core_rate();
191 for (prcm = rate_table; prcm->mpu_speed; prcm++) {
192 if (!(prcm->flags & cpu_mask))
193 continue;
194 if (prcm->xtal_speed != sys_ck_rate)
195 continue;
196 if (prcm->dpll_speed <= rate)
197 break;
198 }
199 curr_prcm_set = prcm;
200}
201
202/**
203 * omap2xxx_clkt_vps_late_init - store a copy of the sys_ck rate
204 *
205 * Store a copy of the sys_ck rate for later use by the OMAP2xxx DVFS
206 * code. (The sys_ck rate does not -- or rather, must not -- change
207 * during kernel runtime.) Must be called after we have a valid
208 * sys_ck rate, but before the virt_prcm_set clock rate is
209 * recalculated. No return value.
210 */
211void omap2xxx_clkt_vps_late_init(void)
212{
213 struct clk *c;
214
215 c = clk_get(NULL, "sys_ck");
216 if (IS_ERR(c)) {
217 WARN(1, "could not locate sys_ck\n");
218 } else {
219 sys_ck_rate = clk_get_rate(c);
220 clk_put(c);
221 }
222}