summaryrefslogtreecommitdiffstats
path: root/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch
diff options
context:
space:
mode:
authorVladimir Barinov <vladimir.barinov@cogentembedded.com>2017-11-17 12:13:41 +0300
committerVladimir Barinov <vladimir.barinov@cogentembedded.com>2017-11-17 12:13:41 +0300
commitcc609cd55d04afd285fe95eae2fa3f3151f8d66d (patch)
tree199c9f0bc7254e3bebdd1406317e51b32394a74d /meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch
parent3c441bc9a5e5936747c58f49029edf63d0fe96e3 (diff)
V3M IMR/DRM
- Support IMR/VSP/DRM for V3M - Add packeges to use IMR-DRM demo
Diffstat (limited to 'meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch')
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch546
1 files changed, 546 insertions, 0 deletions
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch
new file mode 100644
index 0000000..e3f24a6
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch
@@ -0,0 +1,546 @@
+From b6176e313aea415b83d5762db275b2f364f08820 Mon Sep 17 00:00:00 2001
+From: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+Date: Tue, 14 Nov 2017 01:38:51 -0800
+Subject: [PATCH] gpu: drm: rcar-du: Extend VSP1-DRM interface
+
+Extend VSP1-DRM interface
+
+Signed-off-by: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+---
+ drivers/gpu/drm/drm_framebuffer.c | 1 +
+ drivers/gpu/drm/rcar-du/rcar_du_drv.h | 5 +
+ drivers/gpu/drm/rcar-du/rcar_du_kms.c | 42 ++++++-
+ drivers/gpu/drm/rcar-du/rcar_du_plane.c | 3 +-
+ drivers/gpu/drm/rcar-du/rcar_du_plane.h | 5 +
+ drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 209 ++++++++++++++++++++++++++------
+ drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 7 +-
+ 7 files changed, 232 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
+index 398efd6..4a43e15 100644
+--- a/drivers/gpu/drm/drm_framebuffer.c
++++ b/drivers/gpu/drm/drm_framebuffer.c
+@@ -192,6 +192,7 @@ static int format_check(const struct drm_mode_fb_cmd2 *r)
+ case DRM_FORMAT_YVU422:
+ case DRM_FORMAT_YUV444:
+ case DRM_FORMAT_YVU444:
++ case DRM_FORMAT_R8:
+ return 0;
+ default:
+ format_name = drm_get_format_name(r->pixel_format);
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+index 45d6e7e..bdf2612 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+@@ -104,6 +104,11 @@ struct rcar_du_device {
+ struct {
+ struct drm_property *alpha;
+ struct drm_property *colorkey;
++ struct drm_property *alphaplane;
++ struct drm_property *blend;
++ struct drm_property *ckey;
++ struct drm_property *ckey_set0;
++ struct drm_property *ckey_set1;
+ } props;
+
+ unsigned int dpad0_source;
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+index e955e92..31b48bc 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+@@ -10,7 +10,7 @@
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+-
++//#define DEBUG
+ #include <drm/drmP.h>
+ #include <drm/drm_atomic.h>
+ #include <drm/drm_atomic_helper.h>
+@@ -101,6 +101,12 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
+ .planes = 2,
+ .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
+ .edf = PnDDCR4_EDF_NONE,
++ }, {
++ .fourcc = DRM_FORMAT_R8,
++ .bpp = 8,
++ .planes = 1,
++ .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_8BPP,
++ .edf = PnDDCR4_EDF_NONE,
+ },
+ };
+
+@@ -169,6 +175,10 @@ static const struct rcar_du_format_info rcar_vsp_format_infos[] = {
+ .fourcc = DRM_FORMAT_YVU444,
+ .bpp = 24,
+ .planes = 3,
++ }, {
++ .fourcc = DRM_FORMAT_R8,
++ .bpp = 8,
++ .planes = 1,
+ },
+ };
+
+@@ -565,6 +575,36 @@ static int rcar_du_properties_init(struct rcar_du_device *rcdu)
+ if (rcdu->props.colorkey == NULL)
+ return -ENOMEM;
+
++ rcdu->props.alphaplane =
++ drm_property_create(rcdu->ddev, DRM_MODE_PROP_OBJECT, "alphaplane", 1);
++ if (rcdu->props.alphaplane == NULL)
++ return -ENOMEM;
++ rcdu->props.alphaplane->values[0] = DRM_MODE_OBJECT_FB;
++
++ rcdu->props.blend =
++ drm_property_create_range(rcdu->ddev, 0, "blend",
++ 0, 0xffffffff);
++ if (rcdu->props.blend == NULL)
++ return -ENOMEM;
++
++ rcdu->props.ckey =
++ drm_property_create_range(rcdu->ddev, 0, "ckey",
++ 0, 0xffffffff);
++ if (rcdu->props.ckey == NULL)
++ return -ENOMEM;
++
++ rcdu->props.ckey_set0 =
++ drm_property_create_range(rcdu->ddev, 0, "ckey_set0",
++ 0, 0xffffffff);
++ if (rcdu->props.ckey_set0 == NULL)
++ return -ENOMEM;
++
++ rcdu->props.ckey_set1 =
++ drm_property_create_range(rcdu->ddev, 0, "ckey_set1",
++ 0, 0xffffffff);
++ if (rcdu->props.ckey_set1 == NULL)
++ return -ENOMEM;
++
+ return 0;
+ }
+
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+index e408aa3..2b57f09 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+@@ -10,7 +10,7 @@
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+-
++//#define DEBUG
+ #include <drm/drmP.h>
+ #include <drm/drm_atomic.h>
+ #include <drm/drm_atomic_helper.h>
+@@ -719,6 +719,7 @@ static const uint32_t formats[] = {
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV16,
++ DRM_FORMAT_R8,
+ };
+
+ int rcar_du_planes_init(struct rcar_du_group *rgrp)
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+index c1de338..a6065ef 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+@@ -66,6 +66,11 @@ struct rcar_du_plane_state {
+
+ unsigned int alpha;
+ unsigned int colorkey;
++ struct drm_framebuffer *alphaplane;
++ unsigned int blend;
++ unsigned int ckey;
++ unsigned int ckey_set0;
++ unsigned int ckey_set1;
+ };
+
+ static inline struct rcar_du_plane_state *
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+index 770238a..910e0f0 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+@@ -10,7 +10,7 @@
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+-
++//#define DEBUG
+ #include <drm/drmP.h>
+ #include <drm/drm_atomic.h>
+ #include <drm/drm_atomic_helper.h>
+@@ -91,6 +91,16 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
+
+ void rcar_du_vsp_disable(struct rcar_du_crtc *crtc)
+ {
++ struct rcar_du_vsp *vsp = crtc->vsp;
++ struct rcar_du_vsp_plane *primary = &vsp->planes[0];
++ struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(primary->plane.state);
++
++ /* ...drop alpha-plane associated with primary plane (why only primary? - tbd) */
++ if (rstate->alphaplane) {
++ drm_framebuffer_unreference(rstate->alphaplane);
++ rstate->alphaplane = NULL;
++ }
++
+ vsp1_du_setup_lif(crtc->vsp->vsp, NULL, crtc->lif_index,
+ crtc->suspend);
+ }
+@@ -133,6 +143,7 @@ static const u32 formats_kms[] = {
+ DRM_FORMAT_YVU422,
+ DRM_FORMAT_YUV444,
+ DRM_FORMAT_YVU444,
++ DRM_FORMAT_R8,
+ };
+
+ static const u32 formats_v4l2[] = {
+@@ -162,6 +173,7 @@ static const u32 formats_v4l2[] = {
+ V4L2_PIX_FMT_YVU422M,
+ V4L2_PIX_FMT_YUV444M,
+ V4L2_PIX_FMT_YVU444M,
++ V4L2_PIX_FMT_GREY,
+ };
+
+ static const u32 formats_xlate[][2] = {
+@@ -184,6 +196,7 @@ static const u32 formats_xlate[][2] = {
+ { DRM_FORMAT_NV21, V4L2_PIX_FMT_NV21M },
+ { DRM_FORMAT_NV16, V4L2_PIX_FMT_NV16M },
+ { DRM_FORMAT_NV61, V4L2_PIX_FMT_NV61M },
++ { DRM_FORMAT_R8, V4L2_PIX_FMT_GREY },
+ };
+
+ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
+@@ -226,6 +239,27 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
+ }
+ }
+
++ /* ...add alpha-plane as needed */
++ if (state->alphaplane) {
++ i = state->format->planes;
++ cfg.alpha_mem = sg_dma_address(state->sg_tables[i].sgl);
++ cfg.alpha_pitch = state->alphaplane->pitches[0];
++ pr_debug("alpha-%d: set alpha-mem address: %llx, pitch=%d\n", i, (unsigned long long)cfg.alpha_mem, cfg.alpha_pitch);
++ }
++
++ /* ...add blending formula as needed */
++ if (state->blend) {
++ cfg.blend = state->blend;
++ pr_debug("set blending formula: %X\n", cfg.blend);
++ }
++
++ /* ...add color key property as needed */
++ if (state->ckey) {
++ cfg.ckey = state->ckey;
++ cfg.ckey_set0 = state->ckey_set0;
++ cfg.ckey_set1 = state->ckey_set1;
++ }
++
+ vsp1_du_atomic_update(plane->vsp->vsp, plane->index, &cfg);
+ }
+
+@@ -259,6 +293,23 @@ static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
+ }
+ }
+
++ /* ...check if we have alpha-plane attached */
++ if (rstate->alphaplane) {
++ struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(rstate->alphaplane, 0);
++ struct sg_table *sgt = &rstate->sg_tables[i++];
++
++ ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr, gem->paddr, gem->base.size);
++ if (ret)
++ goto fail;
++
++ ret = vsp1_du_map_sg(vsp->vsp, sgt);
++ if (!ret) {
++ sg_free_table(sgt);
++ ret = -ENOMEM;
++ goto fail;
++ }
++ }
++
+ return 0;
+
+ fail:
+@@ -288,6 +339,14 @@ static void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane,
+ vsp1_du_unmap_sg(vsp->vsp, sgt);
+ sg_free_table(sgt);
+ }
++
++ if (rstate->alphaplane) {
++ struct sg_table *sgt = &rstate->sg_tables[i];
++
++ vsp1_du_unmap_sg(vsp->vsp, sgt);
++ sg_free_table(sgt);
++ pr_debug("unmap alpha-plane\n");
++ }
+ }
+
+ static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane,
+@@ -369,6 +428,11 @@ rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane)
+ if (copy == NULL)
+ return NULL;
+
++ if (copy->alphaplane) {
++ drm_framebuffer_reference(copy->alphaplane);
++ pr_debug("duplicate alpha-plane '%p' (refcount=%d)\n", copy->alphaplane, drm_framebuffer_read_refcount(copy->alphaplane));
++ }
++
+ __drm_atomic_helper_plane_duplicate_state(plane, &copy->state);
+
+ return &copy->state;
+@@ -377,8 +441,15 @@ rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane)
+ static void rcar_du_vsp_plane_atomic_destroy_state(struct drm_plane *plane,
+ struct drm_plane_state *state)
+ {
++ struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
++
++ if (rstate->alphaplane) {
++ pr_debug("unref alpha-plane '%p' (refcount=%d)\n", rstate->alphaplane, drm_framebuffer_read_refcount(rstate->alphaplane));
++ drm_framebuffer_unreference(rstate->alphaplane);
++ }
++
+ __drm_atomic_helper_plane_destroy_state(state);
+- kfree(to_rcar_vsp_plane_state(state));
++ kfree(rstate);
+ }
+
+ static void rcar_du_vsp_plane_reset(struct drm_plane *plane)
+@@ -386,6 +457,7 @@ static void rcar_du_vsp_plane_reset(struct drm_plane *plane)
+ struct rcar_du_vsp_plane_state *state;
+
+ if (plane->state) {
++ pr_debug("reset plane '%p'\n", to_rcar_vsp_plane_state(plane->state)->alphaplane);
+ rcar_du_vsp_plane_atomic_destroy_state(plane, plane->state);
+ plane->state = NULL;
+ }
+@@ -410,7 +482,30 @@ static int rcar_du_vsp_plane_atomic_set_property(struct drm_plane *plane,
+
+ if (property == rcdu->props.alpha)
+ rstate->alpha = val;
+- else
++ else if (property == rcdu->props.blend)
++ rstate->blend = val;
++ else if (property == rcdu->props.ckey)
++ rstate->ckey = val;
++ else if (property == rcdu->props.ckey_set0)
++ rstate->ckey_set0 = val;
++ else if (property == rcdu->props.ckey_set1)
++ rstate->ckey_set1 = val;
++ else if (property == rcdu->props.alphaplane) {
++ if (rstate->alphaplane) {
++ pr_debug("unref alpha-plane '%p' (refcount=%d)\n", rstate->alphaplane, drm_framebuffer_read_refcount(rstate->alphaplane));
++ drm_framebuffer_unreference(rstate->alphaplane);
++ }
++ rstate->alphaplane = drm_framebuffer_lookup(plane->dev, val);
++ if (rstate->alphaplane) {
++ pr_debug("use alpha-plane '%p' (refcount=%d)\n", rstate->alphaplane, drm_framebuffer_read_refcount(rstate->alphaplane));
++ /* ...the way how we handle this leads to a "loss" of plane reference (it is acquired
++ * within "drm_property_change_valid_get" but not returned in symmetric "drm_property_change_valid_put")
++ * Whether it is a bug or was done intentionally, I don't know. For a moment just drop that
++ * extra reference right here
++ */
++ if (0) drm_framebuffer_unreference(rstate->alphaplane);
++ }
++ } else
+ return -EINVAL;
+
+ return 0;
+@@ -426,6 +521,16 @@ static int rcar_du_vsp_plane_atomic_get_property(struct drm_plane *plane,
+
+ if (property == rcdu->props.alpha)
+ *val = rstate->alpha;
++ else if (property == rcdu->props.alphaplane)
++ *val = (rstate->alphaplane ? rstate->alphaplane->base.id : 0);
++ else if (property == rcdu->props.blend)
++ *val = rstate->blend;
++ else if (property == rcdu->props.ckey)
++ *val = rstate->ckey;
++ else if (property == rcdu->props.ckey_set0)
++ *val = rstate->ckey_set0;
++ else if (property == rcdu->props.ckey_set1)
++ *val = rstate->ckey_set1;
+ else
+ return -EINVAL;
+
+@@ -442,9 +547,10 @@ int rcar_du_vsp_write_back(struct drm_device *dev, void *data,
+ struct rcar_du_crtc *rcrtc;
+ struct rcar_du_device *rcdu;
+ const struct drm_display_mode *mode;
+- u32 pixelformat, bpp;
+- unsigned int pitch;
++ struct drm_framebuffer *fb;
+ dma_addr_t mem[3];
++ struct sg_table sg_tables[3];
++ int i = 0;
+
+ obj = drm_mode_object_find(dev, sh->crtc_id, DRM_MODE_OBJECT_CRTC);
+ if (!obj)
+@@ -455,62 +561,79 @@ int rcar_du_vsp_write_back(struct drm_device *dev, void *data,
+ rcdu = rcrtc->group->dev;
+ mode = &rcrtc->crtc.state->adjusted_mode;
+
+- switch (sh->fmt) {
+- case DRM_FORMAT_RGB565:
+- bpp = 16;
+- pixelformat = V4L2_PIX_FMT_RGB565;
+- break;
+- case DRM_FORMAT_ARGB1555:
+- bpp = 16;
+- pixelformat = V4L2_PIX_FMT_ARGB555;
+- break;
+- case DRM_FORMAT_ARGB8888:
+- bpp = 32;
+- pixelformat = V4L2_PIX_FMT_ABGR32;
+- break;
+- default:
+- dev_err(rcdu->dev, "specified format is not supported.\n");
++ fb = drm_framebuffer_lookup(dev, sh->buff);
++ if (!fb) {
++ dev_err(dev->dev, "failed to lookup destination framebuffer '%lu'\n", sh->buff);
+ return -EINVAL;
+ }
+
+- pitch = mode->hdisplay * bpp / 8;
++ /* ...check framebuffer is okay */
++ if ((fb->width != (mode->hdisplay)) ||
++ (fb->height != (mode->vdisplay))) {
++ dev_err(dev->dev, "wrong fb mode: %d*%d vs %d*%d\n", fb->width, fb->height, mode->hdisplay, mode->vdisplay);
++ ret = -EINVAL;
++ goto done;
++ }
+
+- mem[0] = sh->buff;
+- mem[1] = 0;
+- mem[2] = 0;
++ /* ...need to verify compatibility of output format, I guess - tbd */
+
+- if ((sh->width != (mode->hdisplay)) ||
+- (sh->height != (mode->vdisplay)))
+- return -EINVAL;
++ /* ...fill memory planes addresses */
++ for (i = 0; i < 3; i++) {
++ struct drm_gem_cma_object *gem;
++ struct sg_table *sgt = &sg_tables[i];
++ gem = drm_fb_cma_get_gem_obj(fb, i);
++ if (!gem)
++ break;
++ ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr, gem->paddr,
++ gem->base.size);
++ if (ret)
++ goto done;
+
+- if ((pitch * mode->vdisplay) > sh->buff_len)
+- return -EINVAL;
++ ret = vsp1_du_map_sg(rcrtc->vsp->vsp, sgt);
++ if (!ret) {
++ sg_free_table(sgt);
++ ret = -ENOMEM;
++ goto done;
++ }
++ mem[i] = sg_dma_address(sg_tables[i].sgl) + fb->offsets[i];
++ }
++
++ dev_info(dev->dev, "setup write-back (pixfmt=%X, %u*%u, planes: %d)\n", fb->pixel_format, fb->width, fb->height, i);
++
++ vsp1_du_setup_wb(rcrtc->vsp->vsp, fb->pixel_format, fb->pitches[0], mem, rcrtc->lif_index);
+
+- vsp1_du_setup_wb(rcrtc->vsp->vsp, pixelformat, pitch, mem,
+- rcrtc->lif_index);
+ ret = vsp1_du_wait_wb(rcrtc->vsp->vsp, WB_STAT_CATP_SET,
+ rcrtc->lif_index);
+ if (ret != 0)
+- return ret;
++ goto done;
+
+ ret = rcar_du_async_commit(dev, crtc);
+ if (ret != 0)
+- return ret;
++ goto done;
+
+ ret = vsp1_du_wait_wb(rcrtc->vsp->vsp, WB_STAT_CATP_START,
+ rcrtc->lif_index);
+ if (ret != 0)
+- return ret;
++ goto done;
+
+ ret = rcar_du_async_commit(dev, crtc);
+ if (ret != 0)
+- return ret;
++ goto done;
+
+ ret = vsp1_du_wait_wb(rcrtc->vsp->vsp, WB_STAT_CATP_DONE,
+ rcrtc->lif_index);
+ if (ret != 0)
+- return ret;
++ goto done;
++
++done:
++ /* ...unmap all tables */
++ while (i--) {
++ struct sg_table *sgt = &sg_tables[i];
++ vsp1_du_unmap_sg(rcrtc->vsp->vsp, sgt);
++ sg_free_table(sgt);
++ }
+
++ drm_framebuffer_unreference(fb);
+ return ret;
+ }
+
+@@ -574,6 +697,7 @@ static const uint32_t formats[] = {
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV61,
++ DRM_FORMAT_R8,
+ };
+
+ int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
+@@ -653,13 +777,24 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
+ drm_plane_helper_add(&plane->plane,
+ &rcar_du_vsp_plane_helper_funcs);
+
++#if 0 // ...use same set of properties for all planes
+ if (type == DRM_PLANE_TYPE_PRIMARY)
+ continue;
+-
++#endif
+ drm_object_attach_property(&plane->plane.base,
+ rcdu->props.alpha, 255);
+ drm_plane_create_zpos_property(&plane->plane, 1, 1,
+ vsp->num_planes - 1);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.alphaplane, 0);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.blend, 0);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.ckey, 0);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.ckey_set0, 0);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.ckey_set1, 0);
+ }
+
+ return 0;
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
+index 3fd9cef..2f4aa41 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
++++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
+@@ -52,10 +52,15 @@ struct rcar_du_vsp_plane_state {
+ struct drm_plane_state state;
+
+ const struct rcar_du_format_info *format;
+- struct sg_table sg_tables[3];
++ struct sg_table sg_tables[4];
+
+ unsigned int alpha;
+ unsigned int zpos;
++ struct drm_framebuffer *alphaplane;
++ unsigned int blend;
++ unsigned int ckey;
++ unsigned int ckey_set0;
++ unsigned int ckey_set1;
+ };
+
+ static inline struct rcar_du_vsp_plane_state *
+--
+2.7.4
+