diff options
author | Dmitry Baryshkov <dmitry.baryshkov@linaro.org> | 2022-04-19 18:53:46 +0300 |
---|---|---|
committer | Dmitry Baryshkov <dmitry.baryshkov@linaro.org> | 2022-04-26 00:50:46 +0300 |
commit | 6874f48bb8b050b695698f1145e6846ba08baa75 (patch) | |
tree | 9df7bf6ea24b6573c3303e901dc52f15543ee161 /drivers/gpu/drm/msm/disp | |
parent | dc43e923cd1478fad5ec7a2bbb67dc3d00c24f84 (diff) | |
download | linux-stable-6874f48bb8b050b695698f1145e6846ba08baa75.tar.gz linux-stable-6874f48bb8b050b695698f1145e6846ba08baa75.tar.bz2 linux-stable-6874f48bb8b050b695698f1145e6846ba08baa75.zip |
drm/msm: make mdp5/dpu devices master components
The msm_mdss serves several roles at this moment. It provides IRQ domain
used by MDP5 and DPU drivers but it also serves as a component master
for both those usecases. MDP4 (which does not have separate MDSS device)
is the component master on it's own.
Remove this assymmetry and make both MDP5 and DPU component masters too.
This removes a need to care about drm/components from msm_mdss driver,
removes an mdss pointer from struct msm_drm_private and simplifies the
interface between mdp5/dpu and msm_drv.
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/482512/
Link: https://lore.kernel.org/r/20220419155346.1272627-7-dmitry.baryshkov@linaro.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Diffstat (limited to 'drivers/gpu/drm/msm/disp')
-rw-r--r-- | drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 88 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 50 |
3 files changed, 54 insertions, 100 deletions
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 38627ccf3068..7672e1d28665 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -380,9 +380,13 @@ static int dpu_kms_parse_data_bus_icc_path(struct dpu_kms *dpu_kms) struct icc_path *path0; struct icc_path *path1; struct drm_device *dev = dpu_kms->dev; + struct device *dpu_dev = dev->dev; + struct device *mdss_dev = dpu_dev->parent; - path0 = of_icc_get(dev->dev, "mdp0-mem"); - path1 = of_icc_get(dev->dev, "mdp1-mem"); + /* Interconnects are a part of MDSS device tree binding, not the + * MDP/DPU device. */ + path0 = of_icc_get(mdss_dev, "mdp0-mem"); + path1 = of_icc_get(mdss_dev, "mdp1-mem"); if (IS_ERR_OR_NULL(path0)) return PTR_ERR_OR_ZERO(path0); @@ -837,6 +841,9 @@ static void dpu_kms_destroy(struct msm_kms *kms) _dpu_kms_hw_destroy(dpu_kms); msm_kms_destroy(&dpu_kms->base); + + if (dpu_kms->rpm_enabled) + pm_runtime_disable(&dpu_kms->pdev->dev); } static irqreturn_t dpu_irq(struct msm_kms *kms) @@ -973,12 +980,16 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms) struct iommu_domain *domain; struct msm_gem_address_space *aspace; struct msm_mmu *mmu; + struct device *dpu_dev = dpu_kms->dev->dev; + struct device *mdss_dev = dpu_dev->parent; domain = iommu_domain_alloc(&platform_bus_type); if (!domain) return 0; - mmu = msm_iommu_new(dpu_kms->dev->dev, domain); + /* IOMMUs are a part of MDSS device tree binding, not the + * MDP/DPU device. */ + mmu = msm_iommu_new(mdss_dev, domain); if (IS_ERR(mmu)) { iommu_domain_free(domain); return PTR_ERR(mmu); @@ -1172,40 +1183,15 @@ error: return rc; } -static int dpu_kms_init(struct drm_device *dev) -{ - struct msm_drm_private *priv; - struct dpu_kms *dpu_kms; - int irq; - - if (!dev) { - DPU_ERROR("drm device node invalid\n"); - return -EINVAL; - } - - priv = dev->dev_private; - dpu_kms = to_dpu_kms(priv->kms); - - irq = irq_of_parse_and_map(dpu_kms->pdev->dev.of_node, 0); - if (irq < 0) { - DPU_ERROR("failed to get irq: %d\n", irq); - return irq; - } - dpu_kms->base.irq = irq; - - return 0; -} - -static int dpu_bind(struct device *dev, struct device *master, void *data) +static int dpu_kms_init(struct drm_device *ddev) { - struct msm_drm_private *priv = dev_get_drvdata(master); + struct msm_drm_private *priv = ddev->dev_private; + struct device *dev = ddev->dev; struct platform_device *pdev = to_platform_device(dev); - struct drm_device *ddev = priv->dev; struct dpu_kms *dpu_kms; + int irq; int ret = 0; - priv->kms_init = dpu_kms_init; - dpu_kms = devm_kzalloc(&pdev->dev, sizeof(*dpu_kms), GFP_KERNEL); if (!dpu_kms) return -ENOMEM; @@ -1227,8 +1213,6 @@ static int dpu_bind(struct device *dev, struct device *master, void *data) } dpu_kms->num_clocks = ret; - platform_set_drvdata(pdev, dpu_kms); - ret = msm_kms_init(&dpu_kms->base, &kms_funcs); if (ret) { DPU_ERROR("failed to init kms, ret=%d\n", ret); @@ -1242,31 +1226,25 @@ static int dpu_bind(struct device *dev, struct device *master, void *data) priv->kms = &dpu_kms->base; - return ret; -} - -static void dpu_unbind(struct device *dev, struct device *master, void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - struct dpu_kms *dpu_kms = platform_get_drvdata(pdev); + irq = irq_of_parse_and_map(dpu_kms->pdev->dev.of_node, 0); + if (irq < 0) { + DPU_ERROR("failed to get irq: %d\n", irq); + return irq; + } + dpu_kms->base.irq = irq; - if (dpu_kms->rpm_enabled) - pm_runtime_disable(&pdev->dev); + return 0; } -static const struct component_ops dpu_ops = { - .bind = dpu_bind, - .unbind = dpu_unbind, -}; - static int dpu_dev_probe(struct platform_device *pdev) { - return component_add(&pdev->dev, &dpu_ops); + return msm_drv_probe(&pdev->dev, dpu_kms_init); } static int dpu_dev_remove(struct platform_device *pdev) { - component_del(&pdev->dev, &dpu_ops); + component_master_del(&pdev->dev, &msm_drm_ops); + return 0; } @@ -1274,7 +1252,8 @@ static int __maybe_unused dpu_runtime_suspend(struct device *dev) { int i; struct platform_device *pdev = to_platform_device(dev); - struct dpu_kms *dpu_kms = platform_get_drvdata(pdev); + struct msm_drm_private *priv = platform_get_drvdata(pdev); + struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); /* Drop the performance state vote */ dev_pm_opp_set_rate(dev, 0); @@ -1290,7 +1269,8 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) { int rc = -1; struct platform_device *pdev = to_platform_device(dev); - struct dpu_kms *dpu_kms = platform_get_drvdata(pdev); + struct msm_drm_private *priv = platform_get_drvdata(pdev); + struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); struct drm_encoder *encoder; struct drm_device *ddev; int i; @@ -1320,9 +1300,11 @@ static const struct dev_pm_ops dpu_pm_ops = { SET_RUNTIME_PM_OPS(dpu_runtime_suspend, dpu_runtime_resume, NULL) SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) + .prepare = msm_pm_prepare, + .complete = msm_pm_complete, }; -const struct of_device_id dpu_dt_match[] = { +static const struct of_device_id dpu_dt_match[] = { { .compatible = "qcom,msm8998-dpu", }, { .compatible = "qcom,qcm2290-dpu", }, { .compatible = "qcom,sdm845-dpu", }, diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index 1a14f1d3cdf7..834d16bced9d 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -577,21 +577,7 @@ static const struct dev_pm_ops mdp4_pm_ops = { static int mdp4_probe(struct platform_device *pdev) { - struct msm_drm_private *priv; - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->kms_init = mdp4_kms_init; - - platform_set_drvdata(pdev, priv); - - /* - * on MDP4 based platforms, the MDP platform device is the component - * that adds other display interface components to itself. - */ - return msm_drv_probe(&pdev->dev, &pdev->dev); + return msm_drv_probe(&pdev->dev, mdp4_kms_init); } static int mdp4_remove(struct platform_device *pdev) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index 0c78608832c3..7676b4d3620e 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -203,6 +203,8 @@ static int mdp5_set_split_display(struct msm_kms *kms, slave_encoder); } +static void mdp5_destroy(struct platform_device *pdev); + static void mdp5_kms_destroy(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); @@ -221,6 +223,7 @@ static void mdp5_kms_destroy(struct msm_kms *kms) } mdp_kms_destroy(&mdp5_kms->base); + mdp5_destroy(mdp5_kms->pdev); } #ifdef CONFIG_DEBUG_FS @@ -544,6 +547,8 @@ static int get_clk(struct platform_device *pdev, struct clk **clkp, return 0; } +static int mdp5_init(struct platform_device *pdev, struct drm_device *dev); + static int mdp5_kms_init(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; @@ -555,6 +560,8 @@ static int mdp5_kms_init(struct drm_device *dev) int irq, i, ret; struct device *iommu_dev; + ret = mdp5_init(to_platform_device(dev->dev), dev); + /* priv->kms would have been populated by the MDP5 driver */ kms = priv->kms; if (!kms) @@ -804,8 +811,6 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev) u32 major, minor; int ret; - priv->kms_init = mdp5_kms_init; - mdp5_kms = devm_kzalloc(&pdev->dev, sizeof(*mdp5_kms), GFP_KERNEL); if (!mdp5_kms) { ret = -ENOMEM; @@ -915,35 +920,14 @@ fail: return ret; } -static int mdp5_bind(struct device *dev, struct device *master, void *data) -{ - struct msm_drm_private *priv = dev_get_drvdata(master); - struct drm_device *ddev = priv->dev; - struct platform_device *pdev = to_platform_device(dev); - - DBG(""); - - return mdp5_init(pdev, ddev); -} - -static void mdp5_unbind(struct device *dev, struct device *master, - void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - - mdp5_destroy(pdev); -} - -static const struct component_ops mdp5_ops = { - .bind = mdp5_bind, - .unbind = mdp5_unbind, -}; - static int mdp5_setup_interconnect(struct platform_device *pdev) { - struct icc_path *path0 = of_icc_get(&pdev->dev, "mdp0-mem"); - struct icc_path *path1 = of_icc_get(&pdev->dev, "mdp1-mem"); - struct icc_path *path_rot = of_icc_get(&pdev->dev, "rotator-mem"); + /* Interconnects are a part of MDSS device tree binding, not the + * MDP5 device. */ + struct device *mdss_dev = pdev->dev.parent; + struct icc_path *path0 = of_icc_get(mdss_dev, "mdp0-mem"); + struct icc_path *path1 = of_icc_get(mdss_dev, "mdp1-mem"); + struct icc_path *path_rot = of_icc_get(mdss_dev, "rotator-mem"); if (IS_ERR(path0)) return PTR_ERR(path0); @@ -979,13 +963,13 @@ static int mdp5_dev_probe(struct platform_device *pdev) if (ret) return ret; - return component_add(&pdev->dev, &mdp5_ops); + return msm_drv_probe(&pdev->dev, mdp5_kms_init); } static int mdp5_dev_remove(struct platform_device *pdev) { DBG(""); - component_del(&pdev->dev, &mdp5_ops); + component_master_del(&pdev->dev, &msm_drm_ops); return 0; } @@ -1011,9 +995,11 @@ static __maybe_unused int mdp5_runtime_resume(struct device *dev) static const struct dev_pm_ops mdp5_pm_ops = { SET_RUNTIME_PM_OPS(mdp5_runtime_suspend, mdp5_runtime_resume, NULL) + .prepare = msm_pm_prepare, + .complete = msm_pm_complete, }; -const struct of_device_id mdp5_dt_match[] = { +static const struct of_device_id mdp5_dt_match[] = { { .compatible = "qcom,mdp5", }, /* to support downstream DT files */ { .compatible = "qcom,mdss_mdp", }, |