lkml.org 
[lkml]   [2024]   [Mar]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH v8 4/8] perf: imx_perf: refactor driver for imx93
    On Fri, Mar 22, 2024 at 02:39:26PM +0800, Xu Yang wrote:
    > This driver is initinally used to support imx93 Soc and now it's time to
    > add support for imx95 Soc. However, some macro definitions and events are
    > different on these two Socs. For preparing imx95 supports, this will
    > refactor driver for imx93.
    >
    > Signed-off-by: Xu Yang <xu.yang_2@nxp.com>

    Reviewed-by: Frank Li <Frank.Li@nxp.com>

    >
    > ---
    > Changes in v4:
    > - new patch
    > Changes in v5:
    > - use is_visible to hide unwanted attributes as suggested by Will
    > Changes in v6:
    > - improve imx93_ddr_perf_monitor_config()
    > Changes in v7:
    > - improve imx93_ddr_perf_monitor_config() as suggested by Frank
    > Changes in v8:
    > - adjust is_visable() as suggested by Frank
    > ---
    > drivers/perf/fsl_imx9_ddr_perf.c | 106 ++++++++++++++++++++-----------
    > 1 file changed, 68 insertions(+), 38 deletions(-)
    >
    > diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c
    > index b728719b494c..011377c01dea 100644
    > --- a/drivers/perf/fsl_imx9_ddr_perf.c
    > +++ b/drivers/perf/fsl_imx9_ddr_perf.c
    > @@ -11,14 +11,14 @@
    > #include <linux/perf_event.h>
    >
    > /* Performance monitor configuration */
    > -#define PMCFG1 0x00
    > -#define PMCFG1_RD_TRANS_FILT_EN BIT(31)
    > -#define PMCFG1_WR_TRANS_FILT_EN BIT(30)
    > -#define PMCFG1_RD_BT_FILT_EN BIT(29)
    > -#define PMCFG1_ID_MASK GENMASK(17, 0)
    > +#define PMCFG1 0x00
    > +#define MX93_PMCFG1_RD_TRANS_FILT_EN BIT(31)
    > +#define MX93_PMCFG1_WR_TRANS_FILT_EN BIT(30)
    > +#define MX93_PMCFG1_RD_BT_FILT_EN BIT(29)
    > +#define MX93_PMCFG1_ID_MASK GENMASK(17, 0)
    >
    > -#define PMCFG2 0x04
    > -#define PMCFG2_ID GENMASK(17, 0)
    > +#define PMCFG2 0x04
    > +#define MX93_PMCFG2_ID GENMASK(17, 0)
    >
    > /* Global control register affects all counters and takes priority over local control registers */
    > #define PMGC0 0x40
    > @@ -76,6 +76,11 @@ static const struct imx_ddr_devtype_data imx93_devtype_data = {
    > .identifier = "imx93",
    > };
    >
    > +static inline bool is_imx93(struct ddr_pmu *pmu)
    > +{
    > + return pmu->devtype_data == &imx93_devtype_data;
    > +}
    > +
    > static const struct of_device_id imx_ddr_pmu_dt_ids[] = {
    > {.compatible = "fsl,imx93-ddr-pmu", .data = &imx93_devtype_data},
    > { /* sentinel */ }
    > @@ -123,23 +128,36 @@ static const struct attribute_group ddr_perf_cpumask_attr_group = {
    > .attrs = ddr_perf_cpumask_attrs,
    > };
    >
    > +struct imx9_pmu_events_attr {
    > + struct device_attribute attr;
    > + u64 id;
    > + const void *devtype_data;
    > +};
    > +
    > static ssize_t ddr_pmu_event_show(struct device *dev,
    > struct device_attribute *attr, char *page)
    > {
    > - struct perf_pmu_events_attr *pmu_attr;
    > + struct imx9_pmu_events_attr *pmu_attr;
    >
    > - pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
    > + pmu_attr = container_of(attr, struct imx9_pmu_events_attr, attr);
    > return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
    > }
    >
    > #define ID(counter, id) ((counter << CONFIG_COUNTER_OFFSET) | id)
    >
    > -#define IMX9_DDR_PMU_EVENT_ATTR(_name, _id) \
    > - (&((struct perf_pmu_events_attr[]) { \
    > +#define DDR_PMU_EVENT_ATTR_COMM(_name, _id, _data) \
    > + (&((struct imx9_pmu_events_attr[]) { \
    > { .attr = __ATTR(_name, 0444, ddr_pmu_event_show, NULL),\
    > - .id = _id, } \
    > + .id = _id, \
    > + .devtype_data = _data, } \
    > })[0].attr.attr)
    >
    > +#define IMX9_DDR_PMU_EVENT_ATTR(_name, _id) \
    > + DDR_PMU_EVENT_ATTR_COMM(_name, _id, NULL)
    > +
    > +#define IMX93_DDR_PMU_EVENT_ATTR(_name, _id) \
    > + DDR_PMU_EVENT_ATTR_COMM(_name, _id, &imx93_devtype_data)
    > +
    > static struct attribute *ddr_perf_events_attrs[] = {
    > /* counter0 cycles event */
    > IMX9_DDR_PMU_EVENT_ATTR(cycles, 0),
    > @@ -185,7 +203,7 @@ static struct attribute *ddr_perf_events_attrs[] = {
    > IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_6, ID(2, 70)),
    > IMX9_DDR_PMU_EVENT_ATTR(ddrc_ld_wiq_7, ID(2, 71)),
    > IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_empty, ID(2, 72)),
    > - IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pm_rd_trans_filt, ID(2, 73)),
    > + IMX93_DDR_PMU_EVENT_ATTR(eddrtq_pm_rd_trans_filt, ID(2, 73)), /* imx93 specific*/
    >
    > /* counter3 specific events */
    > IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_0, ID(3, 64)),
    > @@ -197,7 +215,7 @@ static struct attribute *ddr_perf_events_attrs[] = {
    > IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_6, ID(3, 70)),
    > IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_collision_7, ID(3, 71)),
    > IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_full, ID(3, 72)),
    > - IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pm_wr_trans_filt, ID(3, 73)),
    > + IMX93_DDR_PMU_EVENT_ATTR(eddrtq_pm_wr_trans_filt, ID(3, 73)), /* imx93 specific*/
    >
    > /* counter4 specific events */
    > IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_0, ID(4, 64)),
    > @@ -209,7 +227,7 @@ static struct attribute *ddr_perf_events_attrs[] = {
    > IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_6, ID(4, 70)),
    > IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_row_open_7, ID(4, 71)),
    > IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pmon_ld_rdq2_rmw, ID(4, 72)),
    > - IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pm_rd_beat_filt, ID(4, 73)),
    > + IMX93_DDR_PMU_EVENT_ATTR(eddrtq_pm_rd_beat_filt, ID(4, 73)), /* imx93 specific*/
    >
    > /* counter5 specific events */
    > IMX9_DDR_PMU_EVENT_ATTR(ddrc_qx_valid_start_0, ID(5, 64)),
    > @@ -244,9 +262,29 @@ static struct attribute *ddr_perf_events_attrs[] = {
    > NULL,
    > };
    >
    > +static umode_t
    > +ddr_perf_events_attrs_is_visible(struct kobject *kobj,
    > + struct attribute *attr, int unused)
    > +{
    > + struct pmu *pmu = dev_get_drvdata(kobj_to_dev(kobj));
    > + struct ddr_pmu *ddr_pmu = to_ddr_pmu(pmu);
    > + struct imx9_pmu_events_attr *eattr;
    > +
    > + eattr = container_of(attr, typeof(*eattr), attr.attr);
    > +
    > + if (!eattr->devtype_data)
    > + return attr->mode;
    > +
    > + if (eattr->devtype_data != ddr_pmu->devtype_data)
    > + return 0;
    > +
    > + return attr->mode;
    > +}
    > +
    > static const struct attribute_group ddr_perf_events_attr_group = {
    > .name = "events",
    > .attrs = ddr_perf_events_attrs,
    > + .is_visible = ddr_perf_events_attrs_is_visible,
    > };
    >
    > PMU_FORMAT_ATTR(event, "config:0-15");
    > @@ -368,36 +406,28 @@ static void ddr_perf_counter_local_config(struct ddr_pmu *pmu, int config,
    > }
    > }
    >
    > -static void ddr_perf_monitor_config(struct ddr_pmu *pmu, int event,
    > - int counter, int axi_id, int axi_mask)
    > +static void imx93_ddr_perf_monitor_config(struct ddr_pmu *pmu, int event,
    > + int counter, int axi_id, int axi_mask)
    > {
    > u32 pmcfg1, pmcfg2;
    > + u32 mask[] = { MX93_PMCFG1_RD_TRANS_FILT_EN,
    > + MX93_PMCFG1_WR_TRANS_FILT_EN,
    > + MX93_PMCFG1_RD_BT_FILT_EN };
    >
    > pmcfg1 = readl_relaxed(pmu->base + PMCFG1);
    >
    > - if (counter == 2 && event == 73)
    > - pmcfg1 |= PMCFG1_RD_TRANS_FILT_EN;
    > - else if (counter == 2 && event != 73)
    > - pmcfg1 &= ~PMCFG1_RD_TRANS_FILT_EN;
    > -
    > - if (counter == 3 && event == 73)
    > - pmcfg1 |= PMCFG1_WR_TRANS_FILT_EN;
    > - else if (counter == 3 && event != 73)
    > - pmcfg1 &= ~PMCFG1_WR_TRANS_FILT_EN;
    > -
    > - if (counter == 4 && event == 73)
    > - pmcfg1 |= PMCFG1_RD_BT_FILT_EN;
    > - else if (counter == 4 && event != 73)
    > - pmcfg1 &= ~PMCFG1_RD_BT_FILT_EN;
    > + if (counter >= 2 && counter <= 4)
    > + pmcfg1 = event == 73 ? pmcfg1 | mask[counter - 2] :
    > + pmcfg1 & ~mask[counter - 2];
    >
    > - pmcfg1 &= ~FIELD_PREP(PMCFG1_ID_MASK, 0x3FFFF);
    > - pmcfg1 |= FIELD_PREP(PMCFG1_ID_MASK, axi_mask);
    > - writel(pmcfg1, pmu->base + PMCFG1);
    > + pmcfg1 &= ~FIELD_PREP(MX93_PMCFG1_ID_MASK, 0x3FFFF);
    > + pmcfg1 |= FIELD_PREP(MX93_PMCFG1_ID_MASK, axi_mask);
    > + writel_relaxed(pmcfg1, pmu->base + PMCFG1);
    >
    > pmcfg2 = readl_relaxed(pmu->base + PMCFG2);
    > - pmcfg2 &= ~FIELD_PREP(PMCFG2_ID, 0x3FFFF);
    > - pmcfg2 |= FIELD_PREP(PMCFG2_ID, axi_id);
    > - writel(pmcfg2, pmu->base + PMCFG2);
    > + pmcfg2 &= ~FIELD_PREP(MX93_PMCFG2_ID, 0x3FFFF);
    > + pmcfg2 |= FIELD_PREP(MX93_PMCFG2_ID, axi_id);
    > + writel_relaxed(pmcfg2, pmu->base + PMCFG2);
    > }
    >
    > static void ddr_perf_event_update(struct perf_event *event)
    > @@ -513,7 +543,7 @@ static int ddr_perf_event_add(struct perf_event *event, int flags)
    > ddr_perf_event_start(event, flags);
    >
    > /* read trans, write trans, read beat */
    > - ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);
    > + imx93_ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);
    >
    > return 0;
    > }
    > --
    > 2.34.1
    >

    \
     
     \ /
      Last update: 2024-05-27 15:59    [W:3.551 / U:3.096 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site