[PATCH v8 01/15] soc: qcom: Separate kryo l2 accessors from PMU driver

2018-05-17 Thread Ilia Lin
The driver provides kernel level API for other drivers
to access the MSM8996 L2 cache registers.
Separating the L2 access code from the PMU driver and
making it public to allow other drivers use it.
The accesses must be separated with a single spinlock,
maintained in this driver.

Signed-off-by: Ilia Lin 
---
 drivers/perf/Kconfig |  1 +
 drivers/perf/qcom_l2_pmu.c   | 90 ++--
 drivers/soc/qcom/Kconfig |  3 ++
 drivers/soc/qcom/Makefile|  1 +
 drivers/soc/qcom/kryo-l2-accessors.c | 56 ++
 include/soc/qcom/kryo-l2-accessors.h | 12 +
 6 files changed, 97 insertions(+), 66 deletions(-)
 create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
 create mode 100644 include/soc/qcom/kryo-l2-accessors.h

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 28bb5a0..561252a 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -69,6 +69,7 @@ config HISI_PMU
 config QCOM_L2_PMU
bool "Qualcomm Technologies L2-cache PMU"
depends on ARCH_QCOM && ARM64 && ACPI
+   select QCOM_KRYO_L2_ACCESSORS
  help
  Provides support for the L2 cache performance monitor unit (PMU)
  in Qualcomm Technologies processors.
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 842135c..cc31f51 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MAX_L2_CTRS 9
 
@@ -87,8 +88,6 @@
 #define L2_COUNTER_RELOAD   BIT_ULL(31)
 #define L2_CYCLE_COUNTER_RELOAD BIT_ULL(63)
 
-#define L2CPUSRSELR_EL1 sys_reg(3, 3, 15, 0, 6)
-#define L2CPUSRDR_EL1   sys_reg(3, 3, 15, 0, 7)
 
 #define reg_idx(reg, i) (((i) * IA_L2_REG_OFFSET) + reg##_BASE)
 
@@ -107,48 +106,7 @@
 #define L2_EVENT_STREX 0x421
 #define L2_EVENT_CLREX 0x422
 
-static DEFINE_RAW_SPINLOCK(l2_access_lock);
 
-/**
- * set_l2_indirect_reg: write value to an L2 register
- * @reg: Address of L2 register.
- * @value: Value to be written to register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static void set_l2_indirect_reg(u64 reg, u64 val)
-{
-   unsigned long flags;
-
-   raw_spin_lock_irqsave(_access_lock, flags);
-   write_sysreg_s(reg, L2CPUSRSELR_EL1);
-   isb();
-   write_sysreg_s(val, L2CPUSRDR_EL1);
-   isb();
-   raw_spin_unlock_irqrestore(_access_lock, flags);
-}
-
-/**
- * get_l2_indirect_reg: read an L2 register value
- * @reg: Address of L2 register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static u64 get_l2_indirect_reg(u64 reg)
-{
-   u64 val;
-   unsigned long flags;
-
-   raw_spin_lock_irqsave(_access_lock, flags);
-   write_sysreg_s(reg, L2CPUSRSELR_EL1);
-   isb();
-   val = read_sysreg_s(L2CPUSRDR_EL1);
-   raw_spin_unlock_irqrestore(_access_lock, flags);
-
-   return val;
-}
 
 struct cluster_pmu;
 
@@ -219,28 +177,28 @@ static inline struct cluster_pmu *get_cluster_pmu(
 static void cluster_pmu_reset(void)
 {
/* Reset all counters */
-   set_l2_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
-   set_l2_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
-   set_l2_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
-   set_l2_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
+   kryo_l2_set_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
 }
 
 static inline void cluster_pmu_enable(void)
 {
-   set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
 }
 
 static inline void cluster_pmu_disable(void)
 {
-   set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
 }
 
 static inline void cluster_pmu_counter_set_value(u32 idx, u64 value)
 {
if (idx == l2_cycle_ctr_idx)
-   set_l2_indirect_reg(L2PMCCNTR, value);
+   kryo_l2_set_indirect_reg(L2PMCCNTR, value);
else
-   set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
+   kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
 }
 
 static inline u64 cluster_pmu_counter_get_value(u32 idx)
@@ -248,46 +206,46 @@ static inline u64 cluster_pmu_counter_get_value(u32 idx)
u64 value;
 
if (idx == l2_cycle_ctr_idx)
-   value = get_l2_indirect_reg(L2PMCCNTR);
+   value = kryo_l2_get_indirect_reg(L2PMCCNTR);
else
-   value = get_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx));
+

