aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-11 14:25:08 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-11 14:25:08 -0500
commit93874681aa3f538a2b9d59a6c5b7c0e882a36978 (patch)
tree6ec88fb9fb50e2b5e15b008e7353cc7d6395e1f8 /drivers/mfd
parent505cbedab9c7c565957e64af6348e5d84acd510e (diff)
parent8f87189653d60656e262060665f52c855508a301 (diff)
Merge tag 'clk-for-linus' of git://git.linaro.org/people/mturquette/linux
Pull clock framework changes from Mike Turquette: "The common clock framework changes for 3.8 are comprised of lots of fixes for existing platforms as well as new ports for some ARM platforms. In addition there are new clk drivers for audio devices and MFDs." Fix up trivial conflict in <linux/clk-provider.h> (removal of 'inline' clashing with return type fixes) * tag 'clk-for-linus' of git://git.linaro.org/people/mturquette/linux: (51 commits) MAINTAINERS: bad email address for Mike Turquette clk: introduce optional disable_unused callback clk: ux500: fix bit error clk: clock multiplexers may register out of order clk: ux500: Initial support for abx500 clock driver CLK: SPEAr: Remove unused dummy apb_pclk CLK: SPEAr: Correct index scanning done for clock synths CLK: SPEAr: Update clock rate table CLK: SPEAr: Add missing clocks CLK: SPEAr: Set CLK_SET_RATE_PARENT for few clocks CLK: SPEAr13xx: fix parent names of multiple clocks CLK: SPEAr13xx: Fix mux clock names CLK: SPEAr: Fix dev_id & con_id for multiple clocks clk: move IM-PD1 clocks to drivers/clk clk: make ICST driver handle the VCO registers clk: add GPLv2 headers to the Versatile clock files clk: mxs: Use a better name for the USB PHY clock clk: spear: Add stub functions for spear3[0|1|2]0_clk_init() CLK: clk-twl6040: fix return value check in twl6040_clk_probe() clk: ux500: Register nomadik keypad clock lookups for u8500 ...
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/db8500-prcmu.c86
1 files changed, 71 insertions, 15 deletions
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 00b8b0f3dfb6..b96661d453aa 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -31,6 +31,7 @@
31#include <linux/mfd/abx500/ab8500.h> 31#include <linux/mfd/abx500/ab8500.h>
32#include <linux/regulator/db8500-prcmu.h> 32#include <linux/regulator/db8500-prcmu.h>
33#include <linux/regulator/machine.h> 33#include <linux/regulator/machine.h>
34#include <linux/cpufreq.h>
34#include <asm/hardware/gic.h> 35#include <asm/hardware/gic.h>
35#include <mach/hardware.h> 36#include <mach/hardware.h>
36#include <mach/irqs.h> 37#include <mach/irqs.h>
@@ -420,9 +421,6 @@ static struct {
420 421
421static atomic_t ac_wake_req_state = ATOMIC_INIT(0); 422static atomic_t ac_wake_req_state = ATOMIC_INIT(0);
422 423
423/* Functions definition */
424static void compute_armss_rate(void);
425
426/* Spinlocks */ 424/* Spinlocks */
427static DEFINE_SPINLOCK(prcmu_lock); 425static DEFINE_SPINLOCK(prcmu_lock);
428static DEFINE_SPINLOCK(clkout_lock); 426static DEFINE_SPINLOCK(clkout_lock);
@@ -1019,7 +1017,6 @@ int db8500_prcmu_set_arm_opp(u8 opp)
1019 (mb1_transfer.ack.arm_opp != opp)) 1017 (mb1_transfer.ack.arm_opp != opp))
1020 r = -EIO; 1018 r = -EIO;
1021 1019
1022 compute_armss_rate();
1023 mutex_unlock(&mb1_transfer.lock); 1020 mutex_unlock(&mb1_transfer.lock);
1024 1021
1025 return r; 1022 return r;
@@ -1169,12 +1166,12 @@ int db8500_prcmu_get_ape_opp(void)
1169} 1166}
1170 1167
1171/** 1168/**
1172 * prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage 1169 * db8500_prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage
1173 * @enable: true to request the higher voltage, false to drop a request. 1170 * @enable: true to request the higher voltage, false to drop a request.
1174 * 1171 *
1175 * Calls to this function to enable and disable requests must be balanced. 1172 * Calls to this function to enable and disable requests must be balanced.
1176 */ 1173 */
1177int prcmu_request_ape_opp_100_voltage(bool enable) 1174int db8500_prcmu_request_ape_opp_100_voltage(bool enable)
1178{ 1175{
1179 int r = 0; 1176 int r = 0;
1180 u8 header; 1177 u8 header;
@@ -1669,13 +1666,8 @@ static unsigned long clock_rate(u8 clock)
1669 else 1666 else
1670 return 0; 1667 return 0;
1671} 1668}
1672static unsigned long latest_armss_rate;
1673static unsigned long armss_rate(void)
1674{
1675 return latest_armss_rate;
1676}
1677 1669
1678static void compute_armss_rate(void) 1670static unsigned long armss_rate(void)
1679{ 1671{
1680 u32 r; 1672 u32 r;
1681 unsigned long rate; 1673 unsigned long rate;
@@ -1700,7 +1692,7 @@ static void compute_armss_rate(void)
1700 rate = pll_rate(PRCM_PLLARM_FREQ, ROOT_CLOCK_RATE, PLL_DIV); 1692 rate = pll_rate(PRCM_PLLARM_FREQ, ROOT_CLOCK_RATE, PLL_DIV);
1701 } 1693 }
1702 1694
1703 latest_armss_rate = rate; 1695 return rate;
1704} 1696}
1705 1697
1706static unsigned long dsiclk_rate(u8 n) 1698static unsigned long dsiclk_rate(u8 n)
@@ -1820,6 +1812,35 @@ static long round_clock_rate(u8 clock, unsigned long rate)
1820 return rounded_rate; 1812 return rounded_rate;
1821} 1813}
1822 1814
1815/* CPU FREQ table, may be changed due to if MAX_OPP is supported. */
1816static struct cpufreq_frequency_table db8500_cpufreq_table[] = {
1817 { .frequency = 200000, .index = ARM_EXTCLK,},
1818 { .frequency = 400000, .index = ARM_50_OPP,},
1819 { .frequency = 800000, .index = ARM_100_OPP,},
1820 { .frequency = CPUFREQ_TABLE_END,}, /* To be used for MAX_OPP. */
1821 { .frequency = CPUFREQ_TABLE_END,},
1822};
1823
1824static long round_armss_rate(unsigned long rate)
1825{
1826 long freq = 0;
1827 int i = 0;
1828
1829 /* cpufreq table frequencies is in KHz. */
1830 rate = rate / 1000;
1831
1832 /* Find the corresponding arm opp from the cpufreq table. */
1833 while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) {
1834 freq = db8500_cpufreq_table[i].frequency;
1835 if (freq == rate)
1836 break;
1837 i++;
1838 }
1839
1840 /* Return the last valid value, even if a match was not found. */
1841 return freq * 1000;
1842}
1843
1823#define MIN_PLL_VCO_RATE 600000000ULL 1844#define MIN_PLL_VCO_RATE 600000000ULL
1824#define MAX_PLL_VCO_RATE 1680640000ULL 1845#define MAX_PLL_VCO_RATE 1680640000ULL
1825 1846
@@ -1891,6 +1912,8 @@ long prcmu_round_clock_rate(u8 clock, unsigned long rate)
1891{ 1912{
1892 if (clock < PRCMU_NUM_REG_CLOCKS) 1913 if (clock < PRCMU_NUM_REG_CLOCKS)
1893 return round_clock_rate(clock, rate); 1914 return round_clock_rate(clock, rate);
1915 else if (clock == PRCMU_ARMSS)
1916 return round_armss_rate(rate);
1894 else if (clock == PRCMU_PLLDSI) 1917 else if (clock == PRCMU_PLLDSI)
1895 return round_plldsi_rate(rate); 1918 return round_plldsi_rate(rate);
1896 else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK)) 1919 else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))
@@ -1950,6 +1973,27 @@ static void set_clock_rate(u8 clock, unsigned long rate)
1950 spin_unlock_irqrestore(&clk_mgt_lock, flags); 1973 spin_unlock_irqrestore(&clk_mgt_lock, flags);
1951} 1974}
1952 1975
1976static int set_armss_rate(unsigned long rate)
1977{
1978 int i = 0;
1979
1980 /* cpufreq table frequencies is in KHz. */
1981 rate = rate / 1000;
1982
1983 /* Find the corresponding arm opp from the cpufreq table. */
1984 while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) {
1985 if (db8500_cpufreq_table[i].frequency == rate)
1986 break;
1987 i++;
1988 }
1989
1990 if (db8500_cpufreq_table[i].frequency != rate)
1991 return -EINVAL;
1992
1993 /* Set the new arm opp. */
1994 return db8500_prcmu_set_arm_opp(db8500_cpufreq_table[i].index);
1995}
1996
1953static int set_plldsi_rate(unsigned long rate) 1997static int set_plldsi_rate(unsigned long rate)
1954{ 1998{
1955 unsigned long src_rate; 1999 unsigned long src_rate;
@@ -2030,6 +2074,8 @@ int prcmu_set_clock_rate(u8 clock, unsigned long rate)
2030{ 2074{
2031 if (clock < PRCMU_NUM_REG_CLOCKS) 2075 if (clock < PRCMU_NUM_REG_CLOCKS)
2032 set_clock_rate(clock, rate); 2076 set_clock_rate(clock, rate);
2077 else if (clock == PRCMU_ARMSS)
2078 return set_armss_rate(rate);
2033 else if (clock == PRCMU_PLLDSI) 2079 else if (clock == PRCMU_PLLDSI)
2034 return set_plldsi_rate(rate); 2080 return set_plldsi_rate(rate);
2035 else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK)) 2081 else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))
@@ -2754,8 +2800,6 @@ void __init db8500_prcmu_early_init(void)
2754 init_completion(&mb5_transfer.work); 2800 init_completion(&mb5_transfer.work);
2755 2801
2756 INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work); 2802 INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work);
2757
2758 compute_armss_rate();
2759} 2803}
2760 2804
2761static void __init init_prcm_registers(void) 2805static void __init init_prcm_registers(void)
@@ -3020,6 +3064,8 @@ static struct mfd_cell db8500_prcmu_devs[] = {
3020 { 3064 {
3021 .name = "cpufreq-u8500", 3065 .name = "cpufreq-u8500",
3022 .of_compatible = "stericsson,cpufreq-u8500", 3066 .of_compatible = "stericsson,cpufreq-u8500",
3067 .platform_data = &db8500_cpufreq_table,
3068 .pdata_size = sizeof(db8500_cpufreq_table),
3023 }, 3069 },
3024 { 3070 {
3025 .name = "ab8500-core", 3071 .name = "ab8500-core",
@@ -3030,6 +3076,14 @@ static struct mfd_cell db8500_prcmu_devs[] = {
3030 }, 3076 },
3031}; 3077};
3032 3078
3079static void db8500_prcmu_update_cpufreq(void)
3080{
3081 if (prcmu_has_arm_maxopp()) {
3082 db8500_cpufreq_table[3].frequency = 1000000;
3083 db8500_cpufreq_table[3].index = ARM_MAX_OPP;
3084 }
3085}
3086
3033/** 3087/**
3034 * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic 3088 * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic
3035 * 3089 *
@@ -3074,6 +3128,8 @@ static int __devinit db8500_prcmu_probe(struct platform_device *pdev)
3074 if (cpu_is_u8500v20_or_later()) 3128 if (cpu_is_u8500v20_or_later())
3075 prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); 3129 prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);
3076 3130
3131 db8500_prcmu_update_cpufreq();
3132
3077 err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, 3133 err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs,
3078 ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL); 3134 ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL);
3079 if (err) { 3135 if (err) {