4747#include <linux/kernel.h>
4848#include <linux/list.h>
4949#include <linux/msi.h>
50+ #include <linux/of.h>
5051#include <linux/perf_event.h>
5152#include <linux/platform_device.h>
5253#include <linux/smp.h>
7576#define SMMU_PMCG_CR 0xE04
7677#define SMMU_PMCG_CR_ENABLE BIT(0)
7778#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)
7883#define SMMU_PMCG_CEID0 0xE20
7984#define SMMU_PMCG_CEID1 0xE28
8085#define SMMU_PMCG_IRQ_CTRL 0xE50
8388#define SMMU_PMCG_IRQ_CFG1 0xE60
8489#define SMMU_PMCG_IRQ_CFG2 0xE64
8590
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+
86105/* MSI config fields */
87106#define MSI_CFG0_ADDR_MASK GENMASK_ULL(51, 2)
88107#define MSI_CFG2_MEMATTR_DEVICE_nGnRE 0x1
@@ -754,6 +773,41 @@ static void smmu_pmu_get_acpi_options(struct smmu_pmu *smmu_pmu)
754773 dev_notice (smmu_pmu -> dev , "option mask 0x%x\n" , smmu_pmu -> options );
755774}
756775
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+
757811static int smmu_pmu_probe (struct platform_device * pdev )
758812{
759813 struct smmu_pmu * smmu_pmu ;
@@ -825,7 +879,7 @@ static int smmu_pmu_probe(struct platform_device *pdev)
825879 return err ;
826880 }
827881
828- smmu_pmu -> iidr = readl_relaxed (smmu_pmu -> reg_base + SMMU_PMCG_IIDR );
882+ smmu_pmu_get_iidr (smmu_pmu );
829883
830884 name = devm_kasprintf (& pdev -> dev , GFP_KERNEL , "smmuv3_pmcg_%llx" ,
831885 (res_0 -> start ) >> SMMU_PMCG_PA_SHIFT );
@@ -834,7 +888,8 @@ static int smmu_pmu_probe(struct platform_device *pdev)
834888 return - EINVAL ;
835889 }
836890
837- smmu_pmu_get_acpi_options (smmu_pmu );
891+ if (!dev -> of_node )
892+ smmu_pmu_get_acpi_options (smmu_pmu );
838893
839894 /* Pick one CPU to be the preferred one to use */
840895 smmu_pmu -> on_cpu = raw_smp_processor_id ();
@@ -884,9 +939,16 @@ static void smmu_pmu_shutdown(struct platform_device *pdev)
884939 smmu_pmu_disable (& smmu_pmu -> pmu );
885940}
886941
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+
887948static struct platform_driver smmu_pmu_driver = {
888949 .driver = {
889950 .name = "arm-smmu-v3-pmcg" ,
951+ .of_match_table = of_match_ptr (smmu_pmu_of_match ),
890952 .suppress_bind_attrs = true,
891953 },
892954 .probe = smmu_pmu_probe ,
0 commit comments