soc: qcom: rpmh-rsc: adjust probe for U-Boot

Rework the rpmh-rsc initialization to use U-Boot's driver model and
initialize cmd-db.

Acked-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
This commit is contained in:
Caleb Connolly
2024-07-15 12:08:09 +02:00
parent 3b2f15f530
commit 3f02b06fbc
2 changed files with 34 additions and 103 deletions

View File

@@ -8,7 +8,6 @@
#define __RPM_INTERNAL_H__
#include <linux/bitmap.h>
#include <linux/wait.h>
#include <soc/qcom/tcs.h>
#define TCS_TYPE_NR 4
@@ -17,6 +16,8 @@
#define MAX_TCS_NR (MAX_TCS_PER_TYPE * TCS_TYPE_NR)
#define MAX_TCS_SLOTS (MAX_CMDS_PER_TCS * MAX_TCS_PER_TYPE)
#define USEC_PER_SEC 1000000UL
struct rsc_drv;
/**
@@ -64,8 +65,7 @@ struct tcs_group {
struct rpmh_request {
struct tcs_request msg;
struct tcs_cmd cmd[MAX_RPMH_PAYLOAD];
struct completion *completion;
const struct device *dev;
const struct udevice *dev;
bool needs_free;
};
@@ -79,7 +79,6 @@ struct rpmh_request {
*/
struct rpmh_ctrlr {
struct list_head cache;
spinlock_t cache_lock;
bool dirty;
struct list_head batch_cache;
};
@@ -123,15 +122,10 @@ struct rsc_drv {
void __iomem *tcs_base;
int id;
int num_tcs;
struct notifier_block rsc_pm;
struct notifier_block genpd_nb;
atomic_t cpus_in_pm;
struct tcs_group tcs[TCS_TYPE_NR];
DECLARE_BITMAP(tcs_in_use, MAX_TCS_NR);
spinlock_t lock;
wait_queue_head_t tcs_wait;
struct rpmh_ctrlr client;
struct device *dev;
struct udevice *dev;
struct rsc_ver ver;
u32 *regs;
};

View File

