diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2012-10-10 07:42:26 -0400 |
---|---|---|
committer | Mike Turquette <mturquette@ti.com> | 2012-11-09 19:47:05 -0500 |
commit | b2302c873bb7959958ffad4625a0876fc9294640 (patch) | |
tree | 59846adcade5981a64a7268375c56e91aa30b5b9 /drivers/mfd/db8500-prcmu.c | |
parent | fdb44464ce844dc72e194a6671996fa8cfdbc532 (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.c | 78 |
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 | ||
422 | static atomic_t ac_wake_req_state = ATOMIC_INIT(0); | 422 | static atomic_t ac_wake_req_state = ATOMIC_INIT(0); |
423 | 423 | ||
424 | /* Functions definition */ | ||
425 | static void compute_armss_rate(void); | ||
426 | |||
427 | /* Spinlocks */ | 424 | /* Spinlocks */ |
428 | static DEFINE_SPINLOCK(prcmu_lock); | 425 | static DEFINE_SPINLOCK(prcmu_lock); |
429 | static DEFINE_SPINLOCK(clkout_lock); | 426 | static 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 | } |
1673 | static unsigned long latest_armss_rate; | ||
1674 | static unsigned long armss_rate(void) | ||
1675 | { | ||
1676 | return latest_armss_rate; | ||
1677 | } | ||
1678 | 1669 | ||
1679 | static void compute_armss_rate(void) | 1670 | static 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 | ||
1707 | static unsigned long dsiclk_rate(u8 n) | 1698 | static 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. */ | ||
1816 | static 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 | |||
1824 | static 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 | ||
1976 | static 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 | |||
1954 | static int set_plldsi_rate(unsigned long rate) | 1997 | static 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 | ||
2762 | static void __init init_prcm_registers(void) | 2805 | static 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. */ | ||
3007 | static 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 | |||
3015 | static struct resource ab8500_resources[] = { | 3049 | static struct resource ab8500_resources[] = { |
3016 | [0] = { | 3050 | [0] = { |
3017 | .start = IRQ_DB8500_AB8500, | 3051 | .start = IRQ_DB8500_AB8500, |