msm: clock-8960: Add support for measuring CPU and L2 clocks
Add measurement support for l2_m_clk, krait0_m_clk and
krait1_m_clk to debugfs, which can be used to route out these
clocks to the PLL test pin. Software measurement is also
supported, but its usefulness is limited due to dynamic gating
of these clocks during the measurements, and the fact that some
rates for these clocks may be higher than the maximum rate the
measurement hardware can resolve.
Signed-off-by: Matt Wagantall <mattw@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 76d9590..3b10784 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -37,6 +37,7 @@
#define REG(off) (MSM_CLK_CTL_BASE + (off))
#define REG_MM(off) (MSM_MMSS_CLK_CTL_BASE + (off))
#define REG_LPA(off) (MSM_LPASS_CLK_CTL_BASE + (off))
+#define REG_GCC(off) (MSM_APCS_GCC_BASE + (off))
/* Peripheral clock registers. */
#define CE1_HCLK_CTL_REG REG(0x2720)
@@ -209,6 +210,8 @@
#define LCC_SLIMBUS_STATUS_REG REG_LPA(0x00D4)
#define LCC_AHBEX_BRANCH_CTL_REG REG_LPA(0x00E4)
+#define GCC_APCS_CLK_DIAG REG_GCC(0x001C)
+
/* MUX source input identifiers. */
#define pxo_to_bb_mux 0
#define cxo_to_bb_mux pxo_to_bb_mux
@@ -237,6 +240,7 @@
#define TEST_TYPE_MM_LS 3
#define TEST_TYPE_MM_HS 4
#define TEST_TYPE_LPA 5
+#define TEST_TYPE_CPUL2 6
#define TEST_TYPE_SHIFT 24
#define TEST_CLK_SEL_MASK BM(23, 0)
#define TEST_VECTOR(s, t) (((t) << TEST_TYPE_SHIFT) | BVAL(23, 0, (s)))
@@ -245,6 +249,7 @@
#define TEST_MM_LS(s) TEST_VECTOR((s), TEST_TYPE_MM_LS)
#define TEST_MM_HS(s) TEST_VECTOR((s), TEST_TYPE_MM_HS)
#define TEST_LPA(s) TEST_VECTOR((s), TEST_TYPE_LPA)
+#define TEST_CPUL2(s) TEST_VECTOR((s), TEST_TYPE_CPUL2)
#define MN_MODE_DUAL_EDGE 0x2
@@ -3418,6 +3423,10 @@
struct clk *clk;
};
+static DEFINE_CLK_MEASURE(l2_m_clk);
+static DEFINE_CLK_MEASURE(krait0_m_clk);
+static DEFINE_CLK_MEASURE(krait1_m_clk);
+
static struct measure_sel measure_mux[] = {
{ TEST_PER_LS(0x08), &slimbus_xo_src_clk.c },
{ TEST_PER_LS(0x12), &sdc1_p_clk.c },
@@ -3579,6 +3588,10 @@
{ TEST_LPA(0x13), &spare_i2s_spkr_bit_clk.c },
{ TEST_LPA(0x14), &pcm_clk.c },
{ TEST_LPA(0x1D), &audio_slimbus_clk.c },
+
+ { TEST_CPUL2(0x1), &l2_m_clk },
+ { TEST_CPUL2(0x2), &krait0_m_clk },
+ { TEST_CPUL2(0x3), &krait1_m_clk },
};
static struct measure_sel *find_measure_sel(struct clk *clk)
@@ -3591,11 +3604,12 @@
return NULL;
}
-static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
+static int measure_clk_set_parent(struct clk *c, struct clk *parent)
{
int ret = 0;
u32 clk_sel;
struct measure_sel *p;
+ struct measure_clk *clk = to_measure_clk(c);
unsigned long flags;
if (!parent)
@@ -3607,8 +3621,13 @@
spin_lock_irqsave(&local_clock_reg_lock, flags);
- /* Program the test vector. */
+ /*
+ * Program the test vector, measurement period (sample_ticks)
+ * and scaling multiplier.
+ */
+ clk->sample_ticks = 0x10000;
clk_sel = p->test_vector & TEST_CLK_SEL_MASK;
+ clk->multiplier = 1;
switch (p->test_vector >> TEST_TYPE_SHIFT) {
case TEST_TYPE_PER_LS:
writel_relaxed(0x4030D00|BVAL(7, 0, clk_sel), CLK_TEST_REG);
@@ -3629,6 +3648,12 @@
writel_relaxed(BVAL(6, 1, clk_sel)|BIT(0),
LCC_CLK_LS_DEBUG_CFG_REG);
break;
+ case TEST_TYPE_CPUL2:
+ writel_relaxed(0x4030400, CLK_TEST_REG);
+ writel_relaxed(0x80|BVAL(5, 3, clk_sel), GCC_APCS_CLK_DIAG);
+ clk->sample_ticks = 0x4000;
+ clk->multiplier = 2;
+ break;
default:
ret = -EPERM;
}
@@ -3666,11 +3691,12 @@
/* Perform a hardware rate measurement for a given clock.
FOR DEBUG USE ONLY: Measurements take ~15 ms! */
-static unsigned measure_clk_get_rate(struct clk *clk)
+static unsigned measure_clk_get_rate(struct clk *c)
{
unsigned long flags;
u32 pdm_reg_backup, ringosc_reg_backup;
u64 raw_count_short, raw_count_full;
+ struct measure_clk *clk = to_measure_clk(c);
unsigned ret;
spin_lock_irqsave(&local_clock_reg_lock, flags);
@@ -3691,7 +3717,7 @@
/* Run a short measurement. (~1 ms) */
raw_count_short = run_measurement(0x1000);
/* Run a full measurement. (~14 ms) */
- raw_count_full = run_measurement(0x10000);
+ raw_count_full = run_measurement(clk->sample_ticks);
writel_relaxed(ringosc_reg_backup, RINGOSC_NS_REG);
writel_relaxed(pdm_reg_backup, PDM_CLK_NS_REG);
@@ -3702,8 +3728,8 @@
else {
/* Compute rate in Hz. */
raw_count_full = ((raw_count_full * 10) + 15) * 4800000;
- do_div(raw_count_full, ((0x10000 * 10) + 35));
- ret = raw_count_full;
+ do_div(raw_count_full, ((clk->sample_ticks * 10) + 35));
+ ret = (raw_count_full * clk->multiplier);
}
/* Route dbg_hs_clk to PLLTEST. 300mV single-ended amplitude. */
@@ -3730,10 +3756,13 @@
.is_local = local_clk_is_local,
};
-static struct clk measure_clk = {
- .dbg_name = "measure_clk",
- .ops = &measure_clk_ops,
- CLK_INIT(measure_clk),
+static struct measure_clk measure_clk = {
+ .c = {
+ .dbg_name = "measure_clk",
+ .ops = &measure_clk_ops,
+ CLK_INIT(measure_clk.c),
+ },
+ .multiplier = 1,
};
static struct clk_lookup msm_clocks_8960[] = {
@@ -3741,7 +3770,7 @@
CLK_LOOKUP("pll2", pll2_clk.c, NULL),
CLK_LOOKUP("pll8", pll8_clk.c, NULL),
CLK_LOOKUP("pll4", pll4_clk.c, NULL),
- CLK_LOOKUP("measure", measure_clk, "debug"),
+ CLK_LOOKUP("measure", measure_clk.c, "debug"),
CLK_LOOKUP("afab_clk", afab_clk.c, NULL),
CLK_LOOKUP("afab_a_clk", afab_a_clk.c, NULL),
@@ -3948,6 +3977,10 @@
CLK_LOOKUP("ebi1_msmbus_clk", ebi1_msmbus_clk.c, NULL),
CLK_LOOKUP("ebi1_clk", ebi1_adm_clk.c, "msm_dmov"),
+
+ CLK_LOOKUP("l2_mclk", l2_m_clk, NULL),
+ CLK_LOOKUP("krait0_mclk", krait0_m_clk, NULL),
+ CLK_LOOKUP("krait1_mclk", krait1_m_clk, NULL),
};
/*