aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/db8500-prcmu.c
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2012-10-10 07:42:26 -0400
committerMike Turquette <mturquette@ti.com>2012-11-09 19:47:05 -0500
commitb2302c873bb7959958ffad4625a0876fc9294640 (patch)
tree59846adcade5981a64a7268375c56e91aa30b5b9 /drivers/mfd/db8500-prcmu.c
parentfdb44464ce844dc72e194a6671996fa8cfdbc532 (diff)
mfd: db8500: Connect ARMSS clk to ARM OPP
ARMSS clk directly maps it's frequency towards the cpufreq table. To be able to update the ARMSS clk rate, a new set_rate function for the ARMSS clk is added, which also will trigger a corresponding ARM OPP request. Additionally an ARMSS clk round_rate function is added to fetch valid cpufreq frequencies. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Samuel Ortiz <sameo@linux.intel.com> Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/mfd/db8500-prcmu.c')
-rw-r--r--drivers/mfd/db8500-prcmu.c78
1 files changed, 56 insertions, 22 deletions
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index ea1565018899..b96661d453aa 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -421,9 +421,6 @@ static struct {
421 421
422static atomic_t ac_wake_req_state = ATOMIC_INIT(0); 422static atomic_t ac_wake_req_state = ATOMIC_INIT(0);
423 423
424/* Functions definition */
425static void compute_armss_rate(void);
426
427/* Spinlocks */ 424/* Spinlocks */
428static DEFINE_SPINLOCK(prcmu_lock); 425static DEFINE_SPINLOCK(prcmu_lock);
429static DEFINE_SPINLOCK(clkout_lock); 426static DEFINE_SPINLOCK(clkout_lock);
@@ -1020,7 +1017,6 @@ int db8500_prcmu_set_arm_opp(u8 opp)
1020 (mb1_transfer.ack.arm_opp != opp)) 1017 (mb1_transfer.ack.arm_opp != opp))
1021 r = -EIO; 1018 r = -EIO;
1022 1019
1023 compute_armss_rate();
1024 mutex_unlock(&mb1_transfer.lock); 1020 mutex_unlock(&mb1_transfer.lock);
1025 1021
1026 return r; 1022 return r;
@@ -1670,13 +1666,8 @@ static unsigned long clock_rate(u8 clock)
1670 else 1666 else
1671 return 0; 1667 return 0;
1672} 1668}
1673static unsigned long latest_armss_rate;
1674static unsigned long armss_rate(void)
1675{
1676 return latest_armss_rate;
1677}
1678 1669
1679static void compute_armss_rate(void) 1670static unsigned long armss_rate(void)
1680{ 1671{
1681 u32 r; 1672 u32 r;
1682 unsigned long rate; 1673 unsigned long rate;
@@ -1701,7 +1692,7 @@ static void compute_armss_rate(void)
1701 rate = pll_rate(PRCM_PLLARM_FREQ, ROOT_CLOCK_RATE, PLL_DIV); 1692 rate = pll_rate(PRCM_PLLARM_FREQ, ROOT_CLOCK_RATE, PLL_DIV);
1702 } 1693 }
1703 1694
1704 latest_armss_rate = rate; 1695 return rate;
1705} 1696}
1706 1697
1707static unsigned long dsiclk_rate(u8 n) 1698static unsigned long dsiclk_rate(u8 n)
@@ -1821,6 +1812,35 @@ static long round_clock_rate(u8 clock, unsigned long rate)
1821 return rounded_rate; 1812 return rounded_rate;
1822} 1813}
1823 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
1824#define MIN_PLL_VCO_RATE 600000000ULL 1844#define MIN_PLL_VCO_RATE 600000000ULL
1825#define MAX_PLL_VCO_RATE 1680640000ULL 1845#define MAX_PLL_VCO_RATE 1680640000ULL
1826 1846
@@ -1892,6 +1912,8 @@ long prcmu_round_clock_rate(u8 clock, unsigned long rate)
1892{ 1912{
1893 if (clock < PRCMU_NUM_REG_CLOCKS) 1913 if (clock < PRCMU_NUM_REG_CLOCKS)
1894 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);
1895 else if (clock == PRCMU_PLLDSI) 1917 else if (clock == PRCMU_PLLDSI)
1896 return round_plldsi_rate(rate); 1918 return round_plldsi_rate(rate);
1897 else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK)) 1919 else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))
@@ -1951,6 +1973,27 @@ static void set_clock_rate(u8 clock, unsigned long rate)
1951 spin_unlock_irqrestore(&clk_mgt_lock, flags); 1973 spin_unlock_irqrestore(&clk_mgt_lock, flags);
1952} 1974}
1953 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
1954static int set_plldsi_rate(unsigned long rate) 1997static int set_plldsi_rate(unsigned long rate)
1955{ 1998{
1956 unsigned long src_rate; 1999 unsigned long src_rate;
@@ -2031,6 +2074,8 @@ int prcmu_set_clock_rate(u8 clock, unsigned long rate)
2031{ 2074{
2032 if (clock < PRCMU_NUM_REG_CLOCKS) 2075 if (clock < PRCMU_NUM_REG_CLOCKS)
2033 set_clock_rate(clock, rate); 2076 set_clock_rate(clock, rate);
2077 else if (clock == PRCMU_ARMSS)
2078 return set_armss_rate(rate);
2034 else if (clock == PRCMU_PLLDSI) 2079 else if (clock == PRCMU_PLLDSI)
2035 return set_plldsi_rate(rate); 2080 return set_plldsi_rate(rate);
2036 else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK)) 2081 else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))
@@ -2755,8 +2800,6 @@ void __init db8500_prcmu_early_init(void)
2755 init_completion(&mb5_transfer.work); 2800 init_completion(&mb5_transfer.work);
2756 2801
2757 INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work); 2802 INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work);
2758
2759 compute_armss_rate();
2760} 2803}
2761 2804
2762static void __init init_prcm_registers(void) 2805static void __init init_prcm_registers(void)
@@ -3003,15 +3046,6 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
3003 }, 3046 },
3004}; 3047};
3005 3048
3006/* CPU FREQ table, may be changed due to if MAX_OPP is supported. */
3007static struct cpufreq_frequency_table db8500_cpufreq_table[] = {
3008 { .frequency = 200000, .index = ARM_EXTCLK,},
3009 { .frequency = 400000, .index = ARM_50_OPP,},
3010 { .frequency = 800000, .index = ARM_100_OPP,},
3011 { .frequency = CPUFREQ_TABLE_END,}, /* To be used for MAX_OPP. */
3012 { .frequency = CPUFREQ_TABLE_END,},
3013};
3014
3015static struct resource ab8500_resources[] = { 3049static struct resource ab8500_resources[] = {
3016 [0] = { 3050 [0] = {
3017 .start = IRQ_DB8500_AB8500, 3051 .start = IRQ_DB8500_AB8500,