--- 8871caa741eb11990cd9e4198e126163b73a8543 +++ fe181f76b0a281d66df201a66361841cf73d9b09 @@ -10,6 +10,7 @@ * GNU General Public License for more details. */ +#define ZVMIN 900000 #define pr_fmt(fmt) "%s: " fmt, __func__ #include @@ -40,6 +41,7 @@ #include #endif + /* * Source IDs. * These must be negative to not overlap with the source IDs @@ -72,6 +74,7 @@ #define HFPLL_NOMINAL_VDD 1050000 #define HFPLL_LOW_VDD 800000 +#define HFPLL_HIGH_VDD 1350000 #define HFPLL_LOW_VDD_PLL_L_MAX 0x28 #define SECCLKAGD BIT(4) @@ -1663,8 +1666,8 @@ static const int krait_needs_vmin(void) static void kraitv2_apply_vmin(struct acpu_level *tbl) { for (; tbl->speed.khz != 0; tbl++) - if (tbl->vdd_core < 1150000) - tbl->vdd_core = 1150000; + if (tbl->vdd_core < ZVMIN) + tbl->vdd_core = ZVMIN; } #ifdef CONFIG_SEC_L1_DCACHE_PANIC_CHK @@ -1811,3 +1814,33 @@ struct acpuclk_soc_data acpuclk_8960_soc struct acpuclk_soc_data acpuclk_8930_soc_data __initdata = { .init = acpuclk_8960_init, }; + +#ifdef CONFIG_VDD_USERSPACE +ssize_t acpuclk_get_vdd_levels_str(char *buf) +{ + int i, len = 0; + if (buf) { + mutex_lock(&driver_lock); + len += sprintf(buf + len, "Min: %4d\n", HFPLL_LOW_VDD); + len += sprintf(buf + len, "Max: %4d\n", HFPLL_HIGH_VDD); + for (i = 0; acpu_freq_tbl[i].speed.khz; i++) { + len += sprintf(buf + len, "%8u: %4d\n", acpu_freq_tbl[i].speed.khz, acpu_freq_tbl[i].vdd_core); + } + mutex_unlock(&driver_lock); + } + return len; +} + +void acpuclk_set_vdd(unsigned int khz, int vdd) +{ + int i; + mutex_lock(&driver_lock); + for (i = 0; acpu_freq_tbl[i].speed.khz; i++) { + if (khz == 0) + acpu_freq_tbl[i].vdd_core = min(max((unsigned int)(acpu_freq_tbl[i].vdd_core + vdd), (unsigned int)HFPLL_LOW_VDD), (unsigned int)HFPLL_HIGH_VDD); + else if (acpu_freq_tbl[i].speed.khz == khz) + acpu_freq_tbl[i].vdd_core = min(max((unsigned int)vdd, (unsigned int)HFPLL_LOW_VDD), (unsigned int)HFPLL_HIGH_VDD); + } + mutex_unlock(&driver_lock); +} +#endif