diff options
Diffstat (limited to 'drivers/gpu/drm/msm/mdp/mdp5')
| -rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 29 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 44 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 13 |
5 files changed, 60 insertions, 31 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index f2794021f08..ebe2e60f3ab 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -102,7 +102,7 @@ static void update_fb(struct drm_crtc *crtc, struct drm_framebuffer *new_fb) /* grab reference to incoming scanout fb: */ drm_framebuffer_reference(new_fb); - mdp5_crtc->base.fb = new_fb; + mdp5_crtc->base.primary->fb = new_fb; mdp5_crtc->fb = new_fb; if (old_fb) @@ -195,8 +195,6 @@ static void mdp5_crtc_destroy(struct drm_crtc *crtc) { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); - mdp5_crtc->plane->funcs->destroy(mdp5_crtc->plane); - drm_crtc_cleanup(crtc); drm_flip_work_cleanup(&mdp5_crtc->unref_fb_work); @@ -289,14 +287,14 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc, mode->type, mode->flags); /* grab extra ref for update_scanout() */ - drm_framebuffer_reference(crtc->fb); + drm_framebuffer_reference(crtc->primary->fb); - ret = mdp5_plane_mode_set(mdp5_crtc->plane, crtc, crtc->fb, + ret = mdp5_plane_mode_set(mdp5_crtc->plane, crtc, crtc->primary->fb, 0, 0, mode->hdisplay, mode->vdisplay, x << 16, y << 16, mode->hdisplay << 16, mode->vdisplay << 16); if (ret) { - drm_framebuffer_unreference(crtc->fb); + drm_framebuffer_unreference(crtc->primary->fb); dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", mdp5_crtc->name, ret); return ret; @@ -306,8 +304,8 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc, MDP5_LM_OUT_SIZE_WIDTH(mode->hdisplay) | MDP5_LM_OUT_SIZE_HEIGHT(mode->vdisplay)); - update_fb(crtc, crtc->fb); - update_scanout(crtc, crtc->fb); + update_fb(crtc, crtc->primary->fb); + update_scanout(crtc, crtc->primary->fb); return 0; } @@ -338,19 +336,19 @@ static int mdp5_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, int ret; /* grab extra ref for update_scanout() */ - drm_framebuffer_reference(crtc->fb); + drm_framebuffer_reference(crtc->primary->fb); - ret = mdp5_plane_mode_set(plane, crtc, crtc->fb, + ret = mdp5_plane_mode_set(plane, crtc, crtc->primary->fb, 0, 0, mode->hdisplay, mode->vdisplay, x << 16, y << 16, mode->hdisplay << 16, mode->vdisplay << 16); if (ret) { - drm_framebuffer_unreference(crtc->fb); + drm_framebuffer_unreference(crtc->primary->fb); return ret; } - update_fb(crtc, crtc->fb); - update_scanout(crtc, crtc->fb); + update_fb(crtc, crtc->primary->fb); + update_scanout(crtc, crtc->primary->fb); return 0; } @@ -524,6 +522,9 @@ void mdp5_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane) void mdp5_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane) { + /* don't actually detatch our primary plane: */ + if (to_mdp5_crtc(crtc)->plane == plane) + return; set_attach(crtc, mdp5_plane_pipe(plane), NULL); } @@ -559,7 +560,7 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, INIT_FENCE_CB(&mdp5_crtc->pageflip_cb, pageflip_cb); - drm_crtc_init(dev, crtc, &mdp5_crtc_funcs); + drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp5_crtc_funcs); drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs); mdp5_plane_install_properties(mdp5_crtc->plane, &crtc->base); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c index 353d494a497..f2b985bc2ad 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c @@ -71,11 +71,11 @@ static void mdp5_irq_mdp(struct mdp_kms *mdp_kms) VERB("status=%08x", status); + mdp_dispatch_irqs(mdp_kms, status); + for (id = 0; id < priv->num_crtcs; id++) if (status & mdp5_crtc_vblank(priv->crtcs[id])) drm_handle_vblank(dev, id); - - mdp_dispatch_irqs(mdp_kms, status); } irqreturn_t mdp5_irq(struct msm_kms *kms) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index ee8446c1b5f..71510ee26e9 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -20,6 +20,10 @@ #include "msm_mmu.h" #include "mdp5_kms.h" +static const char *iommu_ports[] = { + "mdp_0", +}; + static struct mdp5_platform_config *mdp5_get_config(struct platform_device *dev); static int mdp5_hw_init(struct msm_kms *kms) @@ -104,6 +108,12 @@ static void mdp5_preclose(struct msm_kms *kms, struct drm_file *file) static void mdp5_destroy(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); + struct msm_mmu *mmu = mdp5_kms->mmu; + + if (mmu) { + mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); + mmu->funcs->destroy(mmu); + } kfree(mdp5_kms); } @@ -216,10 +226,6 @@ fail: return ret; } -static const char *iommu_ports[] = { - "mdp_0", -}; - static int get_clk(struct platform_device *pdev, struct clk **clkp, const char *name) { @@ -280,12 +286,22 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) goto fail; } - ret = get_clk(pdev, &mdp5_kms->axi_clk, "bus_clk") || - get_clk(pdev, &mdp5_kms->ahb_clk, "iface_clk") || - get_clk(pdev, &mdp5_kms->src_clk, "core_clk_src") || - get_clk(pdev, &mdp5_kms->core_clk, "core_clk") || - get_clk(pdev, &mdp5_kms->lut_clk, "lut_clk") || - get_clk(pdev, &mdp5_kms->vsync_clk, "vsync_clk"); + ret = get_clk(pdev, &mdp5_kms->axi_clk, "bus_clk"); + if (ret) + goto fail; + ret = get_clk(pdev, &mdp5_kms->ahb_clk, "iface_clk"); + if (ret) + goto fail; + ret = get_clk(pdev, &mdp5_kms->src_clk, "core_clk_src"); + if (ret) + goto fail; + ret = get_clk(pdev, &mdp5_kms->core_clk, "core_clk"); + if (ret) + goto fail; + ret = get_clk(pdev, &mdp5_kms->lut_clk, "lut_clk"); + if (ret) + goto fail; + ret = get_clk(pdev, &mdp5_kms->vsync_clk, "vsync_clk"); if (ret) goto fail; @@ -307,17 +323,23 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) mmu = msm_iommu_new(dev, config->iommu); if (IS_ERR(mmu)) { ret = PTR_ERR(mmu); + dev_err(dev->dev, "failed to init iommu: %d\n", ret); goto fail; } + ret = mmu->funcs->attach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); - if (ret) + if (ret) { + dev_err(dev->dev, "failed to attach iommu: %d\n", ret); + mmu->funcs->destroy(mmu); goto fail; + } } else { dev_info(dev->dev, "no iommu, fallback to phys " "contig buffers for scanout\n"); mmu = NULL; } + mdp5_kms->mmu = mmu; mdp5_kms->id = msm_register_mmu(dev, mmu); if (mdp5_kms->id < 0) { diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index c8b1a2522c2..6e981b692d1 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -33,6 +33,7 @@ struct mdp5_kms { /* mapper-id used to request GEM buffer mapped for scanout: */ int id; + struct msm_mmu *mmu; /* for tracking smp allocation amongst pipes: */ mdp5_smp_state_t smp_state; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 0ac8bb5e7e8..f3daec4412a 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -85,8 +85,11 @@ static int mdp5_plane_disable(struct drm_plane *plane) static void mdp5_plane_destroy(struct drm_plane *plane) { struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); + struct msm_drm_private *priv = plane->dev->dev_private; + + if (priv->kms) + mdp5_plane_disable(plane); - mdp5_plane_disable(plane); drm_plane_cleanup(plane); kfree(mdp5_plane); @@ -358,6 +361,7 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev, struct drm_plane *plane = NULL; struct mdp5_plane *mdp5_plane; int ret; + enum drm_plane_type type; mdp5_plane = kzalloc(sizeof(*mdp5_plane), GFP_KERNEL); if (!mdp5_plane) { @@ -373,9 +377,10 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev, mdp5_plane->nformats = mdp5_get_formats(pipe, mdp5_plane->formats, ARRAY_SIZE(mdp5_plane->formats)); - drm_plane_init(dev, plane, 0xff, &mdp5_plane_funcs, - mdp5_plane->formats, mdp5_plane->nformats, - private_plane); + type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; + drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs, + mdp5_plane->formats, mdp5_plane->nformats, + type); mdp5_plane_install_properties(plane, &plane->base); |
