Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf/arm_cspmu: Add pmpidr support

The PMIIDR value is composed by the values in PMPIDR registers.
We can use PMPIDR registers as alternative for device
identification for systems that do not implement PMIIDR.

Reviewed-by: Ilkka Koskinen <ilkka@os.amperecomputing.com>
Signed-off-by: Besar Wicaksono <bwicaksono@nvidia.com>
Signed-off-by: Will Deacon <will@kernel.org>

authored by

Besar Wicaksono and committed by
Will Deacon
04330be8 a2573bc7

+75 -6
+41 -3
drivers/perf/arm_cspmu/arm_cspmu.c
··· 322 322 { 323 323 .module_name = "nvidia_cspmu", 324 324 .pmiidr_val = ARM_CSPMU_IMPL_ID_NVIDIA, 325 - .pmiidr_mask = ARM_CSPMU_PMIIDR_IMPLEMENTER, 325 + .pmiidr_mask = PMIIDR_IMPLEMENTER, 326 326 .module = NULL, 327 327 .impl_init_ops = NULL, 328 328 }, 329 329 { 330 330 .module_name = "ampere_cspmu", 331 331 .pmiidr_val = ARM_CSPMU_IMPL_ID_AMPERE, 332 - .pmiidr_mask = ARM_CSPMU_PMIIDR_IMPLEMENTER, 332 + .pmiidr_mask = PMIIDR_IMPLEMENTER, 333 333 .module = NULL, 334 334 .impl_init_ops = NULL, 335 335 }, ··· 351 351 return NULL; 352 352 } 353 353 354 + static u32 arm_cspmu_get_pmiidr(struct arm_cspmu *cspmu) 355 + { 356 + u32 pmiidr, pmpidr; 357 + 358 + pmiidr = readl(cspmu->base0 + PMIIDR); 359 + 360 + if (pmiidr != 0) 361 + return pmiidr; 362 + 363 + /* Construct PMIIDR value from PMPIDRs. */ 364 + 365 + pmpidr = readl(cspmu->base0 + PMPIDR0); 366 + pmiidr |= FIELD_PREP(PMIIDR_PRODUCTID_PART_0, 367 + FIELD_GET(PMPIDR0_PART_0, pmpidr)); 368 + 369 + pmpidr = readl(cspmu->base0 + PMPIDR1); 370 + pmiidr |= FIELD_PREP(PMIIDR_PRODUCTID_PART_1, 371 + FIELD_GET(PMPIDR1_PART_1, pmpidr)); 372 + pmiidr |= FIELD_PREP(PMIIDR_IMPLEMENTER_DES_0, 373 + FIELD_GET(PMPIDR1_DES_0, pmpidr)); 374 + 375 + pmpidr = readl(cspmu->base0 + PMPIDR2); 376 + pmiidr |= FIELD_PREP(PMIIDR_VARIANT, 377 + FIELD_GET(PMPIDR2_REVISION, pmpidr)); 378 + pmiidr |= FIELD_PREP(PMIIDR_IMPLEMENTER_DES_1, 379 + FIELD_GET(PMPIDR2_DES_1, pmpidr)); 380 + 381 + pmpidr = readl(cspmu->base0 + PMPIDR3); 382 + pmiidr |= FIELD_PREP(PMIIDR_REVISION, 383 + FIELD_GET(PMPIDR3_REVAND, pmpidr)); 384 + 385 + pmpidr = readl(cspmu->base0 + PMPIDR4); 386 + pmiidr |= FIELD_PREP(PMIIDR_IMPLEMENTER_DES_2, 387 + FIELD_GET(PMPIDR4_DES_2, pmpidr)); 388 + 389 + return pmiidr; 390 + } 391 + 354 392 #define DEFAULT_IMPL_OP(name) .name = arm_cspmu_##name 355 393 356 394 static int arm_cspmu_init_impl_ops(struct arm_cspmu *cspmu) ··· 399 361 400 362 /* Start with a default PMU implementation */ 401 363 cspmu->impl.module = THIS_MODULE; 402 - cspmu->impl.pmiidr = readl(cspmu->base0 + PMIIDR); 364 + cspmu->impl.pmiidr = arm_cspmu_get_pmiidr(cspmu); 403 365 cspmu->impl.ops = (struct arm_cspmu_impl_ops) { 404 366 DEFAULT_IMPL_OP(get_event_attrs), 405 367 DEFAULT_IMPL_OP(get_format_attrs),
+33 -2
drivers/perf/arm_cspmu/arm_cspmu.h
··· 86 86 #define PMCFGR 0xE00 87 87 #define PMCR 0xE04 88 88 #define PMIIDR 0xE08 89 + #define PMPIDR0 0xFE0 90 + #define PMPIDR1 0xFE4 91 + #define PMPIDR2 0xFE8 92 + #define PMPIDR3 0xFEC 93 + #define PMPIDR4 0xFD0 89 94 90 95 /* PMCFGR register field */ 91 96 #define PMCFGR_NCG GENMASK(31, 28) ··· 120 115 #define PMCR_E BIT(0) 121 116 122 117 /* PMIIDR register field */ 123 - #define ARM_CSPMU_PMIIDR_IMPLEMENTER GENMASK(11, 0) 124 - #define ARM_CSPMU_PMIIDR_PRODUCTID GENMASK(31, 20) 118 + #define PMIIDR_IMPLEMENTER GENMASK(11, 0) 119 + #define PMIIDR_IMPLEMENTER_DES_0 GENMASK(3, 0) 120 + #define PMIIDR_IMPLEMENTER_DES_1 GENMASK(6, 4) 121 + #define PMIIDR_IMPLEMENTER_DES_2 GENMASK(11, 8) 122 + #define PMIIDR_REVISION GENMASK(15, 12) 123 + #define PMIIDR_VARIANT GENMASK(19, 16) 124 + #define PMIIDR_PRODUCTID GENMASK(31, 20) 125 + #define PMIIDR_PRODUCTID_PART_0 GENMASK(27, 20) 126 + #define PMIIDR_PRODUCTID_PART_1 GENMASK(31, 28) 127 + 128 + /* PMPIDR0 register field */ 129 + #define PMPIDR0_PART_0 GENMASK(7, 0) 130 + 131 + /* PMPIDR1 register field */ 132 + #define PMPIDR1_DES_0 GENMASK(7, 4) 133 + #define PMPIDR1_PART_1 GENMASK(3, 0) 134 + 135 + /* PMPIDR2 register field */ 136 + #define PMPIDR2_REVISION GENMASK(7, 4) 137 + #define PMPIDR2_DES_1 GENMASK(2, 0) 138 + 139 + /* PMPIDR3 register field */ 140 + #define PMPIDR3_REVAND GENMASK(7, 4) 141 + #define PMPIDR3_CMOD GENMASK(3, 0) 142 + 143 + /* PMPIDR4 register field */ 144 + #define PMPIDR4_SIZE GENMASK(7, 4) 145 + #define PMPIDR4_DES_2 GENMASK(3, 0) 125 146 126 147 /* JEDEC-assigned JEP106 identification code */ 127 148 #define ARM_CSPMU_IMPL_ID_NVIDIA 0x36B
+1 -1
drivers/perf/arm_cspmu/nvidia_cspmu.c
··· 322 322 if (!ctx) 323 323 return -ENOMEM; 324 324 325 - prodid = FIELD_GET(ARM_CSPMU_PMIIDR_PRODUCTID, cspmu->impl.pmiidr); 325 + prodid = FIELD_GET(PMIIDR_PRODUCTID, cspmu->impl.pmiidr); 326 326 327 327 /* Find matching PMU. */ 328 328 for (; match->prodid; match++) {