1024 lines
35 KiB
Diff
1024 lines
35 KiB
Diff
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Jonas Karlman <jonas@kwiboo.se>
|
||
|
Date: Sat, 23 May 2020 10:18:16 +0000
|
||
|
Subject: [PATCH] WIP: media: rkvdec: continue to gate clock when decoding
|
||
|
finish
|
||
|
|
||
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||
|
---
|
||
|
drivers/staging/media/rkvdec/rkvdec.c | 6 ++++--
|
||
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
|
||
|
index d068383aeea8..5c03fdbd45ec 100644
|
||
|
--- a/drivers/staging/media/rkvdec/rkvdec.c
|
||
|
+++ b/drivers/staging/media/rkvdec/rkvdec.c
|
||
|
@@ -986,7 +986,8 @@ static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
|
||
|
state = (status & RKVDEC_RDY_STA) ?
|
||
|
VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
|
||
|
|
||
|
- writel(0, rkvdec->regs + RKVDEC_REG_INTERRUPT);
|
||
|
+ writel(RKVDEC_CONFIG_DEC_CLK_GATE_E,
|
||
|
+ rkvdec->regs + RKVDEC_REG_INTERRUPT);
|
||
|
if (cancel_delayed_work(&rkvdec->watchdog_work)) {
|
||
|
struct rkvdec_ctx *ctx;
|
||
|
|
||
|
@@ -1007,7 +1008,8 @@ static void rkvdec_watchdog_func(struct work_struct *work)
|
||
|
ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);
|
||
|
if (ctx) {
|
||
|
dev_err(rkvdec->dev, "Frame processing timed out!\n");
|
||
|
- writel(RKVDEC_IRQ_DIS, rkvdec->regs + RKVDEC_REG_INTERRUPT);
|
||
|
+ writel(RKVDEC_CONFIG_DEC_CLK_GATE_E | RKVDEC_IRQ_DIS,
|
||
|
+ rkvdec->regs + RKVDEC_REG_INTERRUPT);
|
||
|
writel(0, rkvdec->regs + RKVDEC_REG_SYSCTRL);
|
||
|
rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR);
|
||
|
}
|
||
|
|
||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Jonas Karlman <jonas@kwiboo.se>
|
||
|
Date: Sat, 23 May 2020 10:16:01 +0000
|
||
|
Subject: [PATCH] WIP: media: rkvdec: pm runtime dont use autosuspend before
|
||
|
disable and cleanup
|
||
|
|
||
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||
|
---
|
||
|
drivers/staging/media/rkvdec/rkvdec.c | 4 ++--
|
||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
|
||
|
index 5c03fdbd45ec..ad5e02bbd8d0 100644
|
||
|
--- a/drivers/staging/media/rkvdec/rkvdec.c
|
||
|
+++ b/drivers/staging/media/rkvdec/rkvdec.c
|
||
|
@@ -1105,9 +1105,9 @@ static int rkvdec_remove(struct platform_device *pdev)
|
||
|
{
|
||
|
struct rkvdec_dev *rkvdec = platform_get_drvdata(pdev);
|
||
|
|
||
|
- rkvdec_v4l2_cleanup(rkvdec);
|
||
|
- pm_runtime_disable(&pdev->dev);
|
||
|
pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||
|
+ pm_runtime_disable(&pdev->dev);
|
||
|
+ rkvdec_v4l2_cleanup(rkvdec);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Jonas Karlman <jonas@kwiboo.se>
|
||
|
Date: Sat, 23 May 2020 11:23:04 +0000
|
||
|
Subject: [PATCH] WIP: media: rkvdec: h264: return early when no reference
|
||
|
pictures
|
||
|
|
||
|
NOTE: also change from a switch statement to access reflists from a pointer array,
|
||
|
should simplify once we add support for field reference list
|
||
|
|
||
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||
|
---
|
||
|
drivers/staging/media/rkvdec/rkvdec-h264.c | 18 +++++-------------
|
||
|
1 file changed, 5 insertions(+), 13 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c
|
||
|
index c9a551dbd9bc..6ce11b736363 100644
|
||
|
--- a/drivers/staging/media/rkvdec/rkvdec-h264.c
|
||
|
+++ b/drivers/staging/media/rkvdec/rkvdec-h264.c
|
||
|
@@ -734,6 +734,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
|
||
|
const struct v4l2_ctrl_h264_sps *sps = run->sps;
|
||
|
struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu;
|
||
|
u32 max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4);
|
||
|
+ u8 *reflists[3] = { h264_ctx->reflists.p, h264_ctx->reflists.b0, h264_ctx->reflists.b1 };
|
||
|
|
||
|
u32 *hw_rps = priv_tbl->rps;
|
||
|
u32 i, j;
|
||
|
@@ -741,6 +742,9 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
|
||
|
|
||
|
memset(hw_rps, 0, sizeof(priv_tbl->rps));
|
||
|
|
||
|
+ if (!h264_ctx->reflists.num_valid)
|
||
|
+ return;
|
||
|
+
|
||
|
/*
|
||
|
* Assign an invalid pic_num if DPB entry at that position is inactive.
|
||
|
* If we assign 0 in that position hardware will treat that as a real
|
||
|
@@ -763,19 +767,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
|
||
|
for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
|
||
|
for (i = 0; i < h264_ctx->reflists.num_valid; i++) {
|
||
|
u8 dpb_valid = 0;
|
||
|
- u8 idx = 0;
|
||
|
-
|
||
|
- switch (j) {
|
||
|
- case 0:
|
||
|
- idx = h264_ctx->reflists.p[i];
|
||
|
- break;
|
||
|
- case 1:
|
||
|
- idx = h264_ctx->reflists.b0[i];
|
||
|
- break;
|
||
|
- case 2:
|
||
|
- idx = h264_ctx->reflists.b1[i];
|
||
|
- break;
|
||
|
- }
|
||
|
+ u8 idx = reflists[j][i];
|
||
|
|
||
|
if (idx >= ARRAY_SIZE(dec_params->dpb))
|
||
|
continue;
|
||
|
|
||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Jonas Karlman <jonas@kwiboo.se>
|
||
|
Date: Sat, 23 May 2020 14:42:27 +0000
|
||
|
Subject: [PATCH] WIP: media: rkvdec: h264: add field decoding support
|
||
|
|
||
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||
|
---
|
||
|
drivers/staging/media/rkvdec/rkvdec-h264.c | 79 ++++++++++++++++++----
|
||
|
1 file changed, 64 insertions(+), 15 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c
|
||
|
index 6ce11b736363..9c3f08c94800 100644
|
||
|
--- a/drivers/staging/media/rkvdec/rkvdec-h264.c
|
||
|
+++ b/drivers/staging/media/rkvdec/rkvdec-h264.c
|
||
|
@@ -737,7 +737,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
|
||
|
u8 *reflists[3] = { h264_ctx->reflists.p, h264_ctx->reflists.b0, h264_ctx->reflists.b1 };
|
||
|
|
||
|
u32 *hw_rps = priv_tbl->rps;
|
||
|
- u32 i, j;
|
||
|
+ u32 i, j, k;
|
||
|
u16 *p = (u16 *)hw_rps;
|
||
|
|
||
|
memset(hw_rps, 0, sizeof(priv_tbl->rps));
|
||
|
@@ -764,18 +764,71 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
|
||
|
p[i] = dpb[i].frame_num - max_frame_num;
|
||
|
}
|
||
|
|
||
|
- for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
|
||
|
- for (i = 0; i < h264_ctx->reflists.num_valid; i++) {
|
||
|
- u8 dpb_valid = 0;
|
||
|
- u8 idx = reflists[j][i];
|
||
|
+ if (!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC)) {
|
||
|
+ for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
|
||
|
+ for (i = 0; i < h264_ctx->reflists.num_valid; i++) {
|
||
|
+ u8 dpb_valid = 0;
|
||
|
+ u8 idx = reflists[j][i];
|
||
|
|
||
|
- if (idx >= ARRAY_SIZE(dec_params->dpb))
|
||
|
- continue;
|
||
|
- dpb_valid = !!(dpb[idx].flags &
|
||
|
- V4L2_H264_DPB_ENTRY_FLAG_ACTIVE);
|
||
|
+ if (idx >= ARRAY_SIZE(dec_params->dpb))
|
||
|
+ continue;
|
||
|
+ dpb_valid = !!(dpb[idx].flags &
|
||
|
+ V4L2_H264_DPB_ENTRY_FLAG_ACTIVE);
|
||
|
|
||
|
- set_ps_field(hw_rps, DPB_INFO(i, j),
|
||
|
- idx | dpb_valid << 4);
|
||
|
+ set_ps_field(hw_rps, DPB_INFO(i, j),
|
||
|
+ idx | dpb_valid << 4);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
|
||
|
+ enum v4l2_h264_field_reference a_parity =
|
||
|
+ (dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD)
|
||
|
+ ? V4L2_H264_BOTTOM_FIELD_REF : V4L2_H264_TOP_FIELD_REF;
|
||
|
+ enum v4l2_h264_field_reference b_parity =
|
||
|
+ (dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD)
|
||
|
+ ? V4L2_H264_TOP_FIELD_REF : V4L2_H264_BOTTOM_FIELD_REF;
|
||
|
+ u32 flags = V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM;
|
||
|
+ i = 0;
|
||
|
+
|
||
|
+ for (k = 0; k < 2; k++) {
|
||
|
+ u8 a = 0;
|
||
|
+ u8 b = 0;
|
||
|
+ u32 long_term = k ? V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM : 0;
|
||
|
+
|
||
|
+ while (a < h264_ctx->reflists.num_valid || b < h264_ctx->reflists.num_valid) {
|
||
|
+ for (; a < h264_ctx->reflists.num_valid; a++) {
|
||
|
+ u8 idx = reflists[j][a];
|
||
|
+ if (idx >= ARRAY_SIZE(dec_params->dpb))
|
||
|
+ continue;
|
||
|
+ if ((dpb[idx].reference & a_parity) == a_parity &&
|
||
|
+ (dpb[idx].flags & flags) == long_term) {
|
||
|
+ set_ps_field(hw_rps, DPB_INFO(i, j),
|
||
|
+ idx | (1 << 4));
|
||
|
+ set_ps_field(hw_rps, BOTTOM_FLAG(i, j),
|
||
|
+ a_parity == V4L2_H264_BOTTOM_FIELD_REF);
|
||
|
+ i++;
|
||
|
+ a++;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ for (; b < h264_ctx->reflists.num_valid; b++) {
|
||
|
+ u8 idx = reflists[j][b];
|
||
|
+ if (idx >= ARRAY_SIZE(dec_params->dpb))
|
||
|
+ continue;
|
||
|
+ if ((dpb[idx].reference & b_parity) == b_parity &&
|
||
|
+ (dpb[idx].flags & flags) == long_term) {
|
||
|
+ set_ps_field(hw_rps, DPB_INFO(i, j),
|
||
|
+ idx | (1 << 4));
|
||
|
+ set_ps_field(hw_rps, BOTTOM_FLAG(i, j),
|
||
|
+ b_parity == V4L2_H264_BOTTOM_FIELD_REF);
|
||
|
+ i++;
|
||
|
+ b++;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
@@ -968,10 +1021,6 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
||
|
rkvdec->regs + RKVDEC_REG_H264_BASE_REFER15);
|
||
|
}
|
||
|
|
||
|
- /*
|
||
|
- * Since support frame mode only
|
||
|
- * top_field_order_cnt is the same as bottom_field_order_cnt
|
||
|
- */
|
||
|
reg = RKVDEC_CUR_POC(dec_params->top_field_order_cnt);
|
||
|
writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_CUR_POC0);
|
||
|
|
||
|
|
||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Jonas Karlman <jonas@kwiboo.se>
|
||
|
Date: Tue, 29 Oct 2019 01:26:02 +0000
|
||
|
Subject: [PATCH] RFC: media: hantro: Fix H264 decoding of field encoded
|
||
|
content
|
||
|
|
||
|
This still need code cleanup and formatting
|
||
|
|
||
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||
|
---
|
||
|
drivers/staging/media/hantro/hantro_h264.c | 91 ++++++++++++++++------
|
||
|
1 file changed, 69 insertions(+), 22 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c
|
||
|
index 0b4d2491be3b..7b56a68c176c 100644
|
||
|
--- a/drivers/staging/media/hantro/hantro_h264.c
|
||
|
+++ b/drivers/staging/media/hantro/hantro_h264.c
|
||
|
@@ -227,30 +227,67 @@ static void prepare_table(struct hantro_ctx *ctx)
|
||
|
{
|
||
|
const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls;
|
||
|
const struct v4l2_ctrl_h264_decode_params *dec_param = ctrls->decode;
|
||
|
+ const struct v4l2_ctrl_h264_sps *sps = ctrls->sps;
|
||
|
struct hantro_h264_dec_priv_tbl *tbl = ctx->h264_dec.priv.cpu;
|
||
|
const struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb;
|
||
|
u32 dpb_longterm = 0;
|
||
|
u32 dpb_valid = 0;
|
||
|
int i;
|
||
|
|
||
|
- for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) {
|
||
|
- tbl->poc[i * 2] = dpb[i].top_field_order_cnt;
|
||
|
- tbl->poc[i * 2 + 1] = dpb[i].bottom_field_order_cnt;
|
||
|
+ /*
|
||
|
+ * Set up bit maps of valid and long term DPBs.
|
||
|
+ * NOTE: The bits are reversed, i.e. MSb is DPB 0.
|
||
|
+ */
|
||
|
+ if ((dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) || (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)) {
|
||
|
+ for (i = 0; i < HANTRO_H264_DPB_SIZE * 2; ++i) {
|
||
|
+ // check for correct reference use
|
||
|
+ enum v4l2_h264_field_reference parity = (i & 0x1) ?
|
||
|
+ V4L2_H264_BOTTOM_FIELD_REF : V4L2_H264_TOP_FIELD_REF;
|
||
|
+ if (dpb[i / 2].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE &&
|
||
|
+ dpb[i / 2].reference & parity)
|
||
|
+ dpb_valid |= BIT(HANTRO_H264_DPB_SIZE * 2 - 1 - i);
|
||
|
+
|
||
|
+ if (dpb[i / 2].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
|
||
|
+ dpb_longterm |= BIT(HANTRO_H264_DPB_SIZE * 2 - 1 - i);
|
||
|
+ }
|
||
|
|
||
|
- /*
|
||
|
- * Set up bit maps of valid and long term DPBs.
|
||
|
- * NOTE: The bits are reversed, i.e. MSb is DPB 0.
|
||
|
- */
|
||
|
- if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
|
||
|
- dpb_valid |= BIT(HANTRO_H264_DPB_SIZE - 1 - i);
|
||
|
- if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
|
||
|
- dpb_longterm |= BIT(HANTRO_H264_DPB_SIZE - 1 - i);
|
||
|
+ ctx->h264_dec.dpb_valid = dpb_valid;
|
||
|
+ ctx->h264_dec.dpb_longterm = dpb_longterm;
|
||
|
+ } else {
|
||
|
+ for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) {
|
||
|
+ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
|
||
|
+ dpb_valid |= BIT(HANTRO_H264_DPB_SIZE - 1 - i);
|
||
|
+
|
||
|
+ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
|
||
|
+ dpb_longterm |= BIT(HANTRO_H264_DPB_SIZE - 1 - i);
|
||
|
+ }
|
||
|
+
|
||
|
+ ctx->h264_dec.dpb_valid = dpb_valid << 16;
|
||
|
+ ctx->h264_dec.dpb_longterm = dpb_longterm << 16;
|
||
|
}
|
||
|
- ctx->h264_dec.dpb_valid = dpb_valid << 16;
|
||
|
- ctx->h264_dec.dpb_longterm = dpb_longterm << 16;
|
||
|
|
||
|
- tbl->poc[32] = dec_param->top_field_order_cnt;
|
||
|
- tbl->poc[33] = dec_param->bottom_field_order_cnt;
|
||
|
+ for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) {
|
||
|
+ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) {
|
||
|
+ tbl->poc[i * 2] = dpb[i].top_field_order_cnt;
|
||
|
+ tbl->poc[i * 2 + 1] = dpb[i].bottom_field_order_cnt;
|
||
|
+ } else {
|
||
|
+ tbl->poc[i * 2] = 0;
|
||
|
+ tbl->poc[i * 2 + 1] = 0;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) || !(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)) {
|
||
|
+ if ((dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC))
|
||
|
+ tbl->poc[32] = (dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) ?
|
||
|
+ dec_param->bottom_field_order_cnt :
|
||
|
+ dec_param->top_field_order_cnt;
|
||
|
+ else
|
||
|
+ tbl->poc[32] = min(dec_param->top_field_order_cnt, dec_param->bottom_field_order_cnt);
|
||
|
+ tbl->poc[33] = 0;
|
||
|
+ } else {
|
||
|
+ tbl->poc[32] = dec_param->top_field_order_cnt;
|
||
|
+ tbl->poc[33] = dec_param->bottom_field_order_cnt;
|
||
|
+ };
|
||
|
|
||
|
assemble_scaling_list(ctx);
|
||
|
}
|
||
|
@@ -258,8 +295,7 @@ static void prepare_table(struct hantro_ctx *ctx)
|
||
|
static bool dpb_entry_match(const struct v4l2_h264_dpb_entry *a,
|
||
|
const struct v4l2_h264_dpb_entry *b)
|
||
|
{
|
||
|
- return a->top_field_order_cnt == b->top_field_order_cnt &&
|
||
|
- a->bottom_field_order_cnt == b->bottom_field_order_cnt;
|
||
|
+ return a->reference_ts == b->reference_ts;
|
||
|
}
|
||
|
|
||
|
static void update_dpb(struct hantro_ctx *ctx)
|
||
|
@@ -273,13 +309,13 @@ static void update_dpb(struct hantro_ctx *ctx)
|
||
|
|
||
|
/* Disable all entries by default. */
|
||
|
for (i = 0; i < ARRAY_SIZE(ctx->h264_dec.dpb); i++)
|
||
|
- ctx->h264_dec.dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
|
||
|
+ ctx->h264_dec.dpb[i].flags = 0;
|
||
|
|
||
|
/* Try to match new DPB entries with existing ones by their POCs. */
|
||
|
for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
|
||
|
const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
|
||
|
|
||
|
- if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
|
||
|
+ if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_VALID))
|
||
|
continue;
|
||
|
|
||
|
/*
|
||
|
@@ -290,8 +326,7 @@ static void update_dpb(struct hantro_ctx *ctx)
|
||
|
struct v4l2_h264_dpb_entry *cdpb;
|
||
|
|
||
|
cdpb = &ctx->h264_dec.dpb[j];
|
||
|
- if (cdpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE ||
|
||
|
- !dpb_entry_match(cdpb, ndpb))
|
||
|
+ if (!dpb_entry_match(cdpb, ndpb))
|
||
|
continue;
|
||
|
|
||
|
*cdpb = *ndpb;
|
||
|
@@ -327,7 +362,10 @@ dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
|
||
|
unsigned int dpb_idx)
|
||
|
{
|
||
|
struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb;
|
||
|
+ const struct v4l2_ctrl_h264_decode_params *dec_param = ctx->h264_dec.ctrls.decode;
|
||
|
dma_addr_t dma_addr = 0;
|
||
|
+ s32 cur_poc;
|
||
|
+ u32 flags;
|
||
|
|
||
|
if (dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
|
||
|
dma_addr = hantro_get_ref(ctx, dpb[dpb_idx].reference_ts);
|
||
|
@@ -345,7 +383,16 @@ dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
|
||
|
dma_addr = hantro_get_dec_buf_addr(ctx, buf);
|
||
|
}
|
||
|
|
||
|
- return dma_addr;
|
||
|
+ cur_poc = dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD ?
|
||
|
+ dec_param->bottom_field_order_cnt :
|
||
|
+ dec_param->top_field_order_cnt;
|
||
|
+ flags = dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD ? 0x2 : 0;
|
||
|
+ flags |= abs(dpb[dpb_idx].top_field_order_cnt - cur_poc) <
|
||
|
+ abs(dpb[dpb_idx].bottom_field_order_cnt - cur_poc) ?
|
||
|
+ 0x1 : 0;
|
||
|
+
|
||
|
+ return dma_addr | flags;
|
||
|
+
|
||
|
}
|
||
|
|
||
|
u16 hantro_h264_get_ref_nbr(struct hantro_ctx *ctx, unsigned int dpb_idx)
|
||
|
|
||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Alex Bee <knaerzche@gmail.com>
|
||
|
Date: Wed, 14 Oct 2020 13:27:12 +0200
|
||
|
Subject: [PATCH] media: hantro: adapt to match 5.11 H.264 uapi changes
|
||
|
|
||
|
Signed-off-by: Alex Bee <knaerzche@gmail.com>
|
||
|
---
|
||
|
drivers/staging/media/hantro/hantro_h264.c | 4 ++--
|
||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c
|
||
|
index 7b56a68c176c..befa69d5c855 100644
|
||
|
--- a/drivers/staging/media/hantro/hantro_h264.c
|
||
|
+++ b/drivers/staging/media/hantro/hantro_h264.c
|
||
|
@@ -241,10 +241,10 @@ static void prepare_table(struct hantro_ctx *ctx)
|
||
|
if ((dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) || (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)) {
|
||
|
for (i = 0; i < HANTRO_H264_DPB_SIZE * 2; ++i) {
|
||
|
// check for correct reference use
|
||
|
- enum v4l2_h264_field_reference parity = (i & 0x1) ?
|
||
|
+ u8 parity = (i & 0x1) ?
|
||
|
V4L2_H264_BOTTOM_FIELD_REF : V4L2_H264_TOP_FIELD_REF;
|
||
|
if (dpb[i / 2].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE &&
|
||
|
- dpb[i / 2].reference & parity)
|
||
|
+ dpb[i / 2].fields & parity)
|
||
|
dpb_valid |= BIT(HANTRO_H264_DPB_SIZE * 2 - 1 - i);
|
||
|
|
||
|
if (dpb[i / 2].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
|
||
|
|
||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Alex Bee <knaerzche@gmail.com>
|
||
|
Date: Wed, 14 Oct 2020 13:42:01 +0200
|
||
|
Subject: [PATCH] media: rkvdec: adapt to match 5.11 H.264 uapi changes
|
||
|
|
||
|
Signed-off-by: Alex Bee <knaerzche@gmail.com>
|
||
|
---
|
||
|
drivers/staging/media/rkvdec/rkvdec-h264.c | 8 ++++----
|
||
|
1 file changed, 4 insertions(+), 4 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c
|
||
|
index 9c3f08c94800..7238117b6cf4 100644
|
||
|
--- a/drivers/staging/media/rkvdec/rkvdec-h264.c
|
||
|
+++ b/drivers/staging/media/rkvdec/rkvdec-h264.c
|
||
|
@@ -783,10 +783,10 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
|
||
|
}
|
||
|
|
||
|
for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
|
||
|
- enum v4l2_h264_field_reference a_parity =
|
||
|
+ u8 a_parity =
|
||
|
(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD)
|
||
|
? V4L2_H264_BOTTOM_FIELD_REF : V4L2_H264_TOP_FIELD_REF;
|
||
|
- enum v4l2_h264_field_reference b_parity =
|
||
|
+ u8 b_parity =
|
||
|
(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD)
|
||
|
? V4L2_H264_TOP_FIELD_REF : V4L2_H264_BOTTOM_FIELD_REF;
|
||
|
u32 flags = V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM;
|
||
|
@@ -802,7 +802,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
|
||
|
u8 idx = reflists[j][a];
|
||
|
if (idx >= ARRAY_SIZE(dec_params->dpb))
|
||
|
continue;
|
||
|
- if ((dpb[idx].reference & a_parity) == a_parity &&
|
||
|
+ if ((dpb[idx].fields & a_parity) == a_parity &&
|
||
|
(dpb[idx].flags & flags) == long_term) {
|
||
|
set_ps_field(hw_rps, DPB_INFO(i, j),
|
||
|
idx | (1 << 4));
|
||
|
@@ -817,7 +817,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
|
||
|
u8 idx = reflists[j][b];
|
||
|
if (idx >= ARRAY_SIZE(dec_params->dpb))
|
||
|
continue;
|
||
|
- if ((dpb[idx].reference & b_parity) == b_parity &&
|
||
|
+ if ((dpb[idx].fields & b_parity) == b_parity &&
|
||
|
(dpb[idx].flags & flags) == long_term) {
|
||
|
set_ps_field(hw_rps, DPB_INFO(i, j),
|
||
|
idx | (1 << 4));
|
||
|
|
||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Randy Li <ayaka@soulik.info>
|
||
|
Date: Sun, 6 Jan 2019 01:48:37 +0800
|
||
|
Subject: [PATCH] soc: rockchip: power-domain: export idle request
|
||
|
|
||
|
We need to put the power status of HEVC IP into IDLE unless
|
||
|
we can't reset that IP or the SoC would crash down.
|
||
|
rockchip_pmu_idle_request(dev, true)---> enter idle
|
||
|
rockchip_pmu_idle_request(dev, false)---> exit idle
|
||
|
|
||
|
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
|
||
|
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
|
||
|
Signed-off-by: Randy Li <ayaka@soulik.info>
|
||
|
---
|
||
|
drivers/soc/rockchip/pm_domains.c | 23 +++++++++++++++++++++++
|
||
|
include/linux/rockchip_pmu.h | 15 +++++++++++++++
|
||
|
include/soc/rockchip/pm_domains.h | 18 ++++++++++++++++++
|
||
|
3 files changed, 56 insertions(+)
|
||
|
create mode 100644 include/linux/rockchip_pmu.h
|
||
|
create mode 100644 include/soc/rockchip/pm_domains.h
|
||
|
|
||
|
diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
|
||
|
index 0868b7d406fb..fddb4022c376 100644
|
||
|
--- a/drivers/soc/rockchip/pm_domains.c
|
||
|
+++ b/drivers/soc/rockchip/pm_domains.c
|
||
|
@@ -204,6 +204,29 @@ static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+int rockchip_pmu_idle_request(struct device *dev, bool idle)
|
||
|
+{
|
||
|
+ struct generic_pm_domain *genpd;
|
||
|
+ struct rockchip_pm_domain *pd;
|
||
|
+ int ret;
|
||
|
+
|
||
|
+ if (IS_ERR_OR_NULL(dev))
|
||
|
+ return -EINVAL;
|
||
|
+
|
||
|
+ if (IS_ERR_OR_NULL(dev->pm_domain))
|
||
|
+ return -EINVAL;
|
||
|
+
|
||
|
+ genpd = pd_to_genpd(dev->pm_domain);
|
||
|
+ pd = to_rockchip_pd(genpd);
|
||
|
+
|
||
|
+ mutex_lock(&pd->pmu->mutex);
|
||
|
+ ret = rockchip_pmu_set_idle_request(pd, idle);
|
||
|
+ mutex_unlock(&pd->pmu->mutex);
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+EXPORT_SYMBOL(rockchip_pmu_idle_request);
|
||
|
+
|
||
|
static int rockchip_pmu_save_qos(struct rockchip_pm_domain *pd)
|
||
|
{
|
||
|
int i;
|
||
|
diff --git a/include/linux/rockchip_pmu.h b/include/linux/rockchip_pmu.h
|
||
|
new file mode 100644
|
||
|
index 000000000000..720b3314e71a
|
||
|
--- /dev/null
|
||
|
+++ b/include/linux/rockchip_pmu.h
|
||
|
@@ -0,0 +1,15 @@
|
||
|
+/*
|
||
|
+ * pm_domain.h - Definitions and headers related to device power domains.
|
||
|
+ *
|
||
|
+ * Copyright (C) 2017 Randy Li <ayaka@soulik.info>.
|
||
|
+ *
|
||
|
+ * This file is released under the GPLv2.
|
||
|
+ */
|
||
|
+
|
||
|
+#ifndef _LINUX_ROCKCHIP_PM_H
|
||
|
+#define _LINUX_ROCKCHIP_PM_H
|
||
|
+#include <linux/device.h>
|
||
|
+
|
||
|
+int rockchip_pmu_idle_request(struct device *dev, bool idle);
|
||
|
+
|
||
|
+#endif /* _LINUX_ROCKCHIP_PM_H */
|
||
|
diff --git a/include/soc/rockchip/pm_domains.h b/include/soc/rockchip/pm_domains.h
|
||
|
new file mode 100644
|
||
|
index 000000000000..690db6118636
|
||
|
--- /dev/null
|
||
|
+++ b/include/soc/rockchip/pm_domains.h
|
||
|
@@ -0,0 +1,18 @@
|
||
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
||
|
+#ifndef __SOC_ROCKCHIP_PM_DOMAINS_H
|
||
|
+#define __SOC_ROCKCHIP_PM_DOMAINS_H
|
||
|
+
|
||
|
+#include <linux/errno.h>
|
||
|
+
|
||
|
+struct device;
|
||
|
+
|
||
|
+#ifdef CONFIG_ROCKCHIP_PM_DOMAINS
|
||
|
+int rockchip_pmu_idle_request(struct device *dev, bool idle);
|
||
|
+#else
|
||
|
+static inline int rockchip_pmu_idle_request(struct device *dev, bool idle)
|
||
|
+{
|
||
|
+ return -ENOTSUPP;
|
||
|
+}
|
||
|
+#endif
|
||
|
+
|
||
|
+#endif
|
||
|
|
||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Alex Bee <knaerzche@gmail.com>
|
||
|
Date: Wed, 20 May 2020 17:04:47 +0200
|
||
|
Subject: [PATCH] WIP: media: rkvdec: implement reset controls
|
||
|
|
||
|
---
|
||
|
.../bindings/media/rockchip,vdec.yaml | 19 +++++++
|
||
|
drivers/staging/media/rkvdec/rkvdec-regs.h | 5 ++
|
||
|
drivers/staging/media/rkvdec/rkvdec.c | 53 +++++++++++++++++++
|
||
|
drivers/staging/media/rkvdec/rkvdec.h | 11 +++-
|
||
|
4 files changed, 87 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml
|
||
|
index 089f11d21b25..3f4772c8d095 100644
|
||
|
--- a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml
|
||
|
+++ b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml
|
||
|
@@ -51,6 +51,18 @@ properties:
|
||
|
iommus:
|
||
|
maxItems: 1
|
||
|
|
||
|
+ resets:
|
||
|
+ maxItems: 6
|
||
|
+
|
||
|
+ reset-names:
|
||
|
+ items:
|
||
|
+ - const: video_h
|
||
|
+ - const: video_a
|
||
|
+ - const: video_core
|
||
|
+ - const: video_cabac
|
||
|
+ - const: niu_a
|
||
|
+ - const: niu_h
|
||
|
+
|
||
|
required:
|
||
|
- compatible
|
||
|
- reg
|
||
|
@@ -58,6 +70,8 @@ required:
|
||
|
- clocks
|
||
|
- clock-names
|
||
|
- power-domains
|
||
|
+ - resets
|
||
|
+ - reset-names
|
||
|
|
||
|
additionalProperties: false
|
||
|
|
||
|
@@ -76,6 +90,11 @@ examples:
|
||
|
clock-names = "axi", "ahb", "cabac", "core";
|
||
|
power-domains = <&power RK3399_PD_VDU>;
|
||
|
iommus = <&vdec_mmu>;
|
||
|
+ resets = <&cru SRST_H_VDU>, <&cru SRST_A_VDU>,
|
||
|
+ <&cru SRST_VDU_CORE>, <&cru SRST_VDU_CA>,
|
||
|
+ <&cru SRST_A_VDU_NOC>, <&cru SRST_H_VDU_NOC>;
|
||
|
+ reset-names = "video_h", "video_a", "video_core", "video_cabac",
|
||
|
+ "niu_a", "niu_h";
|
||
|
};
|
||
|
|
||
|
...
|
||
|
diff --git a/drivers/staging/media/rkvdec/rkvdec-regs.h b/drivers/staging/media/rkvdec/rkvdec-regs.h
|
||
|
index 15b9bee92016..3acc914888f6 100644
|
||
|
--- a/drivers/staging/media/rkvdec/rkvdec-regs.h
|
||
|
+++ b/drivers/staging/media/rkvdec/rkvdec-regs.h
|
||
|
@@ -28,6 +28,11 @@
|
||
|
#define RKVDEC_SOFTRST_EN_P BIT(20)
|
||
|
#define RKVDEC_FORCE_SOFTRESET_VALID BIT(21)
|
||
|
#define RKVDEC_SOFTRESET_RDY BIT(22)
|
||
|
+#define RKVDEC_ERR_MASK (RKVDEC_BUS_STA \
|
||
|
+ | RKVDEC_ERR_STA \
|
||
|
+ | RKVDEC_TIMEOUT_STA \
|
||
|
+ | RKVDEC_BUF_EMPTY_STA \
|
||
|
+ | RKVDEC_COLMV_REF_ERR_STA )
|
||
|
|
||
|
#define RKVDEC_REG_SYSCTRL 0x008
|
||
|
#define RKVDEC_IN_ENDIAN BIT(0)
|
||
|
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
|
||
|
index ad5e02bbd8d0..6abce36eee7f 100644
|
||
|
--- a/drivers/staging/media/rkvdec/rkvdec.c
|
||
|
+++ b/drivers/staging/media/rkvdec/rkvdec.c
|
||
|
@@ -10,12 +10,15 @@
|
||
|
*/
|
||
|
|
||
|
#include <linux/clk.h>
|
||
|
+#include <linux/delay.h>
|
||
|
#include <linux/interrupt.h>
|
||
|
#include <linux/module.h>
|
||
|
#include <linux/of.h>
|
||
|
#include <linux/platform_device.h>
|
||
|
#include <linux/pm.h>
|
||
|
#include <linux/pm_runtime.h>
|
||
|
+#include <linux/reset.h>
|
||
|
+#include <linux/rockchip_pmu.h>
|
||
|
#include <linux/slab.h>
|
||
|
#include <linux/videodev2.h>
|
||
|
#include <linux/workqueue.h>
|
||
|
@@ -687,6 +690,11 @@ static void rkvdec_job_finish(struct rkvdec_ctx *ctx,
|
||
|
|
||
|
pm_runtime_mark_last_busy(rkvdec->dev);
|
||
|
pm_runtime_put_autosuspend(rkvdec->dev);
|
||
|
+
|
||
|
+ if (result == VB2_BUF_STATE_ERROR &&
|
||
|
+ rkvdec->reset_mask == RESET_NONE)
|
||
|
+ rkvdec->reset_mask |= RESET_SOFT;
|
||
|
+
|
||
|
rkvdec_job_finish_no_pm(ctx, result);
|
||
|
}
|
||
|
|
||
|
@@ -724,6 +732,33 @@ static void rkvdec_device_run(void *priv)
|
||
|
|
||
|
if (WARN_ON(!desc))
|
||
|
return;
|
||
|
+ if (rkvdec->reset_mask != RESET_NONE) {
|
||
|
+
|
||
|
+ if (rkvdec->reset_mask & RESET_SOFT) {
|
||
|
+ writel(RKVDEC_SOFTRST_EN_P,
|
||
|
+ rkvdec->regs + RKVDEC_REG_INTERRUPT);
|
||
|
+ udelay(RKVDEC_RESET_DELAY);
|
||
|
+ if (readl(rkvdec->regs + RKVDEC_REG_INTERRUPT)
|
||
|
+ & RKVDEC_SOFTRESET_RDY)
|
||
|
+ dev_info_ratelimited(rkvdec->dev,
|
||
|
+ "softreset failed\n");
|
||
|
+ }
|
||
|
+
|
||
|
+ if (rkvdec->reset_mask & RESET_HARD) {
|
||
|
+ rockchip_pmu_idle_request(rkvdec->dev, true);
|
||
|
+ ret = reset_control_assert(rkvdec->rstc);
|
||
|
+ if (!ret) {
|
||
|
+ udelay(RKVDEC_RESET_DELAY);
|
||
|
+ ret = reset_control_deassert(rkvdec->rstc);
|
||
|
+ }
|
||
|
+ rockchip_pmu_idle_request(rkvdec->dev, false);
|
||
|
+ if (ret)
|
||
|
+ dev_notice_ratelimited(rkvdec->dev,
|
||
|
+ "hardreset failed\n");
|
||
|
+ }
|
||
|
+ rkvdec->reset_mask = RESET_NONE;
|
||
|
+ pm_runtime_suspend(rkvdec->dev);
|
||
|
+ }
|
||
|
|
||
|
ret = pm_runtime_resume_and_get(rkvdec->dev);
|
||
|
if (ret < 0) {
|
||
|
@@ -991,6 +1026,11 @@ static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
|
||
|
if (cancel_delayed_work(&rkvdec->watchdog_work)) {
|
||
|
struct rkvdec_ctx *ctx;
|
||
|
|
||
|
+ if (state == VB2_BUF_STATE_ERROR) {
|
||
|
+ rkvdec->reset_mask |= (status & RKVDEC_ERR_MASK) ?
|
||
|
+ RESET_HARD : RESET_SOFT;
|
||
|
+ }
|
||
|
+
|
||
|
ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);
|
||
|
rkvdec_job_finish(ctx, state);
|
||
|
}
|
||
|
@@ -1008,6 +1048,7 @@ static void rkvdec_watchdog_func(struct work_struct *work)
|
||
|
ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);
|
||
|
if (ctx) {
|
||
|
dev_err(rkvdec->dev, "Frame processing timed out!\n");
|
||
|
+ rkvdec->reset_mask |= RESET_HARD;
|
||
|
writel(RKVDEC_CONFIG_DEC_CLK_GATE_E | RKVDEC_IRQ_DIS,
|
||
|
rkvdec->regs + RKVDEC_REG_INTERRUPT);
|
||
|
writel(0, rkvdec->regs + RKVDEC_REG_SYSCTRL);
|
||
|
@@ -1085,6 +1126,18 @@ static int rkvdec_probe(struct platform_device *pdev)
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
+
|
||
|
+ rkvdec->rstc = devm_reset_control_array_get(&pdev->dev, false, true);
|
||
|
+ if (IS_ERR(rkvdec->rstc)) {
|
||
|
+ dev_err(&pdev->dev,
|
||
|
+ "get resets failed %ld\n", PTR_ERR(rkvdec->rstc));
|
||
|
+ return PTR_ERR(rkvdec->rstc);
|
||
|
+ } else {
|
||
|
+ dev_dbg(&pdev->dev,
|
||
|
+ "requested %d resets\n",
|
||
|
+ reset_control_get_count(&pdev->dev));
|
||
|
+ }
|
||
|
+
|
||
|
pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
|
||
|
pm_runtime_use_autosuspend(&pdev->dev);
|
||
|
pm_runtime_enable(&pdev->dev);
|
||
|
diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h
|
||
|
index 7b6f44ee8a1a..fa24bcb6ff42 100644
|
||
|
--- a/drivers/staging/media/rkvdec/rkvdec.h
|
||
|
+++ b/drivers/staging/media/rkvdec/rkvdec.h
|
||
|
@@ -11,10 +11,11 @@
|
||
|
#ifndef RKVDEC_H_
|
||
|
#define RKVDEC_H_
|
||
|
|
||
|
+#include <linux/clk.h>
|
||
|
#include <linux/platform_device.h>
|
||
|
+#include <linux/reset.h>
|
||
|
#include <linux/videodev2.h>
|
||
|
#include <linux/wait.h>
|
||
|
-#include <linux/clk.h>
|
||
|
|
||
|
#include <media/v4l2-ctrls.h>
|
||
|
#include <media/v4l2-device.h>
|
||
|
@@ -22,6 +23,12 @@
|
||
|
#include <media/videobuf2-core.h>
|
||
|
#include <media/videobuf2-dma-contig.h>
|
||
|
|
||
|
+#define RESET_NONE 0
|
||
|
+#define RESET_SOFT BIT(0)
|
||
|
+#define RESET_HARD BIT(1)
|
||
|
+
|
||
|
+#define RKVDEC_RESET_DELAY 5
|
||
|
+
|
||
|
struct rkvdec_ctx;
|
||
|
|
||
|
struct rkvdec_ctrl_desc {
|
||
|
@@ -90,6 +97,8 @@ struct rkvdec_dev {
|
||
|
void __iomem *regs;
|
||
|
struct mutex vdev_lock; /* serializes ioctls */
|
||
|
struct delayed_work watchdog_work;
|
||
|
+ struct reset_control *rstc;
|
||
|
+ u8 reset_mask;
|
||
|
};
|
||
|
|
||
|
struct rkvdec_ctx {
|
||
|
|
||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Alex Bee <knaerzche@gmail.com>
|
||
|
Date: Tue, 18 Aug 2020 11:38:04 +0200
|
||
|
Subject: [PATCH] WIP: arm64: dts: add resets to vdec for RK3399
|
||
|
|
||
|
---
|
||
|
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 10 +++++++++-
|
||
|
1 file changed, 9 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
||
|
index 52a748053a97..2c7b263a82cd 100644
|
||
|
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
||
|
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
||
|
@@ -993,7 +993,10 @@ power-domain@RK3399_PD_VCODEC {
|
||
|
power-domain@RK3399_PD_VDU {
|
||
|
reg = <RK3399_PD_VDU>;
|
||
|
clocks = <&cru ACLK_VDU>,
|
||
|
- <&cru HCLK_VDU>;
|
||
|
+ <&cru HCLK_VDU>,
|
||
|
+ <&cru SCLK_VDU_CA>,
|
||
|
+ <&cru SCLK_VDU_CORE>;
|
||
|
+
|
||
|
pm_qos = <&qos_video_m1_r>,
|
||
|
<&qos_video_m1_w>;
|
||
|
#power-domain-cells = <0>;
|
||
|
@@ -1266,6 +1269,11 @@ vdec: video-codec@ff660000 {
|
||
|
clock-names = "axi", "ahb", "cabac", "core";
|
||
|
iommus = <&vdec_mmu>;
|
||
|
power-domains = <&power RK3399_PD_VDU>;
|
||
|
+ resets = <&cru SRST_H_VDU>, <&cru SRST_A_VDU>,
|
||
|
+ <&cru SRST_VDU_CORE>, <&cru SRST_VDU_CA>,
|
||
|
+ <&cru SRST_A_VDU_NOC>, <&cru SRST_H_VDU_NOC>;
|
||
|
+ reset-names = "video_h", "video_a", "video_core", "video_cabac",
|
||
|
+ "niu_a", "niu_h";
|
||
|
};
|
||
|
|
||
|
vdec_mmu: iommu@ff660480 {
|
||
|
|
||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Alex Bee <knaerzche@gmail.com>
|
||
|
Date: Fri, 1 Jan 2021 12:11:12 +0200
|
||
|
Subject: [PATCH] arm64: dts: rockchip: fix RK3399 vdec register witdh
|
||
|
|
||
|
Signed-off-by: Alex Bee <knaerzche@gmail.com>
|
||
|
---
|
||
|
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 2 +-
|
||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
||
|
index 2c7b263a82cd..ec3561d147d5 100644
|
||
|
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
||
|
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
||
|
@@ -1262,7 +1262,7 @@ vpu_mmu: iommu@ff650800 {
|
||
|
|
||
|
vdec: video-codec@ff660000 {
|
||
|
compatible = "rockchip,rk3399-vdec";
|
||
|
- reg = <0x0 0xff660000 0x0 0x400>;
|
||
|
+ reg = <0x0 0xff660000 0x0 0x480>;
|
||
|
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>;
|
||
|
clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>,
|
||
|
<&cru SCLK_VDU_CA>, <&cru SCLK_VDU_CORE>;
|
||
|
|
||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Alex Bee <knaerzche@gmail.com>
|
||
|
Date: Wed, 19 Aug 2020 21:12:54 +0200
|
||
|
Subject: [PATCH] arm64: dts: rockchip: add rkvdec node for RK3328
|
||
|
|
||
|
Signed-off-by: Alex Bee <knaerzche@gmail.com>
|
||
|
---
|
||
|
.../bindings/media/rockchip,vdec.yaml | 3 +++
|
||
|
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 25 ++++++++++++++++++-
|
||
|
2 files changed, 27 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml
|
||
|
index 3f4772c8d095..21a78372dae6 100644
|
||
|
--- a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml
|
||
|
+++ b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml
|
||
|
@@ -20,6 +20,9 @@ properties:
|
||
|
- items:
|
||
|
- const: rockchip,rk3228-vdec
|
||
|
- const: rockchip,rk3399-vdec
|
||
|
+ - items:
|
||
|
+ - const: rockchip,rk3328-vdec
|
||
|
+ - const: rockchip,rk3399-vdec
|
||
|
|
||
|
reg:
|
||
|
maxItems: 1
|
||
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
|
||
|
index 9c10b6e3b9bc..23021373e15b 100644
|
||
|
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
|
||
|
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
|
||
|
@@ -306,6 +306,10 @@ power-domain@RK3328_PD_HEVC {
|
||
|
};
|
||
|
power-domain@RK3328_PD_VIDEO {
|
||
|
reg = <RK3328_PD_VIDEO>;
|
||
|
+ clocks = <&cru ACLK_RKVDEC>,
|
||
|
+ <&cru HCLK_RKVDEC>,
|
||
|
+ <&cru SCLK_VDEC_CABAC>,
|
||
|
+ <&cru SCLK_VDEC_CORE>;
|
||
|
#power-domain-cells = <0>;
|
||
|
};
|
||
|
power-domain@RK3328_PD_VPU {
|
||
|
@@ -660,6 +664,25 @@ vpu_mmu: iommu@ff350800 {
|
||
|
power-domains = <&power RK3328_PD_VPU>;
|
||
|
};
|
||
|
|
||
|
+ rkvdec: video-codec@ff360000 {
|
||
|
+ compatible = "rockchip,rk3328-vdec", "rockchip,rk3399-vdec";
|
||
|
+ reg = <0x0 0xff360000 0x0 0x480>;
|
||
|
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
|
||
|
+ assigned-clocks = <&cru ACLK_RKVDEC>, <&cru SCLK_VDEC_CABAC>,
|
||
|
+ <&cru SCLK_VDEC_CORE>;
|
||
|
+ assigned-clock-rates = <400000000>, <400000000>, <300000000>;
|
||
|
+ clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>,
|
||
|
+ <&cru SCLK_VDEC_CABAC>, <&cru SCLK_VDEC_CORE>;
|
||
|
+ clock-names = "axi", "ahb", "cabac", "core";
|
||
|
+ iommus = <&rkvdec_mmu>;
|
||
|
+ power-domains = <&power RK3328_PD_VIDEO>;
|
||
|
+ resets = <&cru SRST_VDEC_H>, <&cru SRST_VDEC_A>,
|
||
|
+ <&cru SRST_VDEC_CORE>, <&cru SRST_VDEC_CABAC>,
|
||
|
+ <&cru SRST_VDEC_NIU_A>, <&cru SRST_VDEC_NIU_H>;
|
||
|
+ reset-names = "video_h", "video_a", "video_core", "video_cabac",
|
||
|
+ "niu_a", "niu_h";
|
||
|
+ };
|
||
|
+
|
||
|
rkvdec_mmu: iommu@ff360480 {
|
||
|
compatible = "rockchip,iommu";
|
||
|
reg = <0x0 0xff360480 0x0 0x40>, <0x0 0xff3604c0 0x0 0x40>;
|
||
|
@@ -667,7 +690,7 @@ rkvdec_mmu: iommu@ff360480 {
|
||
|
clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>;
|
||
|
clock-names = "aclk", "iface";
|
||
|
#iommu-cells = <0>;
|
||
|
- status = "disabled";
|
||
|
+ power-domains = <&power RK3328_PD_VIDEO>;
|
||
|
};
|
||
|
|
||
|
vop: vop@ff370000 {
|
||
|
|
||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Alex Bee <knaerzche@gmail.com>
|
||
|
Date: Sun, 3 May 2020 18:34:56 +0200
|
||
|
Subject: [PATCH] WIP: media/rkvdec: don't overclock IP
|
||
|
|
||
|
Signed-off-by: Alex Bee <knaerzche@gmail.com>
|
||
|
---
|
||
|
drivers/staging/media/rkvdec/rkvdec.c | 8 +++++---
|
||
|
1 file changed, 5 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
|
||
|
index 6abce36eee7f..fbaf0303f7c2 100644
|
||
|
--- a/drivers/staging/media/rkvdec/rkvdec.c
|
||
|
+++ b/drivers/staging/media/rkvdec/rkvdec.c
|
||
|
@@ -1096,10 +1096,12 @@ static int rkvdec_probe(struct platform_device *pdev)
|
||
|
return ret;
|
||
|
|
||
|
/*
|
||
|
- * Bump ACLK to max. possible freq. (500 MHz) to improve performance
|
||
|
- * When 4k video playback.
|
||
|
+ * Don't bump ACLK to max. possible freq. (500 MHz) to improve performance,
|
||
|
+ * since it will lead to non-recoverable decoder lockups in case of decoding
|
||
|
+ * errors, instead put it to 400 MHz, which seems to have no drawbacks
|
||
|
+ * in decoding performance and doesn't result in those hangs.
|
||
|
*/
|
||
|
- clk_set_rate(rkvdec->clocks[0].clk, 500 * 1000 * 1000);
|
||
|
+ clk_set_rate(rkvdec->clocks[0].clk, 400 * 1000 * 1000);
|
||
|
|
||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||
|
rkvdec->regs = devm_ioremap_resource(&pdev->dev, res);
|
||
|
|
||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Alex Bee <knaerzche@gmail.com>
|
||
|
Date: Sat, 21 Aug 2021 16:12:36 +0200
|
||
|
Subject: [PATCH] media: hantro: rockchip: Increase RK3288's max ACLK
|
||
|
|
||
|
Required to proper decode H.264@4K
|
||
|
|
||
|
Signed-off-by: Alex Bee <knaerzche@gmail.com>
|
||
|
---
|
||
|
drivers/staging/media/hantro/rockchip_vpu_hw.c | 14 +++++++++++---
|
||
|
1 file changed, 11 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c
|
||
|
index d4f52957cc53..3d98e2251ea5 100644
|
||
|
--- a/drivers/staging/media/hantro/rockchip_vpu_hw.c
|
||
|
+++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c
|
||
|
@@ -15,7 +15,8 @@
|
||
|
#include "rockchip_vpu2_regs.h"
|
||
|
|
||
|
#define RK3066_ACLK_MAX_FREQ (300 * 1000 * 1000)
|
||
|
-#define RK3288_ACLK_MAX_FREQ (400 * 1000 * 1000)
|
||
|
+#define RK3288_ACLK_MAX_FREQ (600 * 1000 * 1000)
|
||
|
+#define RK3399_ACLK_MAX_FREQ (400 * 1000 * 1000)
|
||
|
|
||
|
/*
|
||
|
* Supported formats.
|
||
|
@@ -272,13 +273,20 @@ static int rk3066_vpu_hw_init(struct hantro_dev *vpu)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
-static int rockchip_vpu_hw_init(struct hantro_dev *vpu)
|
||
|
+static int rk3288_vpu_hw_init(struct hantro_dev *vpu)
|
||
|
{
|
||
|
/* Bump ACLK to max. possible freq. to improve performance. */
|
||
|
clk_set_rate(vpu->clocks[0].clk, RK3288_ACLK_MAX_FREQ);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static int rockchip_vpu_hw_init(struct hantro_dev *vpu)
|
||
|
+{
|
||
|
+ /* Bump ACLK to max. possible freq. to improve performance. */
|
||
|
+ clk_set_rate(vpu->clocks[0].clk, RK3399_ACLK_MAX_FREQ);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
static void rk3066_vpu_dec_reset(struct hantro_ctx *ctx)
|
||
|
{
|
||
|
struct hantro_dev *vpu = ctx->dev;
|
||
|
@@ -511,7 +519,7 @@ const struct hantro_variant rk3288_vpu_variant = {
|
||
|
.codec_ops = rk3288_vpu_codec_ops,
|
||
|
.irqs = rockchip_vpu1_irqs,
|
||
|
.num_irqs = ARRAY_SIZE(rockchip_vpu1_irqs),
|
||
|
- .init = rockchip_vpu_hw_init,
|
||
|
+ .init = rk3288_vpu_hw_init,
|
||
|
.clk_names = rockchip_vpu_clk_names,
|
||
|
.num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names)
|
||
|
};
|