diff options
Diffstat (limited to 'drivers/media/platform/amphion')
-rw-r--r-- | drivers/media/platform/amphion/vdec.c | 2 | ||||
-rw-r--r-- | drivers/media/platform/amphion/vpu.h | 1 | ||||
-rw-r--r-- | drivers/media/platform/amphion/vpu_core.c | 7 | ||||
-rw-r--r-- | drivers/media/platform/amphion/vpu_malone.c | 39 |
4 files changed, 40 insertions, 9 deletions
diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c index 6a38a0fa0e2d..85d518823159 100644 --- a/drivers/media/platform/amphion/vdec.c +++ b/drivers/media/platform/amphion/vdec.c @@ -805,7 +805,7 @@ static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame) cur_fmt = vpu_get_format(inst, inst->cap_format.type); vbuf = &vpu_buf->m2m_buf.vb; if (vbuf->vb2_buf.index != frame->id) - dev_err(inst->dev, "[%d] buffer id(%d, %d) dismatch\n", + dev_err(inst->dev, "[%d] buffer id(%d, %d) mismatch\n", inst->id, vbuf->vb2_buf.index, frame->id); if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_READY && vdec->params.display_delay_enable) diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h index 22f0da26ccec..1451549c9dd2 100644 --- a/drivers/media/platform/amphion/vpu.h +++ b/drivers/media/platform/amphion/vpu.h @@ -162,7 +162,6 @@ struct vpu_core { struct delayed_work msg_delayed_work; struct kfifo msg_fifo; void *msg_buffer; - unsigned int msg_buffer_size; struct vpu_dev *vpu; void *iface; diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c index 8df85c14ab3f..da00f5fc0e5d 100644 --- a/drivers/media/platform/amphion/vpu_core.c +++ b/drivers/media/platform/amphion/vpu_core.c @@ -250,6 +250,7 @@ static void vpu_core_get_vpu(struct vpu_core *core) static int vpu_core_register(struct device *dev, struct vpu_core *core) { struct vpu_dev *vpu = dev_get_drvdata(dev); + unsigned int buffer_size; int ret = 0; dev_dbg(core->dev, "register core %s\n", vpu_core_type_desc(core->type)); @@ -263,14 +264,14 @@ static int vpu_core_register(struct device *dev, struct vpu_core *core) } INIT_WORK(&core->msg_work, vpu_msg_run_work); INIT_DELAYED_WORK(&core->msg_delayed_work, vpu_msg_delayed_work); - core->msg_buffer_size = roundup_pow_of_two(VPU_MSG_BUFFER_SIZE); - core->msg_buffer = vzalloc(core->msg_buffer_size); + buffer_size = roundup_pow_of_two(VPU_MSG_BUFFER_SIZE); + core->msg_buffer = vzalloc(buffer_size); if (!core->msg_buffer) { dev_err(core->dev, "failed allocate buffer for fifo\n"); ret = -ENOMEM; goto error; } - ret = kfifo_init(&core->msg_fifo, core->msg_buffer, core->msg_buffer_size); + ret = kfifo_init(&core->msg_fifo, core->msg_buffer, buffer_size); if (ret) { dev_err(core->dev, "failed init kfifo\n"); goto error; diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c index 4769c053c6c2..feca7d4220ed 100644 --- a/drivers/media/platform/amphion/vpu_malone.c +++ b/drivers/media/platform/amphion/vpu_malone.c @@ -3,6 +3,7 @@ * Copyright 2020-2021 NXP */ +#include <linux/bitfield.h> #include <linux/init.h> #include <linux/interconnect.h> #include <linux/ioctl.h> @@ -25,6 +26,10 @@ #include "vpu_imx8q.h" #include "vpu_malone.h" +static bool low_latency; +module_param(low_latency, bool, 0644); +MODULE_PARM_DESC(low_latency, "Set low latency frame flush mode: 0 (disable) or 1 (enable)"); + #define CMD_SIZE 25600 #define MSG_SIZE 25600 #define CODEC_SIZE 0x1000 @@ -68,6 +73,12 @@ #define MALONE_DEC_FMT_RV_MASK BIT(21) +#define MALONE_VERSION_MASK 0xFFFFF +#define MALONE_VERSION(maj, min, inc) \ + (FIELD_PREP(0xF0000, maj) | FIELD_PREP(0xFF00, min) | FIELD_PREP(0xFF, inc)) +#define CHECK_VERSION(iface, maj, min) \ + (FIELD_GET(MALONE_VERSION_MASK, (iface)->fw_version) >= MALONE_VERSION(maj, min, 0)) + enum vpu_malone_stream_input_mode { INVALID_MODE = 0, FRAME_LVL, @@ -332,6 +343,8 @@ struct vpu_dec_ctrl { u32 buf_addr[VID_API_NUM_STREAMS]; }; +static const struct malone_padding_scode *get_padding_scode(u32 type, u32 fmt); + u32 vpu_malone_get_data_size(void) { return sizeof(struct vpu_dec_ctrl); @@ -654,9 +667,15 @@ static int vpu_malone_set_params(struct vpu_shared_addr *shared, hc->jpg[instance].jpg_mjpeg_interlaced = 0; } - hc->codec_param[instance].disp_imm = params->display_delay_enable ? 1 : 0; - if (malone_format != MALONE_FMT_AVC) + if (params->display_delay_enable && + get_padding_scode(SCODE_PADDING_BUFFLUSH, params->codec_format)) + hc->codec_param[instance].disp_imm = 1; + else + hc->codec_param[instance].disp_imm = 0; + + if (params->codec_format == V4L2_PIX_FMT_HEVC && !CHECK_VERSION(iface, 1, 9)) hc->codec_param[instance].disp_imm = 0; + hc->codec_param[instance].dbglog_enable = 0; iface->dbglog_desc.level = 0; @@ -1023,6 +1042,7 @@ static const struct malone_padding_scode padding_scodes[] = { {SCODE_PADDING_EOS, V4L2_PIX_FMT_JPEG, {0x0, 0x0}}, {SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264, {0x15010000, 0x0}}, {SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264_MVC, {0x15010000, 0x0}}, + {SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_HEVC, {0x3e010000, 0x20}}, }; static const struct malone_padding_scode padding_scode_dft = {0x0, 0x0}; @@ -1057,8 +1077,11 @@ static int vpu_malone_add_padding_scode(struct vpu_buffer *stream_buffer, int ret; ps = get_padding_scode(scode_type, pixelformat); - if (!ps) + if (!ps) { + if (scode_type == SCODE_PADDING_BUFFLUSH) + return 0; return -EINVAL; + } wptr = readl(&str_buf->wptr); if (wptr < stream_buffer->phys || wptr > stream_buffer->phys + stream_buffer->length) @@ -1562,7 +1585,15 @@ static int vpu_malone_input_frame_data(struct vpu_malone_str_buffer __iomem *str vpu_malone_update_wptr(str_buf, wptr); - if (disp_imm && !vpu_vb_is_codecconfig(vbuf)) { + /* + * Enable the low latency flush mode if display delay is set to 0 + * or the low latency frame flush mode if it is set to 1. + * The low latency flush mode requires some padding data to be appended to each frame, + * but there must not be any padding data between the sequence header and the frame. + * This module is currently only supported for the H264 and HEVC formats, + * for other formats, vpu_malone_add_scode() will return 0. + */ + if ((disp_imm || low_latency) && !vpu_vb_is_codecconfig(vbuf)) { ret = vpu_malone_add_scode(inst->core->iface, inst->id, &inst->stream_buffer, |