Initial INC MR3 commit with EVO/BRAVO included and majority of the compile warnings ...
/arch/arm/mach-msm/acpuclock-scorpion.c
blob:44e9b60ca0569c7bde4caa5e05595996596a2ed7 -> blob:da51162d5ad0246de7a488ffefec9e192a73472e
--- arch/arm/mach-msm/acpuclock-scorpion.c
+++ arch/arm/mach-msm/acpuclock-scorpion.c
@@ -27,6 +27,9 @@
#include <mach/msm_iomap.h>
#include "acpuclock.h"
+#ifdef CONFIG_MSM_CPU_AVS
+#include "avs.h"
+#endif
#include "proc_comm.h"
#include "clock.h"
@@ -73,28 +76,32 @@ struct clkctl_acpu_speed {
#define SRC_PLL1 3 /* 768 MHz */
struct clkctl_acpu_speed acpu_freq_tbl[] = {
- { 19200, CCTL(CLK_TCXO, 1), SRC_RAW, 0, 0, 1050, 14000},
- { 128000, CCTL(CLK_TCXO, 1), SRC_AXI, 0, 0, 1050, 14000 },
- { 245000, CCTL(CLK_MODEM_PLL, 1), SRC_RAW, 0, 0, 1050, 29000 },
- /* Work arround for acpu resume hung, GPLL is turn off by arm9 */
- /*{ 256000, CCTL(CLK_GLOBAL_PLL, 3), SRC_RAW, 0, 0, 1050, 29000 },*/
- { 384000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0A, 0, 1050, 58000 },
- { 422400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0B, 0, 1050, 117000 },
- { 460800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0C, 0, 1050, 117000 },
- { 499200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0D, 0, 1075, 117000 },
- { 537600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0E, 0, 1100, 117000 },
- { 576000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0F, 0, 1100, 117000 },
- { 614400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x10, 0, 1125, 117000 },
- { 652800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x11, 0, 1150, 117000 },
- { 691200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x12, 0, 1175, 117000 },
- { 729600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x13, 0, 1200, 117000 },
- { 768000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x14, 0, 1200, 128000 },
- { 806400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x15, 0, 1225, 128000 },
- { 844800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x16, 0, 1250, 128000 },
- { 883200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x17, 0, 1275, 128000 },
- { 921600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x18, 0, 1300, 128000 },
- { 960000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x19, 0, 1300, 128000 },
- { 998400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1A, 0, 1300, 128000 },
+ { 19200, CCTL(CLK_TCXO, 1), SRC_RAW, 0, 0, 925, 14000},
+ { 128000, CCTL(CLK_TCXO, 1), SRC_AXI, 0, 0, 925, 14000 },
+ { 245000, CCTL(CLK_MODEM_PLL, 1), SRC_RAW, 0, 0, 925, 29000 },
+ { 384000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0A, 0, 975, 58000 },
+ { 422400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0B, 0, 975, 117000 },
+ { 460800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0C, 0, 1000, 117000 },
+ { 499200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0D, 0, 1025, 117000 },
+ { 537600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0E, 0, 1050, 117000 },
+ { 576000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0F, 0, 1075, 117000 },
+ { 614400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x10, 0, 1075, 117000 },
+ { 652800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x11, 0, 1100, 117000 },
+ { 691200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x12, 0, 1125, 117000 },
+ { 729600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x13, 0, 1150, 117000 },
+ { 768000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x14, 0, 1175, 128000 },
+ { 806400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x15, 0, 1200, 128000 },
+ { 844800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x16, 0, 1200, 128000 },
+ { 883200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x17, 0, 1225, 128000 },
+ { 921600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x18, 0, 1225, 128000 },
+ { 960000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x19, 0, 1250, 128000 },
+ { 998400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1A, 0, 1250, 128000 },
+ { 1036800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1B, 0, 1300, 128000 },
+ { 1075200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1C, 0, 1300, 128000 },
+ { 1113600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1D, 0, 1325, 128000 },
+ { 1152000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1E, 0, 1350, 128000 },
+ { 1190400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1F, 0, 1350, 128000 },
+ { 1228800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x20, 0, 1400, 128000 },
{ 0 },
};
@@ -134,7 +141,7 @@ static void __init acpuclk_init_cpufreq_
}
/* Take the fastest speed available at the specified VDD level */
- if (vdd != acpu_freq_tbl[i + 1].vdd)
+// if (vdd != acpu_freq_tbl[i + 1].vdd)
freq_table[i].frequency = acpu_freq_tbl[i].acpu_khz;
}
@@ -149,14 +156,15 @@ static void __init acpuclk_init_cpufreq_
struct clock_state {
struct clkctl_acpu_speed *current_speed;
- struct mutex lock;
+ struct mutex lock;
uint32_t acpu_switch_time_us;
uint32_t max_speed_delta_khz;
uint32_t vdd_switch_time_us;
- unsigned long power_collapse_khz;
- unsigned long wait_for_irq_khz;
+ unsigned long power_collapse_khz;
+ unsigned long wait_for_irq_khz;
struct clk* clk_ebi1;
- struct regulator *regulator;
+ struct regulator *regulator;
+ int (*acpu_set_vdd) (int mvolts);
};
static struct clock_state drv_state = { 0 };
@@ -280,27 +288,41 @@ static void select_clock(unsigned src, u
writel(val | ((src & 3) << 1), SPSS_CLK_SEL_ADDR);
}
-static int acpuclk_set_vdd_level(int vdd)
+static int acpu_set_vdd(int vdd)
{
if (!drv_state.regulator || IS_ERR(drv_state.regulator)) {
drv_state.regulator = regulator_get(NULL, "acpu_vcore");
if (IS_ERR(drv_state.regulator)) {
- pr_info("acpuclk_set_vdd_level %d no regulator\n", vdd);
+ pr_info("acpu_set_vdd %d no regulator\n", vdd);
/* Assume that the PMIC supports scaling the processor
* to its maximum frequency at its default voltage.
*/
- return 0;
+ return -ENODEV;
}
- pr_info("acpuclk_set_vdd_level got regulator\n");
+ pr_info("acpu_set_vdd got regulator\n");
}
vdd *= 1000; /* mV -> uV */
return regulator_set_voltage(drv_state.regulator, vdd, vdd);
}
+static int acpuclk_set_vdd_level(int vdd)
+{
+ if (drv_state.acpu_set_vdd)
+ return drv_state.acpu_set_vdd(vdd);
+ else {
+ /* Assume that the PMIC supports scaling the processor
+ * to its maximum frequency at its default voltage.
+ */
+ return 0;
+ }
+}
+
int acpuclk_set_rate(unsigned long rate, enum setrate_reason reason)
{
struct clkctl_acpu_speed *cur, *next;
unsigned long flags;
+ int rc = 0;
+ int freq_index = 0;
cur = drv_state.current_speed;
@@ -319,16 +341,29 @@ int acpuclk_set_rate(unsigned long rate,
if (next->acpu_khz == 0)
return -EINVAL;
next++;
+ freq_index++;
}
if (reason == SETRATE_CPUFREQ) {
mutex_lock(&drv_state.lock);
+#ifdef CONFIG_MSM_CPU_AVS
+ /* Notify avs before changing frequency */
+ rc = avs_adjust_freq(freq_index, 1);
+ if (rc) {
+ printk(KERN_ERR
+ "acpuclock: Unable to increase ACPU "
+ "vdd: %d.\n", (int) rate);
+ mutex_unlock(&drv_state.lock);
+ return rc;
+ }
+#endif
/* Increase VDD if needed. */
if (next->vdd > cur->vdd) {
- if (acpuclk_set_vdd_level(next->vdd)) {
- pr_err("acpuclock: Unable to increase ACPU VDD.\n");
+ rc = acpuclk_set_vdd_level(next->vdd);
+ if (rc) {
+ pr_err("acpuclock: Unable to increase ACPU VDD from %d to %d setting rate to %d.\n", cur->vdd, next->vdd, (int) rate);
mutex_unlock(&drv_state.lock);
- return -EINVAL;
+ return rc;
}
}
}
@@ -361,24 +396,28 @@ int acpuclk_set_rate(unsigned long rate,
spin_unlock_irqrestore(&acpu_lock, flags);
-#ifndef CONFIG_AXI_SCREEN_POLICY
if (reason == SETRATE_CPUFREQ || reason == SETRATE_PC) {
if (cur->axiclk_khz != next->axiclk_khz)
clk_set_rate(drv_state.clk_ebi1, next->axiclk_khz * 1000);
- DEBUG("acpuclk_set_rate switch axi to %d\n",
- clk_get_rate(drv_state.clk_ebi1));
}
-#endif
+
if (reason == SETRATE_CPUFREQ) {
+#ifdef CONFIG_MSM_CPU_AVS
+ /* notify avs after changing frequency */
+ rc = avs_adjust_freq(freq_index, 0);
+ if (rc)
+ printk(KERN_ERR "acpuclock: Unable to drop ACPU vdd: %d.\n", (int) rate);
+#endif
/* Drop VDD level if we can. */
if (next->vdd < cur->vdd) {
- if (acpuclk_set_vdd_level(next->vdd))
- pr_err("acpuclock: Unable to drop ACPU VDD.\n");
+ rc = acpuclk_set_vdd_level(next->vdd);
+ if (rc)
+ pr_err("acpuclock: Unable to drop ACPU VDD from %d to %d setting rate to %d.\n", cur->vdd, next->vdd, (int) rate);
}
mutex_unlock(&drv_state.lock);
}
- return 0;
+ return rc;
}
static unsigned __init acpuclk_find_speed(void)
@@ -407,57 +446,6 @@ static int pll_request(unsigned id, unsi
return msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on);
}
-/* Spare register populated with efuse data on max ACPU freq. */
-#define CT_CSR_PHYS 0xA8700000
-#define TCSR_SPARE2_ADDR (ct_csr_base + 0x60)
-
-void __init acpu_freq_tbl_fixup(void)
-{
- void __iomem *ct_csr_base;
- uint32_t tcsr_spare2;
- unsigned int max_acpu_khz;
- unsigned int i;
-
- ct_csr_base = ioremap(CT_CSR_PHYS, PAGE_SIZE);
- BUG_ON(ct_csr_base == NULL);
-
- tcsr_spare2 = readl(TCSR_SPARE2_ADDR);
-
- /* Check if the register is supported and meaningful. */
- if ((tcsr_spare2 & 0xF000) != 0xA000) {
- pr_info("Efuse data on Max ACPU freq not present.\n");
- goto skip_efuse_fixup;
- }
-
- switch (tcsr_spare2 & 0xF0) {
- case 0x70:
- max_acpu_khz = 768000;
- break;
- case 0x30:
- case 0x00:
- max_acpu_khz = 998400;
- break;
- case 0x10:
- max_acpu_khz = 1267200;
- break;
- default:
- pr_warning("Invalid efuse data (%x) on Max ACPU freq!\n",
- tcsr_spare2);
- goto skip_efuse_fixup;
- }
-
- pr_info("Max ACPU freq from efuse data is %d KHz\n", max_acpu_khz);
-
- for (i = 0; acpu_freq_tbl[i].acpu_khz != 0; i++) {
- if (acpu_freq_tbl[i].acpu_khz > max_acpu_khz) {
- acpu_freq_tbl[i].acpu_khz = 0;
- break;
- }
- }
-skip_efuse_fixup:
- iounmap(ct_csr_base);
-}
-
static void __init acpuclk_init(void)
{
struct clkctl_acpu_speed *speed;
@@ -480,15 +468,15 @@ static void __init acpuclk_init(void)
BUG();
}
- /* Move to 768MHz for boot, which is a safe frequency
+ /* Move to 998MHz for boot, which is a safe frequency
* for all versions of Scorpion at the moment.
*/
speed = acpu_freq_tbl;
for (;;) {
- if (speed->acpu_khz == 768000)
+ if (speed->acpu_khz == 998400)
break;
if (speed->acpu_khz == 0) {
- pr_err("acpuclk_init: cannot find 768MHz\n");
+ pr_err("acpuclk_init: cannot find 998MHz\n");
BUG();
}
speed++;
@@ -546,6 +534,23 @@ unsigned long acpuclk_wait_for_irq(void)
return ret * 1000;
}
+#ifdef CONFIG_MSM_CPU_AVS
+static int __init acpu_avs_init(int (*set_vdd) (int), int khz)
+{
+ int i;
+ int freq_count = 0;
+ int freq_index = -1;
+
+ for (i = 0; acpu_freq_tbl[i].acpu_khz; i++) {
+ freq_count++;
+ if (acpu_freq_tbl[i].acpu_khz == khz)
+ freq_index = i;
+ }
+
+ return avs_init(set_vdd, freq_count, freq_index);
+}
+#endif
+
void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *clkdata)
{
spin_lock_init(&acpu_lock);
@@ -556,15 +561,66 @@ void __init msm_acpu_clock_init(struct m
drv_state.vdd_switch_time_us = clkdata->vdd_switch_time_us;
drv_state.power_collapse_khz = clkdata->power_collapse_khz;
drv_state.wait_for_irq_khz = clkdata->wait_for_irq_khz;
-
+ drv_state.acpu_set_vdd = acpu_set_vdd;
+
if (clkdata->mpll_khz)
acpu_mpll->acpu_khz = clkdata->mpll_khz;
- acpu_freq_tbl_fixup();
acpuclk_init();
acpuclk_init_cpufreq_table();
drv_state.clk_ebi1 = clk_get(NULL,"ebi1_clk");
-#ifndef CONFIG_AXI_SCREEN_POLICY
clk_set_rate(drv_state.clk_ebi1, drv_state.current_speed->axiclk_khz * 1000);
+
+#ifdef CONFIG_MSM_CPU_AVS
+ if (!acpu_avs_init(drv_state.acpu_set_vdd,
+ drv_state.current_speed->acpu_khz)) {
+ /* avs init successful. avs will handle voltage changes */
+ drv_state.acpu_set_vdd = NULL;
+ }
#endif
}
+
+#ifdef CONFIG_CPU_FREQ_VDD_LEVELS
+#ifndef CONFIG_MSM_CPU_AVS
+ssize_t acpuclk_get_vdd_levels_str(char *buf)
+{
+ int i, len = 0;
+ if (buf)
+ {
+ mutex_lock(&drv_state.lock);
+ for (i = 0; acpu_freq_tbl[i].acpu_khz; i++)
+ {
+ if (freq_table[i].frequency != CPUFREQ_ENTRY_INVALID)
+ len += sprintf(buf + len, "%8u: %4d\n", acpu_freq_tbl[i].acpu_khz, acpu_freq_tbl[i].vdd);
+ }
+ mutex_unlock(&drv_state.lock);
+ }
+ return len;
+}
+
+void acpuclk_set_vdd(unsigned acpu_khz, int max_vdd)
+{
+ int i;
+ struct clkctl_acpu_speed *cur;
+ cur = drv_state.current_speed;
+ max_vdd = max_vdd / 25 * 25; //! regulator only accepts multiples of 25 (mV)
+ mutex_lock(&drv_state.lock);
+ for (i = 0; acpu_freq_tbl[i].acpu_khz; i++)
+ {
+ if (freq_table[i].frequency != CPUFREQ_ENTRY_INVALID)
+ {
+ if (acpu_khz == 0) {
+ acpu_freq_tbl[i].vdd = min(max((acpu_freq_tbl[i].vdd + max_vdd), CONFIG_CPU_FREQ_VDD_LEVELS_MIN), CONFIG_CPU_FREQ_VDD_LEVELS_MAX);
+ if(cur->acpu_khz == acpu_freq_tbl[i].acpu_khz)
+ acpuclk_set_vdd_level(acpu_freq_tbl[i].vdd);
+ } else if (acpu_freq_tbl[i].acpu_khz == acpu_khz) {
+ acpu_freq_tbl[i].vdd = min(max(max_vdd, CONFIG_CPU_FREQ_VDD_LEVELS_MIN), CONFIG_CPU_FREQ_VDD_LEVELS_MAX);
+ if(cur->acpu_khz == acpu_freq_tbl[i].acpu_khz)
+ acpuclk_set_vdd_level(acpu_freq_tbl[i].vdd);
+ }
+ }
+ }
+ mutex_unlock(&drv_state.lock);
+}
+#endif
+#endif