Re: [PATCH v2 1/4] soc: qcom: Separate kryo l2 accessors from PMU driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Quoting Loic Poulain (2020-06-04 03:35:24)
> From: Ilia Lin <ilialin@xxxxxxxxxxxxxx>
> 
> 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 <ilialin@xxxxxxxxxxxxxx>
> Signed-off-by: Loic Poulain <loic.poulain@xxxxxxxxxx>
> ---

This needs an ack from perf maintainers. Leaving the rest of the patch
intact to help provide context.

-Stephen

>  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 | 57 +++++++++++++++++++++++
>  include/soc/qcom/kryo-l2-accessors.h | 12 +++++
>  6 files changed, 98 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 09ae8a9..8e6510c1 100644
> --- a/drivers/perf/Kconfig
> +++ b/drivers/perf/Kconfig
> @@ -89,6 +89,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 21d6991..02ca1fa 100644
> --- a/drivers/perf/qcom_l2_pmu.c
> +++ b/drivers/perf/qcom_l2_pmu.c
> @@ -23,6 +23,7 @@
>  #include <asm/barrier.h>
>  #include <asm/local64.h>
>  #include <asm/sysreg.h>
> +#include <soc/qcom/kryo-l2-accessors.h>
>  
>  #define MAX_L2_CTRS             9
>  
> @@ -79,8 +80,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)
>  
> @@ -99,48 +98,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(&l2_access_lock, flags);
> -       write_sysreg_s(reg, L2CPUSRSELR_EL1);
> -       isb();
> -       write_sysreg_s(val, L2CPUSRDR_EL1);
> -       isb();
> -       raw_spin_unlock_irqrestore(&l2_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(&l2_access_lock, flags);
> -       write_sysreg_s(reg, L2CPUSRSELR_EL1);
> -       isb();
> -       val = read_sysreg_s(L2CPUSRDR_EL1);
> -       raw_spin_unlock_irqrestore(&l2_access_lock, flags);
> -
> -       return val;
> -}
>  
>  struct cluster_pmu;
>  
> @@ -211,28 +169,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)
> @@ -240,46 +198,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 = kryo_l2_get_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx));
>  
>         return value;
>  }
>  
>  static inline void cluster_pmu_counter_enable(u32 idx)
>  {
> -       set_l2_indirect_reg(L2PMCNTENSET, idx_to_reg_bit(idx));
> +       kryo_l2_set_indirect_reg(L2PMCNTENSET, idx_to_reg_bit(idx));
>  }
>  
>  static inline void cluster_pmu_counter_disable(u32 idx)
>  {
> -       set_l2_indirect_reg(L2PMCNTENCLR, idx_to_reg_bit(idx));
> +       kryo_l2_set_indirect_reg(L2PMCNTENCLR, idx_to_reg_bit(idx));
>  }
>  
>  static inline void cluster_pmu_counter_enable_interrupt(u32 idx)
>  {
> -       set_l2_indirect_reg(L2PMINTENSET, idx_to_reg_bit(idx));
> +       kryo_l2_set_indirect_reg(L2PMINTENSET, idx_to_reg_bit(idx));
>  }
>  
>  static inline void cluster_pmu_counter_disable_interrupt(u32 idx)
>  {
> -       set_l2_indirect_reg(L2PMINTENCLR, idx_to_reg_bit(idx));
> +       kryo_l2_set_indirect_reg(L2PMINTENCLR, idx_to_reg_bit(idx));
>  }
>  
>  static inline void cluster_pmu_set_evccntcr(u32 val)
>  {
> -       set_l2_indirect_reg(L2PMCCNTCR, val);
> +       kryo_l2_set_indirect_reg(L2PMCCNTCR, val);
>  }
>  
>  static inline void cluster_pmu_set_evcntcr(u32 ctr, u32 val)
>  {
> -       set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTCR, ctr), val);
> +       kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTCR, ctr), val);
>  }
>  
>  static inline void cluster_pmu_set_evtyper(u32 ctr, u32 val)
>  {
> -       set_l2_indirect_reg(reg_idx(IA_L2PMXEVTYPER, ctr), val);
> +       kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVTYPER, ctr), val);
>  }
>  
>  static void cluster_pmu_set_resr(struct cluster_pmu *cluster,
> @@ -295,11 +253,11 @@ static void cluster_pmu_set_resr(struct cluster_pmu *cluster,
>  
>         spin_lock_irqsave(&cluster->pmu_lock, flags);
>  
> -       resr_val = get_l2_indirect_reg(L2PMRESR);
> +       resr_val = kryo_l2_get_indirect_reg(L2PMRESR);
>         resr_val &= ~(L2PMRESR_GROUP_MASK << shift);
>         resr_val |= field;
>         resr_val |= L2PMRESR_EN;
> -       set_l2_indirect_reg(L2PMRESR, resr_val);
> +       kryo_l2_set_indirect_reg(L2PMRESR, resr_val);
>  
>         spin_unlock_irqrestore(&cluster->pmu_lock, flags);
>  }
> @@ -315,14 +273,14 @@ static inline void cluster_pmu_set_evfilter_sys_mode(u32 ctr)
>                    L2PMXEVFILTER_ORGFILTER_IDINDEP |
>                    L2PMXEVFILTER_ORGFILTER_ALL;
>  
> -       set_l2_indirect_reg(reg_idx(IA_L2PMXEVFILTER, ctr), val);
> +       kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVFILTER, ctr), val);
>  }
>  
>  static inline u32 cluster_pmu_getreset_ovsr(void)
>  {
> -       u32 result = get_l2_indirect_reg(L2PMOVSSET);
> +       u32 result = kryo_l2_get_indirect_reg(L2PMOVSSET);
>  
> -       set_l2_indirect_reg(L2PMOVSCLR, result);
> +       kryo_l2_set_indirect_reg(L2PMOVSCLR, result);
>         return result;
>  }
>  
> @@ -767,7 +725,7 @@ static int get_num_counters(void)
>  {
>         int val;
>  
> -       val = get_l2_indirect_reg(L2PMCR);
> +       val = kryo_l2_get_indirect_reg(L2PMCR);
>  
>         /*
>          * Read number of counters from L2PMCR and add 1
> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
> index bf42a17..1782186 100644
> --- a/drivers/soc/qcom/Kconfig
> +++ b/drivers/soc/qcom/Kconfig
> @@ -62,6 +62,9 @@ config QCOM_LLCC
>           SDM845. This provides interfaces to clients that use the LLCC.
>           Say yes here to enable LLCC slice driver.
>  
> +config QCOM_KRYO_L2_ACCESSORS
> +       bool
> +
>  config QCOM_MDT_LOADER
>         tristate
>         select QCOM_SCM
> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
> index 5d6b83d..fcf6ef7 100644
> --- a/drivers/soc/qcom/Makefile
> +++ b/drivers/soc/qcom/Makefile
> @@ -26,3 +26,4 @@ obj-$(CONFIG_QCOM_APR) += apr.o
>  obj-$(CONFIG_QCOM_LLCC) += llcc-qcom.o
>  obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o
>  obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o
> +obj-$(CONFIG_QCOM_KRYO_L2_ACCESSORS) +=        kryo-l2-accessors.o
> diff --git a/drivers/soc/qcom/kryo-l2-accessors.c b/drivers/soc/qcom/kryo-l2-accessors.c
> new file mode 100644
> index 0000000..c20cb92
> --- /dev/null
> +++ b/drivers/soc/qcom/kryo-l2-accessors.c
> @@ -0,0 +1,57 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018, The Linux Foundation. All rights reserved.
> + */
> +
> +#include <linux/spinlock.h>
> +#include <asm/barrier.h>
> +#include <asm/sysreg.h>
> +#include <soc/qcom/kryo-l2-accessors.h>
> +
> +#define L2CPUSRSELR_EL1         sys_reg(3, 3, 15, 0, 6)
> +#define L2CPUSRDR_EL1           sys_reg(3, 3, 15, 0, 7)
> +
> +static DEFINE_RAW_SPINLOCK(l2_access_lock);
> +
> +/**
> + * kryo_l2_set_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, and system registers with respect to device memory
> + */
> +void kryo_l2_set_indirect_reg(u64 reg, u64 val)
> +{
> +       unsigned long flags;
> +
> +       raw_spin_lock_irqsave(&l2_access_lock, flags);
> +       write_sysreg_s(reg, L2CPUSRSELR_EL1);
> +       isb();
> +       write_sysreg_s(val, L2CPUSRDR_EL1);
> +       isb();
> +       raw_spin_unlock_irqrestore(&l2_access_lock, flags);
> +}
> +EXPORT_SYMBOL(kryo_l2_set_indirect_reg);
> +
> +/**
> + * kryo_l2_get_indirect_reg() - read an L2 register value
> + * @reg: Address of L2 register.
> + *
> + * Use architecturally required barriers for ordering between system register
> + * accesses, and system registers with respect to device memory
> + */
> +u64 kryo_l2_get_indirect_reg(u64 reg)
> +{
> +       u64 val;
> +       unsigned long flags;
> +
> +       raw_spin_lock_irqsave(&l2_access_lock, flags);
> +       write_sysreg_s(reg, L2CPUSRSELR_EL1);
> +       isb();
> +       val = read_sysreg_s(L2CPUSRDR_EL1);
> +       raw_spin_unlock_irqrestore(&l2_access_lock, flags);
> +
> +       return val;
> +}
> +EXPORT_SYMBOL(kryo_l2_get_indirect_reg);
> diff --git a/include/soc/qcom/kryo-l2-accessors.h b/include/soc/qcom/kryo-l2-accessors.h
> new file mode 100644
> index 0000000..673c534
> --- /dev/null
> +++ b/include/soc/qcom/kryo-l2-accessors.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2018, The Linux Foundation. All rights reserved.
> + */
> +
> +#ifndef __SOC_ARCH_QCOM_KRYO_L2_ACCESSORS_H
> +#define __SOC_ARCH_QCOM_KRYO_L2_ACCESSORS_H
> +
> +void kryo_l2_set_indirect_reg(u64 reg, u64 val);
> +u64 kryo_l2_get_indirect_reg(u64 reg);
> +
> +#endif




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [Linux for Sparc]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux