perf/x86/intel/uncore: Implement global init callback for GNR uncore

On Sierra Forest and Clearwater Forest, the FRZ_ALL bit in the global
control register defaults to 0 at boot, but UBOX PMON units do not
work until the global control register is explicitly written with 0
to trigger hardware initialization properly.

Implement the generic uncore_msr_global_init() callback and add it to
gnr_uncore_init[], which is shared by GNR, GRR, SRF, and CWF.

Fixes: 632c4bf6d0 ("perf/x86/intel/uncore: Support Granite Rapids")
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20260602144908.263680-8-zide.chen@intel.com
This commit is contained in:
Zide Chen 2026-06-02 07:49:08 -07:00 committed by Peter Zijlstra
parent 2aa7dacf8a
commit 1a308a168c
3 changed files with 18 additions and 6 deletions

View File

@ -1716,7 +1716,7 @@ static int __init uncore_mmio_init(void)
return ret;
}
static int uncore_mmio_global_init(u64 ctl)
static int uncore_mmio_global_init(int die, u64 ctl)
{
void __iomem *io_addr;
@ -1731,6 +1731,16 @@ static int uncore_mmio_global_init(u64 ctl)
return 0;
}
static int uncore_msr_global_init(int die, u64 msr)
{
int cpu = uncore_die_to_cpu(die);
if (cpu == -1)
return -ENODEV;
return wrmsrq_on_cpu(cpu, msr, 0);
}
static const struct uncore_plat_init nhm_uncore_init __initconst = {
.cpu_init = nhm_uncore_cpu_init,
};
@ -1871,6 +1881,7 @@ static const struct uncore_plat_init gnr_uncore_init __initconst = {
.domain[0].base_is_pci = true,
.domain[0].discovery_base = UNCORE_DISCOVERY_TABLE_DEVICE,
.domain[0].units_ignore = gnr_uncore_units_ignore,
.domain[0].global_init = uncore_msr_global_init,
};
static const struct uncore_plat_init dmr_uncore_init __initconst = {

View File

@ -53,7 +53,7 @@ struct uncore_discovery_domain {
/* MSR address or PCI device used as the discovery base */
u32 discovery_base;
bool base_is_pci;
int (*global_init)(u64 ctl);
int (*global_init)(int die, u64 ctl);
/* The units in the discovery table should be ignored. */
int *units_ignore;

View File

@ -287,7 +287,7 @@ static int __parse_discovery_table(struct uncore_discovery_domain *domain,
if (!io_addr)
return -ENOMEM;
if (domain->global_init && domain->global_init(global.ctl)) {
if (domain->global_init && domain->global_init(die, global.ctl)) {
ret = -ENODEV;
goto out;
}
@ -399,7 +399,6 @@ static bool uncore_discovery_msr(struct uncore_discovery_domain *domain)
if (!die_mask)
return false;
cpus_read_lock();
for_each_online_cpu(cpu) {
die = topology_logical_die_id(cpu);
if (__test_and_set_bit(die, die_mask))
@ -414,8 +413,6 @@ static bool uncore_discovery_msr(struct uncore_discovery_domain *domain)
__parse_discovery_table(domain, base, die, &parsed);
}
cpus_read_unlock();
kfree(die_mask);
return parsed;
}
@ -429,10 +426,14 @@ bool uncore_discovery(struct uncore_plat_init *init)
for (i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++) {
domain = &init->domain[i];
if (domain->discovery_base) {
cpus_read_lock();
if (!domain->base_is_pci)
ret |= uncore_discovery_msr(domain);
else
ret |= uncore_discovery_pci(domain);
cpus_read_unlock();
}
}