armbian_build/patch/kernel/archive/sunxi-5.18/patches.armbian/drv-media-cedrus-10-bit-HEVC-support.patch
The-going 0c438d8c56
sunxi-5.18: Add armbian patches (#3846)
* sunxi-5.18 Initial state for armbian patches

* Adapting patches to the new kernel, sort, add new megous patches

* DEBUG

* Add the latest patches

* fix: compile error

drivers/spi/spi.c:3548:3: note: in expansion of macro ‘dev_info’
   dev_info(&spi->dev, "spi_setup / gpio_is_valid(%d) ... doing gpio_request ...\n", spi->cs_gpio);
   ^~~~~~~~
drivers/spi/spi.c:3549:9: error:
 implicit declaration of function ‘gpio_request’;
 did you mean ‘gpio_to_desc’? [-Werror=implicit-function-declaration]
   ret = gpio_request(spi->cs_gpio, dev_name(&spi->dev));
         ^~~~~~~~~~~~
         gpio_to_desc
drivers/spi/spi.c:3549:27: error:
 ‘struct spi_device’ has no member named ‘cs_gpio’;
 did you mean ‘cs_gpiod’?
   ret = gpio_request(spi->cs_gpio, dev_name(&spi->dev));
                           ^~~~~~~
                           cs_gpiod
drivers/spi/spi.c:3554:4: error:
 implicit declaration of function ‘gpio_direction_output’;
 did you mean ‘gpiod_direction_output’? [-Werror=implicit-function-declaration]
    gpio_direction_output(spi->cs_gpio,
    ^~~~~~~~~~~~~~~~~~~~~
    gpiod_direction_output
drivers/spi/spi.c:3554:31: error:
	‘struct spi_device’ has no member named ‘cs_gpio’;
	did you mean ‘cs_gpiod’?
    gpio_direction_output(spi->cs_gpio,
                               ^~~~~~~
                               cs_gpiod
In file included from ./include/linux/device.h:15,
                 from drivers/spi/spi.c:8:
drivers/spi/spi.c:3556:79: error:
 ‘struct spi_device’ has no member named ‘cs_gpio’;
 did you mean ‘cs_gpiod’?

* Remove pre-applied patches
2022-06-01 17:10:19 +02:00

171 lines
6.0 KiB
Diff

From 649d9696074a8446bda17be77b2277e72be2c2eb Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Sun, 15 Mar 2020 21:35:39 +0100
Subject: [PATCH 056/101] drv:media:cedrus: 10-bit HEVC support
WIp: 10-bit HEVC support
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
drivers/staging/media/sunxi/cedrus/cedrus.c | 4 +--
.../staging/media/sunxi/cedrus/cedrus_h265.c | 12 ++++++++
.../staging/media/sunxi/cedrus/cedrus_regs.h | 4 +++
.../staging/media/sunxi/cedrus/cedrus_video.c | 30 +++++++++++++++----
.../staging/media/sunxi/cedrus/cedrus_video.h | 2 +-
5 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
index 314afde91..180fa9cee 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
@@ -336,7 +336,7 @@ static int cedrus_open(struct file *file)
goto err_ctrls;
}
ctx->dst_fmt.pixelformat = V4L2_PIX_FMT_NV12_32L32;
- cedrus_prepare_format(&ctx->dst_fmt);
+ cedrus_prepare_format(&ctx->dst_fmt, 0);
ctx->src_fmt.pixelformat = V4L2_PIX_FMT_MPEG2_SLICE;
/*
* TILED_NV12 has more strict requirements, so copy the width and
@@ -344,7 +344,7 @@ static int cedrus_open(struct file *file)
*/
ctx->src_fmt.width = ctx->dst_fmt.width;
ctx->src_fmt.height = ctx->dst_fmt.height;
- cedrus_prepare_format(&ctx->src_fmt);
+ cedrus_prepare_format(&ctx->src_fmt, 0);
v4l2_fh_add(&ctx->fh);
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
index 3d7f87a80..7caec0e57 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
@@ -534,6 +534,18 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
cedrus_write(dev, VE_DEC_H265_DEC_PCM_CTRL, reg);
+ if (sps->bit_depth_luma_minus8 == 2) {
+ unsigned int size;
+
+ size = ALIGN(ctx->src_fmt.width, 16) * ALIGN(ctx->src_fmt.height, 16);
+
+ reg = (size * 3) / 2;
+ cedrus_write(dev, VE_DEC_H265_OFFSET_ADDR_FIRST_OUT, reg);
+
+ reg = DIV_ROUND_UP(ctx->src_fmt.width, 4);
+ cedrus_write(dev, VE_DEC_H265_10BIT_CONFIGURE, ALIGN(reg, 32));
+ }
+
/* PPS. */
reg = VE_DEC_H265_DEC_PPS_CTRL0_PPS_CR_QP_OFFSET(pps->pps_cr_qp_offset) |
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
index bdb062ad8..7ab3a2b0a 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
@@ -499,6 +499,10 @@
#define VE_DEC_H265_LOW_ADDR (VE_ENGINE_DEC_H265 + 0x80)
+#define VE_DEC_H265_OFFSET_ADDR_FIRST_OUT (VE_ENGINE_DEC_H265 + 0x84)
+#define VE_DEC_H265_OFFSET_ADDR_SECOND_OUT (VE_ENGINE_DEC_H265 + 0x88)
+#define VE_DEC_H265_10BIT_CONFIGURE (VE_ENGINE_DEC_H265 + 0x8c)
+
#define VE_DEC_H265_LOW_ADDR_PRIMARY_CHROMA(a) \
SHIFT_AND_MASK_BITS(a, 31, 24)
#define VE_DEC_H265_LOW_ADDR_SECONDARY_CHROMA(a) \
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
index 80e33775b..247377138 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
@@ -100,7 +100,7 @@ static struct cedrus_format *cedrus_find_format(u32 pixelformat, u32 directions,
return &cedrus_formats[i];
}
-void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
+void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt, int extended)
{
unsigned int width = pix_fmt->width;
unsigned int height = pix_fmt->height;
@@ -155,6 +155,17 @@ void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
break;
}
+ if (extended) {
+ unsigned int extra_size;
+
+ extra_size = DIV_ROUND_UP(pix_fmt->width, 4);
+ extra_size = ALIGN(extra_size, 32);
+ extra_size *= ALIGN(pix_fmt->height, 16) * 3;
+ extra_size /= 2;
+
+ sizeimage += extra_size;
+ }
+
pix_fmt->width = width;
pix_fmt->height = height;
@@ -247,17 +258,27 @@ static int cedrus_try_fmt_vid_cap(struct file *file, void *priv,
struct cedrus_ctx *ctx = cedrus_file2ctx(file);
struct cedrus_dev *dev = ctx->dev;
struct v4l2_pix_format *pix_fmt = &f->fmt.pix;
+ const struct v4l2_ctrl_hevc_sps *sps;
struct cedrus_format *fmt =
cedrus_find_format(pix_fmt->pixelformat, CEDRUS_DECODE_DST,
dev->capabilities);
+ int extended;
if (!fmt)
return -EINVAL;
+ sps = cedrus_find_control_data(ctx, V4L2_CID_MPEG_VIDEO_HEVC_SPS);
+
+ /* The 10-bitHEVC decoder needs extra size on the output buffer. */
+ extended = ctx->src_fmt.pixelformat == V4L2_PIX_FMT_HEVC_SLICE &&
+ sps->bit_depth_luma_minus8 == 2;
+
pix_fmt->pixelformat = fmt->pixelformat;
pix_fmt->width = ctx->src_fmt.width;
pix_fmt->height = ctx->src_fmt.height;
- cedrus_prepare_format(pix_fmt);
+
+ pix_fmt->pixelformat = fmt->pixelformat;
+ cedrus_prepare_format(pix_fmt, extended);
return 0;
}
@@ -275,8 +296,7 @@ static int cedrus_try_fmt_vid_out(struct file *file, void *priv,
if (!fmt)
return -EINVAL;
- pix_fmt->pixelformat = fmt->pixelformat;
- cedrus_prepare_format(pix_fmt);
+ cedrus_prepare_format(pix_fmt, 0);
return 0;
}
@@ -357,7 +377,7 @@ static int cedrus_s_fmt_vid_out(struct file *file, void *priv,
ctx->dst_fmt.quantization = f->fmt.pix.quantization;
ctx->dst_fmt.width = ctx->src_fmt.width;
ctx->dst_fmt.height = ctx->src_fmt.height;
- cedrus_prepare_format(&ctx->dst_fmt);
+ cedrus_prepare_format(&ctx->dst_fmt, 0);
return 0;
}
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.h b/drivers/staging/media/sunxi/cedrus/cedrus_video.h
index 05050c0a0..d42e4ebf6 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.h
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.h
@@ -26,6 +26,6 @@ extern const struct v4l2_ioctl_ops cedrus_ioctl_ops;
int cedrus_queue_init(void *priv, struct vb2_queue *src_vq,
struct vb2_queue *dst_vq);
-void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt);
+void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt, int extended);
#endif
--
2.31.1