summaryrefslogtreecommitdiffstats
path: root/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0104-media-vsp1-extend-DRM-VSP1-interface.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0104-media-vsp1-extend-DRM-VSP1-interface.patch')
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0104-media-vsp1-extend-DRM-VSP1-interface.patch367
1 files changed, 367 insertions, 0 deletions
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0104-media-vsp1-extend-DRM-VSP1-interface.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0104-media-vsp1-extend-DRM-VSP1-interface.patch
new file mode 100644
index 0000000..2f6fa35
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0104-media-vsp1-extend-DRM-VSP1-interface.patch
@@ -0,0 +1,367 @@
+From 0cbfce87c1a16b80111cdcecdd703ad5f75cc6e7 Mon Sep 17 00:00:00 2001
+From: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+Date: Tue, 14 Nov 2017 01:41:06 -0800
+Subject: [PATCH] media: platform: vsp1: extend DRM-VSP1 interface
+
+- Extend DRM-VSP1 interface
+- Add alpha-plane support for VSP1
+
+Signed-off-by: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+---
+ drivers/media/platform/vsp1/vsp1_bru.c | 13 ++++++++++++-
+ drivers/media/platform/vsp1/vsp1_dl.c | 5 +++++
+ drivers/media/platform/vsp1/vsp1_drm.c | 34 ++++++++++++++++++++++++++-------
+ drivers/media/platform/vsp1/vsp1_lif.c | 2 +-
+ drivers/media/platform/vsp1/vsp1_pipe.c | 4 ++++
+ drivers/media/platform/vsp1/vsp1_rpf.c | 24 ++++++++++++++++++++---
+ drivers/media/platform/vsp1/vsp1_rwpf.c | 2 +-
+ drivers/media/platform/vsp1/vsp1_rwpf.h | 6 ++++++
+ drivers/media/platform/vsp1/vsp1_wpf.c | 4 +++-
+ include/media/vsp1.h | 6 ++++++
+ 10 files changed, 86 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
+index 8b3164a..2c131be 100644
+--- a/drivers/media/platform/vsp1/vsp1_bru.c
++++ b/drivers/media/platform/vsp1/vsp1_bru.c
+@@ -387,6 +387,16 @@ static void bru_configure(struct vsp1_entity *entity,
+ ctrl |= VI6_BRU_CTRL_SRCSEL_BRUIN(i);
+
+ vsp1_bru_write(bru, dl, VI6_BRU_CTRL(i), ctrl);
++ dev_dbg(entity->vsp1->dev, "bru#%d: ctrl=%X\n", i, ctrl);
++
++ /* ...set blending formula as defined by the input RPF */
++ if (bru->inputs[i].rpf) {
++ if (bru->inputs[i].rpf->blend) {
++ vsp1_bru_write(bru, dl, VI6_BRU_BLD(i), bru->inputs[i].rpf->blend);
++ dev_dbg(entity->vsp1->dev, "bru#%d(#%d): setup blending formula: %X\n", i, bru->inputs[i].rpf->entity.index, bru->inputs[i].rpf->blend);
++ continue;
++ }
++ }
+
+ /* Harcode the blending formula to
+ *
+@@ -441,7 +451,8 @@ struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1)
+ v4l2_ctrl_new_std(&bru->ctrls, &bru_ctrl_ops, V4L2_CID_BG_COLOR,
+ 0, 0xffffff, 1, 0);
+
+- bru->bgcolor = 0;
++ /* ...for YUV, set black background */
++ bru->bgcolor = 0x00800080;
+
+ bru->entity.subdev.ctrl_handler = &bru->ctrls;
+
+diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
+index 478e093..f9c6d09 100644
+--- a/drivers/media/platform/vsp1/vsp1_dl.c
++++ b/drivers/media/platform/vsp1/vsp1_dl.c
+@@ -272,6 +272,7 @@ void vsp1_dl_set_addr_auto_fld(struct vsp1_dl_list *dl, struct vsp1_rwpf *rpf)
+ u32 y_top_index, y_bot_index;
+ u32 u_top_index, u_bot_index;
+ u32 v_top_index, v_bot_index;
++ u32 alpha_index;
+ dma_addr_t y_top_addr, y_bot_addr;
+ dma_addr_t u_top_addr, u_bot_addr;
+ dma_addr_t v_top_addr, v_bot_addr;
+@@ -287,6 +288,7 @@ void vsp1_dl_set_addr_auto_fld(struct vsp1_dl_list *dl, struct vsp1_rwpf *rpf)
+ u_bot_index = rpf->entity.index * 8 + 3;
+ v_top_index = rpf->entity.index * 8 + 4;
+ v_bot_index = rpf->entity.index * 8 + 5;
++ alpha_index = rpf->entity.index * 8 + 6;
+
+ switch (rpf->fmtinfo->fourcc) {
+ case V4L2_PIX_FMT_YUV420M:
+@@ -359,6 +361,9 @@ void vsp1_dl_set_addr_auto_fld(struct vsp1_dl_list *dl, struct vsp1_rwpf *rpf)
+ dl->src_dst_addr[u_bot_index].addr = u_bot_addr;
+ dl->src_dst_addr[v_top_index].addr = v_top_addr;
+ dl->src_dst_addr[v_bot_index].addr = v_bot_addr;
++
++ /* ...set alpha-plane address as needed */
++ dl->src_dst_addr[alpha_index].addr = rpf->mem.alpha;
+ }
+
+ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm)
+diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
+index 2681c8a..542ca5a 100644
+--- a/drivers/media/platform/vsp1/vsp1_drm.c
++++ b/drivers/media/platform/vsp1/vsp1_drm.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 <linux/device.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/slab.h>
+@@ -201,7 +201,9 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg,
+
+ format.format.width = cfg->width;
+ format.format.height = cfg->height;
+- format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ //format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ /* ...always blend in YUV colorspace; apply conversion as needed */
++ format.format.code = MEDIA_BUS_FMT_AYUV8_1X32;
+ format.format.field = V4L2_FIELD_NONE;
+
+ ret = v4l2_subdev_call(&brs->entity.subdev, pad,
+@@ -222,7 +224,9 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg,
+
+ format.format.width = cfg->width;
+ format.format.height = cfg->height;
+- format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ //format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ /* ...always blend in YUV colorspace; apply conversion as needed */
++ format.format.code = MEDIA_BUS_FMT_AYUV8_1X32;
+ format.format.field = V4L2_FIELD_NONE;
+
+ ret = v4l2_subdev_call(&bru->entity.subdev, pad,
+@@ -241,7 +245,8 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg,
+
+ format.format.width = cfg->width;
+ format.format.height = cfg->height;
+- format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ //format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ format.format.code = MEDIA_BUS_FMT_AYUV8_1X32;
+ format.format.field = V4L2_FIELD_NONE;
+
+ if (lif_index == 1) {
+@@ -275,6 +280,13 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg,
+ format.format.code, lif_index);
+
+ format.pad = RWPF_PAD_SOURCE;
++ /* ...force conversion back to ARGB at the output */
++ format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ ret = v4l2_subdev_call(&vsp1->wpf[0]->entity.subdev, pad, set_fmt, NULL,
++ &format);
++ if (ret < 0)
++ return ret;
++
+ ret = v4l2_subdev_call(&vsp1->wpf[lif_index]->entity.subdev,
+ pad, get_fmt, NULL, &format);
+ if (ret < 0)
+@@ -402,12 +414,12 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
+ }
+
+ dev_dbg(vsp1->dev,
+- "%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u dma { %pad, %pad, %pad } zpos %u\n",
++ "%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u dma { %pad, %pad, %pad } zpos %u, alpha %pad, ckey %x/%x/%x\n",
+ __func__, rpf_index,
+ cfg->src.left, cfg->src.top, cfg->src.width, cfg->src.height,
+ cfg->dst.left, cfg->dst.top, cfg->dst.width, cfg->dst.height,
+ cfg->pixelformat, cfg->pitch, &cfg->mem[0], &cfg->mem[1],
+- &cfg->mem[2], cfg->zpos);
++ &cfg->mem[2], cfg->zpos, &cfg->alpha_mem, cfg->ckey, cfg->ckey_set0, cfg->ckey_set1);
+
+ /*
+ * Store the format, stride, memory buffer address, crop and compose
+@@ -432,6 +444,11 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
+ rpf->format.plane_fmt[1].bytesperline = cfg->pitch;
+ rpf->alpha = cfg->alpha;
+ rpf->interlaced = cfg->interlaced;
++ rpf->alpha_pitch = cfg->alpha_pitch;
++ rpf->ckey = cfg->ckey;
++ rpf->ckey_set0 = cfg->ckey_set0;
++ rpf->ckey_set1 = cfg->ckey_set1;
++ rpf->blend = cfg->blend;
+
+ if ((vsp1->ths_quirks & VSP1_AUTO_FLD_NOT_SUPPORT) &&
+ rpf->interlaced) {
+@@ -443,6 +460,7 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
+ rpf->mem.addr[0] = cfg->mem[0];
+ rpf->mem.addr[1] = cfg->mem[1];
+ rpf->mem.addr[2] = cfg->mem[2];
++ rpf->mem.alpha = cfg->alpha_mem;
+
+ vsp1->drm->inputs[rpf_index].crop = cfg->src;
+ vsp1->drm->inputs[rpf_index].compose = cfg->dst;
+@@ -517,7 +535,9 @@ static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
+ __func__, format.format.width, format.format.height,
+ format.format.code, rpf->entity.index);
+
+- format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ //format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ /* ...do blending in YUV color-space; apply conversion as needed */
++ format.format.code = MEDIA_BUS_FMT_AYUV8_1X32;
+
+ ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL,
+ &format);
+diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
+index e79f9e6..753763d 100644
+--- a/drivers/media/platform/vsp1/vsp1_lif.c
++++ b/drivers/media/platform/vsp1/vsp1_lif.c
+@@ -162,7 +162,7 @@ static void lif_configure(struct vsp1_entity *entity,
+
+ vsp1_lif_write(lif, dl, VI6_LIF_CTRL(lif->entity.index),
+ (obth << VI6_LIF_CTRL_OBTH_SHIFT) |
+- (format->code == 0 ? VI6_LIF_CTRL_CFMT : 0) |
++ (format->code != MEDIA_BUS_FMT_ARGB8888_1X32 ? VI6_LIF_CTRL_CFMT : 0) |
+ VI6_LIF_CTRL_REQSEL | VI6_LIF_CTRL_LIF_EN);
+
+ if (soc_device_match(r8a7797))
+diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
+index 8379962..86d4a85 100644
+--- a/drivers/media/platform/vsp1/vsp1_pipe.c
++++ b/drivers/media/platform/vsp1/vsp1_pipe.c
+@@ -137,6 +137,10 @@ static const struct vsp1_format_info vsp1_video_formats[] = {
+ VI6_FMT_Y_U_V_444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+ 3, { 8, 8, 8 }, false, false, 1, 1, false },
++ { V4L2_PIX_FMT_GREY, MEDIA_BUS_FMT_Y8_1X8,
++ /*VI6_FMT_Y_U_V_444*/0xDEAD, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
++ 1, { 8, 0, 0 }, false, false, 0, 0, false },
+ };
+
+ /**
+diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
+index ff25470..2cce294 100644
+--- a/drivers/media/platform/vsp1/vsp1_rpf.c
++++ b/drivers/media/platform/vsp1/vsp1_rpf.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 <linux/device.h>
+
+ #include <media/v4l2-subdev.h>
+@@ -253,8 +253,10 @@ static void rpf_configure(struct vsp1_entity *entity,
+ if (sink_format->code != source_format->code)
+ infmt |= VI6_RPF_INFMT_CSC;
+
++ dev_dbg(vsp1->dev, "rpf#%d: infmt=%x (csc=%d)\n", rpf->entity.index, infmt, !!(infmt & VI6_RPF_INFMT_CSC));
++
+ vsp1_rpf_write(rpf, dl, VI6_RPF_INFMT, infmt);
+- vsp1_rpf_write(rpf, dl, VI6_RPF_DSWAP, fmtinfo->swap);
++ vsp1_rpf_write(rpf, dl, VI6_RPF_DSWAP, fmtinfo->swap | 0xF00);
+
+ /* Output location */
+ if (pipe->bru) {
+@@ -288,6 +290,15 @@ static void rpf_configure(struct vsp1_entity *entity,
+ (left << VI6_RPF_LOC_HCOORD_SHIFT) |
+ (top << VI6_RPF_LOC_VCOORD_SHIFT));
+
++ // ...setup alpha-plane as required
++ if (rpf->mem.alpha) {
++ vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_AI, rpf->mem.alpha);
++ vsp1_rpf_write(rpf, dl, VI6_RPF_ALPH_SEL, VI6_RPF_ALPH_SEL_ASEL_8B_PLANE);
++ vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ASTRIDE, rpf->alpha_pitch);
++ dev_dbg(vsp1->dev, "rpf#%d: setup alpha-plane: buffer=%pad, stride=%u\n", rpf->entity.index, &rpf->mem.alpha, rpf->alpha_pitch);
++ goto out;
++ }
++
+ /* On Gen2 use the alpha channel (extended to 8 bits) when available or
+ * a fixed alpha value set through the V4L2_CID_ALPHA_COMPONENT control
+ * otherwise.
+@@ -342,7 +353,9 @@ static void rpf_configure(struct vsp1_entity *entity,
+ if (entity->vsp1->info->gen == 3) {
+ u32 mult;
+
+- if ((fmtinfo->alpha) &&
++ dev_dbg(vsp1->dev, "rpf#%d: alpha=%x, fourcc=%x\n", rpf->entity.index, fmtinfo->alpha, fmtinfo->fourcc);
++
++ if (0 && (fmtinfo->alpha) &&
+ (fmtinfo->fourcc != V4L2_PIX_FMT_ARGB555)) {
+ /* When the input contains an alpha channel enable the
+ * alpha multiplier. If the input is premultiplied we
+@@ -371,9 +384,14 @@ static void rpf_configure(struct vsp1_entity *entity,
+ rpf->mult_alpha = mult;
+ }
+
++out:
+ vsp1_rpf_write(rpf, dl, VI6_RPF_MSK_CTRL, 0);
+ vsp1_rpf_write(rpf, dl, VI6_RPF_CKEY_CTRL, 0);
+
++ /* ...set up color keying */
++ vsp1_rpf_write(rpf, dl, VI6_RPF_CKEY_CTRL, rpf->ckey);
++ vsp1_rpf_write(rpf, dl, VI6_RPF_CKEY_SET0, rpf->ckey_set0);
++ vsp1_rpf_write(rpf, dl, VI6_RPF_CKEY_SET1, rpf->ckey_set1);
+ }
+
+ static const struct vsp1_entity_operations rpf_entity_ops = {
+diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c
+index 66e4d7e..d7e730f 100644
+--- a/drivers/media/platform/vsp1/vsp1_rwpf.c
++++ b/drivers/media/platform/vsp1/vsp1_rwpf.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 <media/v4l2-subdev.h>
+
+ #include "vsp1.h"
+diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
+index fbe6aa6..7553f2b 100644
+--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
++++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
+@@ -33,6 +33,7 @@ struct vsp1_video;
+
+ struct vsp1_rwpf_memory {
+ dma_addr_t addr[3];
++ dma_addr_t alpha;
+ };
+
+ struct vsp1_rwpf {
+@@ -72,6 +73,11 @@ struct vsp1_rwpf {
+
+ int write_back;
+ dma_addr_t buf_addr[3];
++ unsigned int alpha_pitch;
++ unsigned int ckey;
++ unsigned int ckey_set0;
++ unsigned int ckey_set1;
++ unsigned int blend;
+ };
+
+ static inline struct vsp1_rwpf *to_rwpf(struct v4l2_subdev *subdev)
+diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
+index e8b3cfb..cb81848 100644
+--- a/drivers/media/platform/vsp1/vsp1_wpf.c
++++ b/drivers/media/platform/vsp1/vsp1_wpf.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 <linux/device.h>
+
+ #include <media/v4l2-subdev.h>
+@@ -358,6 +358,8 @@ static void wpf_configure(struct vsp1_entity *entity,
+
+ wpf->outfmt = outfmt;
+
++ dev_dbg(vsp1->dev, "wpf#%d: outfmt=%x (csc=%d)\n", wpf->entity.index, outfmt, !!(outfmt & VI6_WPF_OUTFMT_CSC));
++
+ vsp1_dl_list_write(dl, VI6_DPR_WPF_FPORCH(wpf->entity.index),
+ VI6_DPR_WPF_FPORCH_FP_WPFN);
+
+diff --git a/include/media/vsp1.h b/include/media/vsp1.h
+index d5d93ed..c1c3201 100644
+--- a/include/media/vsp1.h
++++ b/include/media/vsp1.h
+@@ -53,11 +53,17 @@ struct vsp1_du_atomic_config {
+ u32 pixelformat;
+ unsigned int pitch;
+ dma_addr_t mem[3];
++ dma_addr_t alpha_mem;
++ unsigned int alpha_pitch;
++ unsigned int ckey;
++ unsigned int ckey_set0;
++ unsigned int ckey_set1;
+ struct v4l2_rect src;
+ struct v4l2_rect dst;
+ unsigned int alpha;
+ unsigned int zpos;
+ bool interlaced;
++ unsigned int blend;
+ };
+
+ void vsp1_du_atomic_begin(struct device *dev, unsigned int lif_index);
+--
+2.7.4
+