]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
soc: qcom: rpmh-rsc: adjust probe for U-Boot
authorCaleb Connolly <caleb.connolly@linaro.org>
Mon, 15 Jul 2024 10:08:09 +0000 (12:08 +0200)
committerCaleb Connolly <caleb.connolly@linaro.org>
Thu, 25 Jul 2024 23:28:11 +0000 (01:28 +0200)
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>
drivers/soc/qcom/rpmh-internal.h
drivers/soc/qcom/rpmh-rsc.c

index 12c5b8d9cf86eedd7b7adfcda190dbc12c9856d9..ac8f6c35a7a45b40df6c0c4d5645f7ff185c0de2 100644 (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;
 };
index 6b47c8001cac393aa88770f63f496566e1ed68a8..2afe5005facf4c366cc02a5b4ea86a0addc39174 100644 (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 = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
-       if (!drv)
-               return -ENOMEM;
+       drv = dev_get_priv(dev);
 
-       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,
-       },
-};
 
-static int __init rpmh_driver_init(void)
-{
-       return platform_driver_register(&rpmh_driver);
-}
-core_initcall(rpmh_driver_init);
+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,
+};
 
 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. RPMh Driver");
 MODULE_LICENSE("GPL v2");