5353#define to_ddr_pmu (p ) container_of(p, struct ddr_pmu, pmu)
5454
5555#define DDR_PERF_DEV_NAME "imx8_ddr"
56+ #define DB_PERF_DEV_NAME "imx8_db"
5657#define DDR_CPUHP_CB_NAME DDR_PERF_DEV_NAME "_perf_pmu"
5758
5859static DEFINE_IDA (ddr_ida );
60+ static DEFINE_IDA (db_ida );
5961
6062/* DDR Perf hardware feature */
6163#define DDR_CAP_AXI_ID_FILTER 0x1 /* support AXI ID filter */
6264#define DDR_CAP_AXI_ID_FILTER_ENHANCED 0x3 /* support enhanced AXI ID filter */
6365#define DDR_CAP_AXI_ID_PORT_CHANNEL_FILTER 0x4 /* support AXI ID PORT CHANNEL filter */
6466
67+ /* Perf type */
68+ enum fsl_ddr_type {
69+ DDR_PERF_TYPE = 0 , /* ddr Perf (default) */
70+ DB_PERF_TYPE , /* db Perf */
71+ };
72+
6573struct fsl_ddr_devtype_data {
6674 unsigned int quirks ; /* quirks needed for different DDR Perf core */
6775 const char * identifier ; /* system PMU identifier for userspace */
76+ enum fsl_ddr_type type ; /* types of Perf, ddr or db */
6877};
6978
7079static const struct fsl_ddr_devtype_data imx8_devtype_data ;
@@ -98,6 +107,12 @@ static const struct fsl_ddr_devtype_data imx8dxl_devtype_data = {
98107 .identifier = "i.MX8DXL" ,
99108};
100109
110+ static const struct fsl_ddr_devtype_data imx8dxl_db_devtype_data = {
111+ .quirks = DDR_CAP_AXI_ID_PORT_CHANNEL_FILTER ,
112+ .identifier = "i.MX8DXL" ,
113+ .type = DB_PERF_TYPE ,
114+ };
115+
101116static const struct of_device_id imx_ddr_pmu_dt_ids [] = {
102117 { .compatible = "fsl,imx8-ddr-pmu" , .data = & imx8_devtype_data },
103118 { .compatible = "fsl,imx8m-ddr-pmu" , .data = & imx8m_devtype_data },
@@ -106,6 +121,7 @@ static const struct of_device_id imx_ddr_pmu_dt_ids[] = {
106121 { .compatible = "fsl,imx8mn-ddr-pmu" , .data = & imx8mn_devtype_data },
107122 { .compatible = "fsl,imx8mp-ddr-pmu" , .data = & imx8mp_devtype_data },
108123 { .compatible = "fsl,imx8dxl-ddr-pmu" , .data = & imx8dxl_devtype_data },
124+ { .compatible = "fsl,imx8dxl-db-pmu" , .data = & imx8dxl_db_devtype_data },
109125 { /* sentinel */ }
110126};
111127MODULE_DEVICE_TABLE (of , imx_ddr_pmu_dt_ids );
@@ -285,9 +301,37 @@ static struct attribute *ddr_perf_events_attrs[] = {
285301 NULL ,
286302};
287303
304+ static const int ddr_perf_db_visible_event_list [] = {
305+ EVENT_CYCLES_ID ,
306+ 0x41 ,
307+ 0x42 ,
308+ };
309+
310+ static umode_t ddr_perf_events_attrs_is_visible (struct kobject * kobj ,
311+ struct attribute * attr , int n )
312+ {
313+ struct device * dev = kobj_to_dev (kobj );
314+ struct ddr_pmu * pmu = dev_get_drvdata (dev );
315+ struct perf_pmu_events_attr * pmu_attr ;
316+ unsigned int i ;
317+
318+ pmu_attr = container_of (attr , struct perf_pmu_events_attr , attr .attr );
319+
320+ if (pmu -> devtype_data -> type == DDR_PERF_TYPE )
321+ return attr -> mode ;
322+
323+ /* DB Type */
324+ for (i = 0 ; i < ARRAY_SIZE (ddr_perf_db_visible_event_list ); i ++ )
325+ if (pmu_attr -> id == ddr_perf_db_visible_event_list [i ])
326+ return attr -> mode ;
327+
328+ return 0 ;
329+ }
330+
288331static const struct attribute_group ddr_perf_events_attr_group = {
289332 .name = "events" ,
290333 .attrs = ddr_perf_events_attrs ,
334+ .is_visible = ddr_perf_events_attrs_is_visible ,
291335};
292336
293337PMU_FORMAT_ATTR (event , "config:0-7" );
@@ -737,6 +781,7 @@ static int ddr_perf_probe(struct platform_device *pdev)
737781 struct ddr_pmu * pmu ;
738782 struct device_node * np ;
739783 void __iomem * base ;
784+ struct ida * ida ;
740785 char * name ;
741786 int nclks ;
742787 int num ;
@@ -761,21 +806,25 @@ static int ddr_perf_probe(struct platform_device *pdev)
761806 if (nclks < 0 )
762807 return dev_err_probe (& pdev -> dev , nclks , "Failure get clks\n" );
763808
764- num = ida_alloc (& ddr_ida , GFP_KERNEL );
809+ pmu -> devtype_data = of_device_get_match_data (& pdev -> dev );
810+
811+ ida = pmu -> devtype_data -> type == DDR_PERF_TYPE ? & ddr_ida : & db_ida ;
812+ num = ida_alloc (ida , GFP_KERNEL );
765813 if (num < 0 )
766814 return num ;
767815
768816 pmu -> id = num ;
769817
770- name = devm_kasprintf (& pdev -> dev , GFP_KERNEL , DDR_PERF_DEV_NAME "%d" ,
771- num );
818+ if (pmu -> devtype_data -> type == DDR_PERF_TYPE )
819+ name = devm_kasprintf (& pdev -> dev , GFP_KERNEL , DDR_PERF_DEV_NAME "%d" , num );
820+ else
821+ name = devm_kasprintf (& pdev -> dev , GFP_KERNEL , DB_PERF_DEV_NAME "%d" , num );
822+
772823 if (!name ) {
773824 ret = - ENOMEM ;
774825 goto idr_free ;
775826 }
776827
777- pmu -> devtype_data = of_device_get_match_data (& pdev -> dev );
778-
779828 pmu -> cpu = raw_smp_processor_id ();
780829 ret = cpuhp_setup_state_multi (CPUHP_AP_ONLINE_DYN ,
781830 DDR_CPUHP_CB_NAME ,
@@ -832,7 +881,7 @@ static int ddr_perf_probe(struct platform_device *pdev)
832881cpuhp_instance_err :
833882 cpuhp_remove_multi_state (pmu -> cpuhp_state );
834883idr_free :
835- ida_free (& ddr_ida , pmu -> id );
884+ ida_free (ida , pmu -> id );
836885 dev_warn (& pdev -> dev , "i.MX8 DDR Perf PMU failed (%d), disabled\n" , ret );
837886 return ret ;
838887}
@@ -846,7 +895,11 @@ static void ddr_perf_remove(struct platform_device *pdev)
846895
847896 perf_pmu_unregister (& pmu -> pmu );
848897
849- ida_free (& ddr_ida , pmu -> id );
898+ if (pmu -> devtype_data -> type == DDR_PERF_TYPE )
899+ ida_free (& ddr_ida , pmu -> id );
900+ else
901+ ida_free (& db_ida , pmu -> id );
902+
850903}
851904
852905static struct platform_driver imx_ddr_pmu_driver = {
0 commit comments