Kaanapali's DPU is supplied by both CORE and INT2 GDSCs. The
power-domain core only auto-attaches a single domain; with multiple
domains the device is left unattached, so both domains must be attached
explicitly.

The DPU OPP table also needs to continue controlling the MMCX
performance state. Mark CORE as the required OPP domain so its vote is
propagated through the genpd hierarchy to MMCX. INT2 has no OPP of its
own and is attached as a regular runtime-PM supplier.

Platforms with a single power domain remain unaffected and continue to
use the existing automatic attachment.

Reviewed-by: Dmitry Baryshkov <[email protected]>
Signed-off-by: Yongxing Mou <[email protected]>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index da3556eb6ecc..502e50ea5aca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -12,6 +12,7 @@
 #include <linux/debugfs.h>
 #include <linux/dma-buf.h>
 #include <linux/of_irq.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_opp.h>
 
 #include <drm/drm_crtc.h>
@@ -1376,6 +1377,33 @@ static int dpu_kms_mmap_dpu(struct dpu_kms *dpu_kms)
        return 0;
 }
 
+static int dpu_kms_attach_power_domains(struct device *dev)
+{
+       static const char * const core_names[] = { "core" };
+       static const char * const int2_names[] = { "int2" };
+       const struct dev_pm_domain_attach_data core_pd = {
+               .pd_names = core_names,
+               .num_pd_names = ARRAY_SIZE(core_names),
+               .pd_flags = PD_FLAG_REQUIRED_OPP,
+       };
+       const struct dev_pm_domain_attach_data int2_pd = {
+               .pd_names = int2_names,
+               .num_pd_names = ARRAY_SIZE(int2_names),
+       };
+       struct dev_pm_domain_list *core_list, *int2_list;
+       int ret;
+
+       if (of_count_phandle_with_args(dev->of_node, "power-domains",
+                                      "#power-domain-cells") <= 1)
+               return 0;
+
+       ret = devm_pm_domain_attach_list(dev, &core_pd, &core_list);
+       if (ret < 0)
+               return ret;
+
+       return devm_pm_domain_attach_list(dev, &int2_pd, &int2_list);
+}
+
 static int dpu_dev_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -1392,6 +1420,10 @@ static int dpu_dev_probe(struct platform_device *pdev)
 
        dpu_kms->pdev = pdev;
 
+       ret = dpu_kms_attach_power_domains(dev);
+       if (ret < 0)
+               return dev_err_probe(dev, ret, "failed to attach power 
domains\n");
+
        ret = devm_pm_opp_set_clkname(dev, "core");
        if (ret)
                return ret;

-- 
2.43.0

Reply via email to