Existing MDP5 devices have slightly different bindings. The main register region is called `mdp_phys' instead of `mdp'. Also vbif register regions are a part of the parent, MDSS device. Add support for handling this binding differences.
Signed-off-by: Dmitry Baryshkov <dmitry.barysh...@linaro.org> --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 88 ++++++++++++++++++++----- drivers/gpu/drm/msm/msm_drv.h | 3 + drivers/gpu/drm/msm/msm_io_utils.c | 18 +++++ 3 files changed, 91 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index aa6ba2cf4b84..a9ba67e24e11 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1054,37 +1054,53 @@ unsigned long dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name) #define DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE 412500000 -static int dpu_kms_hw_init(struct msm_kms *kms) +static int dpu_kms_mmap_mdp5(struct dpu_kms *dpu_kms) { - struct dpu_kms *dpu_kms; - struct drm_device *dev; - int i, rc = -EINVAL; - unsigned long max_core_clk_rate; - u32 core_rev; + struct platform_device *mdss_dev; + int rc; - if (!kms) { - DPU_ERROR("invalid kms\n"); + mdss_dev = to_platform_device(dpu_kms->pdev->dev.parent); + + dpu_kms->mmio = msm_ioremap(dpu_kms->pdev, "mdp_phys"); + if (IS_ERR(dpu_kms->mmio)) { + rc = PTR_ERR(dpu_kms->mmio); + DPU_ERROR("mdp register memory map failed: %d\n", rc); + dpu_kms->mmio = NULL; return rc; } + DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio); - dpu_kms = to_dpu_kms(kms); - dev = dpu_kms->dev; + dpu_kms->vbif[VBIF_RT] = msm_ioremap_mdss(mdss_dev, + dpu_kms->pdev, + "vbif_phys"); + if (IS_ERR(dpu_kms->vbif[VBIF_RT])) { + rc = PTR_ERR(dpu_kms->vbif[VBIF_RT]); + DPU_ERROR("vbif register memory map failed: %d\n", rc); + dpu_kms->vbif[VBIF_RT] = NULL; + return rc; + } - dev->mode_config.cursor_width = 512; - dev->mode_config.cursor_height = 512; + dpu_kms->vbif[VBIF_NRT] = msm_ioremap_mdss(mdss_dev, + dpu_kms->pdev, + "vbif_nrt_phys"); + if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) { + dpu_kms->vbif[VBIF_NRT] = NULL; + DPU_DEBUG("VBIF NRT is not defined"); + } - rc = dpu_kms_global_obj_init(dpu_kms); - if (rc) - return rc; + return 0; +} - atomic_set(&dpu_kms->bandwidth_ref, 0); +static int dpu_kms_mmap_dpu(struct dpu_kms *dpu_kms) +{ + int rc; dpu_kms->mmio = msm_ioremap(dpu_kms->pdev, "mdp"); if (IS_ERR(dpu_kms->mmio)) { rc = PTR_ERR(dpu_kms->mmio); DPU_ERROR("mdp register memory map failed: %d\n", rc); dpu_kms->mmio = NULL; - goto error; + return rc; } DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio); @@ -1093,14 +1109,50 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = PTR_ERR(dpu_kms->vbif[VBIF_RT]); DPU_ERROR("vbif register memory map failed: %d\n", rc); dpu_kms->vbif[VBIF_RT] = NULL; - goto error; + return rc; } + dpu_kms->vbif[VBIF_NRT] = msm_ioremap_quiet(dpu_kms->pdev, "vbif_nrt"); if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) { dpu_kms->vbif[VBIF_NRT] = NULL; DPU_DEBUG("VBIF NRT is not defined"); } + return 0; +} + +static int dpu_kms_hw_init(struct msm_kms *kms) +{ + struct dpu_kms *dpu_kms; + struct drm_device *dev; + int i, rc = -EINVAL; + unsigned long max_core_clk_rate; + u32 core_rev; + + if (!kms) { + DPU_ERROR("invalid kms\n"); + return rc; + } + + dpu_kms = to_dpu_kms(kms); + dev = dpu_kms->dev; + + dev->mode_config.cursor_width = 512; + dev->mode_config.cursor_height = 512; + + rc = dpu_kms_global_obj_init(dpu_kms); + if (rc) + return rc; + + atomic_set(&dpu_kms->bandwidth_ref, 0); + + if (of_device_is_compatible(dpu_kms->pdev->dev.of_node, "qcom,mdp5")) + rc = dpu_kms_mmap_mdp5(dpu_kms); + else + rc = dpu_kms_mmap_dpu(dpu_kms); + if (rc) + return rc; + dpu_kms_parse_data_bus_icc_path(dpu_kms); rc = pm_runtime_resume_and_get(&dpu_kms->pdev->dev); diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 02fd6c7d0bb7..fdcbb02fa396 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -485,6 +485,9 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name); void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name, phys_addr_t *size); void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name); +void __iomem *msm_ioremap_mdss(struct platform_device *mdss_pdev, + struct platform_device *dev, + const char *name); struct icc_path *msm_icc_get(struct device *dev, const char *name); diff --git a/drivers/gpu/drm/msm/msm_io_utils.c b/drivers/gpu/drm/msm/msm_io_utils.c index 59d2788c4510..9d0d76f3a319 100644 --- a/drivers/gpu/drm/msm/msm_io_utils.c +++ b/drivers/gpu/drm/msm/msm_io_utils.c @@ -50,6 +50,24 @@ struct clk *msm_clk_get(struct platform_device *pdev, const char *name) return clk; } +void __iomem *msm_ioremap_mdss(struct platform_device *mdss_pdev, + struct platform_device *pdev, + const char *name) +{ + struct resource *res; + void __iomem *ptr; + + res = platform_get_resource_byname(mdss_pdev, IORESOURCE_MEM, name); + if (!res) + return ERR_PTR(-EINVAL); + + ptr = devm_ioremap_resource(&pdev->dev, res); + if (!ptr) + return ERR_PTR(-ENOMEM); + + return ptr; +} + static void __iomem *_msm_ioremap(struct platform_device *pdev, const char *name, bool quiet, phys_addr_t *psize) { -- 2.39.2