diff options
| author | Ingo Molnar <mingo@kernel.org> | 2013-01-24 06:47:48 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2013-01-24 06:47:48 -0500 |
| commit | befddb21c845f8fb49e637997891ef97c6a869dc (patch) | |
| tree | 0e7629123184f2dd50291ad6d477b894175f0f26 /arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c | |
| parent | e716efde75267eab919cdb2bef5b2cb77f305326 (diff) | |
| parent | 7d1f9aeff1ee4a20b1aeb377dd0f579fe9647619 (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.c | 85 |
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 | ||
| 47 | const struct prcm_config *curr_prcm_set; | 45 | const struct prcm_config *curr_prcm_set; |
| 48 | const struct prcm_config *rate_table; | 46 | const 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 | */ | ||
| 53 | static 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 | */ |
| 56 | unsigned long omap2_table_mpu_recalc(struct clk *clk) | 61 | unsigned 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 | */ |
| 68 | long omap2_round_to_table_rate(struct clk *clk, unsigned long rate) | 74 | long 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 */ |
| 92 | int omap2_select_table_rate(struct clk *clk, unsigned long rate) | 98 | int 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 | */ | ||
| 185 | void 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 | */ | ||
| 211 | void 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 | } | ||
