msm_xo: Work around RPM treating CXO_CLK and D0 as the same
On the RPM turning on the CXO_CLK resource turns on the D0
resource. Voting on the D0 resource doesn't do much besides
toggle the buffer on the PMIC. Since the D0_EN signal coming from
the MSM dictates if the buffer is on or not using the D0 buffer
resource is essentially a nop.
Remap the D0 buffer users to the CXO clock in the clock driver so
that the callers of the API don't have to deal with this problem.
Once the RPM properly separates the D0 buffer from the CXO_CLK
resource we can remove this.
Change-Id: I3d69fab415913489b70555e7e7e871000835f346
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 119f89c..9ab630d 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4865,6 +4865,7 @@
CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.2"),
CLK_LOOKUP("xo", cxo_clk.c, "pil_gss"),
CLK_LOOKUP("xo", cxo_clk.c, "BAM_RMNT"),
+ CLK_LOOKUP("xo", cxo_clk.c, "msm_xo"),
CLK_LOOKUP("pll2", pll2_clk.c, NULL),
CLK_LOOKUP("pll8", pll8_clk.c, NULL),
CLK_LOOKUP("pll4", pll4_clk.c, NULL),
@@ -5147,6 +5148,7 @@
CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.1"),
CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.2"),
CLK_LOOKUP("xo", cxo_clk.c, "BAM_RMNT"),
+ CLK_LOOKUP("xo", cxo_clk.c, "msm_xo"),
CLK_LOOKUP("pll2", pll2_clk.c, NULL),
CLK_LOOKUP("pll8", pll8_clk.c, NULL),
CLK_LOOKUP("pll4", pll4_clk.c, NULL),
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 3e059b6..e1dc2ae 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1602,6 +1602,7 @@
CLK_LOOKUP("xo", cxo_a_clk.c, ""),
CLK_LOOKUP("xo", cxo_clk.c, "msm_otg"),
CLK_LOOKUP("xo", cxo_clk.c, "BAM_RMNT"),
+ CLK_LOOKUP("xo", cxo_clk.c, "msm_xo"),
CLK_LOOKUP("pll0", pll0_clk.c, NULL),
CLK_LOOKUP("pll8", pll8_clk.c, NULL),
CLK_LOOKUP("pll14", pll14_clk.c, NULL),
diff --git a/arch/arm/mach-msm/msm_xo.c b/arch/arm/mach-msm/msm_xo.c
index 936fd6b..86776d3 100644
--- a/arch/arm/mach-msm/msm_xo.c
+++ b/arch/arm/mach-msm/msm_xo.c
@@ -21,6 +21,7 @@
#include <linux/seq_file.h>
#include <linux/uaccess.h>
#include <linux/string.h>
+#include <linux/clk.h>
#include <mach/msm_xo.h>
#include <mach/rpm.h>
@@ -232,6 +233,9 @@
{
int ret;
struct msm_xo *xo = xo_voter->xo;
+ int is_d0 = xo == &msm_xo_sources[MSM_XO_TCXO_D0];
+ int needs_workaround = cpu_is_msm8960() || cpu_is_apq8064() ||
+ cpu_is_msm8930() || cpu_is_msm9615();
if (xo_voter->mode == mode)
return 0;
@@ -244,6 +248,20 @@
xo->votes[mode]--;
goto out;
}
+ /* TODO: Remove once RPM separates the concept of D0 and CXO */
+ if (is_d0 && needs_workaround) {
+ static struct clk *xo_clk;
+
+ if (!xo_clk) {
+ xo_clk = clk_get_sys("msm_xo", "xo");
+ BUG_ON(IS_ERR(xo_clk));
+ }
+ /* Ignore transitions from pin to on or vice versa */
+ if (mode && xo_voter->mode == MSM_XO_MODE_OFF)
+ clk_enable(xo_clk);
+ else if (!mode)
+ clk_disable(xo_clk);
+ }
xo_voter->mode = mode;
out:
return ret;