[PATCH v8 01/15] soc: qcom: Separate kryo l2 accessors from PMU driver

2018-05-17 Thread Ilia Lin
The driver provides kernel level API for other drivers
to access the MSM8996 L2 cache registers.
Separating the L2 access code from the PMU driver and
making it public to allow other drivers use it.
The accesses must be separated with a single spinlock,
maintained in this driver.

Signed-off-by: Ilia Lin 
---
 drivers/perf/Kconfig |  1 +
 drivers/perf/qcom_l2_pmu.c   | 90 ++--
 drivers/soc/qcom/Kconfig |  3 ++
 drivers/soc/qcom/Makefile|  1 +
 drivers/soc/qcom/kryo-l2-accessors.c | 56 ++
 include/soc/qcom/kryo-l2-accessors.h | 12 +
 6 files changed, 97 insertions(+), 66 deletions(-)
 create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
 create mode 100644 include/soc/qcom/kryo-l2-accessors.h

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 28bb5a0..561252a 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -69,6 +69,7 @@ config HISI_PMU
 config QCOM_L2_PMU
bool "Qualcomm Technologies L2-cache PMU"
depends on ARCH_QCOM && ARM64 && ACPI
+   select QCOM_KRYO_L2_ACCESSORS
  help
  Provides support for the L2 cache performance monitor unit (PMU)
  in Qualcomm Technologies processors.
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 842135c..cc31f51 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MAX_L2_CTRS 9
 
@@ -87,8 +88,6 @@
 #define L2_COUNTER_RELOAD   BIT_ULL(31)
 #define L2_CYCLE_COUNTER_RELOAD BIT_ULL(63)
 
-#define L2CPUSRSELR_EL1 sys_reg(3, 3, 15, 0, 6)
-#define L2CPUSRDR_EL1   sys_reg(3, 3, 15, 0, 7)
 
 #define reg_idx(reg, i) (((i) * IA_L2_REG_OFFSET) + reg##_BASE)
 
@@ -107,48 +106,7 @@
 #define L2_EVENT_STREX 0x421
 #define L2_EVENT_CLREX 0x422
 
-static DEFINE_RAW_SPINLOCK(l2_access_lock);
 
-/**
- * set_l2_indirect_reg: write value to an L2 register
- * @reg: Address of L2 register.
- * @value: Value to be written to register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static void set_l2_indirect_reg(u64 reg, u64 val)
-{
-   unsigned long flags;
-
-   raw_spin_lock_irqsave(_access_lock, flags);
-   write_sysreg_s(reg, L2CPUSRSELR_EL1);
-   isb();
-   write_sysreg_s(val, L2CPUSRDR_EL1);
-   isb();
-   raw_spin_unlock_irqrestore(_access_lock, flags);
-}
-
-/**
- * get_l2_indirect_reg: read an L2 register value
- * @reg: Address of L2 register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static u64 get_l2_indirect_reg(u64 reg)
-{
-   u64 val;
-   unsigned long flags;
-
-   raw_spin_lock_irqsave(_access_lock, flags);
-   write_sysreg_s(reg, L2CPUSRSELR_EL1);
-   isb();
-   val = read_sysreg_s(L2CPUSRDR_EL1);
-   raw_spin_unlock_irqrestore(_access_lock, flags);
-
-   return val;
-}
 
 struct cluster_pmu;
 
@@ -219,28 +177,28 @@ static inline struct cluster_pmu *get_cluster_pmu(
 static void cluster_pmu_reset(void)
 {
/* Reset all counters */
-   set_l2_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
-   set_l2_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
-   set_l2_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
-   set_l2_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
+   kryo_l2_set_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
+   kryo_l2_set_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
 }
 
 static inline void cluster_pmu_enable(void)
 {
-   set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
 }
 
 static inline void cluster_pmu_disable(void)
 {
-   set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
+   kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
 }
 
 static inline void cluster_pmu_counter_set_value(u32 idx, u64 value)
 {
if (idx == l2_cycle_ctr_idx)
-   set_l2_indirect_reg(L2PMCCNTR, value);
+   kryo_l2_set_indirect_reg(L2PMCCNTR, value);
else
-   set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
+   kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
 }
 
 static inline u64 cluster_pmu_counter_get_value(u32 idx)
@@ -248,46 +206,46 @@ static inline u64 cluster_pmu_counter_get_value(u32 idx)
u64 value;
 
if (idx == l2_cycle_ctr_idx)
-   value = get_l2_indirect_reg(L2PMCCNTR);
+   value = kryo_l2_get_indirect_reg(L2PMCCNTR);
else
-   value = get_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx));
+   value =