@@ -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);
@@ -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);
@@ -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)
{
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.baryshkov@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(-)