aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_dec.c1
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_hw.c15
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_hw.h1
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_regs.h10
4 files changed, 27 insertions, 0 deletions
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
index fbbf9e6f0f50..31a1e60a3105 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
@@ -92,6 +92,7 @@ void cedrus_device_run(void *priv)
v4l2_m2m_buf_copy_metadata(run.src, run.dst, true);
+ cedrus_engine_reset(dev);
cedrus_dst_format_set(dev, &ctx->dst_fmt);
error = ctx->current_codec->setup(ctx, &run);
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
index 17e91bb5c26a..735437480706 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
@@ -31,6 +31,21 @@
#include "cedrus_hw.h"
#include "cedrus_regs.h"
+void cedrus_engine_reset(struct cedrus_dev *dev)
+{
+ u32 reg, flags;
+ int ret;
+
+ /* Wait for the cache and memory access to idle. */
+ flags = VE_RESET_SYNC_IDLE | VE_RESET_CACHE_SYNC_IDLE;
+ readl_poll_timeout_atomic(dev->base + VE_RESET, reg,
+ (reg & flags) == flags, 1, 100);
+
+ /* Reset anyway if busy for 100 ms. */
+ cedrus_write(dev, VE_RESET, reg | VE_RESET_DECODER);
+ cedrus_write(dev, VE_RESET, reg);
+}
+
int cedrus_engine_enable(struct cedrus_ctx *ctx)
{
u32 reg = 0;
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
index 6f1e701b1ea8..8b7d325d2b69 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
@@ -16,6 +16,7 @@
#ifndef _CEDRUS_HW_H_
#define _CEDRUS_HW_H_
+void cedrus_engine_reset(struct cedrus_dev *dev);
int cedrus_engine_enable(struct cedrus_ctx *ctx);
void cedrus_engine_disable(struct cedrus_dev *dev);
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
index 94667cab3727..85629f31c727 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
@@ -46,6 +46,16 @@
#define VE_MODE_DEC_H264 (0x01 << 0)
#define VE_MODE_DEC_MPEG (0x00 << 0)
+#define VE_RESET 0x04
+
+#define VE_RESET_ENCODER_MASK BIT(25)
+#define VE_RESET_ENCODER BIT(24)
+#define VE_RESET_DECODER_MASK BIT(17)
+#define VE_RESET_DECODER BIT(16)
+#define VE_RESET_SYNC_IDLE BIT(9)
+#define VE_RESET_CACHE_SYNC_IDLE BIT(8)
+#define VE_RESET_RESET BIT(0)
+
#define VE_BUF_CTRL 0x50
#define VE_BUF_CTRL_INTRAPRED_EXT_RAM (0x02 << 2)