summarylogtreecommitdiffstats
path: root/drv-media-cedrus-hevc-tiles-hack.patch
diff options
context:
space:
mode:
authoryjun2022-05-17 12:16:32 +0800
committeryjun2022-05-17 12:16:32 +0800
commitd66c7d0fc0b35270f9fe591a311563cc0d851555 (patch)
tree78708ccbe7b46d0494838100815004e5f5fff152 /drv-media-cedrus-hevc-tiles-hack.patch
parentdf61abd38d06cbb1f4eca16f1e070d986a8b6dbd (diff)
downloadaur-d66c7d0fc0b35270f9fe591a311563cc0d851555.tar.gz
updpkg: linux-tqc-a01 5.17.7
Diffstat (limited to 'drv-media-cedrus-hevc-tiles-hack.patch')
-rw-r--r--drv-media-cedrus-hevc-tiles-hack.patch180
1 files changed, 180 insertions, 0 deletions
diff --git a/drv-media-cedrus-hevc-tiles-hack.patch b/drv-media-cedrus-hevc-tiles-hack.patch
new file mode 100644
index 000000000000..7d1238b08c63
--- /dev/null
+++ b/drv-media-cedrus-hevc-tiles-hack.patch
@@ -0,0 +1,180 @@
+From 08ec2c0d449a9e91f9174b347bd3f560f50ca872 Mon Sep 17 00:00:00 2001
+From: Jernej Skrabec <jernej.skrabec@siol.net>
+Date: Sat, 26 Oct 2019 21:23:55 +0200
+Subject: [PATCH 046/101] drv:media: cedrus: hevc: tiles hack
+
+Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
+---
+ drivers/staging/media/sunxi/cedrus/cedrus.h | 2 +
+ .../staging/media/sunxi/cedrus/cedrus_h265.c | 93 +++++++++++++++++--
+ 2 files changed, 89 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
+index 9c7bfd2b6..c790963ef 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
++++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
+@@ -144,6 +144,8 @@ struct cedrus_ctx {
+ ssize_t mv_col_buf_unit_size;
+ void *neighbor_info_buf;
+ dma_addr_t neighbor_info_buf_addr;
++ void *entry_points_buf;
++ dma_addr_t entry_points_buf_addr;
+ } h265;
+ struct {
+ unsigned int last_frame_p_type;
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+index bb7eb5610..4fa5016a2 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+@@ -301,6 +301,61 @@ static void cedrus_h265_write_scaling_list(struct cedrus_ctx *ctx,
+ }
+ }
+
++static void write_entry_point_list(struct cedrus_ctx *ctx,
++ struct cedrus_run *run,
++ unsigned int ctb_addr_x,
++ unsigned int ctb_addr_y)
++{
++ const struct v4l2_ctrl_hevc_slice_params *slice_params;
++ const struct v4l2_ctrl_hevc_pps *pps;
++ struct cedrus_dev *dev = ctx->dev;
++ int i, x, tx, y, ty;
++ u32 *entry_points;
++
++ pps = run->h265.pps;
++ slice_params = run->h265.slice_params;
++
++ for (x = 0, tx = 0; tx < pps->num_tile_columns_minus1 + 1; tx++) {
++ if (x + pps->column_width_minus1[tx] + 1 > ctb_addr_x)
++ break;
++
++ x += pps->column_width_minus1[tx] + 1;
++ }
++
++ for (y = 0, ty = 0; ty < pps->num_tile_rows_minus1 + 1; ty++) {
++ if (y + pps->row_height_minus1[ty] + 1 > ctb_addr_y)
++ break;
++
++ y += pps->row_height_minus1[ty] + 1;
++ }
++
++ cedrus_write(dev, VE_DEC_H265_TILE_START_CTB, (y << 16) | (x << 0));
++ cedrus_write(dev, VE_DEC_H265_TILE_END_CTB,
++ ((y + pps->row_height_minus1[ty]) << 16) |
++ ((x + pps->column_width_minus1[tx]) << 0));
++
++ entry_points = ctx->codec.h265.entry_points_buf;
++ if (pps->flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED) {
++ for (i = 0; i < slice_params->num_entry_point_offsets; i++)
++ entry_points[i] = slice_params->entry_point_offset_minus1[i] + 1;
++ } else {
++ for (i = 0; i < slice_params->num_entry_point_offsets; i++) {
++ if (tx + 1 >= pps->num_tile_columns_minus1 + 1) {
++ x = 0;
++ tx = 0;
++ y += pps->row_height_minus1[ty++] + 1;
++ } else {
++ x += pps->column_width_minus1[tx++] + 1;
++ }
++
++ entry_points[i * 4 + 0] = slice_params->entry_point_offset_minus1[i] + 1;
++ entry_points[i * 4 + 1] = 0x0;
++ entry_points[i * 4 + 2] = (y << 16) | (x << 0);
++ entry_points[i * 4 + 3] = ((y + pps->row_height_minus1[ty]) << 16) | ((x + pps->column_width_minus1[tx]) << 0);
++ }
++ }
++}
++
+ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
+ struct cedrus_run *run)
+ {
+@@ -312,6 +367,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
+ const struct v4l2_hevc_pred_weight_table *pred_weight_table;
+ unsigned int width_in_ctb_luma, ctb_size_luma;
+ unsigned int log2_max_luma_coding_block_size;
++ unsigned int ctb_addr_x, ctb_addr_y;
+ dma_addr_t src_buf_addr;
+ dma_addr_t src_buf_end_addr;
+ u32 chroma_log2_weight_denom;
+@@ -390,12 +446,19 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
+ cedrus_write(dev, VE_DEC_H265_BITS_END_ADDR, reg);
+
+ /* Coding tree block address */
+- reg = VE_DEC_H265_DEC_CTB_ADDR_X(slice_params->slice_segment_addr % width_in_ctb_luma);
+- reg |= VE_DEC_H265_DEC_CTB_ADDR_Y(slice_params->slice_segment_addr / width_in_ctb_luma);
++ ctb_addr_x = slice_params->slice_segment_addr % width_in_ctb_luma;
++ ctb_addr_y = slice_params->slice_segment_addr / width_in_ctb_luma;
++ reg = VE_DEC_H265_DEC_CTB_ADDR_X(ctb_addr_x);
++ reg |= VE_DEC_H265_DEC_CTB_ADDR_Y(ctb_addr_y);
+ cedrus_write(dev, VE_DEC_H265_DEC_CTB_ADDR, reg);
+
+- cedrus_write(dev, VE_DEC_H265_TILE_START_CTB, 0);
+- cedrus_write(dev, VE_DEC_H265_TILE_END_CTB, 0);
++ if ((pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED) ||
++ (pps->flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED)) {
++ write_entry_point_list(ctx, run, ctb_addr_x, ctb_addr_y);
++ } else {
++ cedrus_write(dev, VE_DEC_H265_TILE_START_CTB, 0);
++ cedrus_write(dev, VE_DEC_H265_TILE_END_CTB, 0);
++ }
+
+ /* Clear the number of correctly-decoded coding tree blocks. */
+ if (ctx->fh.m2m_ctx->new_frame)
+@@ -499,7 +562,9 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
+ V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED,
+ pps->flags);
+
+- /* TODO: VE_DEC_H265_DEC_PPS_CTRL1_FLAG_TILES_ENABLED */
++ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_TILES_ENABLED,
++ V4L2_HEVC_PPS_FLAG_TILES_ENABLED,
++ pps->flags);
+
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_TRANSQUANT_BYPASS_ENABLED,
+ V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED,
+@@ -575,12 +640,14 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
+
+ chroma_log2_weight_denom = pred_weight_table->luma_log2_weight_denom +
+ pred_weight_table->delta_chroma_log2_weight_denom;
+- reg = VE_DEC_H265_DEC_SLICE_HDR_INFO2_NUM_ENTRY_POINT_OFFSETS(0) |
++ reg = VE_DEC_H265_DEC_SLICE_HDR_INFO2_NUM_ENTRY_POINT_OFFSETS(slice_params->num_entry_point_offsets) |
+ VE_DEC_H265_DEC_SLICE_HDR_INFO2_CHROMA_LOG2_WEIGHT_DENOM(chroma_log2_weight_denom) |
+ VE_DEC_H265_DEC_SLICE_HDR_INFO2_LUMA_LOG2_WEIGHT_DENOM(pred_weight_table->luma_log2_weight_denom);
+
+ cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO2, reg);
+
++ cedrus_write(dev, VE_DEC_H265_ENTRY_POINT_OFFSET_ADDR, ctx->codec.h265.entry_points_buf_addr >> 8);
++
+ /* Decoded picture size. */
+
+ reg = VE_DEC_H265_DEC_PIC_SIZE_WIDTH(ctx->src_fmt.width) |
+@@ -674,6 +741,17 @@ static int cedrus_h265_start(struct cedrus_ctx *ctx)
+ if (!ctx->codec.h265.neighbor_info_buf)
+ return -ENOMEM;
+
++ ctx->codec.h265.entry_points_buf =
++ dma_alloc_coherent(dev->dev, CEDRUS_H265_ENTRY_POINTS_BUF_SIZE,
++ &ctx->codec.h265.entry_points_buf_addr,
++ GFP_KERNEL);
++ if (!ctx->codec.h265.entry_points_buf) {
++ dma_free_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
++ ctx->codec.h265.neighbor_info_buf,
++ ctx->codec.h265.neighbor_info_buf_addr);
++ return -ENOMEM;
++ }
++
+ return 0;
+ }
+
+@@ -694,6 +772,9 @@ static void cedrus_h265_stop(struct cedrus_ctx *ctx)
+ ctx->codec.h265.neighbor_info_buf,
+ ctx->codec.h265.neighbor_info_buf_addr,
+ DMA_ATTR_NO_KERNEL_MAPPING);
++ dma_free_coherent(dev->dev, CEDRUS_H265_ENTRY_POINTS_BUF_SIZE,
++ ctx->codec.h265.entry_points_buf,
++ ctx->codec.h265.entry_points_buf_addr);
+ }
+
+ static void cedrus_h265_trigger(struct cedrus_ctx *ctx)
+--
+2.31.1
+