aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c66
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c19
-rw-r--r--arch/arm/mach-omap2/clock2430_data.c19
-rw-r--r--arch/arm/mach-omap2/clock2xxx.h2
4 files changed, 70 insertions, 36 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 @@
46const struct prcm_config *curr_prcm_set; 46const struct prcm_config *curr_prcm_set;
47const struct prcm_config *rate_table; 47const 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 */
54static 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)
67long omap2_round_to_table_rate(struct clk *clk, unsigned long rate) 74long 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 */
183void 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 */
209void 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}
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index d1034858b87a..1d1d77e510a3 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * OMAP2420 clock data 2 * OMAP2420 clock data
3 * 3 *
4 * Copyright (C) 2005-2009 Texas Instruments, Inc. 4 * Copyright (C) 2005-2009, 2012 Texas Instruments, Inc.
5 * Copyright (C) 2004-2011 Nokia Corporation 5 * Copyright (C) 2004-2011 Nokia Corporation
6 * 6 *
7 * Contacts: 7 * Contacts:
@@ -1925,9 +1925,7 @@ static struct omap_clk omap2420_clks[] = {
1925 1925
1926int __init omap2420_clk_init(void) 1926int __init omap2420_clk_init(void)
1927{ 1927{
1928 const struct prcm_config *prcm;
1929 struct omap_clk *c; 1928 struct omap_clk *c;
1930 u32 clkrate;
1931 1929
1932 prcm_clksrc_ctrl = OMAP2420_PRCM_CLKSRC_CTRL; 1930 prcm_clksrc_ctrl = OMAP2420_PRCM_CLKSRC_CTRL;
1933 cm_idlest_pll = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST); 1931 cm_idlest_pll = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST);
@@ -1950,20 +1948,13 @@ int __init omap2420_clk_init(void)
1950 omap2_init_clk_clkdm(c->lk.clk); 1948 omap2_init_clk_clkdm(c->lk.clk);
1951 } 1949 }
1952 1950
1951 omap2xxx_clkt_vps_late_init();
1952
1953 /* Disable autoidle on all clocks; let the PM code enable it later */ 1953 /* Disable autoidle on all clocks; let the PM code enable it later */
1954 omap_clk_disable_autoidle_all(); 1954 omap_clk_disable_autoidle_all();
1955 1955
1956 /* Check the MPU rate set by bootloader */ 1956 /* XXX Can this be done from the virt_prcm_set clk init function? */
1957 clkrate = omap2xxx_clk_get_core_rate(); 1957 omap2xxx_clkt_vps_check_bootloader_rates();
1958 for (prcm = rate_table; prcm->mpu_speed; prcm++) {
1959 if (!(prcm->flags & cpu_mask))
1960 continue;
1961 if (prcm->xtal_speed != sys_ck.rate)
1962 continue;
1963 if (prcm->dpll_speed <= clkrate)
1964 break;
1965 }
1966 curr_prcm_set = prcm;
1967 1958
1968 recalculate_root_clocks(); 1959 recalculate_root_clocks();
1969 1960
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index 3e16eab4691d..15d859ae283b 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * OMAP2430 clock data 2 * OMAP2430 clock data
3 * 3 *
4 * Copyright (C) 2005-2009 Texas Instruments, Inc. 4 * Copyright (C) 2005-2009, 2012 Texas Instruments, Inc.
5 * Copyright (C) 2004-2011 Nokia Corporation 5 * Copyright (C) 2004-2011 Nokia Corporation
6 * 6 *
7 * Contacts: 7 * Contacts:
@@ -2024,9 +2024,7 @@ static struct omap_clk omap2430_clks[] = {
2024 2024
2025int __init omap2430_clk_init(void) 2025int __init omap2430_clk_init(void)
2026{ 2026{
2027 const struct prcm_config *prcm;
2028 struct omap_clk *c; 2027 struct omap_clk *c;
2029 u32 clkrate;
2030 2028
2031 prcm_clksrc_ctrl = OMAP2430_PRCM_CLKSRC_CTRL; 2029 prcm_clksrc_ctrl = OMAP2430_PRCM_CLKSRC_CTRL;
2032 cm_idlest_pll = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST); 2030 cm_idlest_pll = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST);
@@ -2049,20 +2047,13 @@ int __init omap2430_clk_init(void)
2049 omap2_init_clk_clkdm(c->lk.clk); 2047 omap2_init_clk_clkdm(c->lk.clk);
2050 } 2048 }
2051 2049
2050 omap2xxx_clkt_vps_late_init();
2051
2052 /* Disable autoidle on all clocks; let the PM code enable it later */ 2052 /* Disable autoidle on all clocks; let the PM code enable it later */
2053 omap_clk_disable_autoidle_all(); 2053 omap_clk_disable_autoidle_all();
2054 2054
2055 /* Check the MPU rate set by bootloader */ 2055 /* XXX Can this be done from the virt_prcm_set clk init function? */
2056 clkrate = omap2xxx_clk_get_core_rate(); 2056 omap2xxx_clkt_vps_check_bootloader_rates();
2057 for (prcm = rate_table; prcm->mpu_speed; prcm++) {
2058 if (!(prcm->flags & cpu_mask))
2059 continue;
2060 if (prcm->xtal_speed != sys_ck.rate)
2061 continue;
2062 if (prcm->dpll_speed <= clkrate)
2063 break;
2064 }
2065 curr_prcm_set = prcm;
2066 2057
2067 recalculate_root_clocks(); 2058 recalculate_root_clocks();
2068 2059
diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h
index 19dc065901c7..25b8d0207527 100644
--- a/arch/arm/mach-omap2/clock2xxx.h
+++ b/arch/arm/mach-omap2/clock2xxx.h
@@ -20,6 +20,8 @@ u32 omap2xxx_get_apll_clkin(void);
20u32 omap2xxx_get_sysclkdiv(void); 20u32 omap2xxx_get_sysclkdiv(void);
21void omap2xxx_clk_prepare_for_reboot(void); 21void omap2xxx_clk_prepare_for_reboot(void);
22void omap2xxx_clkt_dpllcore_init(struct clk *clk); 22void omap2xxx_clkt_dpllcore_init(struct clk *clk);
23void omap2xxx_clkt_vps_check_bootloader_rates(void);
24void omap2xxx_clkt_vps_late_init(void);
23 25
24#ifdef CONFIG_SOC_OMAP2420 26#ifdef CONFIG_SOC_OMAP2420
25int omap2420_clk_init(void); 27int omap2420_clk_init(void);