47
47
#include <linux/kernel.h>
48
48
#include <linux/list.h>
49
49
#include <linux/msi.h>
50
+ #include <linux/of.h>
50
51
#include <linux/perf_event.h>
51
52
#include <linux/platform_device.h>
52
53
#include <linux/smp.h>
75
76
#define SMMU_PMCG_CR 0xE04
76
77
#define SMMU_PMCG_CR_ENABLE BIT(0)
77
78
#define SMMU_PMCG_IIDR 0xE08
79
+ #define SMMU_PMCG_IIDR_PRODUCTID GENMASK(31, 20)
80
+ #define SMMU_PMCG_IIDR_VARIANT GENMASK(19, 16)
81
+ #define SMMU_PMCG_IIDR_REVISION GENMASK(15, 12)
82
+ #define SMMU_PMCG_IIDR_IMPLEMENTER GENMASK(11, 0)
78
83
#define SMMU_PMCG_CEID0 0xE20
79
84
#define SMMU_PMCG_CEID1 0xE28
80
85
#define SMMU_PMCG_IRQ_CTRL 0xE50
83
88
#define SMMU_PMCG_IRQ_CFG1 0xE60
84
89
#define SMMU_PMCG_IRQ_CFG2 0xE64
85
90
91
+ /* IMP-DEF ID registers */
92
+ #define SMMU_PMCG_PIDR0 0xFE0
93
+ #define SMMU_PMCG_PIDR0_PART_0 GENMASK(7, 0)
94
+ #define SMMU_PMCG_PIDR1 0xFE4
95
+ #define SMMU_PMCG_PIDR1_DES_0 GENMASK(7, 4)
96
+ #define SMMU_PMCG_PIDR1_PART_1 GENMASK(3, 0)
97
+ #define SMMU_PMCG_PIDR2 0xFE8
98
+ #define SMMU_PMCG_PIDR2_REVISION GENMASK(7, 4)
99
+ #define SMMU_PMCG_PIDR2_DES_1 GENMASK(2, 0)
100
+ #define SMMU_PMCG_PIDR3 0xFEC
101
+ #define SMMU_PMCG_PIDR3_REVAND GENMASK(7, 4)
102
+ #define SMMU_PMCG_PIDR4 0xFD0
103
+ #define SMMU_PMCG_PIDR4_DES_2 GENMASK(3, 0)
104
+
86
105
/* MSI config fields */
87
106
#define MSI_CFG0_ADDR_MASK GENMASK_ULL(51, 2)
88
107
#define MSI_CFG2_MEMATTR_DEVICE_nGnRE 0x1
@@ -754,6 +773,41 @@ static void smmu_pmu_get_acpi_options(struct smmu_pmu *smmu_pmu)
754
773
dev_notice (smmu_pmu -> dev , "option mask 0x%x\n" , smmu_pmu -> options );
755
774
}
756
775
776
+ static bool smmu_pmu_coresight_id_regs (struct smmu_pmu * smmu_pmu )
777
+ {
778
+ return of_device_is_compatible (smmu_pmu -> dev -> of_node ,
779
+ "arm,mmu-600-pmcg" );
780
+ }
781
+
782
+ static void smmu_pmu_get_iidr (struct smmu_pmu * smmu_pmu )
783
+ {
784
+ u32 iidr = readl_relaxed (smmu_pmu -> reg_base + SMMU_PMCG_IIDR );
785
+
786
+ if (!iidr && smmu_pmu_coresight_id_regs (smmu_pmu )) {
787
+ u32 pidr0 = readl (smmu_pmu -> reg_base + SMMU_PMCG_PIDR0 );
788
+ u32 pidr1 = readl (smmu_pmu -> reg_base + SMMU_PMCG_PIDR1 );
789
+ u32 pidr2 = readl (smmu_pmu -> reg_base + SMMU_PMCG_PIDR2 );
790
+ u32 pidr3 = readl (smmu_pmu -> reg_base + SMMU_PMCG_PIDR3 );
791
+ u32 pidr4 = readl (smmu_pmu -> reg_base + SMMU_PMCG_PIDR4 );
792
+
793
+ u32 productid = FIELD_GET (SMMU_PMCG_PIDR0_PART_0 , pidr0 ) |
794
+ (FIELD_GET (SMMU_PMCG_PIDR1_PART_1 , pidr1 ) << 8 );
795
+ u32 variant = FIELD_GET (SMMU_PMCG_PIDR2_REVISION , pidr2 );
796
+ u32 revision = FIELD_GET (SMMU_PMCG_PIDR3_REVAND , pidr3 );
797
+ u32 implementer =
798
+ FIELD_GET (SMMU_PMCG_PIDR1_DES_0 , pidr1 ) |
799
+ (FIELD_GET (SMMU_PMCG_PIDR2_DES_1 , pidr2 ) << 4 ) |
800
+ (FIELD_GET (SMMU_PMCG_PIDR4_DES_2 , pidr4 ) << 8 );
801
+
802
+ iidr = FIELD_PREP (SMMU_PMCG_IIDR_PRODUCTID , productid ) |
803
+ FIELD_PREP (SMMU_PMCG_IIDR_VARIANT , variant ) |
804
+ FIELD_PREP (SMMU_PMCG_IIDR_REVISION , revision ) |
805
+ FIELD_PREP (SMMU_PMCG_IIDR_IMPLEMENTER , implementer );
806
+ }
807
+
808
+ smmu_pmu -> iidr = iidr ;
809
+ }
810
+
757
811
static int smmu_pmu_probe (struct platform_device * pdev )
758
812
{
759
813
struct smmu_pmu * smmu_pmu ;
@@ -825,7 +879,7 @@ static int smmu_pmu_probe(struct platform_device *pdev)
825
879
return err ;
826
880
}
827
881
828
- smmu_pmu -> iidr = readl_relaxed (smmu_pmu -> reg_base + SMMU_PMCG_IIDR );
882
+ smmu_pmu_get_iidr (smmu_pmu );
829
883
830
884
name = devm_kasprintf (& pdev -> dev , GFP_KERNEL , "smmuv3_pmcg_%llx" ,
831
885
(res_0 -> start ) >> SMMU_PMCG_PA_SHIFT );
@@ -834,7 +888,8 @@ static int smmu_pmu_probe(struct platform_device *pdev)
834
888
return - EINVAL ;
835
889
}
836
890
837
- smmu_pmu_get_acpi_options (smmu_pmu );
891
+ if (!dev -> of_node )
892
+ smmu_pmu_get_acpi_options (smmu_pmu );
838
893
839
894
/* Pick one CPU to be the preferred one to use */
840
895
smmu_pmu -> on_cpu = raw_smp_processor_id ();
@@ -884,9 +939,16 @@ static void smmu_pmu_shutdown(struct platform_device *pdev)
884
939
smmu_pmu_disable (& smmu_pmu -> pmu );
885
940
}
886
941
942
+ static const struct of_device_id smmu_pmu_of_match [] = {
943
+ { .compatible = "arm,smmu-v3-pmcg" },
944
+ {}
945
+ };
946
+ MODULE_DEVICE_TABLE (of , smmu_pmu_of_match );
947
+
887
948
static struct platform_driver smmu_pmu_driver = {
888
949
.driver = {
889
950
.name = "arm-smmu-v3-pmcg" ,
951
+ .of_match_table = of_match_ptr (smmu_pmu_of_match ),
890
952
.suppress_bind_attrs = true,
891
953
},
892
954
.probe = smmu_pmu_probe ,
0 commit comments