msm: acpuclock-krait: Enforce CPU HFPLL vdd_dig requirements
Part of the CPU HFPLL logic lives in the vdd_dig domain and has
voltage requirements that vary based on the PLL frequency. Capture
this in the code.
Even without this change, vdd_dig levels are sufficiently high due
to the vdd_dig votes already made for the L2. This change improves
robustness, however, and protects us should the CPU->L2 frequency
mappings ever change.
Change-Id: Id54a97a5be5dbe4ba61d6fa8ba5b259b3538a0be
Signed-off-by: Matt Wagantall <mattw@codeaurora.org>
diff --git a/arch/arm/mach-msm/acpuclock-krait.c b/arch/arm/mach-msm/acpuclock-krait.c
index d6f98b0..f796c5f 100644
--- a/arch/arm/mach-msm/acpuclock-krait.c
+++ b/arch/arm/mach-msm/acpuclock-krait.c
@@ -383,20 +383,28 @@
return drv.l2_freq_tbl[tgt->l2_level].vdd_mem;
}
-static int calculate_vdd_dig(const struct acpu_level *tgt)
+static int get_src_dig(const struct core_speed *s)
{
- int pll_vdd_dig;
const int *hfpll_vdd = drv.hfpll_data->vdd;
const u32 low_vdd_l_max = drv.hfpll_data->low_vdd_l_max;
- if (drv.l2_freq_tbl[tgt->l2_level].speed.src != HFPLL)
- pll_vdd_dig = hfpll_vdd[HFPLL_VDD_NONE];
- else if (drv.l2_freq_tbl[tgt->l2_level].speed.pll_l_val > low_vdd_l_max)
- pll_vdd_dig = hfpll_vdd[HFPLL_VDD_NOM];
+ if (s->src != HFPLL)
+ return hfpll_vdd[HFPLL_VDD_NONE];
+ else if (s->pll_l_val > low_vdd_l_max)
+ return hfpll_vdd[HFPLL_VDD_NOM];
else
- pll_vdd_dig = hfpll_vdd[HFPLL_VDD_LOW];
+ return hfpll_vdd[HFPLL_VDD_LOW];
+}
- return max(drv.l2_freq_tbl[tgt->l2_level].vdd_dig, pll_vdd_dig);
+static int calculate_vdd_dig(const struct acpu_level *tgt)
+{
+ int l2_pll_vdd_dig, cpu_pll_vdd_dig;
+
+ l2_pll_vdd_dig = get_src_dig(&drv.l2_freq_tbl[tgt->l2_level].speed);
+ cpu_pll_vdd_dig = get_src_dig(&tgt->speed);
+
+ return max(drv.l2_freq_tbl[tgt->l2_level].vdd_dig,
+ max(l2_pll_vdd_dig, cpu_pll_vdd_dig));
}
static int calculate_vdd_core(const struct acpu_level *tgt)