diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2016-11-16 07:43:59 +0100 |
---|---|---|
committer | Shawn Guo <shawn.guo@linaro.org> | 2017-01-28 03:17:41 +0100 |
commit | 4e986d3705dfb3fd16b54b795b2427a48af22674 (patch) | |
tree | 2e2cc53614447f29f9f9c15b861336ce054b946d /drivers/gpu/drm/zte/zx_vou.c | |
parent | drm: zte: add .atomic_disable hook to disable graphic layer (diff) | |
download | linux-4e986d3705dfb3fd16b54b795b2427a48af22674.tar.xz linux-4e986d3705dfb3fd16b54b795b2427a48af22674.zip |
drm: zte: add overlay plane support
It enables VOU VL (Video Layer) to support overlay plane with scaling
function. VL0 has some quirks on scaling support. We choose to skip it
and only adds VL1 and VL2 into DRM core for now.
Function zx_plane_atomic_disable() gets moved around with no changes to
save a forward declaration.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Diffstat (limited to 'drivers/gpu/drm/zte/zx_vou.c')
-rw-r--r-- | drivers/gpu/drm/zte/zx_vou.c | 72 |
1 files changed, 64 insertions, 8 deletions
diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c index d299a3528282..fcdd3a155828 100644 --- a/drivers/gpu/drm/zte/zx_vou.c +++ b/drivers/gpu/drm/zte/zx_vou.c @@ -112,6 +112,22 @@ static const struct vou_layer_bits zx_gl_bits[GL_NUM] = { }, }; +static const struct vou_layer_bits zx_vl_bits[VL_NUM] = { + { + .enable = OSD_CTRL0_VL0_EN, + .chnsel = OSD_CTRL0_VL0_SEL, + .clksel = VOU_CLK_VL0_SEL, + }, { + .enable = OSD_CTRL0_VL1_EN, + .chnsel = OSD_CTRL0_VL1_SEL, + .clksel = VOU_CLK_VL1_SEL, + }, { + .enable = OSD_CTRL0_VL2_EN, + .chnsel = OSD_CTRL0_VL2_SEL, + .clksel = VOU_CLK_VL2_SEL, + }, +}; + struct zx_vou_hw { struct device *dev; void __iomem *osd; @@ -460,6 +476,48 @@ void zx_vou_layer_disable(struct drm_plane *plane) zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, 0); } +static void zx_overlay_init(struct drm_device *drm, struct zx_vou_hw *vou) +{ + struct device *dev = vou->dev; + struct zx_plane *zplane; + int i; + int ret; + + /* + * VL0 has some quirks on scaling support which need special handling. + * Let's leave it out for now. + */ + for (i = 1; i < VL_NUM; i++) { + zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL); + if (!zplane) { + DRM_DEV_ERROR(dev, "failed to allocate zplane %d\n", i); + return; + } + + zplane->layer = vou->osd + OSD_VL_OFFSET(i); + zplane->hbsc = vou->osd + HBSC_VL_OFFSET(i); + zplane->rsz = vou->otfppu + RSZ_VL_OFFSET(i); + zplane->bits = &zx_vl_bits[i]; + + ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_OVERLAY); + if (ret) { + DRM_DEV_ERROR(dev, "failed to init overlay %d\n", i); + continue; + } + } +} + +static inline void zx_osd_int_update(struct zx_crtc *zcrtc) +{ + struct drm_crtc *crtc = &zcrtc->crtc; + struct drm_plane *plane; + + vou_chn_set_update(zcrtc); + + drm_for_each_plane_mask(plane, crtc->dev, crtc->state->plane_mask) + zx_plane_set_update(plane); +} + static irqreturn_t vou_irq_handler(int irq, void *dev_id) { struct zx_vou_hw *vou = dev_id; @@ -479,15 +537,11 @@ static irqreturn_t vou_irq_handler(int irq, void *dev_id) state = zx_readl(vou->osd + OSD_INT_STA); zx_writel(vou->osd + OSD_INT_CLRSTA, state); - if (state & OSD_INT_MAIN_UPT) { - vou_chn_set_update(vou->main_crtc); - zx_plane_set_update(vou->main_crtc->primary); - } + if (state & OSD_INT_MAIN_UPT) + zx_osd_int_update(vou->main_crtc); - if (state & OSD_INT_AUX_UPT) { - vou_chn_set_update(vou->aux_crtc); - zx_plane_set_update(vou->aux_crtc->primary); - } + if (state & OSD_INT_AUX_UPT) + zx_osd_int_update(vou->aux_crtc); if (state & OSD_INT_ERROR) DRM_DEV_ERROR(vou->dev, "OSD ERROR: 0x%08x!\n", state); @@ -657,6 +711,8 @@ static int zx_crtc_bind(struct device *dev, struct device *master, void *data) goto disable_ppu_clk; } + zx_overlay_init(drm, vou); + return 0; disable_ppu_clk: |