@@ -386,18 +386,18 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg)
return 0;
}
static int rpmh_probe_tcs_config(struct platform_device *pdev, struct rsc_drv *drv)
static int rpmh_probe_tcs_config(struct udevice *dev, struct rsc_drv *drv)
{
struct tcs_type_config {
u32 type;
u32 n;
} tcs_cfg[TCS_TYPE_NR] = { { 0 } };
struct device_node *dn = pdev->dev.of_node;
ofnode dn = dev_ofnode(dev);
u32 config, max_tcs, ncpt, offset;
int i, ret, n, st = 0;
struct tcs_group *tcs;
ret = of_property_read_u32(dn, "qcom,tcs-offset", &offset);
ret = ofnode_read_u32(dn, "qcom,tcs-offset", &offset);
if (ret)
return ret;
drv->tcs_base = drv->base + offset;
@@ -411,22 +411,13 @@ static int rpmh_probe_tcs_config(struct platform_device *pdev, struct rsc_drv *d
ncpt = config & (DRV_NCPT_MASK << DRV_NCPT_SHIFT);
ncpt = ncpt >> DRV_NCPT_SHIFT;
n = of_property_count_u32_elems(dn, "qcom,tcs-config");
if (n != 2 * TCS_TYPE_NR)
return -EINVAL;
n = ofnode_read_u32_array(dn, "qcom,tcs-config", (u32 *)tcs_cfg, 2 * TCS_TYPE_NR);
if (n < 0) {
log_err("RPMh: %s: error reading qcom,tcs-config %d\n", dev->name, n);
return n;
}
for (i = 0; i < TCS_TYPE_NR; i++) {
ret = of_property_read_u32_index(dn, "qcom,tcs-config",
i * 2, &tcs_cfg[i].type);
if (ret)
return ret;
if (tcs_cfg[i].type >= TCS_TYPE_NR)
return -EINVAL;
ret = of_property_read_u32_index(dn, "qcom,tcs-config",
i * 2 + 1, &tcs_cfg[i].n);
if (ret)
return ret;
if (tcs_cfg[i].n > MAX_TCS_PER_TYPE)
return -EINVAL;
}
@@ -457,41 +448,26 @@ static int rpmh_probe_tcs_config(struct platform_device *pdev, struct rsc_drv *d
return 0;
}
static int rpmh_rsc_probe(struct platform_device *pdev)
static int rpmh_rsc_probe(struct udevice *dev)
{
struct device_node *dn = pdev->dev.of_node;
ofnode dn = dev_ofnode(dev);
struct rsc_drv *drv;
char drv_id[10] = {0};
int ret, irq;
u32 solver_config;
int ret;
u32 rsc_id;
/*
* Even though RPMh doesn't directly use cmd-db, all of its children
* do. To avoid adding this check to our children we'll do it now.
*/
ret = cmd_db_ready();
if (ret) {
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "Command DB not available (%d)\n",
ret);
return ret;
}
drv = dev_get_priv(dev);
drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
if (!drv)
return -ENOMEM;
ret = of_property_read_u32(dn, "qcom,drv-id", &drv->id);
ret = ofnode_read_u32(dn, "qcom,drv-id", &drv->id);
if (ret)
return ret;
drv->name = of_get_property(dn, "label", NULL);
drv->name = ofnode_get_property(dn, "label", NULL);
if (!drv->name)
drv->name = dev_name(&pdev->dev);
drv->name = dev->name;
snprintf(drv_id, ARRAY_SIZE(drv_id), "drv-%d", drv->id);
drv->base = devm_platform_ioremap_resource_byname(pdev, drv_id);
drv->base = (void __iomem *)dev_read_addr_name(dev, drv_id);
if (IS_ERR(drv->base))
return PTR_ERR(drv->base);
@@ -506,7 +482,7 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
else
drv->regs = rpmh_rsc_reg_offset_ver_2_7;
ret = rpmh_probe_tcs_config(pdev, drv);
ret = rpmh_probe_tcs_config(dev, drv);
if (ret)
return ret;
@@ -514,35 +490,6 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
init_waitqueue_head(&drv->tcs_wait);
bitmap_zero(drv->tcs_in_use, MAX_TCS_NR);
irq = platform_get_irq(pdev, drv->id);
if (irq < 0)
return irq;
ret = devm_request_irq(&pdev->dev, irq, tcs_tx_done,
IRQF_TRIGGER_HIGH | IRQF_NO_SUSPEND,
drv->name, drv);
if (ret)
return ret;
/*
* CPU PM/genpd notification are not required for controllers that support
* 'HW solver' mode where they can be in autonomous mode executing low
* power mode to power down.
*/
solver_config = readl_relaxed(drv->base + drv->regs[DRV_SOLVER_CONFIG]);
solver_config &= DRV_HW_SOLVER_MASK << DRV_HW_SOLVER_SHIFT;
solver_config = solver_config >> DRV_HW_SOLVER_SHIFT;
if (!solver_config) {
if (pdev->dev.pm_domain) {
ret = rpmh_rsc_pd_attach(drv, &pdev->dev);
if (ret)
return ret;
} else {
drv->rsc_pm.notifier_call = rpmh_rsc_cpu_pm_callback;
cpu_pm_register_notifier(&drv->rsc_pm);
}
}
/* Enable the active TCS to send requests immediately */
writel_relaxed(drv->tcs[ACTIVE_TCS].mask,
drv->tcs_base + drv->regs[RSC_DRV_IRQ_ENABLE]);
@@ -551,38 +498,28 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&drv->client.cache);
INIT_LIST_HEAD(&drv->client.batch_cache);
dev_set_drvdata(&pdev->dev, drv);
drv->dev = &pdev->dev;
dev_set_drvdata(dev, drv);
drv->dev = dev;
ret = devm_of_platform_populate(&pdev->dev);
if (ret && pdev->dev.pm_domain) {
dev_pm_genpd_remove_notifier(&pdev->dev);
pm_runtime_disable(&pdev->dev);
}
log_debug("RPMh: %s: v%d.%d\n", dev->name, drv->ver.major, drv->ver.minor);
return ret;
}
static const struct of_device_id rpmh_drv_match[] = {
{ .compatible = "qcom,rpmh-rsc", },
static const struct udevice_id qcom_rpmh_ids[] = {
{ .compatible = "qcom,rpmh-rsc" },
{ }
};
MODULE_DEVICE_TABLE(of, rpmh_drv_match);
static struct platform_driver rpmh_driver = {
.probe = rpmh_rsc_probe,
.driver = {
.name = "rpmh",
.of_match_table = rpmh_drv_match,
.suppress_bind_attrs = true,
},
U_BOOT_DRIVER(qcom_rpmh_rsc) = {
.name = "qcom_rpmh_rsc",
.id = UCLASS_MISC,
.priv_auto = sizeof(struct rsc_drv),
.probe = rpmh_rsc_probe,
.of_match = qcom_rpmh_ids,
/* rpmh is under CLUSTER_PD which we don't support, so skip trying to enable PDs */
.flags = DM_FLAG_DEFAULT_PD_CTRL_OFF,
};
static int __init rpmh_driver_init(void)
{
return platform_driver_register(&rpmh_driver);
}
core_initcall(rpmh_driver_init);
MODULE_DESCRIPTION("Qualcomm Technologies, Inc. RPMh Driver");
MODULE_LICENSE("GPL v2");