mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 16:44:58 +02:00
drivers/perf: hisi: Add a common function to retrieve topology from firmware
Currently each type of uncore PMU driver uses almost the same routine and the same firmware interface (or properties) to retrieve the topology information, then reset the unused IDs to -1. Extract the common parts to the framework in hisi_uncore_pmu_init_topology(). Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Yicong Yang <yangyicong@hisilicon.com> Link: https://lore.kernel.org/r/20241210141525.37788-7-yangyicong@huawei.com Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
parent
c192026cee
commit
32528b165e
|
|
@ -180,20 +180,18 @@ MODULE_DEVICE_TABLE(acpi, hisi_cpa_pmu_acpi_match);
|
|||
static int hisi_cpa_pmu_init_data(struct platform_device *pdev,
|
||||
struct hisi_pmu *cpa_pmu)
|
||||
{
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
&cpa_pmu->topo.sicl_id)) {
|
||||
hisi_uncore_pmu_init_topology(cpa_pmu, &pdev->dev);
|
||||
|
||||
if (cpa_pmu->topo.sicl_id < 0) {
|
||||
dev_err(&pdev->dev, "Can not read sicl-id\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
|
||||
&cpa_pmu->topo.index_id)) {
|
||||
if (cpa_pmu->topo.index_id < 0) {
|
||||
dev_err(&pdev->dev, "Cannot read idx-id\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cpa_pmu->topo.ccl_id = -1;
|
||||
cpa_pmu->topo.sccl_id = -1;
|
||||
cpa_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(cpa_pmu->base))
|
||||
return PTR_ERR(cpa_pmu->base);
|
||||
|
|
|
|||
|
|
@ -297,6 +297,8 @@ MODULE_DEVICE_TABLE(acpi, hisi_ddrc_pmu_acpi_match);
|
|||
static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
|
||||
struct hisi_pmu *ddrc_pmu)
|
||||
{
|
||||
hisi_uncore_pmu_init_topology(ddrc_pmu, &pdev->dev);
|
||||
|
||||
/*
|
||||
* Use the SCCL_ID and DDRC channel ID to identify the
|
||||
* DDRC PMU, while SCCL_ID is in MPIDR[aff2].
|
||||
|
|
@ -307,13 +309,10 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
&ddrc_pmu->topo.sccl_id)) {
|
||||
if (ddrc_pmu->topo.sccl_id < 0) {
|
||||
dev_err(&pdev->dev, "Can not read ddrc sccl-id!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
/* DDRC PMUs only share the same SCCL */
|
||||
ddrc_pmu->topo.ccl_id = -1;
|
||||
|
||||
ddrc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(ddrc_pmu->base)) {
|
||||
|
|
@ -323,8 +322,7 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
|
|||
|
||||
ddrc_pmu->identifier = readl(ddrc_pmu->base + DDRC_VERSION);
|
||||
if (ddrc_pmu->identifier >= HISI_PMU_V2) {
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,sub-id",
|
||||
&ddrc_pmu->topo.sub_id)) {
|
||||
if (ddrc_pmu->topo.sub_id < 0) {
|
||||
dev_err(&pdev->dev, "Can not read sub-id!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -295,12 +295,13 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
|||
unsigned long long id;
|
||||
acpi_status status;
|
||||
|
||||
hisi_uncore_pmu_init_topology(hha_pmu, &pdev->dev);
|
||||
|
||||
/*
|
||||
* Use SCCL_ID and UID to identify the HHA PMU, while
|
||||
* SCCL_ID is in MPIDR[aff2].
|
||||
*/
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
&hha_pmu->topo.sccl_id)) {
|
||||
if (hha_pmu->topo.sccl_id < 0) {
|
||||
dev_err(&pdev->dev, "Can not read hha sccl-id!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -309,8 +310,7 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
|||
* Early versions of BIOS support _UID by mistake, so we support
|
||||
* both "hisilicon, idx-id" as preference, if available.
|
||||
*/
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
|
||||
&hha_pmu->topo.index_id)) {
|
||||
if (hha_pmu->topo.index_id < 0) {
|
||||
status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
||||
"_UID", NULL, &id);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
|
|
@ -320,8 +320,6 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
|||
|
||||
hha_pmu->topo.index_id = id;
|
||||
}
|
||||
/* HHA PMUs only share the same SCCL */
|
||||
hha_pmu->topo.ccl_id = -1;
|
||||
|
||||
hha_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(hha_pmu->base)) {
|
||||
|
|
|
|||
|
|
@ -355,18 +355,18 @@ MODULE_DEVICE_TABLE(acpi, hisi_l3c_pmu_acpi_match);
|
|||
static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
||||
struct hisi_pmu *l3c_pmu)
|
||||
{
|
||||
hisi_uncore_pmu_init_topology(l3c_pmu, &pdev->dev);
|
||||
|
||||
/*
|
||||
* Use the SCCL_ID and CCL_ID to identify the L3C PMU, while
|
||||
* SCCL_ID is in MPIDR[aff2] and CCL_ID is in MPIDR[aff1].
|
||||
*/
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
&l3c_pmu->topo.sccl_id)) {
|
||||
if (l3c_pmu->topo.sccl_id < 0) {
|
||||
dev_err(&pdev->dev, "Can not read l3c sccl-id!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
|
||||
&l3c_pmu->topo.ccl_id)) {
|
||||
if (l3c_pmu->topo.ccl_id < 0) {
|
||||
dev_err(&pdev->dev, "Can not read l3c ccl-id!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,25 +269,22 @@ static void hisi_pa_pmu_clear_int_status(struct hisi_pmu *pa_pmu, int idx)
|
|||
static int hisi_pa_pmu_init_data(struct platform_device *pdev,
|
||||
struct hisi_pmu *pa_pmu)
|
||||
{
|
||||
hisi_uncore_pmu_init_topology(pa_pmu, &pdev->dev);
|
||||
|
||||
/*
|
||||
* As PA PMU is in a SICL, use the SICL_ID and the index ID
|
||||
* to identify the PA PMU.
|
||||
*/
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
&pa_pmu->topo.sicl_id)) {
|
||||
if (pa_pmu->topo.sicl_id < 0) {
|
||||
dev_err(&pdev->dev, "Cannot read sicl-id!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
|
||||
&pa_pmu->topo.index_id)) {
|
||||
if (pa_pmu->topo.index_id < 0) {
|
||||
dev_err(&pdev->dev, "Cannot read idx-id!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pa_pmu->topo.ccl_id = -1;
|
||||
pa_pmu->topo.sccl_id = -1;
|
||||
|
||||
pa_pmu->dev_info = device_get_match_data(&pdev->dev);
|
||||
if (!pa_pmu->dev_info)
|
||||
return -ENODEV;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
#include <asm/cputype.h>
|
||||
#include <asm/local64.h>
|
||||
|
|
@ -530,6 +531,35 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
|
|||
}
|
||||
EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_offline_cpu, "HISI_PMU");
|
||||
|
||||
/*
|
||||
* Retrieve the topology information from the firmware for the hisi_pmu device.
|
||||
* The topology ID will be -1 if we cannot initialize it, it may either due to
|
||||
* the PMU doesn't locate on this certain topology or the firmware needs to be
|
||||
* fixed.
|
||||
*/
|
||||
void hisi_uncore_pmu_init_topology(struct hisi_pmu *hisi_pmu, struct device *dev)
|
||||
{
|
||||
struct hisi_pmu_topology *topo = &hisi_pmu->topo;
|
||||
|
||||
topo->sccl_id = -1;
|
||||
topo->ccl_id = -1;
|
||||
topo->index_id = -1;
|
||||
topo->sub_id = -1;
|
||||
|
||||
if (device_property_read_u32(dev, "hisilicon,scl-id", &topo->sccl_id))
|
||||
dev_dbg(dev, "no scl-id present\n");
|
||||
|
||||
if (device_property_read_u32(dev, "hisilicon,ccl-id", &topo->ccl_id))
|
||||
dev_dbg(dev, "no ccl-id present\n");
|
||||
|
||||
if (device_property_read_u32(dev, "hisilicon,idx-id", &topo->index_id))
|
||||
dev_dbg(dev, "no idx-id present\n");
|
||||
|
||||
if (device_property_read_u32(dev, "hisilicon,sub-id", &topo->sub_id))
|
||||
dev_dbg(dev, "no sub-id present\n");
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_init_topology, "HISI_PMU");
|
||||
|
||||
void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module)
|
||||
{
|
||||
struct pmu *pmu = &hisi_pmu->pmu;
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
|
|||
char *page);
|
||||
int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
|
||||
struct platform_device *pdev);
|
||||
void hisi_uncore_pmu_init_topology(struct hisi_pmu *hisi_pmu, struct device *dev);
|
||||
|
||||
void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module);
|
||||
#endif /* __HISI_UNCORE_PMU_H__ */
|
||||
|
|
|
|||
|
|
@ -288,25 +288,22 @@ MODULE_DEVICE_TABLE(acpi, hisi_sllc_pmu_acpi_match);
|
|||
static int hisi_sllc_pmu_init_data(struct platform_device *pdev,
|
||||
struct hisi_pmu *sllc_pmu)
|
||||
{
|
||||
hisi_uncore_pmu_init_topology(sllc_pmu, &pdev->dev);
|
||||
|
||||
/*
|
||||
* Use the SCCL_ID and the index ID to identify the SLLC PMU,
|
||||
* while SCCL_ID is from MPIDR_EL1 by CPU.
|
||||
*/
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
&sllc_pmu->topo.sccl_id)) {
|
||||
if (sllc_pmu->topo.sccl_id < 0) {
|
||||
dev_err(&pdev->dev, "Cannot read sccl-id!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
|
||||
&sllc_pmu->topo.index_id)) {
|
||||
if (sllc_pmu->topo.index_id < 0) {
|
||||
dev_err(&pdev->dev, "Cannot read idx-id!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* SLLC PMUs only share the same SCCL */
|
||||
sllc_pmu->topo.ccl_id = -1;
|
||||
|
||||
sllc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(sllc_pmu->base)) {
|
||||
dev_err(&pdev->dev, "ioremap failed for sllc_pmu resource.\n");
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
#include "hisi_uncore_pmu.h"
|
||||
|
||||
|
|
@ -366,25 +365,24 @@ static void hisi_uc_pmu_clear_int_status(struct hisi_pmu *uc_pmu, int idx)
|
|||
static int hisi_uc_pmu_init_data(struct platform_device *pdev,
|
||||
struct hisi_pmu *uc_pmu)
|
||||
{
|
||||
hisi_uncore_pmu_init_topology(uc_pmu, &pdev->dev);
|
||||
|
||||
/*
|
||||
* Use SCCL (Super CPU Cluster) ID and CCL (CPU Cluster) ID to
|
||||
* identify the topology information of UC PMU devices in the chip.
|
||||
* They have some CCLs per SCCL and then 4 UC PMU per CCL.
|
||||
*/
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
&uc_pmu->topo.sccl_id)) {
|
||||
if (uc_pmu->topo.sccl_id < 0) {
|
||||
dev_err(&pdev->dev, "Can not read uc sccl-id!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
|
||||
&uc_pmu->topo.ccl_id)) {
|
||||
if (uc_pmu->topo.ccl_id < 0) {
|
||||
dev_err(&pdev->dev, "Can not read uc ccl-id!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,sub-id",
|
||||
&uc_pmu->topo.sub_id)) {
|
||||
if (uc_pmu->topo.sub_id < 0) {
|
||||
dev_err(&pdev->dev, "Can not read sub-id!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user