diff options
-rw-r--r-- | drivers/staging/media/sunxi/cedrus/cedrus_dec.c | 1 | ||||
-rw-r--r-- | drivers/staging/media/sunxi/cedrus/cedrus_hw.c | 15 | ||||
-rw-r--r-- | drivers/staging/media/sunxi/cedrus/cedrus_hw.h | 1 | ||||
-rw-r--r-- | drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 10 |
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) |