#include <linux/bitfield.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/perf_event.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#define COUNTER_CNTL …
#define COUNTER_READ …
#define COUNTER_DPCR1 …
#define COUNTER_MUX_CNTL …
#define COUNTER_MASK_COMP …
#define CNTL_OVER …
#define CNTL_CLEAR …
#define CNTL_EN …
#define CNTL_EN_MASK …
#define CNTL_CLEAR_MASK …
#define CNTL_OVER_MASK …
#define CNTL_CP_SHIFT …
#define CNTL_CP_MASK …
#define CNTL_CSV_SHIFT …
#define CNTL_CSV_MASK …
#define READ_PORT_SHIFT …
#define READ_PORT_MASK …
#define READ_CHANNEL_REVERT …
#define WRITE_PORT_SHIFT …
#define WRITE_PORT_MASK …
#define WRITE_CHANNEL_REVERT …
#define EVENT_CYCLES_ID …
#define EVENT_CYCLES_COUNTER …
#define NUM_COUNTERS …
#define CYCLES_COUNTER_MASK …
#define AXI_MASKING_REVERT …
#define to_ddr_pmu(p) …
#define DDR_PERF_DEV_NAME …
#define DDR_CPUHP_CB_NAME …
static DEFINE_IDA(ddr_ida);
#define DDR_CAP_AXI_ID_FILTER …
#define DDR_CAP_AXI_ID_FILTER_ENHANCED …
#define DDR_CAP_AXI_ID_PORT_CHANNEL_FILTER …
struct fsl_ddr_devtype_data { … };
static const struct fsl_ddr_devtype_data imx8_devtype_data;
static const struct fsl_ddr_devtype_data imx8m_devtype_data = …;
static const struct fsl_ddr_devtype_data imx8mq_devtype_data = …;
static const struct fsl_ddr_devtype_data imx8mm_devtype_data = …;
static const struct fsl_ddr_devtype_data imx8mn_devtype_data = …;
static const struct fsl_ddr_devtype_data imx8mp_devtype_data = …;
static const struct fsl_ddr_devtype_data imx8dxl_devtype_data = …;
static const struct of_device_id imx_ddr_pmu_dt_ids[] = …;
MODULE_DEVICE_TABLE(of, imx_ddr_pmu_dt_ids);
struct ddr_pmu { … };
static ssize_t ddr_perf_identifier_show(struct device *dev,
struct device_attribute *attr,
char *page)
{ … }
static umode_t ddr_perf_identifier_attr_visible(struct kobject *kobj,
struct attribute *attr,
int n)
{
struct device *dev = kobj_to_dev(kobj);
struct ddr_pmu *pmu = dev_get_drvdata(dev);
if (!pmu->devtype_data->identifier)
return 0;
return attr->mode;
};
static struct device_attribute ddr_perf_identifier_attr = …;
static struct attribute *ddr_perf_identifier_attrs[] = …;
static const struct attribute_group ddr_perf_identifier_attr_group = …;
enum ddr_perf_filter_capabilities { … };
static u32 ddr_perf_filter_cap_get(struct ddr_pmu *pmu, int cap)
{ … }
static ssize_t ddr_perf_filter_cap_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{ … }
#define PERF_EXT_ATTR_ENTRY(_name, _func, _var) …
#define PERF_FILTER_EXT_ATTR_ENTRY(_name, _var) …
static struct attribute *ddr_perf_filter_cap_attr[] = …;
static const struct attribute_group ddr_perf_filter_cap_attr_group = …;
static ssize_t ddr_perf_cpumask_show(struct device *dev,
struct device_attribute *attr, char *buf)
{ … }
static struct device_attribute ddr_perf_cpumask_attr = …;
static struct attribute *ddr_perf_cpumask_attrs[] = …;
static const struct attribute_group ddr_perf_cpumask_attr_group = …;
static ssize_t
ddr_pmu_event_show(struct device *dev, struct device_attribute *attr,
char *page)
{ … }
#define IMX8_DDR_PMU_EVENT_ATTR(_name, _id) …
static struct attribute *ddr_perf_events_attrs[] = …;
static const struct attribute_group ddr_perf_events_attr_group = …;
PMU_FORMAT_ATTR(…);
PMU_FORMAT_ATTR(…);
PMU_FORMAT_ATTR(…);
PMU_FORMAT_ATTR(…);
PMU_FORMAT_ATTR(…);
static struct attribute *ddr_perf_format_attrs[] = …;
static const struct attribute_group ddr_perf_format_attr_group = …;
static const struct attribute_group *attr_groups[] = …;
static bool ddr_perf_is_filtered(struct perf_event *event)
{ … }
static u32 ddr_perf_filter_val(struct perf_event *event)
{ … }
static bool ddr_perf_filters_compatible(struct perf_event *a,
struct perf_event *b)
{ … }
static bool ddr_perf_is_enhanced_filtered(struct perf_event *event)
{ … }
static u32 ddr_perf_alloc_counter(struct ddr_pmu *pmu, int event)
{ … }
static void ddr_perf_free_counter(struct ddr_pmu *pmu, int counter)
{ … }
static u32 ddr_perf_read_counter(struct ddr_pmu *pmu, int counter)
{ … }
static int ddr_perf_event_init(struct perf_event *event)
{ … }
static void ddr_perf_counter_enable(struct ddr_pmu *pmu, int config,
int counter, bool enable)
{ … }
static bool ddr_perf_counter_overflow(struct ddr_pmu *pmu, int counter)
{ … }
static void ddr_perf_counter_clear(struct ddr_pmu *pmu, int counter)
{ … }
static void ddr_perf_event_update(struct perf_event *event)
{ … }
static void ddr_perf_event_start(struct perf_event *event, int flags)
{ … }
static int ddr_perf_event_add(struct perf_event *event, int flags)
{ … }
static void ddr_perf_event_stop(struct perf_event *event, int flags)
{ … }
static void ddr_perf_event_del(struct perf_event *event, int flags)
{ … }
static void ddr_perf_pmu_enable(struct pmu *pmu)
{ … }
static void ddr_perf_pmu_disable(struct pmu *pmu)
{ … }
static int ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base,
struct device *dev)
{ … }
static irqreturn_t ddr_perf_irq_handler(int irq, void *p)
{ … }
static int ddr_perf_offline_cpu(unsigned int cpu, struct hlist_node *node)
{ … }
static int ddr_perf_probe(struct platform_device *pdev)
{ … }
static void ddr_perf_remove(struct platform_device *pdev)
{ … }
static struct platform_driver imx_ddr_pmu_driver = …;
module_platform_driver(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;