mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
Allwinner: linux: Fix deinterlacer and H265 decoding
This commit is contained in:
parent
36b4af5672
commit
9dca485178
@ -0,0 +1,65 @@
|
||||
From 6fba61d436ed9d610e1001860e2fcdf2ccf96803 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Date: Sat, 7 Oct 2023 08:36:47 +0200
|
||||
Subject: [PATCH 14/23] media: cedrus: h265: Fix configuring bitstream size
|
||||
|
||||
bit_size field holds size of slice, not slice + header. Because of HW
|
||||
quirks, driver can't program in just slice, but also preceeding header.
|
||||
But that means that currently used bit_size is wrong (too small).
|
||||
Instead, just use size of whole buffer. There is no harm in doing this.
|
||||
|
||||
Fixes: 86caab29da78 ("media: cedrus: Add HEVC/H.265 decoding support")
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 10 ++++------
|
||||
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
index fc9297232456..16c822637dc6 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
@@ -454,11 +454,11 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
|
||||
unsigned int ctb_addr_x, ctb_addr_y;
|
||||
struct cedrus_buffer *cedrus_buf;
|
||||
dma_addr_t src_buf_addr;
|
||||
- dma_addr_t src_buf_end_addr;
|
||||
u32 chroma_log2_weight_denom;
|
||||
u32 num_entry_point_offsets;
|
||||
u32 output_pic_list_index;
|
||||
u32 pic_order_cnt[2];
|
||||
+ size_t slice_bytes;
|
||||
u8 padding;
|
||||
int count;
|
||||
u32 reg;
|
||||
@@ -468,6 +468,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
|
||||
decode_params = run->h265.decode_params;
|
||||
pred_weight_table = &slice_params->pred_weight_table;
|
||||
num_entry_point_offsets = slice_params->num_entry_point_offsets;
|
||||
+ slice_bytes = vb2_get_plane_payload(&run->src->vb2_buf, 0);
|
||||
|
||||
/*
|
||||
* If entry points offsets are present, we should get them
|
||||
@@ -490,7 +491,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
|
||||
|
||||
cedrus_write(dev, VE_DEC_H265_BITS_OFFSET, 0);
|
||||
|
||||
- reg = slice_params->bit_size;
|
||||
+ reg = slice_bytes * 8;
|
||||
cedrus_write(dev, VE_DEC_H265_BITS_LEN, reg);
|
||||
|
||||
/* Source beginning and end addresses. */
|
||||
@@ -504,10 +505,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
|
||||
|
||||
cedrus_write(dev, VE_DEC_H265_BITS_ADDR, reg);
|
||||
|
||||
- src_buf_end_addr = src_buf_addr +
|
||||
- DIV_ROUND_UP(slice_params->bit_size, 8);
|
||||
-
|
||||
- reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_end_addr);
|
||||
+ reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_addr + slice_bytes);
|
||||
cedrus_write(dev, VE_DEC_H265_BITS_END_ADDR, reg);
|
||||
|
||||
/* Coding tree block address */
|
||||
--
|
||||
2.42.0
|
||||
|
@ -0,0 +1,150 @@
|
||||
From 239ce64f28fce7cc035a857bb5ed6f51ad6795c8 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Date: Thu, 19 Oct 2023 19:16:18 +0200
|
||||
Subject: [PATCH] wip: media: sunxi: sun8i-di: fix race condition
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
---
|
||||
.../media/platform/sunxi/sun8i-di/sun8i-di.c | 69 ++++++++++---------
|
||||
1 file changed, 35 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
|
||||
index 90ab1d77b6a5..f7ff0937828c 100644
|
||||
--- a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
|
||||
+++ b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
|
||||
@@ -66,6 +66,7 @@ static void deinterlace_device_run(void *priv)
|
||||
struct vb2_v4l2_buffer *src, *dst;
|
||||
unsigned int hstep, vstep;
|
||||
dma_addr_t addr;
|
||||
+ int i;
|
||||
|
||||
src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
|
||||
dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
|
||||
@@ -160,6 +161,26 @@ static void deinterlace_device_run(void *priv)
|
||||
deinterlace_write(dev, DEINTERLACE_CH1_HORZ_FACT, hstep);
|
||||
deinterlace_write(dev, DEINTERLACE_CH1_VERT_FACT, vstep);
|
||||
|
||||
+ /* neutral filter coefficients */
|
||||
+ deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL,
|
||||
+ DEINTERLACE_FRM_CTRL_COEF_ACCESS);
|
||||
+ readl_poll_timeout(dev->base + DEINTERLACE_STATUS, val,
|
||||
+ val & DEINTERLACE_STATUS_COEF_STATUS, 2, 40);
|
||||
+
|
||||
+ for (i = 0; i < 32; i++) {
|
||||
+ deinterlace_write(dev, DEINTERLACE_CH0_HORZ_COEF0 + i * 4,
|
||||
+ DEINTERLACE_IDENTITY_COEF);
|
||||
+ deinterlace_write(dev, DEINTERLACE_CH0_VERT_COEF + i * 4,
|
||||
+ DEINTERLACE_IDENTITY_COEF);
|
||||
+ deinterlace_write(dev, DEINTERLACE_CH1_HORZ_COEF0 + i * 4,
|
||||
+ DEINTERLACE_IDENTITY_COEF);
|
||||
+ deinterlace_write(dev, DEINTERLACE_CH1_VERT_COEF + i * 4,
|
||||
+ DEINTERLACE_IDENTITY_COEF);
|
||||
+ }
|
||||
+
|
||||
+ deinterlace_clr_set_bits(dev, DEINTERLACE_FRM_CTRL,
|
||||
+ DEINTERLACE_FRM_CTRL_COEF_ACCESS, 0);
|
||||
+
|
||||
deinterlace_clr_set_bits(dev, DEINTERLACE_FIELD_CTRL,
|
||||
DEINTERLACE_FIELD_CTRL_FIELD_CNT_MSK,
|
||||
DEINTERLACE_FIELD_CTRL_FIELD_CNT(ctx->field));
|
||||
@@ -248,7 +269,6 @@ static irqreturn_t deinterlace_irq(int irq, void *data)
|
||||
static void deinterlace_init(struct deinterlace_dev *dev)
|
||||
{
|
||||
u32 val;
|
||||
- int i;
|
||||
|
||||
deinterlace_write(dev, DEINTERLACE_BYPASS,
|
||||
DEINTERLACE_BYPASS_CSC);
|
||||
@@ -284,27 +304,7 @@ static void deinterlace_init(struct deinterlace_dev *dev)
|
||||
|
||||
deinterlace_clr_set_bits(dev, DEINTERLACE_CHROMA_DIFF,
|
||||
DEINTERLACE_CHROMA_DIFF_TH_MSK,
|
||||
- DEINTERLACE_CHROMA_DIFF_TH(5));
|
||||
-
|
||||
- /* neutral filter coefficients */
|
||||
- deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL,
|
||||
- DEINTERLACE_FRM_CTRL_COEF_ACCESS);
|
||||
- readl_poll_timeout(dev->base + DEINTERLACE_STATUS, val,
|
||||
- val & DEINTERLACE_STATUS_COEF_STATUS, 2, 40);
|
||||
-
|
||||
- for (i = 0; i < 32; i++) {
|
||||
- deinterlace_write(dev, DEINTERLACE_CH0_HORZ_COEF0 + i * 4,
|
||||
- DEINTERLACE_IDENTITY_COEF);
|
||||
- deinterlace_write(dev, DEINTERLACE_CH0_VERT_COEF + i * 4,
|
||||
- DEINTERLACE_IDENTITY_COEF);
|
||||
- deinterlace_write(dev, DEINTERLACE_CH1_HORZ_COEF0 + i * 4,
|
||||
- DEINTERLACE_IDENTITY_COEF);
|
||||
- deinterlace_write(dev, DEINTERLACE_CH1_VERT_COEF + i * 4,
|
||||
- DEINTERLACE_IDENTITY_COEF);
|
||||
- }
|
||||
-
|
||||
- deinterlace_clr_set_bits(dev, DEINTERLACE_FRM_CTRL,
|
||||
- DEINTERLACE_FRM_CTRL_COEF_ACCESS, 0);
|
||||
+ DEINTERLACE_CHROMA_DIFF_TH(31));
|
||||
}
|
||||
|
||||
static inline struct deinterlace_ctx *deinterlace_file2ctx(struct file *file)
|
||||
@@ -929,11 +929,18 @@ static int deinterlace_runtime_resume(struct device *device)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ ret = reset_control_deassert(dev->rstc);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev->dev, "Failed to apply reset\n");
|
||||
+
|
||||
+ goto err_exclusive_rate;
|
||||
+ }
|
||||
+
|
||||
ret = clk_prepare_enable(dev->bus_clk);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "Failed to enable bus clock\n");
|
||||
|
||||
- goto err_exclusive_rate;
|
||||
+ goto err_rst;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dev->mod_clk);
|
||||
@@ -950,23 +957,16 @@ static int deinterlace_runtime_resume(struct device *device)
|
||||
goto err_mod_clk;
|
||||
}
|
||||
|
||||
- ret = reset_control_deassert(dev->rstc);
|
||||
- if (ret) {
|
||||
- dev_err(dev->dev, "Failed to apply reset\n");
|
||||
-
|
||||
- goto err_ram_clk;
|
||||
- }
|
||||
-
|
||||
deinterlace_init(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
-err_ram_clk:
|
||||
- clk_disable_unprepare(dev->ram_clk);
|
||||
err_mod_clk:
|
||||
clk_disable_unprepare(dev->mod_clk);
|
||||
err_bus_clk:
|
||||
clk_disable_unprepare(dev->bus_clk);
|
||||
+err_rst:
|
||||
+ reset_control_assert(dev->rstc);
|
||||
err_exclusive_rate:
|
||||
clk_rate_exclusive_put(dev->mod_clk);
|
||||
|
||||
@@ -977,11 +977,12 @@ static int deinterlace_runtime_suspend(struct device *device)
|
||||
{
|
||||
struct deinterlace_dev *dev = dev_get_drvdata(device);
|
||||
|
||||
- reset_control_assert(dev->rstc);
|
||||
-
|
||||
clk_disable_unprepare(dev->ram_clk);
|
||||
clk_disable_unprepare(dev->mod_clk);
|
||||
clk_disable_unprepare(dev->bus_clk);
|
||||
+
|
||||
+ reset_control_assert(dev->rstc);
|
||||
+
|
||||
clk_rate_exclusive_put(dev->mod_clk);
|
||||
|
||||
return 0;
|
||||
--
|
||||
2.42.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user