diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-09-01 12:21:32 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-09-01 12:21:32 -0700 |
commit | 307d59039fb26212a84a9aa6a134a7d2bdea34ca (patch) | |
tree | dca021901b6e13b04bd4ab1671d28081a80016d9 /drivers/media/platform | |
parent | b84acc11b1c9552c9ca3a099b1610a6018619332 (diff) | |
parent | 9a5d660fdb25d20748d7f9e9559c86073c3bb368 (diff) |
Merge tag 'media/v6.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- new i2c drivers: ds90ub913, ds90ub953, ds90ub960, dw9719, ds90ub913
- new Intel IVSC MEI drivers
- some Mediatek platform drivers were moved to a common location
- Intel atomisp2 driver is now working with the main ov2680 driver. Due
to that, the atomisp2 ov2680 staging one was removed
- the bttv driver was finally converted to videobuf2 framework. This
was the last one upstream using videobuf version 1 core. We'll likely
remove the old videobuf framework on 6.7
- lots of improvements at atomisp driver: it now works with normal I2C
sensors. Several compile-mode dependecies to select between ISP2400
and ISP2401 are now solved in runtime
- a new ipu-bridge logic was added to work with IVSC MEI drivers
- venus driver gained better support for new VPU versions
- the v4l core async framework has gained lots of improvements and
cleanups
- lots of other cleanups, improvements and driver fixes
* tag 'media/v6.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (358 commits)
media: ivsc: Add ACPI dependency
media: bttv: convert to vb2
media: bttv: use audio defaults for winfast2000
media: bttv: refactor bttv_set_dma()
media: bttv: move vbi_skip/vbi_count out of buffer
media: bttv: remove crop info from bttv_buffer
media: bttv: remove tvnorm field from bttv_buffer
media: bttv: remove format field from bttv_buffer
media: bttv: move do_crop flag out of bttv_fh
media: bttv: copy vbi_fmt from bttv_fh
media: bttv: copy vid fmt/width/height from fh
media: bttv: radio use v4l2_fh instead of bttv_fh
media: bttv: replace BUG with WARN_ON
media: bttv: use video_drvdata to get bttv
media: i2c: rdacm21: Fix uninitialized value
media: coda: Remove duplicated include
media: vivid: fix the racy dev->radio_tx_rds_owner
media: i2c: ccs: Check rules is non-NULL
media: i2c: ds90ub960: Fix PLL config for 1200 MHz CSI rate
media: i2c: ds90ub953: Fix use of uninitialized variables
...
Diffstat (limited to 'drivers/media/platform')
178 files changed, 4946 insertions, 3155 deletions
diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/allegro-core.c index ec03e17727d7..da61f9beb6b4 100644 --- a/drivers/media/platform/allegro-dvt/allegro-core.c +++ b/drivers/media/platform/allegro-dvt/allegro-core.c @@ -17,7 +17,6 @@ #include <linux/mfd/syscon/xlnx-vcu.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> @@ -4007,7 +4006,7 @@ static struct platform_driver allegro_driver = { .remove_new = allegro_remove, .driver = { .name = "allegro", - .of_match_table = of_match_ptr(allegro_dt_ids), + .of_match_table = allegro_dt_ids, .pm = &allegro_pm_ops, }, }; diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c index 6515f3cdb7a7..133d77d1ea0c 100644 --- a/drivers/media/platform/amphion/vdec.c +++ b/drivers/media/platform/amphion/vdec.c @@ -299,7 +299,8 @@ static int vdec_update_state(struct vpu_inst *inst, enum vpu_codec_state state, vdec->state = VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE; if (inst->state != pre_state) - vpu_trace(inst->dev, "[%d] %d -> %d\n", inst->id, pre_state, inst->state); + vpu_trace(inst->dev, "[%d] %s -> %s\n", inst->id, + vpu_codec_state_name(pre_state), vpu_codec_state_name(inst->state)); if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) vdec_handle_resolution_change(inst); @@ -741,6 +742,21 @@ static int vdec_frame_decoded(struct vpu_inst *inst, void *arg) dev_info(inst->dev, "[%d] buf[%d] has been decoded\n", inst->id, info->id); vpu_set_buffer_state(vbuf, VPU_BUF_STATE_DECODED); vdec->decoded_frame_count++; + if (vdec->params.display_delay_enable) { + struct vpu_format *cur_fmt; + + cur_fmt = vpu_get_format(inst, inst->cap_format.type); + vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY); + for (int i = 0; i < vbuf->vb2_buf.num_planes; i++) + vb2_set_plane_payload(&vbuf->vb2_buf, + i, vpu_get_fmt_plane_size(cur_fmt, i)); + vbuf->field = cur_fmt->field; + vbuf->sequence = vdec->sequence++; + dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp); + + v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); + vdec->display_frame_count++; + } exit: vpu_inst_unlock(inst); @@ -768,14 +784,14 @@ static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame) struct vpu_format *cur_fmt; struct vpu_vb2_buffer *vpu_buf; struct vb2_v4l2_buffer *vbuf; - u32 sequence; int i; if (!frame) return; vpu_inst_lock(inst); - sequence = vdec->sequence++; + if (!vdec->params.display_delay_enable) + vdec->sequence++; vpu_buf = vdec_find_buffer(inst, frame->luma); vpu_inst_unlock(inst); if (!vpu_buf) { @@ -794,13 +810,17 @@ static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame) dev_err(inst->dev, "[%d] buffer id(%d, %d) dismatch\n", inst->id, vbuf->vb2_buf.index, frame->id); + if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_READY && vdec->params.display_delay_enable) + return; + if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_DECODED) dev_err(inst->dev, "[%d] buffer(%d) ready without decoded\n", inst->id, frame->id); + vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY); for (i = 0; i < vbuf->vb2_buf.num_planes; i++) vb2_set_plane_payload(&vbuf->vb2_buf, i, vpu_get_fmt_plane_size(cur_fmt, i)); vbuf->field = cur_fmt->field; - vbuf->sequence = sequence; + vbuf->sequence = vdec->sequence; dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp); v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); @@ -999,6 +1019,7 @@ static int vdec_response_frame_abnormal(struct vpu_inst *inst) { struct vdec_t *vdec = inst->priv; struct vpu_fs_info info; + int ret; if (!vdec->req_frame_count) return 0; @@ -1006,7 +1027,9 @@ static int vdec_response_frame_abnormal(struct vpu_inst *inst) memset(&info, 0, sizeof(info)); info.type = MEM_RES_FRAME; info.tag = vdec->seq_tag + 0xf0; - vpu_session_alloc_fs(inst, &info); + ret = vpu_session_alloc_fs(inst, &info); + if (ret) + return ret; vdec->req_frame_count--; return 0; @@ -1037,8 +1060,8 @@ static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vb return -EINVAL; } - dev_dbg(inst->dev, "[%d] state = %d, alloc fs %d, tag = 0x%x\n", - inst->id, inst->state, vbuf->vb2_buf.index, vdec->seq_tag); + dev_dbg(inst->dev, "[%d] state = %s, alloc fs %d, tag = 0x%x\n", + inst->id, vpu_codec_state_name(inst->state), vbuf->vb2_buf.index, vdec->seq_tag); vpu_buf = to_vpu_vb2_buffer(vbuf); memset(&info, 0, sizeof(info)); @@ -1400,7 +1423,7 @@ static void vdec_abort(struct vpu_inst *inst) struct vpu_rpc_buffer_desc desc; int ret; - vpu_trace(inst->dev, "[%d] state = %d\n", inst->id, inst->state); + vpu_trace(inst->dev, "[%d] state = %s\n", inst->id, vpu_codec_state_name(inst->state)); vdec->aborting = true; vpu_iface_add_scode(inst, SCODE_PADDING_ABORT); @@ -1453,9 +1476,7 @@ static void vdec_release(struct vpu_inst *inst) { if (inst->id != VPU_INST_NULL_ID) vpu_trace(inst->dev, "[%d]\n", inst->id); - vpu_inst_lock(inst); vdec_stop(inst, true); - vpu_inst_unlock(inst); } static void vdec_cleanup(struct vpu_inst *inst) diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c index 58480e2755ec..4eb57d793a9c 100644 --- a/drivers/media/platform/amphion/venc.c +++ b/drivers/media/platform/amphion/venc.c @@ -268,7 +268,7 @@ static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm { struct vpu_inst *inst = to_inst(file); struct venc_t *venc = inst->priv; - struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe; + struct v4l2_fract *timeperframe; if (!parm) return -EINVAL; @@ -279,6 +279,7 @@ static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm if (!vpu_helper_check_type(inst, parm->type)) return -EINVAL; + timeperframe = &parm->parm.capture.timeperframe; parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; parm->parm.capture.readbuffers = 0; timeperframe->numerator = venc->params.frame_rate.numerator; @@ -291,7 +292,7 @@ static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm { struct vpu_inst *inst = to_inst(file); struct venc_t *venc = inst->priv; - struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe; + struct v4l2_fract *timeperframe; unsigned long n, d; if (!parm) @@ -303,6 +304,7 @@ static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm if (!vpu_helper_check_type(inst, parm->type)) return -EINVAL; + timeperframe = &parm->parm.capture.timeperframe; if (!timeperframe->numerator) timeperframe->numerator = venc->params.frame_rate.numerator; if (!timeperframe->denominator) diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h index 3bfe193722af..5a701f64289e 100644 --- a/drivers/media/platform/amphion/vpu.h +++ b/drivers/media/platform/amphion/vpu.h @@ -355,6 +355,9 @@ void vpu_inst_record_flow(struct vpu_inst *inst, u32 flow); int vpu_core_driver_init(void); void vpu_core_driver_exit(void); +const char *vpu_id_name(u32 id); +const char *vpu_codec_state_name(enum vpu_codec_state state); + extern bool debug; #define vpu_trace(dev, fmt, arg...) \ do { \ diff --git a/drivers/media/platform/amphion/vpu_cmds.c b/drivers/media/platform/amphion/vpu_cmds.c index fa581ba6bab2..c2337812573e 100644 --- a/drivers/media/platform/amphion/vpu_cmds.c +++ b/drivers/media/platform/amphion/vpu_cmds.c @@ -9,8 +9,6 @@ #include <linux/list.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/types.h> @@ -98,7 +96,7 @@ static struct vpu_cmd_t *vpu_alloc_cmd(struct vpu_inst *inst, u32 id, void *data cmd->id = id; ret = vpu_iface_pack_cmd(inst->core, cmd->pkt, inst->id, id, data); if (ret) { - dev_err(inst->dev, "iface pack cmd(%d) fail\n", id); + dev_err(inst->dev, "iface pack cmd %s fail\n", vpu_id_name(id)); vfree(cmd->pkt); vfree(cmd); return NULL; @@ -125,14 +123,14 @@ static int vpu_session_process_cmd(struct vpu_inst *inst, struct vpu_cmd_t *cmd) { int ret; - dev_dbg(inst->dev, "[%d]send cmd(0x%x)\n", inst->id, cmd->id); + dev_dbg(inst->dev, "[%d]send cmd %s\n", inst->id, vpu_id_name(cmd->id)); vpu_iface_pre_send_cmd(inst); ret = vpu_cmd_send(inst->core, cmd->pkt); if (!ret) { vpu_iface_post_send_cmd(inst); vpu_inst_record_flow(inst, cmd->id); } else { - dev_err(inst->dev, "[%d] iface send cmd(0x%x) fail\n", inst->id, cmd->id); + dev_err(inst->dev, "[%d] iface send cmd %s fail\n", inst->id, vpu_id_name(cmd->id)); } return ret; @@ -149,7 +147,8 @@ static void vpu_process_cmd_request(struct vpu_inst *inst) list_for_each_entry_safe(cmd, tmp, &inst->cmd_q, list) { list_del_init(&cmd->list); if (vpu_session_process_cmd(inst, cmd)) - dev_err(inst->dev, "[%d] process cmd(%d) fail\n", inst->id, cmd->id); + dev_err(inst->dev, "[%d] process cmd %s fail\n", + inst->id, vpu_id_name(cmd->id)); if (cmd->request) { inst->pending = (void *)cmd; break; @@ -305,7 +304,8 @@ static void vpu_core_keep_active(struct vpu_core *core) dev_dbg(core->dev, "try to wake up\n"); mutex_lock(&core->cmd_lock); - vpu_cmd_send(core, &pkt); + if (vpu_cmd_send(core, &pkt)) + dev_err(core->dev, "fail to keep active\n"); mutex_unlock(&core->cmd_lock); } @@ -313,7 +313,7 @@ static int vpu_session_send_cmd(struct vpu_inst *inst, u32 id, void *data) { unsigned long key; int sync = false; - int ret = -EINVAL; + int ret; if (inst->id < 0) return -EINVAL; @@ -339,7 +339,7 @@ static int vpu_session_send_cmd(struct vpu_inst *inst, u32 id, void *data) exit: if (ret) - dev_err(inst->dev, "[%d] send cmd(0x%x) fail\n", inst->id, id); + dev_err(inst->dev, "[%d] send cmd %s fail\n", inst->id, vpu_id_name(id)); return ret; } diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c index 7863b7b53494..1af6fc9460d4 100644 --- a/drivers/media/platform/amphion/vpu_core.c +++ b/drivers/media/platform/amphion/vpu_core.c @@ -9,7 +9,7 @@ #include <linux/list.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -88,6 +88,8 @@ static int vpu_core_boot_done(struct vpu_core *core) core->supported_instance_count = min(core->supported_instance_count, count); } + if (core->supported_instance_count >= BITS_PER_TYPE(core->instance_mask)) + core->supported_instance_count = BITS_PER_TYPE(core->instance_mask); core->fw_version = fw_version; vpu_core_set_state(core, VPU_CORE_ACTIVE); diff --git a/drivers/media/platform/amphion/vpu_dbg.c b/drivers/media/platform/amphion/vpu_dbg.c index 44b830ae01d8..982c2c777484 100644 --- a/drivers/media/platform/amphion/vpu_dbg.c +++ b/drivers/media/platform/amphion/vpu_dbg.c @@ -50,6 +50,13 @@ static char *vpu_stat_name[] = { [VPU_BUF_STATE_ERROR] = "error", }; +static inline const char *to_vpu_stat_name(int state) +{ + if (state <= VPU_BUF_STATE_ERROR) + return vpu_stat_name[state]; + return "unknown"; +} + static int vpu_dbg_instance(struct seq_file *s, void *data) { struct vpu_inst *inst = s->private; @@ -67,7 +74,7 @@ static int vpu_dbg_instance(struct seq_file *s, void *data) num = scnprintf(str, sizeof(str), "tgig = %d,pid = %d\n", inst->tgid, inst->pid); if (seq_write(s, str, num)) return 0; - num = scnprintf(str, sizeof(str), "state = %d\n", inst->state); + num = scnprintf(str, sizeof(str), "state = %s\n", vpu_codec_state_name(inst->state)); if (seq_write(s, str, num)) return 0; num = scnprintf(str, sizeof(str), @@ -141,7 +148,7 @@ static int vpu_dbg_instance(struct seq_file *s, void *data) num = scnprintf(str, sizeof(str), "output [%2d] state = %10s, %8s\n", i, vb2_stat_name[vb->state], - vpu_stat_name[vpu_get_buffer_state(vbuf)]); + to_vpu_stat_name(vpu_get_buffer_state(vbuf))); if (seq_write(s, str, num)) return 0; } @@ -156,7 +163,7 @@ static int vpu_dbg_instance(struct seq_file *s, void *data) num = scnprintf(str, sizeof(str), "capture[%2d] state = %10s, %8s\n", i, vb2_stat_name[vb->state], - vpu_stat_name[vpu_get_buffer_state(vbuf)]); + to_vpu_stat_name(vpu_get_buffer_state(vbuf))); if (seq_write(s, str, num)) return 0; } @@ -188,9 +195,9 @@ static int vpu_dbg_instance(struct seq_file *s, void *data) if (!inst->flows[idx]) continue; - num = scnprintf(str, sizeof(str), "\t[%s]0x%x\n", + num = scnprintf(str, sizeof(str), "\t[%s] %s\n", inst->flows[idx] >= VPU_MSG_ID_NOOP ? "M" : "C", - inst->flows[idx]); + vpu_id_name(inst->flows[idx])); if (seq_write(s, str, num)) { mutex_unlock(&inst->core->cmd_lock); return 0; diff --git a/drivers/media/platform/amphion/vpu_drv.c b/drivers/media/platform/amphion/vpu_drv.c index 4187b2b5562f..2bf70aafd2ba 100644 --- a/drivers/media/platform/amphion/vpu_drv.c +++ b/drivers/media/platform/amphion/vpu_drv.c @@ -10,8 +10,8 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/dma-map-ops.h> -#include <linux/of_device.h> -#include <linux/of_address.h> +#include <linux/of.h> +#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/types.h> diff --git a/drivers/media/platform/amphion/vpu_helpers.c b/drivers/media/platform/amphion/vpu_helpers.c index 019c77e84514..af3b336e5dc3 100644 --- a/drivers/media/platform/amphion/vpu_helpers.c +++ b/drivers/media/platform/amphion/vpu_helpers.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include "vpu.h" +#include "vpu_defs.h" #include "vpu_core.h" #include "vpu_rpc.h" #include "vpu_helpers.h" @@ -447,3 +448,63 @@ int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst) return -EINVAL; } + +const char *vpu_id_name(u32 id) +{ + switch (id) { + case VPU_CMD_ID_NOOP: return "noop"; + case VPU_CMD_ID_CONFIGURE_CODEC: return "configure codec"; + case VPU_CMD_ID_START: return "start"; + case VPU_CMD_ID_STOP: return "stop"; + case VPU_CMD_ID_ABORT: return "abort"; + case VPU_CMD_ID_RST_BUF: return "reset buf"; + case VPU_CMD_ID_SNAPSHOT: return "snapshot"; + case VPU_CMD_ID_FIRM_RESET: return "reset firmware"; + case VPU_CMD_ID_UPDATE_PARAMETER: return "update parameter"; + case VPU_CMD_ID_FRAME_ENCODE: return "encode frame"; + case VPU_CMD_ID_SKIP: return "skip"; + case VPU_CMD_ID_FS_ALLOC: return "alloc fb"; + case VPU_CMD_ID_FS_RELEASE: return "release fb"; + case VPU_CMD_ID_TIMESTAMP: return "timestamp"; + case VPU_CMD_ID_DEBUG: return "debug"; + case VPU_MSG_ID_RESET_DONE: return "reset done"; + case VPU_MSG_ID_START_DONE: return "start done"; + case VPU_MSG_ID_STOP_DONE: return "stop done"; + case VPU_MSG_ID_ABORT_DONE: return "abort done"; + case VPU_MSG_ID_BUF_RST: return "buf reset done"; + case VPU_MSG_ID_MEM_REQUEST: return "mem request"; + case VPU_MSG_ID_PARAM_UPD_DONE: return "param upd done"; + case VPU_MSG_ID_FRAME_INPUT_DONE: return "frame input done"; + case VPU_MSG_ID_ENC_DONE: return "encode done"; + case VPU_MSG_ID_DEC_DONE: return "frame display"; + case VPU_MSG_ID_FRAME_REQ: return "fb request"; + case VPU_MSG_ID_FRAME_RELEASE: return "fb release"; + case VPU_MSG_ID_SEQ_HDR_FOUND: return "seq hdr found"; + case VPU_MSG_ID_RES_CHANGE: return "resolution change"; + case VPU_MSG_ID_PIC_HDR_FOUND: return "pic hdr found"; + case VPU_MSG_ID_PIC_DECODED: return "picture decoded"; + case VPU_MSG_ID_PIC_EOS: return "eos"; + case VPU_MSG_ID_FIFO_LOW: return "fifo low"; + case VPU_MSG_ID_BS_ERROR: return "bs error"; + case VPU_MSG_ID_UNSUPPORTED: return "unsupported"; + case VPU_MSG_ID_FIRMWARE_XCPT: return "exception"; + case VPU_MSG_ID_PIC_SKIPPED: return "skipped"; + } + return "<unknown>"; +} + +const char *vpu_codec_state_name(enum vpu_codec_state state) +{ + switch (state) { + case VPU_CODEC_STATE_DEINIT: return "initialization"; + case VPU_CODEC_STATE_CONFIGURED: return "configured"; + case VPU_CODEC_STATE_START: return "start"; + case VPU_CODEC_STATE_STARTED: return "started"; + case VPU_CODEC_STATE_ACTIVE: return "active"; + case VPU_CODEC_STATE_SEEK: return "seek"; + case VPU_CODEC_STATE_STOP: return "stop"; + case VPU_CODEC_STATE_DRAIN: return "drain"; + case VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE: return "resolution change"; + } + return "<unknown>"; +} diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c index c1d6606ad7e5..f771661980c0 100644 --- a/drivers/media/platform/amphion/vpu_malone.c +++ b/drivers/media/platform/amphion/vpu_malone.c @@ -9,8 +9,6 @@ #include <linux/list.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/delay.h> #include <linux/rational.h> diff --git a/drivers/media/platform/amphion/vpu_mbox.c b/drivers/media/platform/amphion/vpu_mbox.c index b6d5b4844f67..c2963b8deb48 100644 --- a/drivers/media/platform/amphion/vpu_mbox.c +++ b/drivers/media/platform/amphion/vpu_mbox.c @@ -9,8 +9,6 @@ #include <linux/list.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_address.h> #include <linux/platform_device.h> #include "vpu.h" #include "vpu_mbox.h" diff --git a/drivers/media/platform/amphion/vpu_msgs.c b/drivers/media/platform/amphion/vpu_msgs.c index 92672a802b49..d0ead051f7d1 100644 --- a/drivers/media/platform/amphion/vpu_msgs.c +++ b/drivers/media/platform/amphion/vpu_msgs.c @@ -32,7 +32,7 @@ static void vpu_session_handle_start_done(struct vpu_inst *inst, struct vpu_rpc_ static void vpu_session_handle_mem_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt) { - struct vpu_pkt_mem_req_data req_data; + struct vpu_pkt_mem_req_data req_data = { 0 }; vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&req_data); vpu_trace(inst->dev, "[%d] %d:%d %d:%d %d:%d\n", @@ -80,7 +80,7 @@ static void vpu_session_handle_resolution_change(struct vpu_inst *inst, struct v static void vpu_session_handle_enc_frame_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt) { - struct vpu_enc_pic_info info; + struct vpu_enc_pic_info info = { 0 }; vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info); dev_dbg(inst->dev, "[%d] frame id = %d, wptr = 0x%x, size = %d\n", @@ -90,7 +90,7 @@ static void vpu_session_handle_enc_frame_done(struct vpu_inst *inst, struct vpu_ static void vpu_session_handle_frame_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt) { - struct vpu_fs_info fs; + struct vpu_fs_info fs = { 0 }; vpu_iface_unpack_msg_data(inst->core, pkt, &fs); call_void_vop(inst, event_notify, VPU_MSG_ID_FRAME_REQ, &fs); @@ -107,7 +107,7 @@ static void vpu_session_handle_frame_release(struct vpu_inst *inst, struct vpu_r info.type = inst->out_format.type; call_void_vop(inst, buf_done, &info); } else if (inst->core->type == VPU_CORE_TYPE_DEC) { - struct vpu_fs_info fs; + struct vpu_fs_info fs = { 0 }; vpu_iface_unpack_msg_data(inst->core, pkt, &fs); call_void_vop(inst, event_notify, VPU_MSG_ID_FRAME_RELEASE, &fs); @@ -122,7 +122,7 @@ static void vpu_session_handle_input_done(struct vpu_inst *inst, struct vpu_rpc_ static void vpu_session_handle_pic_decoded(struct vpu_inst *inst, struct vpu_rpc_event *pkt) { - struct vpu_dec_pic_info info; + struct vpu_dec_pic_info info = { 0 }; vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info); call_void_vop(inst, get_one_frame, &info); @@ -130,7 +130,7 @@ static void vpu_session_handle_pic_decoded(struct vpu_inst *inst, struct vpu_rpc static void vpu_session_handle_pic_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt) { - struct vpu_dec_pic_info info; + struct vpu_dec_pic_info info = { 0 }; struct vpu_frame_info frame; memset(&frame, 0, sizeof(frame)); @@ -210,7 +210,7 @@ static int vpu_session_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *m return -EINVAL; msg_id = ret; - dev_dbg(inst->dev, "[%d] receive event(0x%x)\n", inst->id, msg_id); + dev_dbg(inst->dev, "[%d] receive event(%s)\n", inst->id, vpu_id_name(msg_id)); for (i = 0; i < ARRAY_SIZE(handlers); i++) { if (handlers[i].id == msg_id) { diff --git a/drivers/media/platform/amphion/vpu_rpc.c b/drivers/media/platform/amphion/vpu_rpc.c index 676f7da041bd..f626a9f835e0 100644 --- a/drivers/media/platform/amphion/vpu_rpc.c +++ b/drivers/media/platform/amphion/vpu_rpc.c @@ -9,8 +9,6 @@ #include <linux/list.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/firmware/imx/ipc.h> #include <linux/firmware/imx/svc/misc.h> diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c index 021235e1c144..0f6e4c666440 100644 --- a/drivers/media/platform/amphion/vpu_v4l2.c +++ b/drivers/media/platform/amphion/vpu_v4l2.c @@ -489,6 +489,11 @@ static int vpu_vb2_queue_setup(struct vb2_queue *vq, for (i = 0; i < cur_fmt->mem_planes; i++) psize[i] = vpu_get_fmt_plane_size(cur_fmt, i); + if (V4L2_TYPE_IS_OUTPUT(vq->type) && inst->state == VPU_CODEC_STATE_SEEK) { + vpu_trace(inst->dev, "reinit when VIDIOC_REQBUFS(OUTPUT, 0)\n"); + call_void_vop(inst, release); + } + return 0; } @@ -773,9 +778,9 @@ int vpu_v4l2_close(struct file *file) v4l2_m2m_ctx_release(inst->fh.m2m_ctx); inst->fh.m2m_ctx = NULL; } + call_void_vop(inst, release); vpu_inst_unlock(inst); - call_void_vop(inst, release); vpu_inst_unregister(inst); vpu_inst_put(inst); diff --git a/drivers/media/platform/amphion/vpu_windsor.c b/drivers/media/platform/amphion/vpu_windsor.c index b245ff6a1102..5f1101d7cf9e 100644 --- a/drivers/media/platform/amphion/vpu_windsor.c +++ b/drivers/media/platform/amphion/vpu_windsor.c @@ -9,8 +9,6 @@ #include <linux/list.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/time64.h> #include <media/videobuf2-v4l2.h> diff --git a/drivers/media/platform/aspeed/aspeed-video.c b/drivers/media/platform/aspeed/aspeed-video.c index 374eb7781936..a9c2c69b2ed9 100644 --- a/drivers/media/platform/aspeed/aspeed-video.c +++ b/drivers/media/platform/aspeed/aspeed-video.c @@ -13,7 +13,6 @@ #include <linux/module.h> #include <linux/mutex.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/of_irq.h> #include <linux/of_reserved_mem.h> #include <linux/platform_device.h> @@ -1130,7 +1129,7 @@ static void aspeed_video_get_resolution(struct aspeed_video *video) static void aspeed_video_set_resolution(struct aspeed_video *video) { struct v4l2_bt_timings *act = &video->active_timings; - unsigned int size = act->width * act->height; + unsigned int size = act->width * ALIGN(act->height, 8); /* Set capture/compression frame sizes */ aspeed_video_calc_compressed_size(video, size); @@ -1147,7 +1146,7 @@ static void aspeed_video_set_resolution(struct aspeed_video *video) u32 width = ALIGN(act->width, 64); aspeed_video_write(video, VE_CAP_WINDOW, width << 16 | act->height); - size = width * act->height; + size = width * ALIGN(act->height, 8); } else { aspeed_video_write(video, VE_CAP_WINDOW, act->width << 16 | act->height); diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c index c29e04864445..4046212d48b4 100644 --- a/drivers/media/platform/atmel/atmel-isi.c +++ b/drivers/media/platform/atmel/atmel-isi.c @@ -1120,7 +1120,7 @@ static int isi_graph_notify_complete(struct v4l2_async_notifier *notifier) static void isi_graph_notify_unbind(struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct atmel_isi *isi = notifier_to_isi(notifier); @@ -1132,7 +1132,7 @@ static void isi_graph_notify_unbind(struct v4l2_async_notifier *notifier, static int isi_graph_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct atmel_isi *isi = notifier_to_isi(notifier); @@ -1151,7 +1151,7 @@ static const struct v4l2_async_notifier_operations isi_graph_notify_ops = { static int isi_graph_init(struct atmel_isi *isi) { - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct device_node *ep; int ret; @@ -1159,11 +1159,11 @@ static int isi_graph_init(struct atmel_isi *isi) if (!ep) return -EINVAL; - v4l2_async_nf_init(&isi->notifier); + v4l2_async_nf_init(&isi->notifier, &isi->v4l2_dev); asd = v4l2_async_nf_add_fwnode_remote(&isi->notifier, of_fwnode_handle(ep), - struct v4l2_async_subdev); + struct v4l2_async_connection); of_node_put(ep); if (IS_ERR(asd)) @@ -1171,7 +1171,7 @@ static int isi_graph_init(struct atmel_isi *isi) isi->notifier.ops = &isi_graph_notify_ops; - ret = v4l2_async_nf_register(&isi->v4l2_dev, &isi->notifier); + ret = v4l2_async_nf_register(&isi->notifier); if (ret < 0) { dev_err(isi->dev, "Notifier registration failed\n"); v4l2_async_nf_cleanup(&isi->notifier); @@ -1187,7 +1187,6 @@ static int atmel_isi_probe(struct platform_device *pdev) int irq; struct atmel_isi *isi; struct vb2_queue *q; - struct resource *regs; int ret, i; isi = devm_kzalloc(&pdev->dev, sizeof(struct atmel_isi), GFP_KERNEL); @@ -1268,8 +1267,7 @@ static int atmel_isi_probe(struct platform_device *pdev) list_add(&isi->dma_desc[i].list, &isi->dma_desc_head); } - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - isi->regs = devm_ioremap_resource(&pdev->dev, regs); + isi->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(isi->regs)) { ret = PTR_ERR(isi->regs); goto err_ioremap; diff --git a/drivers/media/platform/atmel/atmel-isi.h b/drivers/media/platform/atmel/atmel-isi.h index 7ad3895a2c87..ef38eddef5fc 100644 --- a/drivers/media/platform/atmel/atmel-isi.h +++ b/drivers/media/platform/atmel/atmel-isi.h @@ -121,8 +121,6 @@ #define ISI_DATAWIDTH_8 0x01 #define ISI_DATAWIDTH_10 0x02 -struct v4l2_async_subdev; - struct isi_platform_data { u8 has_emb_sync; u8 hsync_act_low; diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index 9755d1c8ceb9..0d879d71d818 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -13,6 +13,7 @@ #include <linux/of_graph.h> #include <linux/phy/phy.h> #include <linux/platform_device.h> +#include <linux/reset.h> #include <linux/slab.h> #include <media/v4l2-ctrls.h> @@ -30,6 +31,12 @@ #define CSI2RX_STATIC_CFG_DLANE_MAP(llane, plane) ((plane) << (16 + (llane) * 4)) #define CSI2RX_STATIC_CFG_LANES_MASK GENMASK(11, 8) +#define CSI2RX_DPHY_LANE_CTRL_REG 0x40 +#define CSI2RX_DPHY_CL_RST BIT(16) +#define CSI2RX_DPHY_DL_RST(i) BIT((i) + 12) +#define CSI2RX_DPHY_CL_EN BIT(4) +#define CSI2RX_DPHY_DL_EN(i) BIT(i) + #define CSI2RX_STREAM_BASE(n) (((n) + 1) * 0x100) #define CSI2RX_STREAM_CTRL_REG(n) (CSI2RX_STREAM_BASE(n) + 0x000) @@ -68,6 +75,9 @@ struct csi2rx_priv { struct clk *sys_clk; struct clk *p_clk; struct clk *pixel_clk[CSI2RX_STREAMS_MAX]; + struct reset_control *sys_rst; + struct reset_control *p_rst; + struct reset_control *pixel_rst[CSI2RX_STREAMS_MAX]; struct phy *dphy; u8 lanes[CSI2RX_LANES_MAX]; @@ -101,6 +111,24 @@ static void csi2rx_reset(struct csi2rx_priv *csi2rx) writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG); } +static int csi2rx_configure_ext_dphy(struct csi2rx_priv *csi2rx) +{ + union phy_configure_opts opts = { }; + int ret; + + ret = phy_power_on(csi2rx->dphy); + if (ret) + return ret; + + ret = phy_configure(csi2rx->dphy, &opts); + if (ret) { + phy_power_off(csi2rx->dphy); + return ret; + } + + return 0; +} + static int csi2rx_start(struct csi2rx_priv *csi2rx) { unsigned int i; @@ -112,6 +140,7 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx) if (ret) return ret; + reset_control_deassert(csi2rx->p_rst); csi2rx_reset(csi2rx); reg = csi2rx->num_lanes << 8; @@ -139,6 +168,17 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx) if (ret) goto err_disable_pclk; + /* Enable DPHY clk and data lanes. */ + if (csi2rx->dphy) { + reg = CSI2RX_DPHY_CL_EN | CSI2RX_DPHY_CL_RST; + for (i = 0; i < csi2rx->num_lanes; i++) { + reg |= CSI2RX_DPHY_DL_EN(csi2rx->lanes[i] - 1); + reg |= CSI2RX_DPHY_DL_RST(csi2rx->lanes[i] - 1); + } + + writel(reg, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG); + } + /* * Create a static mapping between the CSI virtual channels * and the output stream. @@ -154,6 +194,8 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx) if (ret) goto err_disable_pixclk; + reset_control_deassert(csi2rx->pixel_rst[i]); + writel(CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF, csi2rx->base + CSI2RX_STREAM_CFG_REG(i)); @@ -169,13 +211,28 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx) if (ret) goto err_disable_pixclk; + reset_control_deassert(csi2rx->sys_rst); + + if (csi2rx->dphy) { + ret = csi2rx_configure_ext_dphy(csi2rx); + if (ret) { + dev_err(csi2rx->dev, + "Failed to configure external DPHY: %d\n", ret); + goto err_disable_sysclk; + } + } + clk_disable_unprepare(csi2rx->p_clk); return 0; +err_disable_sysclk: + clk_disable_unprepare(csi2rx->sys_clk); err_disable_pixclk: - for (; i > 0; i--) + for (; i > 0; i--) { + reset_control_assert(csi2rx->pixel_rst[i - 1]); clk_disable_unprepare(csi2rx->pixel_clk[i - 1]); + } err_disable_pclk: clk_disable_unprepare(csi2rx->p_clk); @@ -188,18 +245,28 @@ static void csi2rx_stop(struct csi2rx_priv *csi2rx) unsigned int i; clk_prepare_enable(csi2rx->p_clk); + reset_control_assert(csi2rx->sys_rst); clk_disable_unprepare(csi2rx->sys_clk); for (i = 0; i < csi2rx->max_streams; i++) { writel(0, csi2rx->base + CSI2RX_STREAM_CTRL_REG(i)); + reset_control_assert(csi2rx->pixel_rst[i]); clk_disable_unprepare(csi2rx->pixel_clk[i]); } + reset_control_assert(csi2rx->p_rst); clk_disable_unprepare(csi2rx->p_clk); if (v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, false)) dev_warn(csi2rx->dev, "Couldn't disable our subdev\n"); + + if (csi2rx->dphy) { + writel(0, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG); + + if (phy_power_off(csi2rx->dphy)) + dev_warn(csi2rx->dev, "Couldn't power off DPHY\n"); + } } static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable) @@ -246,7 +313,7 @@ static const struct v4l2_subdev_ops csi2rx_subdev_ops = { static int csi2rx_async_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *s_subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct v4l2_subdev *subdev = notifier->sd; struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev); @@ -299,21 +366,22 @@ static int csi2rx_get_resources(struct csi2rx_priv *csi2rx, return PTR_ERR(csi2rx->p_clk); } + csi2rx->sys_rst = devm_reset_control_get_optional_exclusive(&pdev->dev, + "sys"); + if (IS_ERR(csi2rx->sys_rst)) + return PTR_ERR(csi2rx->sys_rst); + + csi2rx->p_rst = devm_reset_control_get_optional_exclusive(&pdev->dev, + "reg_bank"); + if (IS_ERR(csi2rx->p_rst)) + return PTR_ERR(csi2rx->p_rst); + csi2rx->dphy = devm_phy_optional_get(&pdev->dev, "dphy"); if (IS_ERR(csi2rx->dphy)) { dev_err(&pdev->dev, "Couldn't get external D-PHY\n"); return PTR_ERR(csi2rx->dphy); } - /* - * FIXME: Once we'll have external D-PHY support, the check - * will need to be removed. - */ - if (csi2rx->dphy) { - dev_err(&pdev->dev, "External D-PHY not supported yet\n"); - return -EINVAL; - } - ret = clk_prepare_enable(csi2rx->p_clk); if (ret) { dev_err(&pdev->dev, "Couldn't prepare and enable P clock\n"); @@ -343,20 +411,27 @@ static int csi2rx_get_resources(struct csi2rx_priv *csi2rx, * FIXME: Once we'll have internal D-PHY support, the check * will need to be removed. */ - if (csi2rx->has_internal_dphy) { + if (!csi2rx->dphy && csi2rx->has_internal_dphy) { dev_err(&pdev->dev, "Internal D-PHY not supported yet\n"); return -EINVAL; } for (i = 0; i < csi2rx->max_streams; i++) { - char clk_name[16]; + char name[16]; - snprintf(clk_name, sizeof(clk_name), "pixel_if%u_clk", i); - csi2rx->pixel_clk[i] = devm_clk_get(&pdev->dev, clk_name); + snprintf(name, sizeof(name), "pixel_if%u_clk", i); + csi2rx->pixel_clk[i] = devm_clk_get(&pdev->dev, name); if (IS_ERR(csi2rx->pixel_clk[i])) { - dev_err(&pdev->dev, "Couldn't get clock %s\n", clk_name); + dev_err(&pdev->dev, "Couldn't get clock %s\n", name); return PTR_ERR(csi2rx->pixel_clk[i]); } + + snprintf(name, sizeof(name), "pixel_if%u", i); + csi2rx->pixel_rst[i] = + devm_reset_control_get_optional_exclusive(&pdev->dev, + name); + if (IS_ERR(csi2rx->pixel_rst[i])) + return PTR_ERR(csi2rx->pixel_rst[i]); } return 0; @@ -365,7 +440,7 @@ static int csi2rx_get_resources(struct csi2rx_priv *csi2rx, static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx) { struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 }; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct fwnode_handle *fwh; struct device_node *ep; int ret; @@ -399,17 +474,17 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx) return -EINVAL; } - v4l2_async_nf_init(&csi2rx->notifier); + v4l2_async_subdev_nf_init(&csi2rx->notifier, &csi2rx->subdev); asd = v4l2_async_nf_add_fwnode_remote(&csi2rx->notifier, fwh, - struct v4l2_async_subdev); + struct v4l2_async_connection); of_node_put(ep); if (IS_ERR(asd)) return PTR_ERR(asd); csi2rx->notifier.ops = &csi2rx_notifier_ops; - ret = v4l2_async_subdev_nf_register(&csi2rx->subdev, &csi2rx->notifier); + ret = v4l2_async_nf_register(&csi2rx->notifier); if (ret) v4l2_async_nf_cleanup(&csi2rx->notifier); @@ -462,6 +537,7 @@ static int csi2rx_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Probed CSI2RX with %u/%u lanes, %u streams, %s D-PHY\n", csi2rx->num_lanes, csi2rx->max_lanes, csi2rx->max_streams, + csi2rx->dphy ? "external" : csi2rx->has_internal_dphy ? "internal" : "no"); return 0; @@ -482,6 +558,7 @@ static void csi2rx_remove(struct platform_device *pdev) } static const struct of_device_id csi2rx_of_table[] = { + { .compatible = "starfive,jh7110-csi2rx" }, { .compatible = "cdns,csi2rx" }, { }, }; diff --git a/drivers/media/platform/chips-media/coda-common.c b/drivers/media/platform/chips-media/coda-common.c index ac9a642ae76f..cc4892129aaf 100644 --- a/drivers/media/platform/chips-media/coda-common.c +++ b/drivers/media/platform/chips-media/coda-common.c @@ -19,12 +19,12 @@ #include <linux/irq.h> #include <linux/kfifo.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/videodev2.h> -#include <linux/of.h> #include <linux/ratelimit.h> #include <linux/reset.h> diff --git a/drivers/media/platform/intel/pxa_camera.c b/drivers/media/platform/intel/pxa_camera.c index 9ed3c2e063de..6e6caf50e11e 100644 --- a/drivers/media/platform/intel/pxa_camera.c +++ b/drivers/media/platform/intel/pxa_camera.c @@ -2044,7 +2044,7 @@ static const struct video_device pxa_camera_videodev_template = { static int pxa_camera_sensor_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { int err; struct v4l2_device *v4l2_dev = notifier->v4l2_dev; @@ -2123,7 +2123,7 @@ out: static void pxa_camera_sensor_unbind(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct pxa_camera_dev *pcdev = v4l2_dev_to_pcdev(notifier->v4l2_dev); @@ -2197,7 +2197,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev, struct pxa_camera_dev *pcdev) { u32 mclk_rate; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct device_node *np = dev->of_node; struct v4l2_fwnode_endpoint ep = { .bus_type = 0 }; int err = of_property_read_u32(np, "clock-frequency", @@ -2252,7 +2252,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev, asd = v4l2_async_nf_add_fwnode_remote(&pcdev->notifier, of_fwnode_handle(np), - struct v4l2_async_subdev); + struct v4l2_async_connection); if (IS_ERR(asd)) err = PTR_ERR(asd); out: @@ -2274,9 +2274,8 @@ static int pxa_camera_probe(struct platform_device *pdev) int irq; int err = 0, i; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); - if (!res || irq < 0) + if (irq < 0) return -ENODEV; pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev), GFP_KERNEL); @@ -2289,27 +2288,41 @@ static int pxa_camera_probe(struct platform_device *pdev) if (IS_ERR(pcdev->clk)) return PTR_ERR(pcdev->clk); - v4l2_async_nf_init(&pcdev->notifier); + /* + * Request the regions. + */ + base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(base)) + return PTR_ERR(base); + + pcdev->irq = irq; + pcdev->base = base; + + err = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev); + if (err) + return err; + + v4l2_async_nf_init(&pcdev->notifier, &pcdev->v4l2_dev); pcdev->res = res; pcdev->pdata = pdev->dev.platform_data; if (pcdev->pdata) { - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; pcdev->platform_flags = pcdev->pdata->flags; pcdev->mclk = pcdev->pdata->mclk_10khz * 10000; asd = v4l2_async_nf_add_i2c(&pcdev->notifier, pcdev->pdata->sensor_i2c_adapter_id, pcdev->pdata->sensor_i2c_address, - struct v4l2_async_subdev); + struct v4l2_async_connection); if (IS_ERR(asd)) err = PTR_ERR(asd); } else if (pdev->dev.of_node) { err = pxa_camera_pdata_from_dt(&pdev->dev, pcdev); } else { - return -ENODEV; + err = -ENODEV; } if (err < 0) - return err; + goto exit_v4l2_device_unregister; if (!(pcdev->platform_flags & (PXA_CAMERA_DATAWIDTH_8 | PXA_CAMERA_DATAWIDTH_9 | PXA_CAMERA_DATAWIDTH_10))) { @@ -2338,21 +2351,12 @@ static int pxa_camera_probe(struct platform_device *pdev) spin_lock_init(&pcdev->lock); mutex_init(&pcdev->mlock); - /* - * Request the regions. - */ - base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); - - pcdev->irq = irq; - pcdev->base = base; - /* request dma */ pcdev->dma_chans[0] = dma_request_chan(&pdev->dev, "CI_Y"); if (IS_ERR(pcdev->dma_chans[0])) { dev_err(&pdev->dev, "Can't request DMA for Y\n"); - return PTR_ERR(pcdev->dma_chans[0]); + err = PTR_ERR(pcdev->dma_chans[0]); + goto exit_notifier_cleanup; } pcdev->dma_chans[1] = dma_request_chan(&pdev->dev, "CI_U"); @@ -2379,36 +2383,30 @@ static int pxa_camera_probe(struct platform_device *pdev) } } - /* request irq */ - err = devm_request_irq(&pdev->dev, pcdev->irq, pxa_camera_irq, 0, - PXA_CAM_DRV_NAME, pcdev); - if (err) { - dev_err(&pdev->dev, "Camera interrupt register failed\n"); - goto exit_free_dma; - } - tasklet_setup(&pcdev->task_eof, pxa_camera_eof); pxa_camera_activate(pcdev); platform_set_drvdata(pdev, pcdev); - err = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev); - if (err) - goto exit_deactivate; err = pxa_camera_init_videobuf2(pcdev); if (err) - goto exit_notifier_cleanup; + goto exit_deactivate; + + /* request irq */ + err = devm_request_irq(&pdev->dev, pcdev->irq, pxa_camera_irq, 0, + PXA_CAM_DRV_NAME, pcdev); + if (err) { + dev_err(&pdev->dev, "Camera interrupt register failed\n"); + goto exit_v4l2_device_unregister; + } pcdev->notifier.ops = &pxa_camera_sensor_ops; - err = v4l2_async_nf_register(&pcdev->v4l2_dev, &pcdev->notifier); + err = v4l2_async_nf_register(&pcdev->notifier); if (err) - goto exit_notifier_cleanup; + goto exit_deactivate; return 0; -exit_notifier_cleanup: - v4l2_async_nf_cleanup(&pcdev->notifier); - v4l2_device_unregister(&pcdev->v4l2_dev); exit_deactivate: pxa_camera_deactivate(pcdev); tasklet_kill(&pcdev->task_eof); @@ -2418,6 +2416,10 @@ exit_free_dma_u: dma_release_channel(pcdev->dma_chans[1]); exit_free_dma_y: dma_release_channel(pcdev->dma_chans[0]); +exit_notifier_cleanup: + v4l2_async_nf_cleanup(&pcdev->notifier); +exit_v4l2_device_unregister: + v4l2_device_unregister(&pcdev->v4l2_dev); return err; } @@ -2454,7 +2456,7 @@ static struct platform_driver pxa_camera_driver = { .driver = { .name = PXA_CAM_DRV_NAME, .pm = &pxa_camera_pm, - .of_match_table = of_match_ptr(pxa_camera_of_match), + .of_match_table = pxa_camera_of_match, }, .probe = pxa_camera_probe, .remove_new = pxa_camera_remove, diff --git a/drivers/media/platform/marvell/cafe-driver.c b/drivers/media/platform/marvell/cafe-driver.c index ae97ce4ead98..ef810249def6 100644 --- a/drivers/media/platform/marvell/cafe-driver.c +++ b/drivers/media/platform/marvell/cafe-driver.c @@ -478,7 +478,7 @@ static int cafe_pci_probe(struct pci_dev *pdev, int ret; struct cafe_camera *cam; struct mcam_camera *mcam; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct i2c_client *i2c_dev; /* @@ -536,19 +536,24 @@ static int cafe_pci_probe(struct pci_dev *pdev, if (ret) goto out_pdown; - v4l2_async_nf_init(&mcam->notifier); + ret = v4l2_device_register(mcam->dev, &mcam->v4l2_dev); + if (ret) + goto out_smbus_shutdown; + + v4l2_async_nf_init(&mcam->notifier, &mcam->v4l2_dev); asd = v4l2_async_nf_add_i2c(&mcam->notifier, i2c_adapter_id(cam->i2c_adapter), - ov7670_info.addr, struct v4l2_async_subdev); + ov7670_info.addr, + struct v4l2_async_connection); if (IS_ERR(asd)) { ret = PTR_ERR(asd); - goto out_smbus_shutdown; + goto out_v4l2_device_unregister; } ret = mccic_register(mcam); if (ret) - goto out_smbus_shutdown; + goto out_v4l2_device_unregister; clkdev_create(mcam->mclk, "xclk", "%d-%04x", i2c_adapter_id(cam->i2c_adapter), ov7670_info.addr); @@ -564,6 +569,8 @@ static int cafe_pci_probe(struct pci_dev *pdev, out_mccic_shutdown: mccic_shutdown(mcam); +out_v4l2_device_unregister: + v4l2_device_unregister(&mcam->v4l2_dev); out_smbus_shutdown: cafe_smbus_shutdown(cam); out_pdown: @@ -586,6 +593,7 @@ out: static void cafe_shutdown(struct cafe_camera *cam) { mccic_shutdown(&cam->mcam); + v4l2_device_unregister(&cam->mcam.v4l2_dev); cafe_smbus_shutdown(cam); free_irq(cam->pdev->irq, cam); pci_iounmap(cam->pdev, cam->mcam.regs); diff --git a/drivers/media/platform/marvell/mcam-core.c b/drivers/media/platform/marvell/mcam-core.c index 154bdcb3f2cc..66688b4aece5 100644 --- a/drivers/media/platform/marvell/mcam-core.c +++ b/drivers/media/platform/marvell/mcam-core.c @@ -1756,7 +1756,7 @@ EXPORT_SYMBOL_GPL(mccic_irq); */ static int mccic_notify_bound(struct v4l2_async_notifier *notifier, - struct v4l2_subdev *subdev, struct v4l2_async_subdev *asd) + struct v4l2_subdev *subdev, struct v4l2_async_connection *asd) { struct mcam_camera *cam = notifier_to_mcam(notifier); int ret; @@ -1801,7 +1801,7 @@ out: } static void mccic_notify_unbind(struct v4l2_async_notifier *notifier, - struct v4l2_subdev *subdev, struct v4l2_async_subdev *asd) + struct v4l2_subdev *subdev, struct v4l2_async_connection *asd) { struct mcam_camera *cam = notifier_to_mcam(notifier); @@ -1863,13 +1863,6 @@ int mccic_register(struct mcam_camera *cam) goto out; } - /* - * Register with V4L - */ - ret = v4l2_device_register(cam->dev, &cam->v4l2_dev); - if (ret) - goto out; - mutex_init(&cam->s_mutex); cam->state = S_NOTREADY; mcam_set_config_needed(cam, 1); @@ -1877,7 +1870,7 @@ int mccic_register(struct mcam_camera *cam) cam->mbus_code = mcam_def_mbus_code; cam->notifier.ops = &mccic_notify_ops; - ret = v4l2_async_nf_register(&cam->v4l2_dev, &cam->notifier); + ret = v4l2_async_nf_register(&cam->notifier); if (ret < 0) { cam_warn(cam, "failed to register a sensor notifier"); goto out; @@ -1915,7 +1908,6 @@ int mccic_register(struct mcam_camera *cam) out: v4l2_async_nf_unregister(&cam->notifier); - v4l2_device_unregister(&cam->v4l2_dev); v4l2_async_nf_cleanup(&cam->notifier); return ret; } @@ -1937,7 +1929,6 @@ void mccic_shutdown(struct mcam_camera *cam) mcam_free_dma_bufs(cam); v4l2_ctrl_handler_free(&cam->ctrl_handler); v4l2_async_nf_unregister(&cam->notifier); - v4l2_device_unregister(&cam->v4l2_dev); v4l2_async_nf_cleanup(&cam->notifier); } EXPORT_SYMBOL_GPL(mccic_shutdown); diff --git a/drivers/media/platform/marvell/mmp-driver.c b/drivers/media/platform/marvell/mmp-driver.c index e93feefb447b..170907cc1885 100644 --- a/drivers/media/platform/marvell/mmp-driver.c +++ b/drivers/media/platform/marvell/mmp-driver.c @@ -180,7 +180,7 @@ static int mmpcam_probe(struct platform_device *pdev) struct resource *res; struct fwnode_handle *ep; struct mmp_camera_platform_data *pdata; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; int ret; cam = devm_kzalloc(&pdev->dev, sizeof(*cam), GFP_KERNEL); @@ -223,8 +223,7 @@ static int mmpcam_probe(struct platform_device *pdev) /* * Get our I/O memory. */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mcam->regs = devm_ioremap_resource(&pdev->dev, res); + mcam->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(mcam->regs)) return PTR_ERR(mcam->regs); mcam->regs_size = resource_size(res); @@ -239,10 +238,10 @@ static int mmpcam_probe(struct platform_device *pdev) if (!ep) return -ENODEV; - v4l2_async_nf_init(&mcam->notifier); + v4l2_async_nf_init(&mcam->notifier, &mcam->v4l2_dev); asd = v4l2_async_nf_add_fwnode_remote(&mcam->notifier, ep, - struct v4l2_async_subdev); + struct v4l2_async_connection); fwnode_handle_put(ep); if (IS_ERR(asd)) { ret = PTR_ERR(asd); @@ -362,7 +361,7 @@ static struct platform_driver mmpcam_driver = { .remove_new = mmpcam_remove, .driver = { .name = "mmp-camera", - .of_match_table = of_match_ptr(mmpcam_of_match), + .of_match_table = mmpcam_of_match, .pm = &mmpcam_pm_ops, } }; diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index 60425c99a2b8..7194f88edc0f 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -1403,6 +1403,7 @@ static void mtk_jpeg_remove(struct platform_device *pdev) { struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev); + cancel_delayed_work_sync(&jpeg->job_timeout_work); pm_runtime_disable(&pdev->dev); video_unregister_device(jpeg->vdev); v4l2_m2m_release(jpeg->m2m_dev); diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c index baa7be58ce69..4a6ee211e18f 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c @@ -12,7 +12,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/slab.h> #include <media/media-device.h> diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c index 244018365b6f..2bbc48c7402c 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c @@ -10,9 +10,9 @@ #include <linux/irq.h> #include <linux/io.h> #include <linux/kernel.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/slab.h> #include <media/media-device.h> diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c b/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c index ad5fab2d8bfa..3501ac411242 100644 --- a/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c +++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c @@ -7,8 +7,6 @@ #include <linux/clk.h> #include <linux/device.h> #include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_platform.h> #include "mtk_mdp_comp.h" diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_core.c b/drivers/media/platform/mediatek/mdp/mtk_mdp_core.c index 77e310e588e5..917cdf38f230 100644 --- a/drivers/media/platform/mediatek/mdp/mtk_mdp_core.c +++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_core.c @@ -28,7 +28,7 @@ EXPORT_SYMBOL(mtk_mdp_dbg_level); module_param(mtk_mdp_dbg_level, int, 0644); -static const struct of_device_id mtk_mdp_comp_dt_ids[] = { +static const struct of_device_id mtk_mdp_comp_dt_ids[] __maybe_unused = { { .compatible = "mediatek,mt8173-mdp-rdma", .data = (void *)MTK_MDP_RDMA diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c index a605e80c7dc3..667933ea15f4 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c @@ -746,7 +746,7 @@ static const struct mdp_comp_ops *mdp_comp_ops[MDP_COMP_TYPE_COUNT] = { [MDP_COMP_TYPE_CCORR] = &ccorr_ops, }; -static const struct of_device_id mdp_comp_dt_ids[] = { +static const struct of_device_id mdp_comp_dt_ids[] __maybe_unused = { { .compatible = "mediatek,mt8183-mdp3-rdma", .data = (void *)MDP_COMP_TYPE_RDMA, @@ -892,11 +892,13 @@ static int mdp_get_subsys_id(struct mdp_dev *mdp, struct device *dev, ret = cmdq_dev_get_client_reg(&comp_pdev->dev, &cmdq_reg, index); if (ret != 0) { dev_err(&comp_pdev->dev, "cmdq_dev_get_subsys fail!\n"); + put_device(&comp_pdev->dev); return -EINVAL; } comp->subsys_id = cmdq_reg.subsys; dev_dbg(&comp_pdev->dev, "subsys id=%d\n", cmdq_reg.subsys); + put_device(&comp_pdev->dev); return 0; } diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c index aa6c225302f0..cc44be10fdb7 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c @@ -322,7 +322,7 @@ static struct platform_driver mdp_driver = { .driver = { .name = MDP_MODULE_NAME, .pm = &mdp_pm_ops, - .of_match_table = of_match_ptr(mdp_of_ids), + .of_match_table = mdp_of_ids, }, }; diff --git a/drivers/media/platform/mediatek/vcodec/Makefile b/drivers/media/platform/mediatek/vcodec/Makefile index 5f4c30fec85a..014abbfbd993 100644 --- a/drivers/media/platform/mediatek/vcodec/Makefile +++ b/drivers/media/platform/mediatek/vcodec/Makefile @@ -1,54 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \ - mtk-vcodec-enc.o \ - mtk-vcodec-common.o \ - mtk-vcodec-dec-hw.o - -mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ - vdec/vdec_vp8_if.o \ - vdec/vdec_vp8_req_if.o \ - vdec/vdec_vp9_if.o \ - vdec/vdec_vp9_req_lat_if.o \ - vdec/vdec_av1_req_lat_if.o \ - vdec/vdec_h264_req_if.o \ - vdec/vdec_h264_req_common.o \ - vdec/vdec_h264_req_multi_if.o \ - vdec/vdec_hevc_req_multi_if.o \ - mtk_vcodec_dec_drv.o \ - vdec_drv_if.o \ - vdec_vpu_if.o \ - vdec_msg_queue.o \ - mtk_vcodec_dec.o \ - mtk_vcodec_dec_stateful.o \ - mtk_vcodec_dec_stateless.o \ - mtk_vcodec_dec_pm.o \ - -mtk-vcodec-dec-hw-y := mtk_vcodec_dec_hw.o - -mtk-vcodec-enc-y := venc/venc_vp8_if.o \ - venc/venc_h264_if.o \ - mtk_vcodec_enc.o \ - mtk_vcodec_enc_drv.o \ - mtk_vcodec_enc_pm.o \ - venc_drv_if.o \ - venc_vpu_if.o \ - - -mtk-vcodec-common-y := mtk_vcodec_intr.o \ - mtk_vcodec_util.o \ - mtk_vcodec_fw.o \ - -ifneq ($(CONFIG_VIDEO_MEDIATEK_VCODEC_VPU),) -mtk-vcodec-common-y += mtk_vcodec_fw_vpu.o -endif - -ifneq ($(CONFIG_VIDEO_MEDIATEK_VCODEC_SCP),) -mtk-vcodec-common-y += mtk_vcodec_fw_scp.o -endif - -ifneq ($(CONFIG_DEBUG_FS),) -obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dbgfs.o - -mtk-vcodec-dbgfs-y := mtk_vcodec_dbgfs.o -endif
\ No newline at end of file +obj-y += common/ +obj-y += encoder/ +obj-y += decoder/ diff --git a/drivers/media/platform/mediatek/vcodec/common/Makefile b/drivers/media/platform/mediatek/vcodec/common/Makefile new file mode 100644 index 000000000000..d0479914dfb3 --- /dev/null +++ b/drivers/media/platform/mediatek/vcodec/common/Makefile @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-common.o + +mtk-vcodec-common-y := mtk_vcodec_intr.o \ + mtk_vcodec_util.o \ + mtk_vcodec_fw.o \ + +ifneq ($(CONFIG_VIDEO_MEDIATEK_VCODEC_VPU),) +mtk-vcodec-common-y += mtk_vcodec_fw_vpu.o +endif + +ifneq ($(CONFIG_VIDEO_MEDIATEK_VCODEC_SCP),) +mtk-vcodec-common-y += mtk_vcodec_fw_scp.o +endif + +ifneq ($(CONFIG_DEBUG_FS),) +obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dbgfs.o + +mtk-vcodec-dbgfs-y := mtk_vcodec_dbgfs.o +endif
\ No newline at end of file diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_cmn_drv.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_cmn_drv.h new file mode 100644 index 000000000000..6087e27bd604 --- /dev/null +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_cmn_drv.h @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2023 MediaTek Inc. + * Author: Yunfei Dong <yunfei.dong@mediatek.com> + */ + +#ifndef _MTK_VCODEC_COM_DRV_H_ +#define _MTK_VCODEC_COM_DRV_H_ + +#include <linux/platform_device.h> +#include <linux/videodev2.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-device.h> +#include <media/v4l2-ioctl.h> +#include <media/v4l2-mem2mem.h> +#include <media/videobuf2-core.h> + +#define MTK_VCODEC_MAX_PLANES 3 + +#define WAIT_INTR_TIMEOUT_MS 1000 + +/* + * enum mtk_q_type - Type of queue + */ +enum mtk_q_type { + MTK_Q_DATA_SRC = 0, + MTK_Q_DATA_DST = 1, +}; + +/* + * enum mtk_hw_reg_idx - MTK hw register base index + */ +enum mtk_hw_reg_idx { + VDEC_SYS, + VDEC_MISC, + VDEC_LD, + VDEC_TOP, + VDEC_CM, + VDEC_AD, + VDEC_AV, + VDEC_PP, + VDEC_HWD, + VDEC_HWQ, + VDEC_HWB, + VDEC_HWG, + NUM_MAX_VDEC_REG_BASE, + /* h264 encoder */ + VENC_SYS = NUM_MAX_VDEC_REG_BASE, + /* vp8 encoder */ + VENC_LT_SYS, + NUM_MAX_VCODEC_REG_BASE +}; + +/* + * struct mtk_vcodec_clk_info - Structure used to store clock name + */ +struct mtk_vcodec_clk_info { + const char *clk_name; + struct clk *vcodec_clk; +}; + +/* + * struct mtk_vcodec_clk - Structure used to store vcodec clock information + */ +struct mtk_vcodec_clk { + struct mtk_vcodec_clk_info *clk_info; + int clk_num; +}; + +/* + * struct mtk_vcodec_pm - Power management data structure + */ +struct mtk_vcodec_pm { + struct mtk_vcodec_clk vdec_clk; + struct mtk_vcodec_clk venc_clk; + struct device *dev; +}; + +/* + * enum mtk_vdec_hw_id - Hardware index used to separate + * different hardware + */ +enum mtk_vdec_hw_id { + MTK_VDEC_CORE, + MTK_VDEC_LAT0, + MTK_VDEC_LAT1, + MTK_VDEC_LAT_SOC, + MTK_VDEC_HW_MAX, +}; + +/** + * enum mtk_instance_state - The state of an MTK Vcodec instance. + * @MTK_STATE_FREE: default state when instance is created + * @MTK_STATE_INIT: vcodec instance is initialized + * @MTK_STATE_HEADER: vdec had sps/pps header parsed or venc + * had sps/pps header encoded + * @MTK_STATE_FLUSH: vdec is flushing. Only used by decoder + * @MTK_STATE_ABORT: vcodec should be aborted + */ +enum mtk_instance_state { + MTK_STATE_FREE = 0, + MTK_STATE_INIT = 1, + MTK_STATE_HEADER = 2, + MTK_STATE_FLUSH = 3, + MTK_STATE_ABORT = 4, +}; + +enum mtk_fmt_type { + MTK_FMT_DEC = 0, + MTK_FMT_ENC = 1, + MTK_FMT_FRAME = 2, +}; + +/* + * struct mtk_video_fmt - Structure used to store information about pixelformats + */ +struct mtk_video_fmt { + u32 fourcc; + enum mtk_fmt_type type; + u32 num_planes; + u32 flags; + struct v4l2_frmsize_stepwise frmsize; +}; + +/* + * struct mtk_q_data - Structure used to store information about queue + */ +struct mtk_q_data { + unsigned int visible_width; + unsigned int visible_height; + unsigned int coded_width; + unsigned int coded_height; + enum v4l2_field field; + unsigned int bytesperline[MTK_VCODEC_MAX_PLANES]; + unsigned int sizeimage[MTK_VCODEC_MAX_PLANES]; + const struct mtk_video_fmt *fmt; +}; + +/* + * enum mtk_instance_type - The type of an MTK Vcodec instance. + */ +enum mtk_instance_type { + MTK_INST_DECODER = 0, + MTK_INST_ENCODER = 1, +}; + +#endif /* _MTK_VCODEC_COM_DRV_H_ */ diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dbgfs.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_dbgfs.c index b5cdbbfcc388..5ad3797836db 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dbgfs.c +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_dbgfs.c @@ -7,10 +7,11 @@ #include <linux/debugfs.h> #include "mtk_vcodec_dbgfs.h" -#include "mtk_vcodec_drv.h" +#include "../decoder/mtk_vcodec_dec_drv.h" +#include "../encoder/mtk_vcodec_enc_drv.h" #include "mtk_vcodec_util.h" -static void mtk_vdec_dbgfs_get_format_type(struct mtk_vcodec_ctx *ctx, char *buf, +static void mtk_vdec_dbgfs_get_format_type(struct mtk_vcodec_dec_ctx *ctx, char *buf, int *used, int total) { int curr_len; @@ -72,7 +73,7 @@ static void mtk_vdec_dbgfs_get_help(char *buf, int *used, int total) static ssize_t mtk_vdec_dbgfs_write(struct file *filp, const char __user *ubuf, size_t count, loff_t *ppos) { - struct mtk_vcodec_dev *vcodec_dev = filp->private_data; + struct mtk_vcodec_dec_dev *vcodec_dev = filp->private_data; struct mtk_vcodec_dbgfs *dbgfs = &vcodec_dev->dbgfs; mutex_lock(&dbgfs->dbgfs_lock); @@ -88,10 +89,10 @@ static ssize_t mtk_vdec_dbgfs_write(struct file *filp, const char __user *ubuf, static ssize_t mtk_vdec_dbgfs_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos) { - struct mtk_vcodec_dev *vcodec_dev = filp->private_data; + struct mtk_vcodec_dec_dev *vcodec_dev = filp->private_data; struct mtk_vcodec_dbgfs *dbgfs = &vcodec_dev->dbgfs; struct mtk_vcodec_dbgfs_inst *dbgfs_inst; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; int total_len = 200 * (dbgfs->inst_count == 0 ? 1 : dbgfs->inst_count); int used_len = 0, curr_len, ret; bool dbgfs_index[MTK_VDEC_DBGFS_MAX] = {0}; @@ -143,10 +144,10 @@ static const struct file_operations vdec_fops = { .read = mtk_vdec_dbgfs_read, }; -void mtk_vcodec_dbgfs_create(struct mtk_vcodec_ctx *ctx) +void mtk_vcodec_dbgfs_create(struct mtk_vcodec_dec_ctx *ctx) { struct mtk_vcodec_dbgfs_inst *dbgfs_inst; - struct mtk_vcodec_dev *vcodec_dev = ctx->dev; + struct mtk_vcodec_dec_dev *vcodec_dev = ctx->dev; dbgfs_inst = kzalloc(sizeof(*dbgfs_inst), GFP_KERNEL); if (!dbgfs_inst) @@ -161,53 +162,68 @@ void mtk_vcodec_dbgfs_create(struct mtk_vcodec_ctx *ctx) } EXPORT_SYMBOL_GPL(mtk_vcodec_dbgfs_create); -void mtk_vcodec_dbgfs_remove(struct mtk_vcodec_dev *vcodec_dev, int ctx_id) +void mtk_vcodec_dbgfs_remove(struct mtk_vcodec_dec_dev *vcodec_dev, int ctx_id) { struct mtk_vcodec_dbgfs_inst *dbgfs_inst; list_for_each_entry(dbgfs_inst, &vcodec_dev->dbgfs.dbgfs_head, node) { if (dbgfs_inst->inst_id == ctx_id) { vcodec_dev->dbgfs.inst_count--; - break; + list_del(&dbgfs_inst->node); + kfree(dbgfs_inst); + return; } } - - if (dbgfs_inst) { - list_del(&dbgfs_inst->node); - kfree(dbgfs_inst); - } } EXPORT_SYMBOL_GPL(mtk_vcodec_dbgfs_remove); -void mtk_vcodec_dbgfs_init(struct mtk_vcodec_dev *vcodec_dev, bool is_encode) +static void mtk_vcodec_dbgfs_vdec_init(struct mtk_vcodec_dec_dev *vcodec_dev) { struct dentry *vcodec_root; - if (is_encode) - vcodec_dev->dbgfs.vcodec_root = debugfs_create_dir("vcodec-enc", NULL); - else - vcodec_dev->dbgfs.vcodec_root = debugfs_create_dir("vcodec-dec", NULL); + vcodec_dev->dbgfs.vcodec_root = debugfs_create_dir("vcodec-dec", NULL); if (IS_ERR(vcodec_dev->dbgfs.vcodec_root)) - dev_err(&vcodec_dev->plat_dev->dev, "create vcodec dir err:%d\n", - IS_ERR(vcodec_dev->dbgfs.vcodec_root)); + dev_err(&vcodec_dev->plat_dev->dev, "create vcodec dir err:%ld\n", + PTR_ERR(vcodec_dev->dbgfs.vcodec_root)); vcodec_root = vcodec_dev->dbgfs.vcodec_root; debugfs_create_x32("mtk_v4l2_dbg_level", 0644, vcodec_root, &mtk_v4l2_dbg_level); debugfs_create_x32("mtk_vcodec_dbg", 0644, vcodec_root, &mtk_vcodec_dbg); vcodec_dev->dbgfs.inst_count = 0; - if (is_encode) - return; - INIT_LIST_HEAD(&vcodec_dev->dbgfs.dbgfs_head); debugfs_create_file("vdec", 0200, vcodec_root, vcodec_dev, &vdec_fops); mutex_init(&vcodec_dev->dbgfs.dbgfs_lock); } + +static void mtk_vcodec_dbgfs_venc_init(struct mtk_vcodec_enc_dev *vcodec_dev) +{ + struct dentry *vcodec_root; + + vcodec_dev->dbgfs.vcodec_root = debugfs_create_dir("vcodec-enc", NULL); + if (IS_ERR(vcodec_dev->dbgfs.vcodec_root)) + dev_err(&vcodec_dev->plat_dev->dev, "create venc dir err:%d\n", + IS_ERR(vcodec_dev->dbgfs.vcodec_root)); + + vcodec_root = vcodec_dev->dbgfs.vcodec_root; + debugfs_create_x32("mtk_v4l2_dbg_level", 0644, vcodec_root, &mtk_v4l2_dbg_level); + debugfs_create_x32("mtk_vcodec_dbg", 0644, vcodec_root, &mtk_vcodec_dbg); + + vcodec_dev->dbgfs.inst_count = 0; +} + +void mtk_vcodec_dbgfs_init(void *vcodec_dev, bool is_encode) +{ + if (is_encode) + mtk_vcodec_dbgfs_venc_init(vcodec_dev); + else + mtk_vcodec_dbgfs_vdec_init(vcodec_dev); +} EXPORT_SYMBOL_GPL(mtk_vcodec_dbgfs_init); -void mtk_vcodec_dbgfs_deinit(struct mtk_vcodec_dev *vcodec_dev) +void mtk_vcodec_dbgfs_deinit(struct mtk_vcodec_dbgfs *dbgfs) { - debugfs_remove_recursive(vcodec_dev->dbgfs.vcodec_root); + debugfs_remove_recursive(dbgfs->vcodec_root); } EXPORT_SYMBOL_GPL(mtk_vcodec_dbgfs_deinit); diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dbgfs.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_dbgfs.h index 241ff8197e73..073d2fedb54a 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dbgfs.h +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_dbgfs.h @@ -7,8 +7,8 @@ #ifndef __MTK_VCODEC_DBGFS_H__ #define __MTK_VCODEC_DBGFS_H__ -struct mtk_vcodec_dev; -struct mtk_vcodec_ctx; +struct mtk_vcodec_dec_dev; +struct mtk_vcodec_dec_ctx; /* * enum mtk_vdec_dbgfs_log_index - used to get different debug information @@ -22,12 +22,12 @@ enum mtk_vdec_dbgfs_log_index { /** * struct mtk_vcodec_dbgfs_inst - debugfs information for each inst * @node: list node for each inst - * @vcodec_ctx: struct mtk_vcodec_ctx + * @vcodec_ctx: struct mtk_vcodec_dec_ctx * @inst_id: index of the context that the same with ctx->id */ struct mtk_vcodec_dbgfs_inst { struct list_head node; - struct mtk_vcodec_ctx *vcodec_ctx; + struct mtk_vcodec_dec_ctx *vcodec_ctx; int inst_id; }; @@ -50,24 +50,24 @@ struct mtk_vcodec_dbgfs { }; #if defined(CONFIG_DEBUG_FS) -void mtk_vcodec_dbgfs_create(struct mtk_vcodec_ctx *ctx); -void mtk_vcodec_dbgfs_remove(struct mtk_vcodec_dev *vcodec_dev, int ctx_id); -void mtk_vcodec_dbgfs_init(struct mtk_vcodec_dev *vcodec_dev, bool is_encode); -void mtk_vcodec_dbgfs_deinit(struct mtk_vcodec_dev *vcodec_dev); +void mtk_vcodec_dbgfs_create(struct mtk_vcodec_dec_ctx *ctx); +void mtk_vcodec_dbgfs_remove(struct mtk_vcodec_dec_dev *vcodec_dev, int ctx_id); +void mtk_vcodec_dbgfs_init(void *vcodec_dev, bool is_encode); +void mtk_vcodec_dbgfs_deinit(struct mtk_vcodec_dbgfs *dbgfs); #else -static inline void mtk_vcodec_dbgfs_create(struct mtk_vcodec_ctx *ctx) +static inline void mtk_vcodec_dbgfs_create(struct mtk_vcodec_dec_ctx *ctx) { } -static inline void mtk_vcodec_dbgfs_remove(struct mtk_vcodec_dev *vcodec_dev, int ctx_id) +static inline void mtk_vcodec_dbgfs_remove(struct mtk_vcodec_dec_dev *vcodec_dev, int ctx_id) { } -static inline void mtk_vcodec_dbgfs_init(struct mtk_vcodec_dev *vcodec_dev, bool is_encode) +static inline void mtk_vcodec_dbgfs_init(void *vcodec_dev, bool is_encode) { } -static inline void mtk_vcodec_dbgfs_deinit(struct mtk_vcodec_dev *vcodec_dev) +static inline void mtk_vcodec_dbgfs_deinit(struct mtk_vcodec_dbgfs *dbgfs) { } #endif diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c index 556e54aadac9..08949b08fbc6 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw.c +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c @@ -1,21 +1,26 @@ // SPDX-License-Identifier: GPL-2.0 -#include "mtk_vcodec_fw.h" +#include "../decoder/mtk_vcodec_dec_drv.h" +#include "../encoder/mtk_vcodec_enc_drv.h" #include "mtk_vcodec_fw_priv.h" -#include "mtk_vcodec_util.h" -#include "mtk_vcodec_drv.h" -struct mtk_vcodec_fw *mtk_vcodec_fw_select(struct mtk_vcodec_dev *dev, - enum mtk_vcodec_fw_type type, +struct mtk_vcodec_fw *mtk_vcodec_fw_select(void *priv, enum mtk_vcodec_fw_type type, enum mtk_vcodec_fw_use fw_use) { + struct platform_device *plat_dev; + + if (fw_use == ENCODER) + plat_dev = ((struct mtk_vcodec_enc_dev *)priv)->plat_dev; + else + plat_dev = ((struct mtk_vcodec_dec_dev *)priv)->plat_dev; + switch (type) { case VPU: - return mtk_vcodec_fw_vpu_init(dev, fw_use); + return mtk_vcodec_fw_vpu_init(priv, fw_use); case SCP: - return mtk_vcodec_fw_scp_init(dev); + return mtk_vcodec_fw_scp_init(priv, fw_use); default: - mtk_v4l2_err("invalid vcodec fw type"); + dev_err(&plat_dev->dev, "Invalid vcodec fw type"); return ERR_PTR(-EINVAL); } } diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.h index 16824114657f..300363a40158 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw.h +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.h @@ -6,9 +6,10 @@ #include <linux/remoteproc.h> #include <linux/remoteproc/mtk_scp.h> -#include "../vpu/mtk_vpu.h" +#include "../../vpu/mtk_vpu.h" -struct mtk_vcodec_dev; +struct mtk_vcodec_dec_dev; +struct mtk_vcodec_enc_dev; enum mtk_vcodec_fw_type { VPU, @@ -25,8 +26,7 @@ struct mtk_vcodec_fw; typedef void (*mtk_vcodec_ipi_handler) (void *data, unsigned int len, void *priv); -struct mtk_vcodec_fw *mtk_vcodec_fw_select(struct mtk_vcodec_dev *dev, - enum mtk_vcodec_fw_type type, +struct mtk_vcodec_fw *mtk_vcodec_fw_select(void *priv, enum mtk_vcodec_fw_type type, enum mtk_vcodec_fw_use fw_use); void mtk_vcodec_fw_release(struct mtk_vcodec_fw *fw); diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_priv.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_priv.h index b41e66185cec..99603accd82e 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_priv.h +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_priv.h @@ -5,13 +5,15 @@ #include "mtk_vcodec_fw.h" -struct mtk_vcodec_dev; +struct mtk_vcodec_dec_dev; +struct mtk_vcodec_enc_dev; struct mtk_vcodec_fw { enum mtk_vcodec_fw_type type; const struct mtk_vcodec_fw_ops *ops; struct platform_device *pdev; struct mtk_scp *scp; + enum mtk_vcodec_fw_use fw_use; }; struct mtk_vcodec_fw_ops { @@ -28,22 +30,20 @@ struct mtk_vcodec_fw_ops { }; #if IS_ENABLED(CONFIG_VIDEO_MEDIATEK_VCODEC_VPU) -struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(struct mtk_vcodec_dev *dev, - enum mtk_vcodec_fw_use fw_use); +struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(void *priv, enum mtk_vcodec_fw_use fw_use); #else static inline struct mtk_vcodec_fw * -mtk_vcodec_fw_vpu_init(struct mtk_vcodec_dev *dev, - enum mtk_vcodec_fw_use fw_use) +mtk_vcodec_fw_vpu_init(void *priv, enum mtk_vcodec_fw_use fw_use) { return ERR_PTR(-ENODEV); } #endif /* CONFIG_VIDEO_MEDIATEK_VCODEC_VPU */ #if IS_ENABLED(CONFIG_VIDEO_MEDIATEK_VCODEC_SCP) -struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev); +struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(void *priv, enum mtk_vcodec_fw_use fw_use); #else static inline struct mtk_vcodec_fw * -mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev) +mtk_vcodec_fw_scp_init(void *priv, enum mtk_vcodec_fw_use fw_use) { return ERR_PTR(-ENODEV); } diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_scp.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c index d8e66b645bd8..9e744d07a1e8 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_scp.c +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 +#include "../decoder/mtk_vcodec_dec_drv.h" +#include "../encoder/mtk_vcodec_enc_drv.h" #include "mtk_vcodec_fw_priv.h" -#include "mtk_vcodec_util.h" -#include "mtk_vcodec_drv.h" static int mtk_vcodec_scp_load_firmware(struct mtk_vcodec_fw *fw) { @@ -53,18 +53,32 @@ static const struct mtk_vcodec_fw_ops mtk_vcodec_rproc_msg = { .release = mtk_vcodec_scp_release, }; -struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev) +struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(void *priv, enum mtk_vcodec_fw_use fw_use) { struct mtk_vcodec_fw *fw; + struct platform_device *plat_dev; struct mtk_scp *scp; - scp = scp_get(dev->plat_dev); + if (fw_use == ENCODER) { + struct mtk_vcodec_enc_dev *enc_dev = priv; + + plat_dev = enc_dev->plat_dev; + } else if (fw_use == DECODER) { + struct mtk_vcodec_dec_dev *dec_dev = priv; + + plat_dev = dec_dev->plat_dev; + } else { + pr_err("Invalid fw_use %d (use a resonable fw id here)\n", fw_use); + return ERR_PTR(-EINVAL); + } + + scp = scp_get(plat_dev); if (!scp) { - mtk_v4l2_err("could not get vdec scp handle"); + dev_err(&plat_dev->dev, "could not get vdec scp handle"); return ERR_PTR(-EPROBE_DEFER); } - fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL); + fw = devm_kzalloc(&plat_dev->dev, sizeof(*fw), GFP_KERNEL); fw->type = SCP; fw->ops = &mtk_vcodec_rproc_msg; fw->scp = scp; diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c index cfc7ebed8fb7..5e03b0886559 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_vpu.c +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 +#include "../decoder/mtk_vcodec_dec_drv.h" +#include "../encoder/mtk_vcodec_enc_drv.h" #include "mtk_vcodec_fw_priv.h" -#include "mtk_vcodec_util.h" -#include "mtk_vcodec_drv.h" static int mtk_vcodec_vpu_load_firmware(struct mtk_vcodec_fw *fw) { @@ -51,18 +51,32 @@ static void mtk_vcodec_vpu_release(struct mtk_vcodec_fw *fw) put_device(&fw->pdev->dev); } -static void mtk_vcodec_vpu_reset_handler(void *priv) +static void mtk_vcodec_vpu_reset_dec_handler(void *priv) { - struct mtk_vcodec_dev *dev = priv; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_dev *dev = priv; + struct mtk_vcodec_dec_ctx *ctx; - mtk_v4l2_err("Watchdog timeout!!"); + dev_err(&dev->plat_dev->dev, "Watchdog timeout!!"); mutex_lock(&dev->dev_mutex); list_for_each_entry(ctx, &dev->ctx_list, list) { ctx->state = MTK_STATE_ABORT; - mtk_v4l2_debug(0, "[%d] Change to state MTK_STATE_ABORT", - ctx->id); + mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id); + } + mutex_unlock(&dev->dev_mutex); +} + +static void mtk_vcodec_vpu_reset_enc_handler(void *priv) +{ + struct mtk_vcodec_enc_dev *dev = priv; + struct mtk_vcodec_enc_ctx *ctx; + + dev_err(&dev->plat_dev->dev, "Watchdog timeout!!"); + + mutex_lock(&dev->dev_mutex); + list_for_each_entry(ctx, &dev->ctx_list, list) { + ctx->state = MTK_STATE_ABORT; + mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id); } mutex_unlock(&dev->dev_mutex); } @@ -77,36 +91,46 @@ static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = { .release = mtk_vcodec_vpu_release, }; -struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(struct mtk_vcodec_dev *dev, - enum mtk_vcodec_fw_use fw_use) +struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(void *priv, enum mtk_vcodec_fw_use fw_use) { struct platform_device *fw_pdev; + struct platform_device *plat_dev; struct mtk_vcodec_fw *fw; enum rst_id rst_id; - switch (fw_use) { - case ENCODER: + if (fw_use == ENCODER) { + struct mtk_vcodec_enc_dev *enc_dev = priv; + + plat_dev = enc_dev->plat_dev; rst_id = VPU_RST_ENC; - break; - case DECODER: - default: + } else if (fw_use == DECODER) { + struct mtk_vcodec_dec_dev *dec_dev = priv; + + plat_dev = dec_dev->plat_dev; rst_id = VPU_RST_DEC; - break; + } else { + pr_err("Invalid fw_use %d (use a resonable fw id here)\n", fw_use); + return ERR_PTR(-EINVAL); } - fw_pdev = vpu_get_plat_device(dev->plat_dev); + fw_pdev = vpu_get_plat_device(plat_dev); if (!fw_pdev) { - mtk_v4l2_err("firmware device is not ready"); + dev_err(&plat_dev->dev, "firmware device is not ready"); return ERR_PTR(-EINVAL); } - vpu_wdt_reg_handler(fw_pdev, mtk_vcodec_vpu_reset_handler, dev, rst_id); - fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL); + if (fw_use == DECODER) + vpu_wdt_reg_handler(fw_pdev, mtk_vcodec_vpu_reset_dec_handler, priv, rst_id); + else + vpu_wdt_reg_handler(fw_pdev, mtk_vcodec_vpu_reset_enc_handler, priv, rst_id); + + fw = devm_kzalloc(&plat_dev->dev, sizeof(*fw), GFP_KERNEL); if (!fw) return ERR_PTR(-ENOMEM); fw->type = VPU; fw->ops = &mtk_vcodec_vpu_msg; fw->pdev = fw_pdev; + fw->fw_use = fw_use; return fw; } diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_intr.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_intr.c new file mode 100644 index 000000000000..f203fc25636b --- /dev/null +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_intr.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* Copyright (c) 2016 MediaTek Inc. +* Author: Tiffany Lin <tiffany.lin@mediatek.com> +*/ + +#include <linux/errno.h> +#include <linux/wait.h> + +#include "../decoder/mtk_vcodec_dec_drv.h" +#include "../encoder/mtk_vcodec_enc_drv.h" +#include "mtk_vcodec_intr.h" + +int mtk_vcodec_wait_for_done_ctx(void *priv, int command, unsigned int timeout_ms, + unsigned int hw_id) +{ + int instance_type = *((int *)priv); + long timeout_jiff, ret; + int ctx_id, ctx_type, status = 0; + int *ctx_int_cond, *ctx_int_type; + wait_queue_head_t *ctx_queue; + struct platform_device *pdev; + + if (instance_type == DECODER) { + struct mtk_vcodec_dec_ctx *ctx; + + ctx = priv; + ctx_id = ctx->id; + ctx_type = ctx->type; + ctx_int_cond = ctx->int_cond; + ctx_int_type = ctx->int_type; + ctx_queue = ctx->queue; + pdev = ctx->dev->plat_dev; + } else { + struct mtk_vcodec_enc_ctx *ctx; + + ctx = priv; + ctx_id = ctx->id; + ctx_type = ctx->type; + ctx_int_cond = ctx->int_cond; + ctx_int_type = ctx->int_type; + ctx_queue = ctx->queue; + pdev = ctx->dev->plat_dev; + } + + timeout_jiff = msecs_to_jiffies(timeout_ms); + ret = wait_event_interruptible_timeout(ctx_queue[hw_id], + ctx_int_cond[hw_id], + timeout_jiff); + + if (!ret) { + status = -1; /* timeout */ + dev_err(&pdev->dev, "[%d] cmd=%d, type=%d, dec timeout=%ums (%d %d)", + ctx_id, command, ctx_type, timeout_ms, + ctx_int_cond[hw_id], ctx_int_type[hw_id]); + } else if (-ERESTARTSYS == ret) { + status = -1; + dev_err(&pdev->dev, "[%d] cmd=%d, type=%d, dec inter fail (%d %d)", + ctx_id, command, ctx_type, + ctx_int_cond[hw_id], ctx_int_type[hw_id]); + } + + ctx_int_cond[hw_id] = 0; + ctx_int_type[hw_id] = 0; + + return status; +} +EXPORT_SYMBOL(mtk_vcodec_wait_for_done_ctx); diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_intr.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_intr.h index 9681f492813b..3e3cc71ee572 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_intr.h +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_intr.h @@ -9,11 +9,11 @@ #define MTK_INST_IRQ_RECEIVED 0x1 -struct mtk_vcodec_ctx; +struct mtk_vcodec_dec_ctx; +struct mtk_vcodec_enc_ctx; /* timeout is ms */ -int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx, - int command, unsigned int timeout_ms, +int mtk_vcodec_wait_for_done_ctx(void *priv, int command, unsigned int timeout_ms, unsigned int hw_id); #endif /* _MTK_VCODEC_INTR_H_ */ diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_util.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c index f214e6f67005..908602031fd0 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_util.c +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c @@ -7,11 +7,11 @@ #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> +#include <linux/regmap.h> -#include "mtk_vcodec_dec_hw.h" -#include "mtk_vcodec_drv.h" -#include "mtk_vcodec_util.h" +#include "../decoder/mtk_vcodec_dec_drv.h" +#include "../encoder/mtk_vcodec_enc_drv.h" +#include "../decoder/mtk_vcodec_dec_hw.h" #if defined(CONFIG_DEBUG_FS) int mtk_vcodec_dbg; @@ -21,59 +21,66 @@ int mtk_v4l2_dbg_level; EXPORT_SYMBOL(mtk_v4l2_dbg_level); #endif -void __iomem *mtk_vcodec_get_reg_addr(struct mtk_vcodec_ctx *data, - unsigned int reg_idx) +void __iomem *mtk_vcodec_get_reg_addr(void __iomem **reg_base, unsigned int reg_idx) { - struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)data; - - if (!data || reg_idx >= NUM_MAX_VCODEC_REG_BASE) { - mtk_v4l2_err("Invalid arguments, reg_idx=%d", reg_idx); + if (reg_idx >= NUM_MAX_VCODEC_REG_BASE) { + pr_err(MTK_DBG_V4L2_STR "Invalid arguments, reg_idx=%d", reg_idx); return NULL; } - return ctx->dev->reg_base[reg_idx]; + return reg_base[reg_idx]; } EXPORT_SYMBOL(mtk_vcodec_get_reg_addr); -int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data, - struct mtk_vcodec_mem *mem) +int mtk_vcodec_write_vdecsys(struct mtk_vcodec_dec_ctx *ctx, unsigned int reg, + unsigned int val) +{ + struct mtk_vcodec_dec_dev *dev = ctx->dev; + + if (dev->vdecsys_regmap) + return regmap_write(dev->vdecsys_regmap, reg, val); + + writel(val, dev->reg_base[VDEC_SYS] + reg); + + return 0; +} +EXPORT_SYMBOL(mtk_vcodec_write_vdecsys); + +int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) { unsigned long size = mem->size; - struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)data; + struct mtk_vcodec_dec_ctx *ctx = priv; struct device *dev = &ctx->dev->plat_dev->dev; mem->va = dma_alloc_coherent(dev, size, &mem->dma_addr, GFP_KERNEL); if (!mem->va) { - mtk_v4l2_err("%s dma_alloc size=%ld failed!", dev_name(dev), - size); + mtk_v4l2_vdec_err(ctx, "%s dma_alloc size=%ld failed!", dev_name(dev), size); return -ENOMEM; } - mtk_v4l2_debug(3, "[%d] - va = %p", ctx->id, mem->va); - mtk_v4l2_debug(3, "[%d] - dma = 0x%lx", ctx->id, - (unsigned long)mem->dma_addr); - mtk_v4l2_debug(3, "[%d] size = 0x%lx", ctx->id, size); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] - va = %p", ctx->id, mem->va); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] - dma = 0x%lx", ctx->id, + (unsigned long)mem->dma_addr); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] size = 0x%lx", ctx->id, size); return 0; } EXPORT_SYMBOL(mtk_vcodec_mem_alloc); -void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data, - struct mtk_vcodec_mem *mem) +void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) { unsigned long size = mem->size; - struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)data; + struct mtk_vcodec_dec_ctx *ctx = priv; struct device *dev = &ctx->dev->plat_dev->dev; if (!mem->va) { - mtk_v4l2_err("%s dma_free size=%ld failed!", dev_name(dev), - size); + mtk_v4l2_vdec_err(ctx, "%s dma_free size=%ld failed!", dev_name(dev), size); return; } - mtk_v4l2_debug(3, "[%d] - va = %p", ctx->id, mem->va); - mtk_v4l2_debug(3, "[%d] - dma = 0x%lx", ctx->id, - (unsigned long)mem->dma_addr); - mtk_v4l2_debug(3, "[%d] size = 0x%lx", ctx->id, size); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] - va = %p", ctx->id, mem->va); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] - dma = 0x%lx", ctx->id, + (unsigned long)mem->dma_addr); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] size = 0x%lx", ctx->id, size); dma_free_coherent(dev, size, mem->va, mem->dma_addr); mem->va = NULL; @@ -82,10 +89,10 @@ void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data, } EXPORT_SYMBOL(mtk_vcodec_mem_free); -void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int hw_idx) +void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dec_dev *dev, int hw_idx) { if (hw_idx >= MTK_VDEC_HW_MAX || hw_idx < 0 || !dev->subdev_dev[hw_idx]) { - mtk_v4l2_err("hw idx is out of range:%d", hw_idx); + dev_err(&dev->plat_dev->dev, "hw idx is out of range:%d", hw_idx); return NULL; } @@ -93,8 +100,8 @@ void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int hw_idx) } EXPORT_SYMBOL(mtk_vcodec_get_hw_dev); -void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev, - struct mtk_vcodec_ctx *ctx, int hw_idx) +void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dec_dev *vdec_dev, + struct mtk_vcodec_dec_ctx *ctx, int hw_idx) { unsigned long flags; struct mtk_vdec_hw_dev *subdev_dev; @@ -103,7 +110,7 @@ void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev, if (vdec_dev->vdec_pdata->is_subdev_supported) { subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx); if (!subdev_dev) { - mtk_v4l2_err("Failed to get hw dev"); + dev_err(&vdec_dev->plat_dev->dev, "Failed to get hw dev"); spin_unlock_irqrestore(&vdec_dev->irqlock, flags); return; } @@ -115,18 +122,18 @@ void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev, } EXPORT_SYMBOL(mtk_vcodec_set_curr_ctx); -struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev, - unsigned int hw_idx) +struct mtk_vcodec_dec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dec_dev *vdec_dev, + unsigned int hw_idx) { unsigned long flags; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; struct mtk_vdec_hw_dev *subdev_dev; spin_lock_irqsave(&vdec_dev->irqlock, flags); if (vdec_dev->vdec_pdata->is_subdev_supported) { subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx); if (!subdev_dev) { - mtk_v4l2_err("Failed to get hw dev"); + dev_err(&vdec_dev->plat_dev->dev, "Failed to get hw dev"); spin_unlock_irqrestore(&vdec_dev->irqlock, flags); return NULL; } diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h new file mode 100644 index 000000000000..85f615cdd4d3 --- /dev/null +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* Copyright (c) 2016 MediaTek Inc. +* Author: PC Chen <pc.chen@mediatek.com> +* Tiffany Lin <tiffany.lin@mediatek.com> +*/ + +#ifndef _MTK_VCODEC_UTIL_H_ +#define _MTK_VCODEC_UTIL_H_ + +#include <linux/types.h> +#include <linux/dma-direction.h> + +#define MTK_DBG_VCODEC_STR "[MTK_VCODEC]" +#define MTK_DBG_V4L2_STR "[MTK_V4L2]" + +struct mtk_vcodec_mem { + size_t size; + void *va; + dma_addr_t dma_addr; +}; + +struct mtk_vcodec_fb { + size_t size; + dma_addr_t dma_addr; +}; + +struct mtk_vcodec_dec_ctx; +struct mtk_vcodec_dec_dev; + +#undef pr_fmt +#define pr_fmt(fmt) "%s(),%d: " fmt, __func__, __LINE__ + +#define mtk_v4l2_err(plat_dev, fmt, args...) \ + dev_err(&(plat_dev)->dev, "[MTK_V4L2][ERROR] " fmt "\n", ##args) + +#define mtk_vcodec_err(inst_id, plat_dev, fmt, args...) \ + dev_err(&(plat_dev)->dev, "[MTK_VCODEC][ERROR][%d]: " fmt "\n", inst_id, ##args) + +#if defined(CONFIG_DEBUG_FS) +extern int mtk_v4l2_dbg_level; +extern int mtk_vcodec_dbg; + +#define mtk_v4l2_debug(plat_dev, level, fmt, args...) \ + do { \ + if (mtk_v4l2_dbg_level >= (level)) \ + dev_dbg(&(plat_dev)->dev, "[MTK_V4L2] %s, %d: " fmt "\n", \ + __func__, __LINE__, ##args); \ + } while (0) + +#define mtk_vcodec_debug(inst_id, plat_dev, fmt, args...) \ + do { \ + if (mtk_vcodec_dbg) \ + dev_dbg(&(plat_dev)->dev, "[MTK_VCODEC][%d]: %s, %d " fmt "\n", \ + inst_id, __func__, __LINE__, ##args); \ + } while (0) +#else +#define mtk_v4l2_debug(plat_dev, level, fmt, args...) \ + dev_dbg(&(plat_dev)->dev, "[MTK_V4L2]: " fmt "\n", ##args) + +#define mtk_vcodec_debug(inst_id, plat_dev, fmt, args...) \ + dev_dbg(&(plat_dev)->dev, "[MTK_VCODEC][%d]: " fmt "\n", inst_id, ##args) +#endif + +void __iomem *mtk_vcodec_get_reg_addr(void __iomem **reg_base, unsigned int reg_idx); +int mtk_vcodec_write_vdecsys(struct mtk_vcodec_dec_ctx *ctx, unsigned int reg, unsigned int val); +int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem); +void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem); +void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dec_dev *vdec_dev, + struct mtk_vcodec_dec_ctx *ctx, int hw_idx); +struct mtk_vcodec_dec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dec_dev *vdec_dev, + unsigned int hw_idx); +void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dec_dev *dev, int hw_idx); + +#endif /* _MTK_VCODEC_UTIL_H_ */ diff --git a/drivers/media/platform/mediatek/vcodec/decoder/Makefile b/drivers/media/platform/mediatek/vcodec/decoder/Makefile new file mode 100644 index 000000000000..904cd22def84 --- /dev/null +++ b/drivers/media/platform/mediatek/vcodec/decoder/Makefile @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \ + mtk-vcodec-dec-hw.o + +mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ + vdec/vdec_vp8_if.o \ + vdec/vdec_vp8_req_if.o \ + vdec/vdec_vp9_if.o \ + vdec/vdec_vp9_req_lat_if.o \ + vdec/vdec_av1_req_lat_if.o \ + vdec/vdec_h264_req_if.o \ + vdec/vdec_h264_req_common.o \ + vdec/vdec_h264_req_multi_if.o \ + vdec/vdec_hevc_req_multi_if.o \ + mtk_vcodec_dec_drv.o \ + vdec_drv_if.o \ + vdec_vpu_if.o \ + vdec_msg_queue.o \ + mtk_vcodec_dec.o \ + mtk_vcodec_dec_stateful.o \ + mtk_vcodec_dec_stateless.o \ + mtk_vcodec_dec_pm.o \ + +mtk-vcodec-dec-hw-y := mtk_vcodec_dec_hw.o diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c index 93fcea821001..91ed576d6821 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c @@ -9,10 +9,8 @@ #include <media/v4l2-mem2mem.h> #include <media/videobuf2-dma-contig.h> -#include "mtk_vcodec_drv.h" +#include "mtk_vcodec_dec_drv.h" #include "mtk_vcodec_dec.h" -#include "mtk_vcodec_intr.h" -#include "mtk_vcodec_util.h" #include "vdec_drv_if.h" #include "mtk_vcodec_dec_pm.h" @@ -35,11 +33,13 @@ mtk_vdec_find_format(struct v4l2_format *f, return NULL; } -static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx *ctx, int format_index) +static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_dec_ctx *ctx, int format_index) { const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata; const struct mtk_video_fmt *fmt; + struct mtk_q_data *q_data; int num_frame_count = 0, i; + bool ret = false; fmt = &dec_pdata->vdec_formats[format_index]; for (i = 0; i < *dec_pdata->num_formats; i++) { @@ -49,13 +49,29 @@ static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx *ctx, int format_index) num_frame_count++; } - if (num_frame_count == 1 || fmt->fourcc == V4L2_PIX_FMT_MM21) + if (num_frame_count == 1 || (!ctx->is_10bit_bitstream && fmt->fourcc == V4L2_PIX_FMT_MM21)) return true; - return false; + q_data = &ctx->q_data[MTK_Q_DATA_SRC]; + switch (q_data->fmt->fourcc) { + case V4L2_PIX_FMT_H264_SLICE: + if (ctx->is_10bit_bitstream && fmt->fourcc == V4L2_PIX_FMT_MT2110R) + ret = true; + break; + case V4L2_PIX_FMT_VP9_FRAME: + case V4L2_PIX_FMT_AV1_FRAME: + case V4L2_PIX_FMT_HEVC_SLICE: + if (ctx->is_10bit_bitstream && fmt->fourcc == V4L2_PIX_FMT_MT2110T) + ret = true; + break; + default: + break; + } + + return ret; } -static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx, +static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_dec_ctx *ctx, enum v4l2_buf_type type) { if (V4L2_TYPE_IS_OUTPUT(type)) @@ -74,7 +90,7 @@ static int vidioc_try_decoder_cmd(struct file *file, void *priv, static int vidioc_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv); struct vb2_queue *src_vq, *dst_vq; int ret; @@ -82,7 +98,7 @@ static int vidioc_decoder_cmd(struct file *file, void *priv, if (ret) return ret; - mtk_v4l2_debug(1, "decoder cmd=%u", cmd->cmd); + mtk_v4l2_vdec_dbg(1, ctx, "decoder cmd=%u", cmd->cmd); dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); switch (cmd->cmd) { @@ -90,11 +106,11 @@ static int vidioc_decoder_cmd(struct file *file, void *priv, src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); if (!vb2_is_streaming(src_vq)) { - mtk_v4l2_debug(1, "Output stream is off. No need to flush."); + mtk_v4l2_vdec_dbg(1, ctx, "Output stream is off. No need to flush."); return 0; } if (!vb2_is_streaming(dst_vq)) { - mtk_v4l2_debug(1, "Capture stream is off. No need to flush."); + mtk_v4l2_vdec_dbg(1, ctx, "Capture stream is off. No need to flush."); return 0; } v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf.vb); @@ -112,23 +128,23 @@ static int vidioc_decoder_cmd(struct file *file, void *priv, return 0; } -void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx) +void mtk_vdec_unlock(struct mtk_vcodec_dec_ctx *ctx) { mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]); } -void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx) +void mtk_vdec_lock(struct mtk_vcodec_dec_ctx *ctx) { mutex_lock(&ctx->dev->dec_mutex[ctx->hw_id]); } -void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx) +void mtk_vcodec_dec_release(struct mtk_vcodec_dec_ctx *ctx) { vdec_if_deinit(ctx); ctx->state = MTK_STATE_FREE; } -void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx) +void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_dec_ctx *ctx) { struct mtk_q_data *q_data; @@ -169,11 +185,10 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx) static int vidioc_vdec_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv); if (ctx->state == MTK_STATE_ABORT) { - mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error", - ctx->id); + mtk_v4l2_vdec_err(ctx, "[%d] Call on QBUF after unrecoverable error", ctx->id); return -EIO; } @@ -183,11 +198,10 @@ static int vidioc_vdec_qbuf(struct file *file, void *priv, static int vidioc_vdec_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv); if (ctx->state == MTK_STATE_ABORT) { - mtk_v4l2_err("[%d] Call on DQBUF after unrecoverable error", - ctx->id); + mtk_v4l2_vdec_err(ctx, "[%d] Call on DQBUF after unrecoverable error", ctx->id); return -EIO; } @@ -196,7 +210,7 @@ static int vidioc_vdec_dqbuf(struct file *file, void *priv, static int mtk_vcodec_dec_get_chip_name(void *priv) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv); struct device *dev = &ctx->dev->plat_dev->dev; if (of_device_is_compatible(dev->of_node, "mediatek,mt8173-vcodec-dec")) @@ -218,7 +232,7 @@ static int mtk_vcodec_dec_get_chip_name(void *priv) static int vidioc_vdec_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv); struct device *dev = &ctx->dev->plat_dev->dev; int platform_name = mtk_vcodec_dec_get_chip_name(priv); @@ -231,7 +245,7 @@ static int vidioc_vdec_querycap(struct file *file, void *priv, static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(fh); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(fh); if (ctx->dev->vdec_pdata->uses_stateless_api) return v4l2_ctrl_subscribe_event(fh, sub); @@ -246,7 +260,7 @@ static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh, } } -static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f, +static int vidioc_try_fmt(struct mtk_vcodec_dec_ctx *ctx, struct v4l2_format *f, const struct mtk_video_fmt *fmt) { struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; @@ -288,11 +302,10 @@ static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f, (pix_fmt_mp->height + 64) <= frmsize->max_height) pix_fmt_mp->height += 64; - mtk_v4l2_debug(0, - "before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d", - tmp_w, tmp_h, pix_fmt_mp->width, - pix_fmt_mp->height, - pix_fmt_mp->width * pix_fmt_mp->height); + mtk_v4l2_vdec_dbg(0, ctx, + "before resize wxh=%dx%d, after resize wxh=%dx%d, sizeimage=%d", + tmp_w, tmp_h, pix_fmt_mp->width, pix_fmt_mp->height, + pix_fmt_mp->width * pix_fmt_mp->height); pix_fmt_mp->num_planes = fmt->num_planes; pix_fmt_mp->plane_fmt[0].sizeimage = @@ -315,7 +328,7 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv, struct v4l2_format *f) { const struct mtk_video_fmt *fmt; - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv); const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata; fmt = mtk_vdec_find_format(f, dec_pdata); @@ -333,7 +346,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, { struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; const struct mtk_video_fmt *fmt; - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv); const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata; fmt = mtk_vdec_find_format(f, dec_pdata); @@ -344,7 +357,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, } if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) { - mtk_v4l2_err("sizeimage of output format must be given"); + mtk_v4l2_vdec_err(ctx, "sizeimage of output format must be given"); return -EINVAL; } @@ -354,7 +367,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, static int vidioc_vdec_g_selection(struct file *file, void *priv, struct v4l2_selection *s) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv); struct mtk_q_data *q_data; if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) @@ -403,7 +416,7 @@ static int vidioc_vdec_g_selection(struct file *file, void *priv, static int vidioc_vdec_s_selection(struct file *file, void *priv, struct v4l2_selection *s) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv); if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -425,14 +438,14 @@ static int vidioc_vdec_s_selection(struct file *file, void *priv, static int vidioc_vdec_s_fmt(struct file *file, void *priv, struct v4l2_format *f) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv); struct v4l2_pix_format_mplane *pix_mp; struct mtk_q_data *q_data; int ret = 0; const struct mtk_video_fmt *fmt; const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata; - mtk_v4l2_debug(3, "[%d]", ctx->id); + mtk_v4l2_vdec_dbg(3, ctx, "[%d]", ctx->id); q_data = mtk_vdec_get_q_data(ctx, f->type); if (!q_data) @@ -446,7 +459,7 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, if (!dec_pdata->uses_stateless_api && f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && vb2_is_busy(&ctx->m2m_ctx->out_q_ctx.q)) { - mtk_v4l2_err("out_q_ctx buffers already requested"); + mtk_v4l2_vdec_err(ctx, "out_q_ctx buffers already requested"); ret = -EBUSY; } @@ -456,7 +469,7 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, */ if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) && vb2_is_busy(&ctx->m2m_ctx->cap_q_ctx.q)) { - mtk_v4l2_err("cap_q_ctx buffers already requested"); + mtk_v4l2_vdec_err(ctx, "cap_q_ctx buffers already requested"); ret = -EBUSY; } @@ -491,8 +504,8 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, if (ctx->state == MTK_STATE_FREE) { ret = vdec_if_init(ctx, q_data->fmt->fourcc); if (ret) { - mtk_v4l2_err("[%d]: vdec_if_init() fail ret=%d", - ctx->id, ret); + mtk_v4l2_vdec_err(ctx, "[%d]: vdec_if_init() fail ret=%d", + ctx->id, ret); return -EINVAL; } ctx->state = MTK_STATE_INIT; @@ -515,8 +528,8 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, */ ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo); if (ret) { - mtk_v4l2_err("[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail", - ctx->id); + mtk_v4l2_vdec_err(ctx, "[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail", + ctx->id); } ctx->last_decoded_picinfo = ctx->picinfo; @@ -540,11 +553,13 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, ctx->q_data[MTK_Q_DATA_DST].coded_width = ctx->picinfo.buf_w; ctx->q_data[MTK_Q_DATA_DST].coded_height = ctx->picinfo.buf_h; - mtk_v4l2_debug(2, "[%d] vdec_if_init() num_plane = %d wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x", - ctx->id, pix_mp->num_planes, ctx->picinfo.buf_w, ctx->picinfo.buf_h, - ctx->picinfo.pic_w, ctx->picinfo.pic_h, - ctx->q_data[MTK_Q_DATA_DST].sizeimage[0], - ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]); + mtk_v4l2_vdec_dbg(2, ctx, + "[%d] init() plane:%d wxh=%dx%d pic wxh=%dx%d sz=0x%x_0x%x", + ctx->id, pix_mp->num_planes, + ctx->picinfo.buf_w, ctx->picinfo.buf_h, + ctx->picinfo.pic_w, ctx->picinfo.pic_h, + ctx->q_data[MTK_Q_DATA_DST].sizeimage[0], + ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]); } return 0; } @@ -553,7 +568,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, struct v4l2_frmsizeenum *fsize) { int i = 0; - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv); const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata; if (fsize->index != 0) @@ -570,14 +585,11 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; fsize->stepwise = dec_pdata->vdec_formats[i].frmsize; - mtk_v4l2_debug(1, "%x, %d %d %d %d %d %d", - ctx->dev->dec_capability, - fsize->stepwise.min_width, - fsize->stepwise.max_width, - fsize->stepwise.step_width, - fsize->stepwise.min_height, - fsize->stepwise.max_height, - fsize->stepwise.step_height); + mtk_v4l2_vdec_dbg(1, ctx, "%x, %d %d %d %d %d %d", + ctx->dev->dec_capability, fsize->stepwise.min_width, + fsize->stepwise.max_width, fsize->stepwise.step_width, + fsize->stepwise.min_height, fsize->stepwise.max_height, + fsize->stepwise.step_height); return 0; } @@ -588,7 +600,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv, bool output_queue) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv); const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata; const struct mtk_video_fmt *fmt; int i, j = 0; @@ -634,14 +646,14 @@ static int vidioc_vdec_enum_fmt_vid_out(struct file *file, void *priv, static int vidioc_vdec_g_fmt(struct file *file, void *priv, struct v4l2_format *f) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv); struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; struct vb2_queue *vq; struct mtk_q_data *q_data; vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); if (!vq) { - mtk_v4l2_err("no vb2 queue for type=%d", f->type); + mtk_v4l2_vdec_err(ctx, "no vb2 queue for type=%d", f->type); return -EINVAL; } @@ -712,8 +724,8 @@ static int vidioc_vdec_g_fmt(struct file *file, void *priv, pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1]; pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1]; - mtk_v4l2_debug(1, "[%d] type=%d state=%d Format information could not be read, not ready yet!", - ctx->id, f->type, ctx->state); + mtk_v4l2_vdec_dbg(1, ctx, "[%d] type=%d state=%d Format information not ready!", + ctx->id, f->type, ctx->state); } return 0; @@ -723,14 +735,14 @@ int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], struct device *alloc_devs[]) { - struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq); + struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vq); struct mtk_q_data *q_data; unsigned int i; q_data = mtk_vdec_get_q_data(ctx, vq->type); if (q_data == NULL) { - mtk_v4l2_err("vq->type=%d err\n", vq->type); + mtk_v4l2_vdec_err(ctx, "vq->type=%d err\n", vq->type); return -EINVAL; } @@ -756,30 +768,28 @@ int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, sizes[i] = q_data->sizeimage[i]; } - mtk_v4l2_debug(1, - "[%d]\t type = %d, get %d plane(s), %d buffer(s) of size 0x%x 0x%x ", - ctx->id, vq->type, *nplanes, *nbuffers, - sizes[0], sizes[1]); + mtk_v4l2_vdec_dbg(1, ctx, + "[%d]\t type = %d, get %d plane(s), %d buffer(s) of size 0x%x 0x%x ", + ctx->id, vq->type, *nplanes, *nbuffers, sizes[0], sizes[1]); return 0; } int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb) { - struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct mtk_q_data *q_data; int i; - mtk_v4l2_debug(3, "[%d] (%d) id=%d", - ctx->id, vb->vb2_queue->type, vb->index); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] (%d) id=%d", + ctx->id, vb->vb2_queue->type, vb->index); q_data = mtk_vdec_get_q_data(ctx, vb->vb2_queue->type); for (i = 0; i < q_data->fmt->num_planes; i++) { if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) { - mtk_v4l2_err("data will not fit into plane %d (%lu < %d)", - i, vb2_plane_size(vb, i), - q_data->sizeimage[i]); + mtk_v4l2_vdec_err(ctx, "data will not fit into plane %d (%lu < %d)", + i, vb2_plane_size(vb, i), q_data->sizeimage[i]); return -EINVAL; } if (!V4L2_TYPE_IS_OUTPUT(vb->type)) @@ -791,7 +801,7 @@ int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb) void vb2ops_vdec_buf_finish(struct vb2_buffer *vb) { - struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct vb2_v4l2_buffer *vb2_v4l2; struct mtk_video_dec_buf *buf; bool buf_error; @@ -807,7 +817,7 @@ void vb2ops_vdec_buf_finish(struct vb2_buffer *vb) mutex_unlock(&ctx->lock); if (buf_error) { - mtk_v4l2_err("Unrecoverable error on buffer."); + mtk_v4l2_vdec_err(ctx, "Unrecoverable error on buffer."); ctx->state = MTK_STATE_ABORT; } } @@ -829,7 +839,7 @@ int vb2ops_vdec_buf_init(struct vb2_buffer *vb) int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count) { - struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q); + struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(q); if (ctx->state == MTK_STATE_FLUSH) ctx->state = MTK_STATE_HEADER; @@ -840,11 +850,11 @@ int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count) void vb2ops_vdec_stop_streaming(struct vb2_queue *q) { struct vb2_v4l2_buffer *src_buf = NULL, *dst_buf = NULL; - struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q); + struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(q); int ret; - mtk_v4l2_debug(3, "[%d] (%d) state=(%x) ctx->decoded_frame_cnt=%d", - ctx->id, q->type, ctx->state, ctx->decoded_frame_cnt); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] (%d) state=(%x) ctx->decoded_frame_cnt=%d", + ctx->id, q->type, ctx->state, ctx->decoded_frame_cnt); if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) { @@ -870,17 +880,17 @@ void vb2ops_vdec_stop_streaming(struct vb2_queue *q) */ ctx->picinfo = ctx->last_decoded_picinfo; - mtk_v4l2_debug(2, - "[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)", - ctx->id, ctx->last_decoded_picinfo.pic_w, - ctx->last_decoded_picinfo.pic_h, - ctx->picinfo.pic_w, ctx->picinfo.pic_h, - ctx->last_decoded_picinfo.buf_w, - ctx->last_decoded_picinfo.buf_h); + mtk_v4l2_vdec_dbg(2, ctx, + "[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)", + ctx->id, ctx->last_decoded_picinfo.pic_w, + ctx->last_decoded_picinfo.pic_h, + ctx->picinfo.pic_w, ctx->picinfo.pic_h, + ctx->last_decoded_picinfo.buf_w, + ctx->last_decoded_picinfo.buf_h); ret = ctx->dev->vdec_pdata->flush_decoder(ctx); if (ret) - mtk_v4l2_err("DecodeFinal failed, ret=%d", ret); + mtk_v4l2_vdec_err(ctx, "DecodeFinal failed, ret=%d", ret); } ctx->state = MTK_STATE_FLUSH; @@ -895,17 +905,17 @@ void vb2ops_vdec_stop_streaming(struct vb2_queue *q) static void m2mops_vdec_device_run(void *priv) { - struct mtk_vcodec_ctx *ctx = priv; - struct mtk_vcodec_dev *dev = ctx->dev; + struct mtk_vcodec_dec_ctx *ctx = priv; + struct mtk_vcodec_dec_dev *dev = ctx->dev; queue_work(dev->decode_workqueue, &ctx->decode_work); } static int m2mops_vdec_job_ready(void *m2m_priv) { - struct mtk_vcodec_ctx *ctx = m2m_priv; + struct mtk_vcodec_dec_ctx *ctx = m2m_priv; - mtk_v4l2_debug(3, "[%d]", ctx->id); + mtk_v4l2_vdec_dbg(3, ctx, "[%d]", ctx->id); if (ctx->state == MTK_STATE_ABORT) return 0; @@ -922,7 +932,7 @@ static int m2mops_vdec_job_ready(void *m2m_priv) static void m2mops_vdec_job_abort(void *priv) { - struct mtk_vcodec_ctx *ctx = priv; + struct mtk_vcodec_dec_ctx *ctx = priv; ctx->state = MTK_STATE_ABORT; } @@ -970,10 +980,10 @@ const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops = { int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) { - struct mtk_vcodec_ctx *ctx = priv; + struct mtk_vcodec_dec_ctx *ctx = priv; int ret = 0; - mtk_v4l2_debug(3, "[%d]", ctx->id); + mtk_v4l2_vdec_dbg(3, ctx, "[%d]", ctx->id); src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; src_vq->io_modes = VB2_DMABUF | VB2_MMAP; @@ -988,7 +998,7 @@ int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq, ret = vb2_queue_init(src_vq); if (ret) { - mtk_v4l2_err("Failed to initialize videobuf2 queue(output)"); + mtk_v4l2_vdec_err(ctx, "Failed to initialize videobuf2 queue(output)"); return ret; } dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; @@ -1004,7 +1014,7 @@ int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq, ret = vb2_queue_init(dst_vq); if (ret) - mtk_v4l2_err("Failed to initialize videobuf2 queue(capture)"); + mtk_v4l2_vdec_err(ctx, "Failed to initialize videobuf2 queue(capture)"); return ret; } diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.h index 4572f92826f2..ece27c880e50 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.h +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.h @@ -11,6 +11,8 @@ #include <media/videobuf2-core.h> #include <media/v4l2-mem2mem.h> +#include "mtk_vcodec_dec_drv.h" + #define VCODEC_DEC_ALIGNED_64 64 #define VCODEC_CAPABILITY_4K_DISABLED 0x10 #define VCODEC_DEC_4K_CODED_WIDTH 4096U @@ -78,12 +80,12 @@ extern const struct mtk_vcodec_dec_pdata mtk_vdec_single_core_pdata; * mtk_vdec_lock get decoder hw lock and set curr_ctx * to ctx instance that get lock */ -void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx); -void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx); +void mtk_vdec_unlock(struct mtk_vcodec_dec_ctx *ctx); +void mtk_vdec_lock(struct mtk_vcodec_dec_ctx *ctx); int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq); -void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx); -void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx); +void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_dec_ctx *ctx); +void mtk_vcodec_dec_release(struct mtk_vcodec_dec_ctx *ctx); /* * VB2 ops diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c index d41f2121b94f..0a89ce452ac3 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c @@ -5,27 +5,28 @@ * Tiffany Lin <tiffany.lin@mediatek.com> */ +#include <linux/bitfield.h> #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/mfd/syscon.h> #include <linux/module.h> -#include <linux/of_device.h> #include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/regmap.h> #include <media/v4l2-event.h> #include <media/v4l2-mem2mem.h> #include <media/videobuf2-dma-contig.h> #include <media/v4l2-device.h> -#include "mtk_vcodec_drv.h" #include "mtk_vcodec_dec.h" #include "mtk_vcodec_dec_hw.h" #include "mtk_vcodec_dec_pm.h" -#include "mtk_vcodec_intr.h" -#include "mtk_vcodec_util.h" -#include "mtk_vcodec_fw.h" +#include "../common/mtk_vcodec_intr.h" -static int mtk_vcodec_get_hw_count(struct mtk_vcodec_dev *dev) +static int mtk_vcodec_get_hw_count(struct mtk_vcodec_dec_ctx *ctx, struct mtk_vcodec_dec_dev *dev) { switch (dev->vdec_pdata->hw_arch) { case MTK_VDEC_PURE_SINGLE_CORE: @@ -33,27 +34,35 @@ static int mtk_vcodec_get_hw_count(struct mtk_vcodec_dev *dev) case MTK_VDEC_LAT_SINGLE_CORE: return MTK_VDEC_ONE_LAT_ONE_CORE; default: - mtk_v4l2_err("hw arch %d not supported", dev->vdec_pdata->hw_arch); + mtk_v4l2_vdec_err(ctx, "hw arch %d not supported", dev->vdec_pdata->hw_arch); return MTK_VDEC_NO_HW; } } +static bool mtk_vcodec_is_hw_active(struct mtk_vcodec_dec_dev *dev) +{ + u32 cg_status; + + if (dev->vdecsys_regmap) + return !regmap_test_bits(dev->vdecsys_regmap, VDEC_HW_ACTIVE_ADDR, + VDEC_HW_ACTIVE_MASK); + + cg_status = readl(dev->reg_base[VDEC_SYS] + VDEC_HW_ACTIVE_ADDR); + return !FIELD_GET(VDEC_HW_ACTIVE_MASK, cg_status); +} + static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv) { - struct mtk_vcodec_dev *dev = priv; - struct mtk_vcodec_ctx *ctx; - u32 cg_status = 0; + struct mtk_vcodec_dec_dev *dev = priv; + struct mtk_vcodec_dec_ctx *ctx; unsigned int dec_done_status = 0; void __iomem *vdec_misc_addr = dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG; ctx = mtk_vcodec_get_curr_ctx(dev, MTK_VDEC_CORE); - /* check if HW active or not */ - cg_status = readl(dev->reg_base[0]); - if ((cg_status & VDEC_HW_ACTIVE) != 0) { - mtk_v4l2_err("DEC ISR, VDEC active is not 0x0 (0x%08x)", - cg_status); + if (!mtk_vcodec_is_hw_active(dev)) { + mtk_v4l2_vdec_err(ctx, "DEC ISR, VDEC active is not 0x0"); return IRQ_HANDLED; } @@ -69,40 +78,86 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv) writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR), dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG); - wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0); + wake_up_dec_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0); - mtk_v4l2_debug(3, - "mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x", - ctx->id, dec_done_status); + mtk_v4l2_vdec_dbg(3, ctx, "wake up ctx %d, dec_done_status=%x", ctx->id, dec_done_status); return IRQ_HANDLED; } -static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev) +static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dec_dev *dev) { struct platform_device *pdev = dev->plat_dev; int reg_num, i; + struct resource *res; + bool has_vdecsys_reg; + int num_max_vdec_regs; + static const char * const mtk_dec_reg_names[] = { + "misc", + "ld", + "top", + "cm", + "ad", + "av", + "pp", + "hwd", + "hwq", + "hwb", + "hwg" + }; + + /* + * If we have reg-names in devicetree, this means that we're on a new + * register organization, which implies that the VDEC_SYS iospace gets + * R/W through a syscon (regmap). + * Here we try to get the "misc" iostart only to check if we have reg-names + */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "misc"); + if (res) + has_vdecsys_reg = false; + else + has_vdecsys_reg = true; + + num_max_vdec_regs = has_vdecsys_reg ? NUM_MAX_VDEC_REG_BASE : + ARRAY_SIZE(mtk_dec_reg_names); /* Sizeof(u32) * 4 bytes for each register base. */ reg_num = of_property_count_elems_of_size(pdev->dev.of_node, "reg", sizeof(u32) * 4); - if (reg_num <= 0 || reg_num > NUM_MAX_VDEC_REG_BASE) { + if (reg_num <= 0 || reg_num > num_max_vdec_regs) { dev_err(&pdev->dev, "Invalid register property size: %d\n", reg_num); return -EINVAL; } - for (i = 0; i < reg_num; i++) { - dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i); - if (IS_ERR(dev->reg_base[i])) - return PTR_ERR(dev->reg_base[i]); + if (has_vdecsys_reg) { + for (i = 0; i < reg_num; i++) { + dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i); + if (IS_ERR(dev->reg_base[i])) + return PTR_ERR(dev->reg_base[i]); + + dev_dbg(&pdev->dev, "reg[%d] base=%p", i, dev->reg_base[i]); + } + } else { + for (i = 0; i < reg_num; i++) { + dev->reg_base[i+1] = devm_platform_ioremap_resource_byname(pdev, mtk_dec_reg_names[i]); + if (IS_ERR(dev->reg_base[i+1])) + return PTR_ERR(dev->reg_base[i+1]); + + dev_dbg(&pdev->dev, "reg[%d] base=%p", i + 1, dev->reg_base[i + 1]); + } - mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]); + dev->vdecsys_regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "mediatek,vdecsys"); + if (IS_ERR(dev->vdecsys_regmap)) { + dev_err(&pdev->dev, "Missing mediatek,vdecsys property"); + return PTR_ERR(dev->vdecsys_regmap); + } } return 0; } -static int mtk_vcodec_init_dec_resources(struct mtk_vcodec_dev *dev) +static int mtk_vcodec_init_dec_resources(struct mtk_vcodec_dec_dev *dev) { struct platform_device *pdev = dev->plat_dev; int ret; @@ -139,8 +194,8 @@ static int mtk_vcodec_init_dec_resources(struct mtk_vcodec_dev *dev) static int fops_vcodec_open(struct file *file) { - struct mtk_vcodec_dev *dev = video_drvdata(file); - struct mtk_vcodec_ctx *ctx = NULL; + struct mtk_vcodec_dec_dev *dev = video_drvdata(file); + struct mtk_vcodec_dec_ctx *ctx = NULL; int ret = 0, i, hw_count; struct vb2_queue *src_vq; @@ -156,7 +211,7 @@ static int fops_vcodec_open(struct file *file) INIT_LIST_HEAD(&ctx->list); ctx->dev = dev; if (ctx->dev->vdec_pdata->is_subdev_supported) { - hw_count = mtk_vcodec_get_hw_count(dev); + hw_count = mtk_vcodec_get_hw_count(ctx, dev); if (!hw_count || !dev->subdev_prob_done) { ret = -EINVAL; goto err_ctrls_setup; @@ -176,15 +231,14 @@ static int fops_vcodec_open(struct file *file) ctx->type = MTK_INST_DECODER; ret = dev->vdec_pdata->ctrls_setup(ctx); if (ret) { - mtk_v4l2_err("Failed to setup mt vcodec controls"); + mtk_v4l2_vdec_err(ctx, "Failed to setup mt vcodec controls"); goto err_ctrls_setup; } ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev_dec, ctx, &mtk_vcodec_dec_queue_init); if (IS_ERR((__force void *)ctx->m2m_ctx)) { ret = PTR_ERR((__force void *)ctx->m2m_ctx); - mtk_v4l2_err("Failed to v4l2_m2m_ctx_init() (%d)", - ret); + mtk_v4l2_vdec_err(ctx, "Failed to v4l2_m2m_ctx_init() (%d)", ret); goto err_m2m_ctx_init; } src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, @@ -202,14 +256,14 @@ static int fops_vcodec_open(struct file *file) * Return 0 if downloading firmware successfully, * otherwise it is failed */ - mtk_v4l2_err("failed to load firmware!"); + mtk_v4l2_vdec_err(ctx, "failed to load firmware!"); goto err_load_fw; } dev->dec_capability = mtk_vcodec_fw_get_vdec_capa(dev->fw_handler); - mtk_v4l2_debug(0, "decoder capability %x", dev->dec_capability); + mtk_v4l2_vdec_dbg(0, ctx, "decoder capability %x", dev->dec_capability); } ctx->dev->vdec_pdata->init_vdec_params(ctx); @@ -218,8 +272,7 @@ static int fops_vcodec_open(struct file *file) mtk_vcodec_dbgfs_create(ctx); mutex_unlock(&dev->dev_mutex); - mtk_v4l2_debug(0, "%s decoder [%d]", dev_name(&dev->plat_dev->dev), - ctx->id); + mtk_v4l2_vdec_dbg(0, ctx, "%s decoder [%d]", dev_name(&dev->plat_dev->dev), ctx->id); return ret; /* Deinit when failure occurred */ @@ -238,10 +291,10 @@ err_ctrls_setup: static int fops_vcodec_release(struct file *file) { - struct mtk_vcodec_dev *dev = video_drvdata(file); - struct mtk_vcodec_ctx *ctx = fh_to_ctx(file->private_data); + struct mtk_vcodec_dec_dev *dev = video_drvdata(file); + struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(file->private_data); - mtk_v4l2_debug(0, "[%d] decoder", ctx->id); + mtk_v4l2_vdec_dbg(0, ctx, "[%d] decoder", ctx->id); mutex_lock(&dev->dev_mutex); /* @@ -275,7 +328,7 @@ static const struct v4l2_file_operations mtk_vcodec_fops = { static int mtk_vcodec_probe(struct platform_device *pdev) { - struct mtk_vcodec_dev *dev; + struct mtk_vcodec_dec_dev *dev; struct video_device *vfd_dec; phandle rproc_phandle; enum mtk_vcodec_fw_type fw_type; @@ -296,7 +349,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) &rproc_phandle)) { fw_type = SCP; } else { - mtk_v4l2_err("Could not get vdec IPI device"); + dev_dbg(&pdev->dev, "Could not get vdec IPI device"); return -ENODEV; } dma_set_max_seg_size(&pdev->dev, UINT_MAX); @@ -316,7 +369,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) alloc_ordered_workqueue("core-decoder", WQ_MEM_RECLAIM | WQ_FREEZABLE); if (!dev->core_workqueue) { - mtk_v4l2_err("Failed to create core workqueue"); + dev_dbg(&pdev->dev, "Failed to create core workqueue"); ret = -EINVAL; goto err_res; } @@ -332,15 +385,13 @@ static int mtk_vcodec_probe(struct platform_device *pdev) ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); if (ret) { - mtk_v4l2_err("v4l2_device_register err=%d", ret); + dev_err(&pdev->dev, "v4l2_device_register err=%d", ret); goto err_core_workq; } - init_waitqueue_head(&dev->queue); - vfd_dec = video_device_alloc(); if (!vfd_dec) { - mtk_v4l2_err("Failed to allocate video device"); + dev_err(&pdev->dev, "Failed to allocate video device"); ret = -ENOMEM; goto err_dec_alloc; } @@ -361,7 +412,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) dev->m2m_dev_dec = v4l2_m2m_init(&mtk_vdec_m2m_ops); if (IS_ERR((__force void *)dev->m2m_dev_dec)) { - mtk_v4l2_err("Failed to init mem2mem dec device"); + dev_err(&pdev->dev, "Failed to init mem2mem dec device"); ret = PTR_ERR((__force void *)dev->m2m_dev_dec); goto err_dec_alloc; } @@ -370,7 +421,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) alloc_ordered_workqueue(MTK_VCODEC_DEC_NAME, WQ_MEM_RECLAIM | WQ_FREEZABLE); if (!dev->decode_workqueue) { - mtk_v4l2_err("Failed to create decode workqueue"); + dev_err(&pdev->dev, "Failed to create decode workqueue"); ret = -EINVAL; goto err_event_workq; } @@ -379,7 +430,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); if (ret) { - mtk_v4l2_err("Main device of_platform_populate failed."); + dev_err(&pdev->dev, "Main device of_platform_populate failed."); goto err_reg_cont; } } else { @@ -392,7 +443,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, -1); if (ret) { - mtk_v4l2_err("Failed to register video device"); + dev_err(&pdev->dev, "Failed to register video device"); goto err_reg_cont; } @@ -411,21 +462,21 @@ static int mtk_vcodec_probe(struct platform_device *pdev) ret = v4l2_m2m_register_media_controller(dev->m2m_dev_dec, dev->vfd_dec, MEDIA_ENT_F_PROC_VIDEO_DECODER); if (ret) { - mtk_v4l2_err("Failed to register media controller"); + dev_err(&pdev->dev, "Failed to register media controller"); goto err_dec_mem_init; } ret = media_device_register(&dev->mdev_dec); if (ret) { - mtk_v4l2_err("Failed to register media device"); + dev_err(&pdev->dev, "Failed to register media device"); goto err_media_reg; } - mtk_v4l2_debug(0, "media registered as /dev/media%d", vfd_dec->minor); + dev_dbg(&pdev->dev, "media registered as /dev/media%d", vfd_dec->minor); } mtk_vcodec_dbgfs_init(dev, false); - mtk_v4l2_debug(0, "decoder registered as /dev/video%d", vfd_dec->minor); + dev_dbg(&pdev->dev, "decoder registered as /dev/video%d", vfd_dec->minor); return 0; @@ -484,7 +535,7 @@ MODULE_DEVICE_TABLE(of, mtk_vcodec_match); static void mtk_vcodec_dec_remove(struct platform_device *pdev) { - struct mtk_vcodec_dev *dev = platform_get_drvdata(pdev); + struct mtk_vcodec_dec_dev *dev = platform_get_drvdata(pdev); destroy_workqueue(dev->decode_workqueue); @@ -500,7 +551,7 @@ static void mtk_vcodec_dec_remove(struct platform_device *pdev) if (dev->vfd_dec) video_unregister_device(dev->vfd_dec); - mtk_vcodec_dbgfs_deinit(dev); + mtk_vcodec_dbgfs_deinit(&dev->dbgfs); v4l2_device_unregister(&dev->v4l2_dev); if (!dev->vdec_pdata->is_subdev_supported) pm_runtime_disable(dev->pm.dev); diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h new file mode 100644 index 000000000000..7e36b2c69b7d --- /dev/null +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h @@ -0,0 +1,324 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2023 MediaTek Inc. + * Author: Yunfei Dong <yunfei.dong@mediatek.com> + */ + +#ifndef _MTK_VCODEC_DEC_DRV_H_ +#define _MTK_VCODEC_DEC_DRV_H_ + +#include "../common/mtk_vcodec_cmn_drv.h" +#include "../common/mtk_vcodec_dbgfs.h" +#include "../common/mtk_vcodec_fw_priv.h" +#include "../common/mtk_vcodec_util.h" +#include "vdec_msg_queue.h" + +#define MTK_VCODEC_DEC_NAME "mtk-vcodec-dec" + +#define IS_VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE) +#define IS_VDEC_INNER_RACING(capability) ((capability) & MTK_VCODEC_INNER_RACING) + +/* + * enum mtk_vdec_format_types - Structure used to get supported + * format types according to decoder capability + */ +enum mtk_vdec_format_types { + MTK_VDEC_FORMAT_MM21 = 0x20, + MTK_VDEC_FORMAT_MT21C = 0x40, + MTK_VDEC_FORMAT_H264_SLICE = 0x100, + MTK_VDEC_FORMAT_VP8_FRAME = 0x200, + MTK_VDEC_FORMAT_VP9_FRAME = 0x400, + MTK_VDEC_FORMAT_AV1_FRAME = 0x800, + MTK_VDEC_FORMAT_HEVC_FRAME = 0x1000, + MTK_VCODEC_INNER_RACING = 0x20000, + MTK_VDEC_IS_SUPPORT_10BIT = 0x40000, +}; + +/* + * enum mtk_vdec_hw_count - Supported hardware count + */ +enum mtk_vdec_hw_count { + MTK_VDEC_NO_HW = 0, + MTK_VDEC_ONE_CORE, + MTK_VDEC_ONE_LAT_ONE_CORE, + MTK_VDEC_MAX_HW_COUNT, +}; + +/* + * enum mtk_vdec_hw_arch - Used to separate different hardware architecture + */ +enum mtk_vdec_hw_arch { + MTK_VDEC_PURE_SINGLE_CORE, + MTK_VDEC_LAT_SINGLE_CORE, +}; + +/** + * struct vdec_pic_info - picture size information + * @pic_w: picture width + * @pic_h: picture height + * @buf_w: picture buffer width (64 aligned up from pic_w) + * @buf_h: picture buffer heiht (64 aligned up from pic_h) + * @fb_sz: bitstream size of each plane + * E.g. suppose picture size is 176x144, + * buffer size will be aligned to 176x160. + * @cap_fourcc: fourcc number(may changed when resolution change) + * @reserved: align struct to 64-bit in order to adjust 32-bit and 64-bit os. + */ +struct vdec_pic_info { + unsigned int pic_w; + unsigned int pic_h; + unsigned int buf_w; + unsigned int buf_h; + unsigned int fb_sz[VIDEO_MAX_PLANES]; + unsigned int cap_fourcc; + unsigned int reserved; +}; + +/** + * struct mtk_vcodec_dec_pdata - compatible data for each IC + * @init_vdec_params: init vdec params + * @ctrls_setup: init vcodec dec ctrls + * @worker: worker to start a decode job + * @flush_decoder: function that flushes the decoder + * @get_cap_buffer: get capture buffer from capture queue + * @cap_to_disp: put capture buffer to disp list for lat and core arch + * @vdec_vb2_ops: struct vb2_ops + * + * @vdec_formats: supported video decoder formats + * @num_formats: count of video decoder formats + * @default_out_fmt: default output buffer format + * @default_cap_fmt: default capture buffer format + * + * @hw_arch: hardware arch is used to separate pure_sin_core and lat_sin_core + * + * @is_subdev_supported: whether support parent-node architecture(subdev) + * @uses_stateless_api: whether the decoder uses the stateless API with requests + */ +struct mtk_vcodec_dec_pdata { + void (*init_vdec_params)(struct mtk_vcodec_dec_ctx *ctx); + int (*ctrls_setup)(struct mtk_vcodec_dec_ctx *ctx); + void (*worker)(struct work_struct *work); + int (*flush_decoder)(struct mtk_vcodec_dec_ctx *ctx); + struct vdec_fb *(*get_cap_buffer)(struct mtk_vcodec_dec_ctx *ctx); + void (*cap_to_disp)(struct mtk_vcodec_dec_ctx *ctx, int error, + struct media_request *src_buf_req); + + const struct vb2_ops *vdec_vb2_ops; + + const struct mtk_video_fmt *vdec_formats; + const int *num_formats; + const struct mtk_video_fmt *default_out_fmt; + const struct mtk_video_fmt *default_cap_fmt; + + enum mtk_vdec_hw_arch hw_arch; + + bool is_subdev_supported; + bool uses_stateless_api; +}; + +/** + * struct mtk_vcodec_dec_ctx - Context (instance) private data. + * + * @type: type of decoder instance + * @dev: pointer to the mtk_vcodec_dec_dev of the device + * @list: link to ctx_list of mtk_vcodec_dec_dev + * + * @fh: struct v4l2_fh + * @m2m_ctx: pointer to the v4l2_m2m_ctx of the context + * @q_data: store information of input and output queue of the context + * @id: index of the context that this structure describes + * @state: state of the context + * + * @dec_if: hooked decoder driver interface + * @drv_handle: driver handle for specific decode/encode instance + * + * @picinfo: store picture info after header parsing + * @dpb_size: store dpb count after header parsing + * + * @int_cond: variable used by the waitqueue + * @int_type: type of the last interrupt + * @queue: waitqueue that can be used to wait for this context to finish + * @irq_status: irq status + * + * @ctrl_hdl: handler for v4l2 framework + * @decode_work: worker for the decoding + * @last_decoded_picinfo: pic information get from latest decode + * @empty_flush_buf: a fake size-0 capture buffer that indicates flush. Used + * for stateful decoder. + * @is_flushing: set to true if flushing is in progress. + * + * @current_codec: current set input codec, in V4L2 pixel format + * @capture_fourcc: capture queue type in V4L2 pixel format + * + * @colorspace: enum v4l2_colorspace; supplemental to pixelformat + * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding + * @quantization: enum v4l2_quantization, colorspace quantization + * @xfer_func: enum v4l2_xfer_func, colorspace transfer function + * + * @decoded_frame_cnt: number of decoded frames + * @lock: protect variables accessed by V4L2 threads and worker thread such as + * mtk_video_dec_buf. + * @hw_id: hardware index used to identify different hardware. + * + * @msg_queue: msg queue used to store lat buffer information. + * @vpu_inst: vpu instance pointer. + * + * @is_10bit_bitstream: set to true if it's 10bit bitstream + */ +struct mtk_vcodec_dec_ctx { + enum mtk_instance_type type; + struct mtk_vcodec_dec_dev *dev; + struct list_head list; + + struct v4l2_fh fh; + struct v4l2_m2m_ctx *m2m_ctx; + struct mtk_q_data q_data[2]; + int id; + enum mtk_instance_state state; + + const struct vdec_common_if *dec_if; + void *drv_handle; + + struct vdec_pic_info picinfo; + int dpb_size; + + int int_cond[MTK_VDEC_HW_MAX]; + int int_type[MTK_VDEC_HW_MAX]; + wait_queue_head_t queue[MTK_VDEC_HW_MAX]; + unsigned int irq_status; + + struct v4l2_ctrl_handler ctrl_hdl; + struct work_struct decode_work; + struct vdec_pic_info last_decoded_picinfo; + struct v4l2_m2m_buffer empty_flush_buf; + bool is_flushing; + + u32 current_codec; + u32 capture_fourcc; + + enum v4l2_colorspace colorspace; + enum v4l2_ycbcr_encoding ycbcr_enc; + enum v4l2_quantization quantization; + enum v4l2_xfer_func xfer_func; + + int decoded_frame_cnt; + struct mutex lock; + int hw_id; + + struct vdec_msg_queue msg_queue; + void *vpu_inst; + + bool is_10bit_bitstream; +}; + +/** + * struct mtk_vcodec_dec_dev - driver data + * @v4l2_dev: V4L2 device to register video devices for. + * @vfd_dec: Video device for decoder + * @mdev_dec: Media device for decoder + * + * @m2m_dev_dec: m2m device for decoder + * @plat_dev: platform device + * @ctx_list: list of struct mtk_vcodec_ctx + * @curr_ctx: The context that is waiting for codec hardware + * + * @reg_base: Mapped address of MTK Vcodec registers. + * @vdec_pdata: decoder IC-specific data + * @vdecsys_regmap: VDEC_SYS register space passed through syscon + * + * @fw_handler: used to communicate with the firmware. + * @id_counter: used to identify current opened instance + * + * @dec_mutex: decoder hardware lock + * @dev_mutex: video_device lock + * @decode_workqueue: decode work queue + * + * @irqlock: protect data access by irq handler and work thread + * @dec_irq: decoder irq resource + * + * @pm: power management control + * @dec_capability: used to identify decode capability, ex: 4k + * + * @core_workqueue: queue used for core hardware decode + * + * @subdev_dev: subdev hardware device + * @subdev_prob_done: check whether all used hw device is prob done + * @subdev_bitmap: used to record hardware is ready or not + * + * @dec_active_cnt: used to mark whether need to record register value + * @vdec_racing_info: record register value + * @dec_racing_info_mutex: mutex lock used for inner racing mode + * @dbgfs: debug log related information + */ +struct mtk_vcodec_dec_dev { + struct v4l2_device v4l2_dev; + struct video_device *vfd_dec; + struct media_device mdev_dec; + + struct v4l2_m2m_dev *m2m_dev_dec; + struct platform_device *plat_dev; + struct list_head ctx_list; + struct mtk_vcodec_dec_ctx *curr_ctx; + + void __iomem *reg_base[NUM_MAX_VCODEC_REG_BASE]; + const struct mtk_vcodec_dec_pdata *vdec_pdata; + struct regmap *vdecsys_regmap; + + struct mtk_vcodec_fw *fw_handler; + u64 id_counter; + + /* decoder hardware mutex lock */ + struct mutex dec_mutex[MTK_VDEC_HW_MAX]; + struct mutex dev_mutex; + struct workqueue_struct *decode_workqueue; + + spinlock_t irqlock; + int dec_irq; + + struct mtk_vcodec_pm pm; + unsigned int dec_capability; + + struct workqueue_struct *core_workqueue; + + void *subdev_dev[MTK_VDEC_HW_MAX]; + int (*subdev_prob_done)(struct mtk_vcodec_dec_dev *vdec_dev); + DECLARE_BITMAP(subdev_bitmap, MTK_VDEC_HW_MAX); + + atomic_t dec_active_cnt; + u32 vdec_racing_info[132]; + /* Protects access to vdec_racing_info data */ + struct mutex dec_racing_info_mutex; + struct mtk_vcodec_dbgfs dbgfs; +}; + +static inline struct mtk_vcodec_dec_ctx *fh_to_dec_ctx(struct v4l2_fh *fh) +{ + return container_of(fh, struct mtk_vcodec_dec_ctx, fh); +} + +static inline struct mtk_vcodec_dec_ctx *ctrl_to_dec_ctx(struct v4l2_ctrl *ctrl) +{ + return container_of(ctrl->handler, struct mtk_vcodec_dec_ctx, ctrl_hdl); +} + +/* Wake up context wait_queue */ +static inline void +wake_up_dec_ctx(struct mtk_vcodec_dec_ctx *ctx, unsigned int reason, unsigned int hw_id) +{ + ctx->int_cond[hw_id] = 1; + ctx->int_type[hw_id] = reason; + wake_up_interruptible(&ctx->queue[hw_id]); +} + +#define mtk_vdec_err(ctx, fmt, args...) \ + mtk_vcodec_err((ctx)->id, (ctx)->dev->plat_dev, fmt, ##args) + +#define mtk_vdec_debug(ctx, fmt, args...) \ + mtk_vcodec_debug((ctx)->id, (ctx)->dev->plat_dev, fmt, ##args) + +#define mtk_v4l2_vdec_err(ctx, fmt, args...) mtk_v4l2_err((ctx)->dev->plat_dev, fmt, ##args) + +#define mtk_v4l2_vdec_dbg(level, ctx, fmt, args...) \ + mtk_v4l2_debug((ctx)->dev->plat_dev, level, fmt, ##args) + +#endif /* _MTK_VCODEC_DEC_DRV_H_ */ diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.c index e1cb2f8dca33..881d5de41e05 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.c @@ -12,12 +12,10 @@ #include <linux/pm_runtime.h> #include <linux/slab.h> -#include "mtk_vcodec_drv.h" #include "mtk_vcodec_dec.h" #include "mtk_vcodec_dec_hw.h" #include "mtk_vcodec_dec_pm.h" -#include "mtk_vcodec_intr.h" -#include "mtk_vcodec_util.h" +#include "../common/mtk_vcodec_intr.h" static const struct of_device_id mtk_vdec_hw_match[] = { { @@ -36,7 +34,7 @@ static const struct of_device_id mtk_vdec_hw_match[] = { }; MODULE_DEVICE_TABLE(of, mtk_vdec_hw_match); -static int mtk_vdec_hw_prob_done(struct mtk_vcodec_dev *vdec_dev) +static int mtk_vdec_hw_prob_done(struct mtk_vcodec_dec_dev *vdec_dev) { struct platform_device *pdev = vdec_dev->plat_dev; struct device_node *subdev_node; @@ -66,7 +64,7 @@ static int mtk_vdec_hw_prob_done(struct mtk_vcodec_dev *vdec_dev) static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv) { struct mtk_vdec_hw_dev *dev = priv; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; u32 cg_status; unsigned int dec_done_status; void __iomem *vdec_misc_addr = dev->reg_base[VDEC_HW_MISC] + @@ -75,10 +73,9 @@ static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv) ctx = mtk_vcodec_get_curr_ctx(dev->main_dev, dev->hw_idx); /* check if HW active or not */ - cg_status = readl(dev->reg_base[VDEC_HW_SYS]); - if (cg_status & VDEC_HW_ACTIVE) { - mtk_v4l2_err("vdec active is not 0x0 (0x%08x)", - cg_status); + cg_status = readl(dev->reg_base[VDEC_HW_SYS] + VDEC_HW_ACTIVE_ADDR); + if (cg_status & VDEC_HW_ACTIVE_MASK) { + mtk_v4l2_vdec_err(ctx, "vdec active is not 0x0 (0x%08x)", cg_status); return IRQ_HANDLED; } @@ -91,10 +88,10 @@ static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv) writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr); writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr); - wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->hw_idx); + wake_up_dec_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->hw_idx); - mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x", - ctx->id, dec_done_status); + mtk_v4l2_vdec_dbg(3, ctx, "wake up ctx %d, dec_done_status=%x", + ctx->id, dec_done_status); return IRQ_HANDLED; } @@ -124,7 +121,7 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct mtk_vdec_hw_dev *subdev_dev; - struct mtk_vcodec_dev *main_dev; + struct mtk_vcodec_dec_dev *main_dev; const struct of_device_id *of_id; int hw_idx; int ret; diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.h index 36faa8d9d681..83fe8b9428e6 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.h +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.h @@ -10,9 +10,10 @@ #include <linux/io.h> #include <linux/platform_device.h> -#include "mtk_vcodec_drv.h" +#include "mtk_vcodec_dec_drv.h" -#define VDEC_HW_ACTIVE 0x10 +#define VDEC_HW_ACTIVE_ADDR 0x0 +#define VDEC_HW_ACTIVE_MASK BIT(4) #define VDEC_IRQ_CFG 0x11 #define VDEC_IRQ_CLR 0x10 #define VDEC_IRQ_CFG_REG 0xa4 @@ -45,10 +46,10 @@ enum mtk_vdec_hw_reg_idx { */ struct mtk_vdec_hw_dev { struct platform_device *plat_dev; - struct mtk_vcodec_dev *main_dev; + struct mtk_vcodec_dec_dev *main_dev; void __iomem *reg_base[VDEC_HW_MAX]; - struct mtk_vcodec_ctx *curr_ctx; + struct mtk_vcodec_dec_ctx *curr_ctx; int dec_irq; struct mtk_vcodec_pm pm; diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_pm.c index 777d445999e9..aefd3e9e3061 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_pm.c @@ -6,13 +6,11 @@ #include <linux/clk.h> #include <linux/interrupt.h> -#include <linux/of_address.h> -#include <linux/of_platform.h> +#include <linux/of.h> #include <linux/pm_runtime.h> #include "mtk_vcodec_dec_hw.h" #include "mtk_vcodec_dec_pm.h" -#include "mtk_vcodec_util.h" int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *pm) { @@ -32,7 +30,7 @@ int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm * if (!dec_clk->clk_info) return -ENOMEM; } else { - mtk_v4l2_err("Failed to get vdec clock count"); + dev_err(&pdev->dev, "Failed to get vdec clock count"); return -EINVAL; } @@ -41,14 +39,13 @@ int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm * ret = of_property_read_string_index(pdev->dev.of_node, "clock-names", i, &clk_info->clk_name); if (ret) { - mtk_v4l2_err("Failed to get clock name id = %d", i); + dev_err(&pdev->dev, "Failed to get clock name id = %d", i); return ret; } clk_info->vcodec_clk = devm_clk_get(&pdev->dev, clk_info->clk_name); if (IS_ERR(clk_info->vcodec_clk)) { - mtk_v4l2_err("devm_clk_get (%d)%s fail", i, - clk_info->clk_name); + dev_err(&pdev->dev, "devm_clk_get (%d)%s fail", i, clk_info->clk_name); return PTR_ERR(clk_info->vcodec_clk); } } @@ -63,7 +60,7 @@ static int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) ret = pm_runtime_resume_and_get(pm->dev); if (ret) - mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret); + dev_err(pm->dev, "pm_runtime_resume_and_get fail %d", ret); return ret; } @@ -74,7 +71,7 @@ static void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm) ret = pm_runtime_put(pm->dev); if (ret && ret != -EAGAIN) - mtk_v4l2_err("pm_runtime_put fail %d", ret); + dev_err(pm->dev, "pm_runtime_put fail %d", ret); } static void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm) @@ -86,7 +83,7 @@ static void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm) for (i = 0; i < dec_clk->clk_num; i++) { ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk); if (ret) { - mtk_v4l2_err("clk_prepare_enable %d %s fail %d", i, + dev_err(pm->dev, "clk_prepare_enable %d %s fail %d", i, dec_clk->clk_info[i].clk_name, ret); goto error; } @@ -108,7 +105,7 @@ static void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm) clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk); } -static void mtk_vcodec_dec_enable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_idx) +static void mtk_vcodec_dec_enable_irq(struct mtk_vcodec_dec_dev *vdec_dev, int hw_idx) { struct mtk_vdec_hw_dev *subdev_dev; @@ -120,13 +117,13 @@ static void mtk_vcodec_dec_enable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_id if (subdev_dev) enable_irq(subdev_dev->dec_irq); else - mtk_v4l2_err("Failed to get hw dev\n"); + dev_err(&vdec_dev->plat_dev->dev, "Failed to get hw dev\n"); } else { enable_irq(vdec_dev->dec_irq); } } -static void mtk_vcodec_dec_disable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_idx) +static void mtk_vcodec_dec_disable_irq(struct mtk_vcodec_dec_dev *vdec_dev, int hw_idx) { struct mtk_vdec_hw_dev *subdev_dev; @@ -138,13 +135,13 @@ static void mtk_vcodec_dec_disable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_i if (subdev_dev) disable_irq(subdev_dev->dec_irq); else - mtk_v4l2_err("Failed to get hw dev\n"); + dev_err(&vdec_dev->plat_dev->dev, "Failed to get hw dev\n"); } else { disable_irq(vdec_dev->dec_irq); } } -static void mtk_vcodec_load_racing_info(struct mtk_vcodec_ctx *ctx) +static void mtk_vcodec_load_racing_info(struct mtk_vcodec_dec_ctx *ctx) { void __iomem *vdec_racing_addr; int j; @@ -158,7 +155,7 @@ static void mtk_vcodec_load_racing_info(struct mtk_vcodec_ctx *ctx) mutex_unlock(&ctx->dev->dec_racing_info_mutex); } -static void mtk_vcodec_record_racing_info(struct mtk_vcodec_ctx *ctx) +static void mtk_vcodec_record_racing_info(struct mtk_vcodec_dec_ctx *ctx) { void __iomem *vdec_racing_addr; int j; @@ -172,7 +169,7 @@ static void mtk_vcodec_record_racing_info(struct mtk_vcodec_ctx *ctx) mutex_unlock(&ctx->dev->dec_racing_info_mutex); } -static struct mtk_vcodec_pm *mtk_vcodec_dec_get_pm(struct mtk_vcodec_dev *vdec_dev, +static struct mtk_vcodec_pm *mtk_vcodec_dec_get_pm(struct mtk_vcodec_dec_dev *vdec_dev, int hw_idx) { struct mtk_vdec_hw_dev *subdev_dev; @@ -185,14 +182,14 @@ static struct mtk_vcodec_pm *mtk_vcodec_dec_get_pm(struct mtk_vcodec_dev *vdec_d if (subdev_dev) return &subdev_dev->pm; - mtk_v4l2_err("Failed to get hw dev\n"); + dev_err(&vdec_dev->plat_dev->dev, "Failed to get hw dev\n"); return NULL; } return &vdec_dev->pm; } -static void mtk_vcodec_dec_child_dev_on(struct mtk_vcodec_dev *vdec_dev, +static void mtk_vcodec_dec_child_dev_on(struct mtk_vcodec_dec_dev *vdec_dev, int hw_idx) { struct mtk_vcodec_pm *pm; @@ -212,7 +209,7 @@ static void mtk_vcodec_dec_child_dev_on(struct mtk_vcodec_dev *vdec_dev, } } -static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dev *vdec_dev, +static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dec_dev *vdec_dev, int hw_idx) { struct mtk_vcodec_pm *pm; @@ -232,7 +229,7 @@ static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dev *vdec_dev, } } -void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx) +void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_dec_ctx *ctx, int hw_idx) { mutex_lock(&ctx->dev->dec_mutex[hw_idx]); @@ -248,7 +245,7 @@ void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx) } EXPORT_SYMBOL_GPL(mtk_vcodec_dec_enable_hardware); -void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx) +void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_dec_ctx *ctx, int hw_idx) { if (IS_VDEC_INNER_RACING(ctx->dev->dec_capability)) mtk_vcodec_record_racing_info(ctx); diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_pm.h index dbcf3cabe6f3..87a50d589d42 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.h +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_pm.h @@ -7,11 +7,11 @@ #ifndef _MTK_VCODEC_DEC_PM_H_ #define _MTK_VCODEC_DEC_PM_H_ -#include "mtk_vcodec_drv.h" +#include "mtk_vcodec_dec_drv.h" int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *pm); -void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx); -void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx); +void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_dec_ctx *ctx, int hw_idx); +void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_dec_ctx *ctx, int hw_idx); #endif /* _MTK_VCODEC_DEC_PM_H_ */ diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateful.c index 0fbd030026c7..11ca2c2fbaad 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateful.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateful.c @@ -4,10 +4,7 @@ #include <media/v4l2-mem2mem.h> #include <media/videobuf2-dma-contig.h> -#include "mtk_vcodec_drv.h" #include "mtk_vcodec_dec.h" -#include "mtk_vcodec_intr.h" -#include "mtk_vcodec_util.h" #include "mtk_vcodec_dec_pm.h" #include "vdec_drv_if.h" @@ -55,21 +52,22 @@ static const unsigned int num_supported_formats = * Note the buffers returned from codec driver may still be in driver's * reference list. */ -static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx) +static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_dec_ctx *ctx) { struct vdec_fb *disp_frame_buffer = NULL; struct mtk_video_dec_buf *dstbuf; struct vb2_v4l2_buffer *vb; - mtk_v4l2_debug(3, "[%d]", ctx->id); + mtk_v4l2_vdec_dbg(3, ctx, "[%d]", ctx->id); if (vdec_if_get_param(ctx, GET_PARAM_DISP_FRAME_BUFFER, &disp_frame_buffer)) { - mtk_v4l2_err("[%d]Cannot get param : GET_PARAM_DISP_FRAME_BUFFER", ctx->id); + mtk_v4l2_vdec_err(ctx, "[%d]Cannot get param : GET_PARAM_DISP_FRAME_BUFFER", + ctx->id); return NULL; } if (!disp_frame_buffer) { - mtk_v4l2_debug(3, "No display frame buffer"); + mtk_v4l2_vdec_dbg(3, ctx, "No display frame buffer"); return NULL; } @@ -78,9 +76,9 @@ static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx) vb = &dstbuf->m2m_buf.vb; mutex_lock(&ctx->lock); if (dstbuf->used) { - mtk_v4l2_debug(2, "[%d]status=%x queue id=%d to done_list %d", - ctx->id, disp_frame_buffer->status, - vb->vb2_buf.index, dstbuf->queued_in_vb2); + mtk_v4l2_vdec_dbg(2, ctx, "[%d]status=%x queue id=%d to done_list %d", + ctx->id, disp_frame_buffer->status, + vb->vb2_buf.index, dstbuf->queued_in_vb2); v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE); ctx->decoded_frame_cnt++; @@ -97,7 +95,7 @@ static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx) * previous sps/pps/resolution change decode, or do nothing if user * space still owns this buffer */ -static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx) +static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_dec_ctx *ctx) { struct mtk_video_dec_buf *dstbuf; struct vdec_fb *free_frame_buffer = NULL; @@ -105,16 +103,16 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx) if (vdec_if_get_param(ctx, GET_PARAM_FREE_FRAME_BUFFER, &free_frame_buffer)) { - mtk_v4l2_err("[%d] Error!! Cannot get param", ctx->id); + mtk_v4l2_vdec_err(ctx, "[%d] Error!! Cannot get param", ctx->id); return NULL; } if (!free_frame_buffer) { - mtk_v4l2_debug(3, " No free frame buffer"); + mtk_v4l2_vdec_dbg(3, ctx, " No free frame buffer"); return NULL; } - mtk_v4l2_debug(3, "[%d] tmp_frame_addr = 0x%p", ctx->id, - free_frame_buffer); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] tmp_frame_addr = 0x%p", ctx->id, + free_frame_buffer); dstbuf = container_of(free_frame_buffer, struct mtk_video_dec_buf, frame_buffer); @@ -131,9 +129,9 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx) * This reduce overheads that dq/q unused capture * buffer. In this case, queued_in_vb2 = true. */ - mtk_v4l2_debug(2, "[%d]status=%x queue id=%d to rdy_queue %d", - ctx->id, free_frame_buffer->status, - vb->vb2_buf.index, dstbuf->queued_in_vb2); + mtk_v4l2_vdec_dbg(2, ctx, "[%d]status=%x queue id=%d to rdy_queue %d", + ctx->id, free_frame_buffer->status, + vb->vb2_buf.index, dstbuf->queued_in_vb2); v4l2_m2m_buf_queue(ctx->m2m_ctx, vb); } else if (!dstbuf->queued_in_vb2 && dstbuf->queued_in_v4l2) { /* @@ -146,10 +144,10 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx) * means this buffer is not from previous decode * output. */ - mtk_v4l2_debug(2, - "[%d]status=%x queue id=%d to rdy_queue", - ctx->id, free_frame_buffer->status, - vb->vb2_buf.index); + mtk_v4l2_vdec_dbg(2, ctx, + "[%d]status=%x queue id=%d to rdy_queue", + ctx->id, free_frame_buffer->status, + vb->vb2_buf.index); v4l2_m2m_buf_queue(ctx->m2m_ctx, vb); dstbuf->queued_in_vb2 = true; } else { @@ -161,10 +159,10 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx) * When this buffer q from user space, it could * directly q to vb2 buffer */ - mtk_v4l2_debug(3, "[%d]status=%x err queue id=%d %d %d", - ctx->id, free_frame_buffer->status, - vb->vb2_buf.index, dstbuf->queued_in_vb2, - dstbuf->queued_in_v4l2); + mtk_v4l2_vdec_dbg(3, ctx, "[%d]status=%x err queue id=%d %d %d", + ctx->id, free_frame_buffer->status, + vb->vb2_buf.index, dstbuf->queued_in_vb2, + dstbuf->queued_in_v4l2); } dstbuf->used = false; } @@ -172,37 +170,37 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx) return &vb->vb2_buf; } -static void clean_display_buffer(struct mtk_vcodec_ctx *ctx) +static void clean_display_buffer(struct mtk_vcodec_dec_ctx *ctx) { while (get_display_buffer(ctx)) ; } -static void clean_free_buffer(struct mtk_vcodec_ctx *ctx) +static void clean_free_buffer(struct mtk_vcodec_dec_ctx *ctx) { while (get_free_buffer(ctx)) ; } -static void mtk_vdec_queue_res_chg_event(struct mtk_vcodec_ctx *ctx) +static void mtk_vdec_queue_res_chg_event(struct mtk_vcodec_dec_ctx *ctx) { static const struct v4l2_event ev_src_ch = { .type = V4L2_EVENT_SOURCE_CHANGE, .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, }; - mtk_v4l2_debug(1, "[%d]", ctx->id); + mtk_v4l2_vdec_dbg(1, ctx, "[%d]", ctx->id); v4l2_event_queue_fh(&ctx->fh, &ev_src_ch); } -static int mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx) +static int mtk_vdec_flush_decoder(struct mtk_vcodec_dec_ctx *ctx) { bool res_chg; int ret; ret = vdec_if_decode(ctx, NULL, NULL, &res_chg); if (ret) - mtk_v4l2_err("DecodeFinal failed, ret=%d", ret); + mtk_v4l2_vdec_err(ctx, "DecodeFinal failed, ret=%d", ret); clean_display_buffer(ctx); clean_free_buffer(ctx); @@ -210,7 +208,7 @@ static int mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx) return 0; } -static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx, +static void mtk_vdec_update_fmt(struct mtk_vcodec_dec_ctx *ctx, unsigned int pixelformat) { const struct mtk_video_fmt *fmt; @@ -221,24 +219,25 @@ static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx, for (k = 0; k < num_supported_formats; k++) { fmt = &mtk_video_formats[k]; if (fmt->fourcc == pixelformat) { - mtk_v4l2_debug(1, "Update cap fourcc(%d -> %d)", - dst_q_data->fmt->fourcc, pixelformat); + mtk_v4l2_vdec_dbg(1, ctx, "Update cap fourcc(%d -> %d)", + dst_q_data->fmt->fourcc, pixelformat); dst_q_data->fmt = fmt; return; } } - mtk_v4l2_err("Cannot get fourcc(%d), using init value", pixelformat); + mtk_v4l2_vdec_err(ctx, "Cannot get fourcc(%d), using init value", pixelformat); } -static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx) +static int mtk_vdec_pic_info_update(struct mtk_vcodec_dec_ctx *ctx) { unsigned int dpbsize = 0; int ret; if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->last_decoded_picinfo)) { - mtk_v4l2_err("[%d]Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR", ctx->id); + mtk_v4l2_vdec_err(ctx, "[%d]Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR", + ctx->id); return -EINVAL; } @@ -246,7 +245,7 @@ static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx) ctx->last_decoded_picinfo.pic_h == 0 || ctx->last_decoded_picinfo.buf_w == 0 || ctx->last_decoded_picinfo.buf_h == 0) { - mtk_v4l2_err("Cannot get correct pic info"); + mtk_v4l2_vdec_err(ctx, "Cannot get correct pic info"); return -EINVAL; } @@ -258,15 +257,15 @@ static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx) ctx->last_decoded_picinfo.pic_h == ctx->picinfo.pic_h) return 0; - mtk_v4l2_debug(1, "[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)", ctx->id, - ctx->last_decoded_picinfo.pic_w, - ctx->last_decoded_picinfo.pic_h, ctx->picinfo.pic_w, - ctx->picinfo.pic_h, ctx->last_decoded_picinfo.buf_w, - ctx->last_decoded_picinfo.buf_h); + mtk_v4l2_vdec_dbg(1, ctx, "[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)", ctx->id, + ctx->last_decoded_picinfo.pic_w, + ctx->last_decoded_picinfo.pic_h, ctx->picinfo.pic_w, + ctx->picinfo.pic_h, ctx->last_decoded_picinfo.buf_w, + ctx->last_decoded_picinfo.buf_h); ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize); if (dpbsize == 0) - mtk_v4l2_err("Incorrect dpb size, ret=%d", ret); + mtk_v4l2_vdec_err(ctx, "Incorrect dpb size, ret=%d", ret); ctx->dpb_size = dpbsize; @@ -275,9 +274,9 @@ static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx) static void mtk_vdec_worker(struct work_struct *work) { - struct mtk_vcodec_ctx *ctx = - container_of(work, struct mtk_vcodec_ctx, decode_work); - struct mtk_vcodec_dev *dev = ctx->dev; + struct mtk_vcodec_dec_ctx *ctx = + container_of(work, struct mtk_vcodec_dec_ctx, decode_work); + struct mtk_vcodec_dec_dev *dev = ctx->dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; struct mtk_vcodec_mem buf; struct vdec_fb *pfb; @@ -288,14 +287,14 @@ static void mtk_vdec_worker(struct work_struct *work) src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); if (!src_buf) { v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); - mtk_v4l2_debug(1, "[%d] src_buf empty!!", ctx->id); + mtk_v4l2_vdec_dbg(1, ctx, "[%d] src_buf empty!!", ctx->id); return; } dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); if (!dst_buf) { v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); - mtk_v4l2_debug(1, "[%d] dst_buf empty!!", ctx->id); + mtk_v4l2_vdec_dbg(1, ctx, "[%d] dst_buf empty!!", ctx->id); return; } @@ -313,15 +312,15 @@ static void mtk_vdec_worker(struct work_struct *work) vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 1); pfb->base_c.size = ctx->picinfo.fb_sz[1]; pfb->status = 0; - mtk_v4l2_debug(3, "===>[%d] vdec_if_decode() ===>", ctx->id); + mtk_v4l2_vdec_dbg(3, ctx, "===>[%d] vdec_if_decode() ===>", ctx->id); - mtk_v4l2_debug(3, - "id=%d Framebuf pfb=%p VA=%p Y_DMA=%pad C_DMA=%pad Size=%zx", - dst_buf->vb2_buf.index, pfb, pfb->base_y.va, - &pfb->base_y.dma_addr, &pfb->base_c.dma_addr, pfb->base_y.size); + mtk_v4l2_vdec_dbg(3, ctx, + "id=%d Framebuf pfb=%p VA=%p Y_DMA=%pad C_DMA=%pad Size=%zx", + dst_buf->vb2_buf.index, pfb, pfb->base_y.va, + &pfb->base_y.dma_addr, &pfb->base_c.dma_addr, pfb->base_y.size); if (src_buf == &ctx->empty_flush_buf.vb) { - mtk_v4l2_debug(1, "Got empty flush input buffer."); + mtk_v4l2_vdec_dbg(1, ctx, "Got empty flush input buffer."); src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); /* update dst buf status */ @@ -350,12 +349,12 @@ static void mtk_vdec_worker(struct work_struct *work) buf.size = (size_t)src_buf->vb2_buf.planes[0].bytesused; if (!buf.va) { v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); - mtk_v4l2_err("[%d] id=%d src_addr is NULL!!", ctx->id, - src_buf->vb2_buf.index); + mtk_v4l2_vdec_err(ctx, "[%d] id=%d src_addr is NULL!!", ctx->id, + src_buf->vb2_buf.index); return; } - mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p", - ctx->id, buf.va, &buf.dma_addr, buf.size, src_buf); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p", + ctx->id, buf.va, &buf.dma_addr, buf.size, src_buf); dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp; dst_buf->timecode = src_buf->timecode; mutex_lock(&ctx->lock); @@ -366,9 +365,10 @@ static void mtk_vdec_worker(struct work_struct *work) ret = vdec_if_decode(ctx, &buf, pfb, &res_chg); if (ret) { - mtk_v4l2_err(" <===[%d], src_buf[%d] sz=0x%zx pts=%llu dst_buf[%d] vdec_if_decode() ret=%d res_chg=%d===>", - ctx->id, src_buf->vb2_buf.index, buf.size, - src_buf->vb2_buf.timestamp, dst_buf->vb2_buf.index, ret, res_chg); + mtk_v4l2_vdec_err(ctx, + "[%d] decode src[%d] sz=0x%zx pts=%llu dst[%d] ret=%d res_chg=%d", + ctx->id, src_buf->vb2_buf.index, buf.size, + src_buf->vb2_buf.timestamp, dst_buf->vb2_buf.index, ret, res_chg); src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); if (ret == -EIO) { mutex_lock(&ctx->lock); @@ -417,12 +417,12 @@ static void vb2ops_vdec_stateful_buf_queue(struct vb2_buffer *vb) bool res_chg = false; int ret; unsigned int dpbsize = 1, i; - struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct vb2_v4l2_buffer *vb2_v4l2; struct mtk_q_data *dst_q_data; - mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", ctx->id, - vb->vb2_queue->type, vb->index, vb); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] (%d) id=%d, vb=%p", ctx->id, + vb->vb2_queue->type, vb->index, vb); /* * check if this buffer is ready to be used after decode */ @@ -448,20 +448,19 @@ static void vb2ops_vdec_stateful_buf_queue(struct vb2_buffer *vb) v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb)); if (ctx->state != MTK_STATE_INIT) { - mtk_v4l2_debug(3, "[%d] already init driver %d", ctx->id, - ctx->state); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] already init driver %d", ctx->id, ctx->state); return; } src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); if (!src_buf) { - mtk_v4l2_err("No src buffer"); + mtk_v4l2_vdec_err(ctx, "No src buffer"); return; } if (src_buf == &ctx->empty_flush_buf.vb) { /* This shouldn't happen. Just in case. */ - mtk_v4l2_err("Invalid flush buffer."); + mtk_v4l2_vdec_err(ctx, "Invalid flush buffer."); v4l2_m2m_src_buf_remove(ctx->m2m_ctx); return; } @@ -469,9 +468,8 @@ static void vb2ops_vdec_stateful_buf_queue(struct vb2_buffer *vb) src_mem.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0); src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); src_mem.size = (size_t)src_buf->vb2_buf.planes[0].bytesused; - mtk_v4l2_debug(2, "[%d] buf id=%d va=%p dma=%pad size=%zx", ctx->id, - src_buf->vb2_buf.index, src_mem.va, &src_mem.dma_addr, - src_mem.size); + mtk_v4l2_vdec_dbg(2, ctx, "[%d] buf id=%d va=%p dma=%pad size=%zx", ctx->id, + src_buf->vb2_buf.index, src_mem.va, &src_mem.dma_addr, src_mem.size); ret = vdec_if_decode(ctx, &src_mem, NULL, &res_chg); if (ret || !res_chg) { @@ -484,20 +482,22 @@ static void vb2ops_vdec_stateful_buf_queue(struct vb2_buffer *vb) src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); if (ret == -EIO) { - mtk_v4l2_err("[%d] Unrecoverable error in vdec_if_decode.", ctx->id); + mtk_v4l2_vdec_err(ctx, "[%d] Unrecoverable error in vdec_if_decode.", + ctx->id); ctx->state = MTK_STATE_ABORT; v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); } else { v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); } - mtk_v4l2_debug(ret ? 0 : 1, - "[%d] vdec_if_decode() src_buf=%d, size=%zu, fail=%d, res_chg=%d", - ctx->id, src_buf->vb2_buf.index, src_mem.size, ret, res_chg); + mtk_v4l2_vdec_dbg(ret ? 0 : 1, ctx, + "[%d] decode() src_buf=%d, size=%zu, fail=%d, res_chg=%d", + ctx->id, src_buf->vb2_buf.index, src_mem.size, ret, res_chg); return; } if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo)) { - mtk_v4l2_err("[%d]Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR", ctx->id); + mtk_v4l2_vdec_err(ctx, "[%d]Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR", + ctx->id); return; } @@ -508,24 +508,24 @@ static void vb2ops_vdec_stateful_buf_queue(struct vb2_buffer *vb) dst_q_data->bytesperline[i] = ctx->picinfo.buf_w; } - mtk_v4l2_debug(2, "[%d] vdec_if_init() OK wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x", - ctx->id, ctx->picinfo.buf_w, ctx->picinfo.buf_h, ctx->picinfo.pic_w, - ctx->picinfo.pic_h, dst_q_data->sizeimage[0], dst_q_data->sizeimage[1]); + mtk_v4l2_vdec_dbg(2, ctx, "[%d] init OK wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x", + ctx->id, ctx->picinfo.buf_w, ctx->picinfo.buf_h, ctx->picinfo.pic_w, + ctx->picinfo.pic_h, dst_q_data->sizeimage[0], dst_q_data->sizeimage[1]); ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize); if (dpbsize == 0) - mtk_v4l2_err("[%d] GET_PARAM_DPB_SIZE fail=%d", ctx->id, ret); + mtk_v4l2_vdec_err(ctx, "[%d] GET_PARAM_DPB_SIZE fail=%d", ctx->id, ret); ctx->dpb_size = dpbsize; ctx->state = MTK_STATE_HEADER; - mtk_v4l2_debug(1, "[%d] dpbsize=%d", ctx->id, ctx->dpb_size); + mtk_v4l2_vdec_dbg(1, ctx, "[%d] dpbsize=%d", ctx->id, ctx->dpb_size); mtk_vdec_queue_res_chg_event(ctx); } static int mtk_vdec_g_v_ctrl(struct v4l2_ctrl *ctrl) { - struct mtk_vcodec_ctx *ctx = ctrl_to_ctx(ctrl); + struct mtk_vcodec_dec_ctx *ctx = ctrl_to_dec_ctx(ctrl); int ret = 0; switch (ctrl->id) { @@ -533,7 +533,7 @@ static int mtk_vdec_g_v_ctrl(struct v4l2_ctrl *ctrl) if (ctx->state >= MTK_STATE_HEADER) { ctrl->val = ctx->dpb_size; } else { - mtk_v4l2_debug(0, "Seqinfo not ready"); + mtk_v4l2_vdec_dbg(0, ctx, "Seqinfo not ready"); ctrl->val = 0; } break; @@ -547,7 +547,7 @@ static const struct v4l2_ctrl_ops mtk_vcodec_dec_ctrl_ops = { .g_volatile_ctrl = mtk_vdec_g_v_ctrl, }; -static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx) +static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_dec_ctx *ctx) { struct v4l2_ctrl *ctrl; @@ -570,7 +570,7 @@ static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx) V4L2_MPEG_VIDEO_H264_PROFILE_MAIN); if (ctx->ctrl_hdl.error) { - mtk_v4l2_err("Adding control failed %d", ctx->ctrl_hdl.error); + mtk_v4l2_vdec_err(ctx, "Adding control failed %d", ctx->ctrl_hdl.error); return ctx->ctrl_hdl.error; } @@ -578,7 +578,7 @@ static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx) return 0; } -static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx) +static void mtk_init_vdec_params(struct mtk_vcodec_dec_ctx *ctx) { unsigned int i; diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c index db1e14a1bd6c..e29c9c58f3da 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c @@ -6,10 +6,7 @@ #include <media/v4l2-mem2mem.h> #include <linux/module.h> -#include "mtk_vcodec_drv.h" #include "mtk_vcodec_dec.h" -#include "mtk_vcodec_intr.h" -#include "mtk_vcodec_util.h" #include "mtk_vcodec_dec_pm.h" #include "vdec_drv_if.h" @@ -203,7 +200,7 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = { #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls) -static struct mtk_video_fmt mtk_video_formats[7]; +static struct mtk_video_fmt mtk_video_formats[9]; static struct mtk_video_fmt default_out_format; static struct mtk_video_fmt default_cap_format; @@ -218,7 +215,7 @@ static const struct v4l2_frmsize_stepwise stepwise_fhd = { .step_height = 16 }; -static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_ctx *ctx, int error, +static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_dec_ctx *ctx, int error, struct media_request *src_buf_req) { struct vb2_v4l2_buffer *vb2_dst; @@ -232,17 +229,17 @@ static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_ctx *ctx, int error vb2_dst = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); if (vb2_dst) { v4l2_m2m_buf_done(vb2_dst, state); - mtk_v4l2_debug(2, "free frame buffer id:%d to done list", - vb2_dst->vb2_buf.index); + mtk_v4l2_vdec_dbg(2, ctx, "free frame buffer id:%d to done list", + vb2_dst->vb2_buf.index); } else { - mtk_v4l2_err("dst buffer is NULL"); + mtk_v4l2_vdec_err(ctx, "dst buffer is NULL"); } if (src_buf_req) v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl); } -static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx) +static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_dec_ctx *ctx) { struct mtk_video_dec_buf *framebuf; struct vb2_v4l2_buffer *vb2_v4l2; @@ -251,7 +248,7 @@ static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx) vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); if (!vb2_v4l2) { - mtk_v4l2_debug(1, "[%d] dst_buf empty!!", ctx->id); + mtk_v4l2_vdec_dbg(1, ctx, "[%d] dst_buf empty!!", ctx->id); return NULL; } @@ -269,25 +266,26 @@ static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx) vb2_dma_contig_plane_dma_addr(dst_buf, 1); pfb->base_c.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]; } - mtk_v4l2_debug(1, "id=%d Framebuf pfb=%p VA=%p Y_DMA=%pad C_DMA=%pad Size=%zx frame_count = %d", - dst_buf->index, pfb, pfb->base_y.va, &pfb->base_y.dma_addr, - &pfb->base_c.dma_addr, pfb->base_y.size, ctx->decoded_frame_cnt); + mtk_v4l2_vdec_dbg(1, ctx, + "id=%d Framebuf pfb=%p VA=%p Y/C_DMA=%pad_%pad Sz=%zx frame_count = %d", + dst_buf->index, pfb, pfb->base_y.va, &pfb->base_y.dma_addr, + &pfb->base_c.dma_addr, pfb->base_y.size, ctx->decoded_frame_cnt); return pfb; } static void vb2ops_vdec_buf_request_complete(struct vb2_buffer *vb) { - struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->ctrl_hdl); } static void mtk_vdec_worker(struct work_struct *work) { - struct mtk_vcodec_ctx *ctx = - container_of(work, struct mtk_vcodec_ctx, decode_work); - struct mtk_vcodec_dev *dev = ctx->dev; + struct mtk_vcodec_dec_ctx *ctx = + container_of(work, struct mtk_vcodec_dec_ctx, decode_work); + struct mtk_vcodec_dec_dev *dev = ctx->dev; struct vb2_v4l2_buffer *vb2_v4l2_src; struct vb2_buffer *vb2_src; struct mtk_vcodec_mem *bs_src; @@ -300,7 +298,7 @@ static void mtk_vdec_worker(struct work_struct *work) vb2_v4l2_src = v4l2_m2m_next_src_buf(ctx->m2m_ctx); if (!vb2_v4l2_src) { v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); - mtk_v4l2_debug(1, "[%d] no available source buffer", ctx->id); + mtk_v4l2_vdec_dbg(1, ctx, "[%d] no available source buffer", ctx->id); return; } @@ -309,33 +307,34 @@ static void mtk_vdec_worker(struct work_struct *work) m2m_buf.vb); bs_src = &dec_buf_src->bs_buffer; - mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", ctx->id, - vb2_src->vb2_queue->type, vb2_src->index, vb2_src); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] (%d) id=%d, vb=%p", ctx->id, + vb2_src->vb2_queue->type, vb2_src->index, vb2_src); bs_src->va = vb2_plane_vaddr(vb2_src, 0); bs_src->dma_addr = vb2_dma_contig_plane_dma_addr(vb2_src, 0); bs_src->size = (size_t)vb2_src->planes[0].bytesused; if (!bs_src->va) { v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); - mtk_v4l2_err("[%d] id=%d source buffer is NULL", ctx->id, - vb2_src->index); + mtk_v4l2_vdec_err(ctx, "[%d] id=%d source buffer is NULL", ctx->id, + vb2_src->index); return; } - mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p", - ctx->id, bs_src->va, &bs_src->dma_addr, bs_src->size, vb2_src); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p", + ctx->id, bs_src->va, &bs_src->dma_addr, bs_src->size, vb2_src); /* Apply request controls. */ src_buf_req = vb2_src->req_obj.req; if (src_buf_req) v4l2_ctrl_request_setup(src_buf_req, &ctx->ctrl_hdl); else - mtk_v4l2_err("vb2 buffer media request is NULL"); + mtk_v4l2_vdec_err(ctx, "vb2 buffer media request is NULL"); ret = vdec_if_decode(ctx, bs_src, NULL, &res_chg); if (ret && ret != -EAGAIN) { - mtk_v4l2_err(" <===[%d], src_buf[%d] sz=0x%zx pts=%llu vdec_if_decode() ret=%d res_chg=%d===>", - ctx->id, vb2_src->index, bs_src->size, - vb2_src->timestamp, ret, res_chg); + mtk_v4l2_vdec_err(ctx, + "[%d] decode src_buf[%d] sz=0x%zx pts=%llu ret=%d res_chg=%d", + ctx->id, vb2_src->index, bs_src->size, + vb2_src->timestamp, ret, res_chg); if (ret == -EIO) { mutex_lock(&ctx->lock); dec_buf_src->error = true; @@ -360,10 +359,11 @@ static void mtk_vdec_worker(struct work_struct *work) static void vb2ops_vdec_stateless_buf_queue(struct vb2_buffer *vb) { - struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct vb2_v4l2_buffer *vb2_v4l2 = to_vb2_v4l2_buffer(vb); - mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", ctx->id, vb->vb2_queue->type, vb->index, vb); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] (%d) id=%d, vb=%p", ctx->id, vb->vb2_queue->type, + vb->index, vb); mutex_lock(&ctx->lock); v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2); @@ -374,35 +374,168 @@ static void vb2ops_vdec_stateless_buf_queue(struct vb2_buffer *vb) /* If an OUTPUT buffer, we may need to update the state */ if (ctx->state == MTK_STATE_INIT) { ctx->state = MTK_STATE_HEADER; - mtk_v4l2_debug(1, "Init driver from init to header."); + mtk_v4l2_vdec_dbg(1, ctx, "Init driver from init to header."); } else { - mtk_v4l2_debug(3, "[%d] already init driver %d", ctx->id, ctx->state); + mtk_v4l2_vdec_dbg(3, ctx, "[%d] already init driver %d", ctx->id, ctx->state); } } -static int mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx) +static int mtk_vdec_flush_decoder(struct mtk_vcodec_dec_ctx *ctx) { bool res_chg; return vdec_if_decode(ctx, NULL, NULL, &res_chg); } -static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx) +static int mtk_vcodec_get_pic_info(struct mtk_vcodec_dec_ctx *ctx) +{ + struct mtk_q_data *q_data; + int ret = 0; + + q_data = &ctx->q_data[MTK_Q_DATA_DST]; + if (q_data->fmt->num_planes == 1) { + mtk_v4l2_vdec_err(ctx, "[%d]Error!! 10bit mode not support one plane", ctx->id); + return -EINVAL; + } + + ctx->capture_fourcc = q_data->fmt->fourcc; + ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo); + if (ret) { + mtk_v4l2_vdec_err(ctx, "[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail", ctx->id); + return ret; + } + + ctx->last_decoded_picinfo = ctx->picinfo; + + q_data->sizeimage[0] = ctx->picinfo.fb_sz[0]; + q_data->bytesperline[0] = ctx->picinfo.buf_w * 5 / 4; + + q_data->sizeimage[1] = ctx->picinfo.fb_sz[1]; + q_data->bytesperline[1] = ctx->picinfo.buf_w * 5 / 4; + + q_data->coded_width = ctx->picinfo.buf_w; + q_data->coded_height = ctx->picinfo.buf_h; + mtk_v4l2_vdec_dbg(1, ctx, "[%d] wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x", + ctx->id, ctx->picinfo.buf_w, ctx->picinfo.buf_h, + ctx->picinfo.pic_w, ctx->picinfo.pic_h, + q_data->sizeimage[0], q_data->sizeimage[1]); + + return ret; +} + +static int mtk_vdec_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct mtk_vcodec_dec_ctx *ctx = ctrl_to_dec_ctx(ctrl); + struct v4l2_ctrl_h264_sps *h264; + struct v4l2_ctrl_hevc_sps *h265; + struct v4l2_ctrl_vp9_frame *frame; + struct v4l2_ctrl_av1_sequence *seq; + struct v4l2_ctrl *hdr_ctrl; + const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata; + const struct mtk_video_fmt *fmt; + int i = 0, ret = 0; + + hdr_ctrl = ctrl; + if (!hdr_ctrl || !hdr_ctrl->p_new.p) + return -EINVAL; + + switch (hdr_ctrl->id) { + case V4L2_CID_STATELESS_H264_SPS: + h264 = (struct v4l2_ctrl_h264_sps *)hdr_ctrl->p_new.p; + + if (h264->bit_depth_chroma_minus8 == 2 && h264->bit_depth_luma_minus8 == 2) { + ctx->is_10bit_bitstream = true; + } else if (h264->bit_depth_chroma_minus8 != 0 && + h264->bit_depth_luma_minus8 != 0) { + mtk_v4l2_vdec_err(ctx, "H264: chroma_minus8:%d, luma_minus8:%d", + h264->bit_depth_chroma_minus8, + h264->bit_depth_luma_minus8); + return -EINVAL; + } + break; + case V4L2_CID_STATELESS_HEVC_SPS: + h265 = (struct v4l2_ctrl_hevc_sps *)hdr_ctrl->p_new.p; + + if (h265->bit_depth_chroma_minus8 == 2 && h265->bit_depth_luma_minus8 == 2) { + ctx->is_10bit_bitstream = true; + } else if (h265->bit_depth_chroma_minus8 != 0 && + h265->bit_depth_luma_minus8 != 0) { + mtk_v4l2_vdec_err(ctx, "HEVC: chroma_minus8:%d, luma_minus8:%d", + h265->bit_depth_chroma_minus8, + h265->bit_depth_luma_minus8); + return -EINVAL; + } + break; + case V4L2_CID_STATELESS_VP9_FRAME: + frame = (struct v4l2_ctrl_vp9_frame *)hdr_ctrl->p_new.p; + + if (frame->bit_depth == 10) { + ctx->is_10bit_bitstream = true; + } else if (frame->bit_depth != 8) { + mtk_v4l2_vdec_err(ctx, "VP9: bit_depth:%d", frame->bit_depth); + return -EINVAL; + } + break; + case V4L2_CID_STATELESS_AV1_SEQUENCE: + seq = (struct v4l2_ctrl_av1_sequence *)hdr_ctrl->p_new.p; + + if (seq->bit_depth == 10) { + ctx->is_10bit_bitstream = true; + } else if (seq->bit_depth != 8) { + mtk_v4l2_vdec_err(ctx, "AV1: bit_depth:%d", seq->bit_depth); + return -EINVAL; + } + break; + default: + mtk_v4l2_vdec_dbg(3, ctx, "Not supported to set ctrl id: 0x%x\n", hdr_ctrl->id); + return ret; + } + + if (!ctx->is_10bit_bitstream) + return ret; + + for (i = 0; i < *dec_pdata->num_formats; i++) { + fmt = &dec_pdata->vdec_formats[i]; + if (fmt->fourcc == V4L2_PIX_FMT_MT2110R && + hdr_ctrl->id == V4L2_CID_STATELESS_H264_SPS) { + ctx->q_data[MTK_Q_DATA_DST].fmt = fmt; + break; + } + + if (fmt->fourcc == V4L2_PIX_FMT_MT2110T && + (hdr_ctrl->id == V4L2_CID_STATELESS_HEVC_SPS || + hdr_ctrl->id == V4L2_CID_STATELESS_VP9_FRAME || + hdr_ctrl->id == V4L2_CID_STATELESS_AV1_SEQUENCE)) { + ctx->q_data[MTK_Q_DATA_DST].fmt = fmt; + break; + } + } + ret = mtk_vcodec_get_pic_info(ctx); + + return ret; +} + +static const struct v4l2_ctrl_ops mtk_vcodec_dec_ctrl_ops = { + .s_ctrl = mtk_vdec_s_ctrl, +}; + +static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_dec_ctx *ctx) { unsigned int i; v4l2_ctrl_handler_init(&ctx->ctrl_hdl, NUM_CTRLS); if (ctx->ctrl_hdl.error) { - mtk_v4l2_err("v4l2_ctrl_handler_init failed\n"); + mtk_v4l2_vdec_err(ctx, "v4l2_ctrl_handler_init failed\n"); return ctx->ctrl_hdl.error; } for (i = 0; i < NUM_CTRLS; i++) { struct v4l2_ctrl_config cfg = mtk_stateless_controls[i].cfg; - + cfg.ops = &mtk_vcodec_dec_ctrl_ops; v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &cfg, NULL); if (ctx->ctrl_hdl.error) { - mtk_v4l2_err("Adding control %d failed %d", i, ctx->ctrl_hdl.error); + mtk_v4l2_vdec_err(ctx, "Adding control %d failed %d", i, + ctx->ctrl_hdl.error); return ctx->ctrl_hdl.error; } } @@ -421,11 +554,11 @@ static int fops_media_request_validate(struct media_request *mreq) /* We expect exactly one buffer with the request */ break; case 0: - mtk_v4l2_debug(1, "No buffer provided with the request"); + pr_debug(MTK_DBG_VCODEC_STR "No buffer provided with the request."); return -ENOENT; default: - mtk_v4l2_debug(1, "Too many buffers (%d) provided with the request", - buffer_cnt); + pr_debug(MTK_DBG_VCODEC_STR "Too many buffers (%d) provided with the request.", + buffer_cnt); return -EINVAL; } @@ -438,9 +571,9 @@ const struct media_device_ops mtk_vcodec_media_ops = { }; static void mtk_vcodec_add_formats(unsigned int fourcc, - struct mtk_vcodec_ctx *ctx) + struct mtk_vcodec_dec_ctx *ctx) { - struct mtk_vcodec_dev *dev = ctx->dev; + struct mtk_vcodec_dec_dev *dev = ctx->dev; const struct mtk_vcodec_dec_pdata *pdata = dev->vdec_pdata; int count_formats = *pdata->num_formats; @@ -465,21 +598,23 @@ static void mtk_vcodec_add_formats(unsigned int fourcc, break; case V4L2_PIX_FMT_MM21: case V4L2_PIX_FMT_MT21C: + case V4L2_PIX_FMT_MT2110T: + case V4L2_PIX_FMT_MT2110R: mtk_video_formats[count_formats].fourcc = fourcc; mtk_video_formats[count_formats].type = MTK_FMT_FRAME; mtk_video_formats[count_formats].num_planes = 2; break; default: - mtk_v4l2_err("Can not add unsupported format type"); + mtk_v4l2_vdec_err(ctx, "Can not add unsupported format type"); return; } num_formats++; - mtk_v4l2_debug(3, "num_formats: %d dec_capability: 0x%x", - count_formats, ctx->dev->dec_capability); + mtk_v4l2_vdec_dbg(3, ctx, "num_formats: %d dec_capability: 0x%x", + count_formats, ctx->dev->dec_capability); } -static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx) +static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_dec_ctx *ctx) { int cap_format_count = 0, out_format_count = 0; @@ -490,6 +625,12 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx) mtk_vcodec_add_formats(V4L2_PIX_FMT_MT21C, ctx); cap_format_count++; } + if (ctx->dev->dec_capability & MTK_VDEC_IS_SUPPORT_10BIT) { + mtk_vcodec_add_formats(V4L2_PIX_FMT_MT2110T, ctx); + cap_format_count++; + mtk_vcodec_add_formats(V4L2_PIX_FMT_MT2110R, ctx); + cap_format_count++; + } if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_MM21) { mtk_vcodec_add_formats(V4L2_PIX_FMT_MM21, ctx); cap_format_count++; @@ -522,7 +663,7 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx) mtk_video_formats[cap_format_count + out_format_count - 1]; } -static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx) +static void mtk_init_vdec_params(struct mtk_vcodec_dec_ctx *ctx) { struct vb2_queue *src_vq; diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c index 404a1a23fd40..2b6a5adbc419 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c @@ -8,9 +8,8 @@ #include <linux/slab.h> #include <media/videobuf2-dma-contig.h> -#include "../mtk_vcodec_util.h" #include "../mtk_vcodec_dec.h" -#include "../mtk_vcodec_intr.h" +#include "../../common/mtk_vcodec_intr.h" #include "../vdec_drv_base.h" #include "../vdec_drv_if.h" #include "../vdec_vpu_if.h" @@ -706,7 +705,7 @@ struct vdec_av1_slice_pfc { * @seq: global picture sequence */ struct vdec_av1_slice_instance { - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; struct vdec_vpu_inst vpu; struct mtk_vcodec_mem iq_table; @@ -756,7 +755,7 @@ static inline bool vdec_av1_slice_need_scale(u32 ref_width, u32 ref_height, (this_height <= (ref_height << 4)); } -static void *vdec_av1_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id) +static void *vdec_av1_get_ctrl_ptr(struct mtk_vcodec_dec_ctx *ctx, int id) { struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id); @@ -769,7 +768,7 @@ static void *vdec_av1_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id) static int vdec_av1_slice_init_cdf_table(struct vdec_av1_slice_instance *instance) { u8 *remote_cdf_table; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; struct vdec_av1_slice_init_vsi *vsi; int ret; @@ -778,12 +777,11 @@ static int vdec_av1_slice_init_cdf_table(struct vdec_av1_slice_instance *instanc remote_cdf_table = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler, (u32)vsi->cdf_table_addr); if (IS_ERR(remote_cdf_table)) { - mtk_vcodec_err(instance, "failed to map cdf table\n"); + mtk_vdec_err(ctx, "failed to map cdf table\n"); return PTR_ERR(remote_cdf_table); } - mtk_vcodec_debug(instance, "map cdf table to 0x%p\n", - remote_cdf_table); + mtk_vdec_debug(ctx, "map cdf table to 0x%p\n", remote_cdf_table); if (instance->cdf_table.va) mtk_vcodec_mem_free(ctx, &instance->cdf_table); @@ -801,7 +799,7 @@ static int vdec_av1_slice_init_cdf_table(struct vdec_av1_slice_instance *instanc static int vdec_av1_slice_init_iq_table(struct vdec_av1_slice_instance *instance) { u8 *remote_iq_table; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; struct vdec_av1_slice_init_vsi *vsi; int ret; @@ -810,11 +808,11 @@ static int vdec_av1_slice_init_iq_table(struct vdec_av1_slice_instance *instance remote_iq_table = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler, (u32)vsi->iq_table_addr); if (IS_ERR(remote_iq_table)) { - mtk_vcodec_err(instance, "failed to map iq table\n"); + mtk_vdec_err(ctx, "failed to map iq table\n"); return PTR_ERR(remote_iq_table); } - mtk_vcodec_debug(instance, "map iq table to 0x%p\n", remote_iq_table); + mtk_vdec_debug(ctx, "map iq table to 0x%p\n", remote_iq_table); if (instance->iq_table.va) mtk_vcodec_mem_free(ctx, &instance->iq_table); @@ -862,8 +860,8 @@ static void vdec_av1_slice_decrease_ref_count(struct vdec_av1_slice_slot *slots, frame_info[fb_idx].ref_count--; if (frame_info[fb_idx].ref_count < 0) { frame_info[fb_idx].ref_count = 0; - mtk_v4l2_err("av1_error: %s() fb_idx %d decrease ref_count error\n", - __func__, fb_idx); + pr_err(MTK_DBG_V4L2_STR "av1_error: %s() fb_idx %d decrease ref_count error\n", + __func__, fb_idx); } vdec_av1_slice_clear_fb(&frame_info[fb_idx]); @@ -911,7 +909,7 @@ static void vdec_av1_slice_setup_slot(struct vdec_av1_slice_instance *instance, vsi->slot_id = vdec_av1_slice_get_new_slot(vsi); if (vsi->slot_id == AV1_INVALID_IDX) { - mtk_v4l2_err("warning:av1 get invalid index slot\n"); + mtk_v4l2_vdec_err(instance->ctx, "warning:av1 get invalid index slot\n"); vsi->slot_id = 0; } cur_frame_info = &vsi->slots.frame_info[vsi->slot_id]; @@ -938,7 +936,7 @@ static void vdec_av1_slice_setup_slot(struct vdec_av1_slice_instance *instance, static int vdec_av1_slice_alloc_working_buffer(struct vdec_av1_slice_instance *instance, struct vdec_av1_slice_vsi *vsi) { - struct mtk_vcodec_ctx *ctx = instance->ctx; + struct mtk_vcodec_dec_ctx *ctx = instance->ctx; enum vdec_av1_slice_resolution_level level; u32 max_sb_w, max_sb_h, max_w, max_h, w, h; int i, ret; @@ -965,8 +963,8 @@ static int vdec_av1_slice_alloc_working_buffer(struct vdec_av1_slice_instance *i if (level == instance->level) return 0; - mtk_vcodec_debug(instance, "resolution level changed from %u to %u, %ux%u", - instance->level, level, w, h); + mtk_vdec_debug(ctx, "resolution level changed from %u to %u, %ux%u", + instance->level, level, w, h); max_sb_w = DIV_ROUND_UP(max_w, 128); max_sb_h = DIV_ROUND_UP(max_h, 128); @@ -1021,7 +1019,7 @@ err: static void vdec_av1_slice_free_working_buffer(struct vdec_av1_slice_instance *instance) { - struct mtk_vcodec_ctx *ctx = instance->ctx; + struct mtk_vcodec_dec_ctx *ctx = instance->ctx; int i; for (i = 0; i < ARRAY_SIZE(instance->mv); i++) @@ -1400,17 +1398,17 @@ static int vdec_av1_slice_setup_tile_group(struct vdec_av1_slice_instance *insta if (tile_group->num_tiles != tge_size || tile_group->num_tiles > V4L2_AV1_MAX_TILE_COUNT) { - mtk_vcodec_err(instance, "invalid tge_size %d, tile_num:%d\n", - tge_size, tile_group->num_tiles); + mtk_vdec_err(instance->ctx, "invalid tge_size %d, tile_num:%d\n", + tge_size, tile_group->num_tiles); return -EINVAL; } for (i = 0; i < tge_size; i++) { if (i != ctrl_tge[i].tile_row * vsi->frame.uh.tile.tile_cols + ctrl_tge[i].tile_col) { - mtk_vcodec_err(instance, "invalid tge info %d, %d %d %d\n", - i, ctrl_tge[i].tile_row, ctrl_tge[i].tile_col, - vsi->frame.uh.tile.tile_rows); + mtk_vdec_err(instance->ctx, "invalid tge info %d, %d %d %d\n", + i, ctrl_tge[i].tile_row, ctrl_tge[i].tile_col, + vsi->frame.uh.tile.tile_rows); return -EINVAL; } tile_group->tile_size[i] = ctrl_tge[i].tile_size; @@ -1505,8 +1503,8 @@ static void vdec_av1_slice_setup_ref(struct vdec_av1_slice_pfc *pfc, slot_id = frame->ref_frame_map[ref_idx]; frame_info = &slots->frame_info[slot_id]; if (slot_id == AV1_INVALID_IDX) { - mtk_v4l2_err("cannot match reference[%d] 0x%llx\n", i, - ctrl_fh->reference_frame_ts[ref_idx]); + pr_err(MTK_DBG_V4L2_STR "cannot match reference[%d] 0x%llx\n", i, + ctrl_fh->reference_frame_ts[ref_idx]); frame->order_hints[i] = 0; frame->ref_frame_valid[i] = 0; continue; @@ -1639,7 +1637,7 @@ static void vdec_av1_slice_setup_seg_buffer(struct vdec_av1_slice_instance *inst /* reset segment buffer */ if (uh->primary_ref_frame == AV1_PRIMARY_REF_NONE || !uh->seg.segmentation_enabled) { - mtk_vcodec_debug(instance, "reset seg %d\n", vsi->slot_id); + mtk_vdec_debug(instance->ctx, "reset seg %d\n", vsi->slot_id); if (vsi->slot_id != AV1_INVALID_IDX) { buf = &instance->seg[vsi->slot_id]; memset(buf->va, 0, buf->size); @@ -1658,9 +1656,9 @@ static void vdec_av1_slice_setup_tile_buffer(struct vdec_av1_slice_instance *ins u32 allow_update_cdf = 0; u32 sb_boundary_x_m1 = 0, sb_boundary_y_m1 = 0; int tile_info_base; - u32 tile_buf_pa; + u64 tile_buf_pa; u32 *tile_info_buf = instance->tile.va; - u32 pa = (u32)bs->dma_addr; + u64 pa = (u64)bs->dma_addr; if (uh->disable_cdf_update == 0) allow_update_cdf = 1; @@ -1673,8 +1671,12 @@ static void vdec_av1_slice_setup_tile_buffer(struct vdec_av1_slice_instance *ins tile_info_buf[tile_info_base + 0] = (tile_group->tile_size[tile_num] << 3); tile_buf_pa = pa + tile_group->tile_start_offset[tile_num]; - tile_info_buf[tile_info_base + 1] = (tile_buf_pa >> 4) << 4; - tile_info_buf[tile_info_base + 2] = (tile_buf_pa % 16) << 3; + /* save av1 tile high 4bits(bit 32-35) address in lower 4 bits position + * and clear original for hw requirement. + */ + tile_info_buf[tile_info_base + 1] = (tile_buf_pa & 0xFFFFFFF0ull) | + ((tile_buf_pa & 0xF00000000ull) >> 32); + tile_info_buf[tile_info_base + 2] = (tile_buf_pa & 0xFull) << 3; sb_boundary_x_m1 = (tile->mi_col_starts[tile_col + 1] - tile->mi_col_starts[tile_col] - 1) & @@ -1690,18 +1692,18 @@ static void vdec_av1_slice_setup_tile_buffer(struct vdec_av1_slice_instance *ins uh->disable_frame_end_update_cdf == 0) tile_info_buf[tile_info_base + 4] |= (1 << 17); - mtk_vcodec_debug(instance, "// tile buf %d pos(%dx%d) offset 0x%x\n", - tile_num, tile_row, tile_col, tile_info_base); - mtk_vcodec_debug(instance, "// %08x %08x %08x %08x\n", - tile_info_buf[tile_info_base + 0], - tile_info_buf[tile_info_base + 1], - tile_info_buf[tile_info_base + 2], - tile_info_buf[tile_info_base + 3]); - mtk_vcodec_debug(instance, "// %08x %08x %08x %08x\n", - tile_info_buf[tile_info_base + 4], - tile_info_buf[tile_info_base + 5], - tile_info_buf[tile_info_base + 6], - tile_info_buf[tile_info_base + 7]); + mtk_vdec_debug(instance->ctx, "// tile buf %d pos(%dx%d) offset 0x%x\n", + tile_num, tile_row, tile_col, tile_info_base); + mtk_vdec_debug(instance->ctx, "// %08x %08x %08x %08x\n", + tile_info_buf[tile_info_base + 0], + tile_info_buf[tile_info_base + 1], + tile_info_buf[tile_info_base + 2], + tile_info_buf[tile_info_base + 3]); + mtk_vdec_debug(instance->ctx, "// %08x %08x %08x %08x\n", + tile_info_buf[tile_info_base + 4], + tile_info_buf[tile_info_base + 5], + tile_info_buf[tile_info_base + 6], + tile_info_buf[tile_info_base + 7]); } } @@ -1743,8 +1745,8 @@ static int vdec_av1_slice_update_lat(struct vdec_av1_slice_instance *instance, struct vdec_av1_slice_vsi *vsi; vsi = &pfc->vsi; - mtk_vcodec_debug(instance, "frame %u LAT CRC 0x%08x, output size is %d\n", - pfc->seq, vsi->state.crc[0], vsi->state.out_size); + mtk_vdec_debug(instance->ctx, "frame %u LAT CRC 0x%08x, output size is %d\n", + pfc->seq, vsi->state.crc[0], vsi->state.out_size); /* buffer full, need to re-decode */ if (vsi->state.full) { @@ -1855,17 +1857,17 @@ static int vdec_av1_slice_update_core(struct vdec_av1_slice_instance *instance, { struct vdec_av1_slice_vsi *vsi = instance->core_vsi; - mtk_vcodec_debug(instance, "frame %u Y_CRC %08x %08x %08x %08x\n", - pfc->seq, vsi->state.crc[0], vsi->state.crc[1], - vsi->state.crc[2], vsi->state.crc[3]); - mtk_vcodec_debug(instance, "frame %u C_CRC %08x %08x %08x %08x\n", - pfc->seq, vsi->state.crc[8], vsi->state.crc[9], - vsi->state.crc[10], vsi->state.crc[11]); + mtk_vdec_debug(instance->ctx, "frame %u Y_CRC %08x %08x %08x %08x\n", + pfc->seq, vsi->state.crc[0], vsi->state.crc[1], + vsi->state.crc[2], vsi->state.crc[3]); + mtk_vdec_debug(instance->ctx, "frame %u C_CRC %08x %08x %08x %08x\n", + pfc->seq, vsi->state.crc[8], vsi->state.crc[9], + vsi->state.crc[10], vsi->state.crc[11]); return 0; } -static int vdec_av1_slice_init(struct mtk_vcodec_ctx *ctx) +static int vdec_av1_slice_init(struct mtk_vcodec_dec_ctx *ctx) { struct vdec_av1_slice_instance *instance; struct vdec_av1_slice_init_vsi *vsi; @@ -1883,14 +1885,14 @@ static int vdec_av1_slice_init(struct mtk_vcodec_ctx *ctx) ret = vpu_dec_init(&instance->vpu); if (ret) { - mtk_vcodec_err(instance, "failed to init vpu dec, ret %d\n", ret); + mtk_vdec_err(ctx, "failed to init vpu dec, ret %d\n", ret); goto error_vpu_init; } /* init vsi and global flags */ vsi = instance->vpu.vsi; if (!vsi) { - mtk_vcodec_err(instance, "failed to get AV1 vsi\n"); + mtk_vdec_err(ctx, "failed to get AV1 vsi\n"); ret = -EINVAL; goto error_vsi; } @@ -1898,20 +1900,20 @@ static int vdec_av1_slice_init(struct mtk_vcodec_ctx *ctx) instance->core_vsi = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler, (u32)vsi->core_vsi); if (!instance->core_vsi) { - mtk_vcodec_err(instance, "failed to get AV1 core vsi\n"); + mtk_vdec_err(ctx, "failed to get AV1 core vsi\n"); ret = -EINVAL; goto error_vsi; } if (vsi->vsi_size != sizeof(struct vdec_av1_slice_vsi)) - mtk_vcodec_err(instance, "remote vsi size 0x%x mismatch! expected: 0x%zx\n", - vsi->vsi_size, sizeof(struct vdec_av1_slice_vsi)); + mtk_vdec_err(ctx, "remote vsi size 0x%x mismatch! expected: 0x%zx\n", + vsi->vsi_size, sizeof(struct vdec_av1_slice_vsi)); instance->irq_enabled = 1; instance->inneracing_mode = IS_VDEC_INNER_RACING(instance->ctx->dev->dec_capability); - mtk_vcodec_debug(instance, "vsi 0x%p core_vsi 0x%llx 0x%p, inneracing_mode %d\n", - vsi, vsi->core_vsi, instance->core_vsi, instance->inneracing_mode); + mtk_vdec_debug(ctx, "vsi 0x%p core_vsi 0x%llx 0x%p, inneracing_mode %d\n", + vsi, vsi->core_vsi, instance->core_vsi, instance->inneracing_mode); ret = vdec_av1_slice_init_cdf_table(instance); if (ret) @@ -1938,7 +1940,7 @@ static void vdec_av1_slice_deinit(void *h_vdec) if (!instance) return; - mtk_vcodec_debug(instance, "h_vdec 0x%p\n", h_vdec); + mtk_vdec_debug(instance->ctx, "h_vdec 0x%p\n", h_vdec); vpu_dec_deinit(&instance->vpu); vdec_av1_slice_free_working_buffer(instance); vdec_msg_queue_deinit(&instance->ctx->msg_queue, instance->ctx); @@ -1951,7 +1953,7 @@ static int vdec_av1_slice_flush(void *h_vdec, struct mtk_vcodec_mem *bs, struct vdec_av1_slice_instance *instance = h_vdec; int i; - mtk_vcodec_debug(instance, "flush ...\n"); + mtk_vdec_debug(instance->ctx, "flush ...\n"); vdec_msg_queue_wait_lat_buf_full(&instance->ctx->msg_queue); @@ -1963,10 +1965,10 @@ static int vdec_av1_slice_flush(void *h_vdec, struct mtk_vcodec_mem *bs, static void vdec_av1_slice_get_pic_info(struct vdec_av1_slice_instance *instance) { - struct mtk_vcodec_ctx *ctx = instance->ctx; + struct mtk_vcodec_dec_ctx *ctx = instance->ctx; u32 data[3]; - mtk_vcodec_debug(instance, "w %u h %u\n", ctx->picinfo.pic_w, ctx->picinfo.pic_h); + mtk_vdec_debug(ctx, "w %u h %u\n", ctx->picinfo.pic_w, ctx->picinfo.pic_h); data[0] = ctx->picinfo.pic_w; data[1] = ctx->picinfo.pic_h; @@ -1989,15 +1991,15 @@ static inline void vdec_av1_slice_get_dpb_size(struct vdec_av1_slice_instance *i static void vdec_av1_slice_get_crop_info(struct vdec_av1_slice_instance *instance, struct v4l2_rect *cr) { - struct mtk_vcodec_ctx *ctx = instance->ctx; + struct mtk_vcodec_dec_ctx *ctx = instance->ctx; cr->left = 0; cr->top = 0; cr->width = ctx->picinfo.pic_w; cr->height = ctx->picinfo.pic_h; - mtk_vcodec_debug(instance, "l=%d, t=%d, w=%d, h=%d\n", - cr->left, cr->top, cr->width, cr->height); + mtk_vdec_debug(ctx, "l=%d, t=%d, w=%d, h=%d\n", + cr->left, cr->top, cr->width, cr->height); } static int vdec_av1_slice_get_param(void *h_vdec, enum vdec_get_param_type type, void *out) @@ -2015,7 +2017,7 @@ static int vdec_av1_slice_get_param(void *h_vdec, enum vdec_get_param_type type, vdec_av1_slice_get_crop_info(instance, out); break; default: - mtk_vcodec_err(instance, "invalid get parameter type=%d\n", type); + mtk_vdec_err(instance->ctx, "invalid get parameter type=%d\n", type); return -EINVAL; } @@ -2029,7 +2031,7 @@ static int vdec_av1_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, struct vdec_lat_buf *lat_buf; struct vdec_av1_slice_pfc *pfc; struct vdec_av1_slice_vsi *vsi; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; int ret; if (!instance || !instance->ctx) @@ -2039,7 +2041,7 @@ static int vdec_av1_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, /* init msgQ for the first time */ if (vdec_msg_queue_init(&ctx->msg_queue, ctx, vdec_av1_slice_core_decode, sizeof(*pfc))) { - mtk_vcodec_err(instance, "failed to init AV1 msg queue\n"); + mtk_vdec_err(ctx, "failed to init AV1 msg queue\n"); return -ENOMEM; } @@ -2049,7 +2051,7 @@ static int vdec_av1_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, lat_buf = vdec_msg_queue_dqbuf(&ctx->msg_queue.lat_ctx); if (!lat_buf) { - mtk_vcodec_err(instance, "failed to get AV1 lat buf\n"); + mtk_vdec_err(ctx, "failed to get AV1 lat buf\n"); return -EAGAIN; } pfc = (struct vdec_av1_slice_pfc *)lat_buf->private_data; @@ -2061,14 +2063,14 @@ static int vdec_av1_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, ret = vdec_av1_slice_setup_lat(instance, bs, lat_buf, pfc); if (ret) { - mtk_vcodec_err(instance, "failed to setup AV1 lat ret %d\n", ret); + mtk_vdec_err(ctx, "failed to setup AV1 lat ret %d\n", ret); goto err_free_fb_out; } vdec_av1_slice_vsi_to_remote(vsi, instance->vsi); ret = vpu_dec_start(&instance->vpu, NULL, 0); if (ret) { - mtk_vcodec_err(instance, "failed to dec AV1 ret %d\n", ret); + mtk_vdec_err(ctx, "failed to dec AV1 ret %d\n", ret); goto err_free_fb_out; } if (instance->inneracing_mode) @@ -2080,7 +2082,7 @@ static int vdec_av1_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, MTK_VDEC_LAT0); /* update remote vsi if decode timeout */ if (ret) { - mtk_vcodec_err(instance, "AV1 Frame %d decode timeout %d\n", pfc->seq, ret); + mtk_vdec_err(ctx, "AV1 Frame %d decode timeout %d\n", pfc->seq, ret); WRITE_ONCE(instance->vsi->state.timeout, 1); } vpu_dec_end(&instance->vpu); @@ -2091,7 +2093,7 @@ static int vdec_av1_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, /* LAT trans full, re-decode */ if (ret == -EAGAIN) { - mtk_vcodec_err(instance, "AV1 Frame %d trans full\n", pfc->seq); + mtk_vdec_err(ctx, "AV1 Frame %d trans full\n", pfc->seq); if (!instance->inneracing_mode) vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf); return 0; @@ -2099,14 +2101,14 @@ static int vdec_av1_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, /* LAT trans full, no more UBE or decode timeout */ if (ret == -ENOMEM || vsi->state.timeout) { - mtk_vcodec_err(instance, "AV1 Frame %d insufficient buffer or timeout\n", pfc->seq); + mtk_vdec_err(ctx, "AV1 Frame %d insufficient buffer or timeout\n", pfc->seq); if (!instance->inneracing_mode) vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf); return -EBUSY; } vsi->trans.dma_addr_end += ctx->msg_queue.wdma_addr.dma_addr; - mtk_vcodec_debug(instance, "lat dma 1 0x%pad 0x%pad\n", - &pfc->vsi.trans.dma_addr, &pfc->vsi.trans.dma_addr_end); + mtk_vdec_debug(ctx, "lat dma 1 0x%pad 0x%pad\n", + &pfc->vsi.trans.dma_addr, &pfc->vsi.trans.dma_addr_end); vdec_msg_queue_update_ube_wptr(&ctx->msg_queue, vsi->trans.dma_addr_end); @@ -2120,7 +2122,7 @@ err_free_fb_out: vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf); if (pfc) - mtk_vcodec_err(instance, "slice dec number: %d err: %d", pfc->seq, ret); + mtk_vdec_err(ctx, "slice dec number: %d err: %d", pfc->seq, ret); return ret; } @@ -2129,7 +2131,7 @@ static int vdec_av1_slice_core_decode(struct vdec_lat_buf *lat_buf) { struct vdec_av1_slice_instance *instance; struct vdec_av1_slice_pfc *pfc; - struct mtk_vcodec_ctx *ctx = NULL; + struct mtk_vcodec_dec_ctx *ctx = NULL; struct vdec_fb *fb = NULL; int ret = -EINVAL; @@ -2153,13 +2155,13 @@ static int vdec_av1_slice_core_decode(struct vdec_lat_buf *lat_buf) ret = vdec_av1_slice_setup_core(instance, fb, lat_buf, pfc); if (ret) { - mtk_vcodec_err(instance, "vdec_av1_slice_setup_core\n"); + mtk_vdec_err(ctx, "vdec_av1_slice_setup_core\n"); goto err; } vdec_av1_slice_vsi_to_remote(&pfc->vsi, instance->core_vsi); ret = vpu_dec_core(&instance->vpu); if (ret) { - mtk_vcodec_err(instance, "vpu_dec_core\n"); + mtk_vdec_err(ctx, "vpu_dec_core\n"); goto err; } @@ -2169,7 +2171,7 @@ static int vdec_av1_slice_core_decode(struct vdec_lat_buf *lat_buf) MTK_VDEC_CORE); /* update remote vsi if decode timeout */ if (ret) { - mtk_vcodec_err(instance, "AV1 frame %d core timeout\n", pfc->seq); + mtk_vdec_err(ctx, "AV1 frame %d core timeout\n", pfc->seq); WRITE_ONCE(instance->vsi->state.timeout, 1); } vpu_dec_core_end(&instance->vpu); @@ -2177,12 +2179,12 @@ static int vdec_av1_slice_core_decode(struct vdec_lat_buf *lat_buf) ret = vdec_av1_slice_update_core(instance, lat_buf, pfc); if (ret) { - mtk_vcodec_err(instance, "vdec_av1_slice_update_core\n"); + mtk_vdec_err(ctx, "vdec_av1_slice_update_core\n"); goto err; } - mtk_vcodec_debug(instance, "core dma_addr_end 0x%pad\n", - &instance->core_vsi->trans.dma_addr_end); + mtk_vdec_debug(ctx, "core dma_addr_end 0x%pad\n", + &instance->core_vsi->trans.dma_addr_end); vdec_msg_queue_update_ube_rptr(&ctx->msg_queue, instance->core_vsi->trans.dma_addr_end); ctx->dev->vdec_pdata->cap_to_disp(ctx, 0, lat_buf->src_buf_req); diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_if.c index 481655bb6016..bf7dffe60d07 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_if.c @@ -8,9 +8,8 @@ #include <linux/slab.h> #include "../vdec_drv_if.h" -#include "../mtk_vcodec_util.h" #include "../mtk_vcodec_dec.h" -#include "../mtk_vcodec_intr.h" +#include "../../common/mtk_vcodec_intr.h" #include "../vdec_vpu_if.h" #include "../vdec_drv_base.h" @@ -117,7 +116,7 @@ struct vdec_h264_vsi { /** * struct vdec_h264_inst - h264 decoder instance * @num_nalu : how many nalus be decoded - * @ctx : point to mtk_vcodec_ctx + * @ctx : point to mtk_vcodec_dec_ctx * @pred_buf : HW working predication buffer * @mv_buf : HW working motion vector buffer * @vpu : VPU instance @@ -125,7 +124,7 @@ struct vdec_h264_vsi { */ struct vdec_h264_inst { unsigned int num_nalu; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; struct mtk_vcodec_mem pred_buf; struct mtk_vcodec_mem mv_buf[H264_MAX_FB_NUM]; struct vdec_vpu_inst vpu; @@ -144,7 +143,7 @@ static int allocate_predication_buf(struct vdec_h264_inst *inst) inst->pred_buf.size = BUF_PREDICTION_SZ; err = mtk_vcodec_mem_alloc(inst->ctx, &inst->pred_buf); if (err) { - mtk_vcodec_err(inst, "failed to allocate ppl buf"); + mtk_vdec_err(inst->ctx, "failed to allocate ppl buf"); return err; } @@ -156,8 +155,6 @@ static void free_predication_buf(struct vdec_h264_inst *inst) { struct mtk_vcodec_mem *mem = NULL; - mtk_vcodec_debug_enter(inst); - inst->vsi->pred_buf_dma = 0; mem = &inst->pred_buf; if (mem->va) @@ -178,7 +175,7 @@ static int alloc_mv_buf(struct vdec_h264_inst *inst, struct vdec_pic_info *pic) mem->size = buf_sz; err = mtk_vcodec_mem_alloc(inst->ctx, mem); if (err) { - mtk_vcodec_err(inst, "failed to allocate mv buf"); + mtk_vdec_err(inst->ctx, "failed to allocate mv buf"); return err; } inst->vsi->mv_buf_dma[i] = mem->dma_addr; @@ -209,9 +206,9 @@ static int check_list_validity(struct vdec_h264_inst *inst, bool disp_list) if (list->count > H264_MAX_FB_NUM || list->read_idx >= H264_MAX_FB_NUM || list->write_idx >= H264_MAX_FB_NUM) { - mtk_vcodec_err(inst, "%s list err: cnt=%d r_idx=%d w_idx=%d", - disp_list ? "disp" : "free", list->count, - list->read_idx, list->write_idx); + mtk_vdec_err(inst->ctx, "%s list err: cnt=%d r_idx=%d w_idx=%d", + disp_list ? "disp" : "free", list->count, + list->read_idx, list->write_idx); return -EINVAL; } @@ -228,12 +225,12 @@ static void put_fb_to_free(struct vdec_h264_inst *inst, struct vdec_fb *fb) list = &inst->vsi->list_free; if (list->count == H264_MAX_FB_NUM) { - mtk_vcodec_err(inst, "[FB] put fb free_list full"); + mtk_vdec_err(inst->ctx, "[FB] put fb free_list full"); return; } - mtk_vcodec_debug(inst, "[FB] put fb into free_list @(%p, %llx)", - fb->base_y.va, (u64)fb->base_y.dma_addr); + mtk_vdec_debug(inst->ctx, "[FB] put fb into free_list @(%p, %llx)", + fb->base_y.va, (u64)fb->base_y.dma_addr); list->fb_list[list->write_idx].vdec_fb_va = (u64)(uintptr_t)fb; list->write_idx = (list->write_idx == H264_MAX_FB_NUM - 1) ? @@ -246,10 +243,9 @@ static void get_pic_info(struct vdec_h264_inst *inst, struct vdec_pic_info *pic) { *pic = inst->vsi->pic; - mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", - pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); - mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)", - pic->fb_sz[0], pic->fb_sz[1]); + mtk_vdec_debug(inst->ctx, "pic(%d, %d), buf(%d, %d)", + pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); + mtk_vdec_debug(inst->ctx, "fb size: Y(%d), C(%d)", pic->fb_sz[0], pic->fb_sz[1]); } static void get_crop_info(struct vdec_h264_inst *inst, struct v4l2_rect *cr) @@ -259,17 +255,17 @@ static void get_crop_info(struct vdec_h264_inst *inst, struct v4l2_rect *cr) cr->width = inst->vsi->crop.width; cr->height = inst->vsi->crop.height; - mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d", - cr->left, cr->top, cr->width, cr->height); + mtk_vdec_debug(inst->ctx, "l=%d, t=%d, w=%d, h=%d", cr->left, cr->top, + cr->width, cr->height); } static void get_dpb_size(struct vdec_h264_inst *inst, unsigned int *dpb_sz) { *dpb_sz = inst->vsi->dec.dpb_sz; - mtk_vcodec_debug(inst, "sz=%d", *dpb_sz); + mtk_vdec_debug(inst->ctx, "sz=%d", *dpb_sz); } -static int vdec_h264_init(struct mtk_vcodec_ctx *ctx) +static int vdec_h264_init(struct mtk_vcodec_dec_ctx *ctx) { struct vdec_h264_inst *inst = NULL; int err; @@ -285,7 +281,7 @@ static int vdec_h264_init(struct mtk_vcodec_ctx *ctx) err = vpu_dec_init(&inst->vpu); if (err) { - mtk_vcodec_err(inst, "vdec_h264 init err=%d", err); + mtk_vdec_err(ctx, "vdec_h264 init err=%d", err); goto error_free_inst; } @@ -294,7 +290,7 @@ static int vdec_h264_init(struct mtk_vcodec_ctx *ctx) if (err) goto error_deinit; - mtk_vcodec_debug(inst, "H264 Instance >> %p", inst); + mtk_vdec_debug(ctx, "H264 Instance >> %p", inst); ctx->drv_handle = inst; return 0; @@ -311,8 +307,6 @@ static void vdec_h264_deinit(void *h_vdec) { struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; - mtk_vcodec_debug_enter(inst); - vpu_dec_deinit(&inst->vpu); free_predication_buf(inst); free_mv_buf(inst); @@ -348,8 +342,8 @@ static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs, uint64_t y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; uint64_t c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; - mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p", - ++inst->num_nalu, y_fb_dma, c_fb_dma, fb); + mtk_vdec_debug(inst->ctx, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p", + ++inst->num_nalu, y_fb_dma, c_fb_dma, fb); /* bs NULL means flush decoder */ if (bs == NULL) @@ -359,15 +353,15 @@ static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs, buf_sz = bs->size; nal_start_idx = find_start_code(buf, buf_sz); if (nal_start_idx < 0) { - mtk_vcodec_err(inst, "invalid nal start code"); + mtk_vdec_err(inst->ctx, "invalid nal start code"); err = -EIO; goto err_free_fb_out; } nal_start = buf[nal_start_idx]; nal_type = NAL_TYPE(buf[nal_start_idx]); - mtk_vcodec_debug(inst, "\n + NALU[%d] type %d +\n", inst->num_nalu, - nal_type); + mtk_vdec_debug(inst->ctx, "\n + NALU[%d] type %d +\n", inst->num_nalu, + nal_type); if (nal_type == NAL_H264_PPS) { buf_sz -= nal_start_idx; @@ -388,8 +382,7 @@ static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs, err = vpu_dec_start(vpu, data, 2); if (err) { if (err > 0 && (DEC_ERR_RET(err) == H264_ERR_NOT_VALID)) { - mtk_vcodec_err(inst, "- error bitstream - err = %d -", - err); + mtk_vdec_err(inst->ctx, "- error bitstream - err = %d -", err); err = -EIO; } goto err_free_fb_out; @@ -399,7 +392,7 @@ static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs, if (*res_chg) { struct vdec_pic_info pic; - mtk_vcodec_debug(inst, "- resolution changed -"); + mtk_vdec_debug(inst->ctx, "- resolution changed -"); get_pic_info(inst, &pic); if (inst->vsi->dec.realloc_mv_buf) { @@ -420,13 +413,12 @@ static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs, vpu_dec_end(vpu); } - mtk_vcodec_debug(inst, "\n - NALU[%d] type=%d -\n", inst->num_nalu, - nal_type); + mtk_vdec_debug(inst->ctx, "\n - NALU[%d] type=%d -\n", inst->num_nalu, nal_type); return 0; err_free_fb_out: put_fb_to_free(inst, fb); - mtk_vcodec_err(inst, "\n - NALU[%d] err=%d -\n", inst->num_nalu, err); + mtk_vdec_err(inst->ctx, "\n - NALU[%d] err=%d -\n", inst->num_nalu, err); return err; } @@ -440,8 +432,7 @@ static void vdec_h264_get_fb(struct vdec_h264_inst *inst, return; if (list->count == 0) { - mtk_vcodec_debug(inst, "[FB] there is no %s fb", - disp_list ? "disp" : "free"); + mtk_vdec_debug(inst->ctx, "[FB] there is no %s fb", disp_list ? "disp" : "free"); *out_fb = NULL; return; } @@ -451,10 +442,10 @@ static void vdec_h264_get_fb(struct vdec_h264_inst *inst, fb->status |= (disp_list ? FB_ST_DISPLAY : FB_ST_FREE); *out_fb = fb; - mtk_vcodec_debug(inst, "[FB] get %s fb st=%d poc=%d %llx", - disp_list ? "disp" : "free", - fb->status, list->fb_list[list->read_idx].poc, - list->fb_list[list->read_idx].vdec_fb_va); + mtk_vdec_debug(inst->ctx, "[FB] get %s fb st=%d poc=%d %llx", + disp_list ? "disp" : "free", + fb->status, list->fb_list[list->read_idx].poc, + list->fb_list[list->read_idx].vdec_fb_va); list->read_idx = (list->read_idx == H264_MAX_FB_NUM - 1) ? 0 : list->read_idx + 1; @@ -488,7 +479,7 @@ static int vdec_h264_get_param(void *h_vdec, enum vdec_get_param_type type, break; default: - mtk_vcodec_err(inst, "invalid get parameter type=%d", type); + mtk_vdec_err(inst->ctx, "invalid get parameter type=%d", type); return -EINVAL; } diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_common.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_common.c index 580ce979e2a3..5ca20d75dc8e 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_common.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_common.c @@ -33,7 +33,7 @@ void mtk_vdec_h264_get_ref_list(u8 *ref_list, memset(&ref_list[num_valid], 0x20, 32 - num_valid); } -void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id) +void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_dec_ctx *ctx, int id) { struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id); @@ -43,7 +43,7 @@ void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id) return ctrl->p_cur.p; } -void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_ctx *ctx, +void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_dec_ctx *ctx, struct slice_api_h264_decode_param *decode_params, struct mtk_h264_dpb_info *h264_dpb_info) { diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_common.h b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_common.h index 53d0a7c962a9..ac82be336055 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_common.h +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_common.h @@ -13,7 +13,7 @@ #include <media/v4l2-mem2mem.h> #include <media/videobuf2-dma-contig.h> -#include "../mtk_vcodec_drv.h" +#include "../mtk_vcodec_dec_drv.h" #define NAL_NON_IDR_SLICE 0x01 #define NAL_IDR_SLICE 0x05 @@ -182,7 +182,7 @@ void mtk_vdec_h264_get_ref_list(u8 *ref_list, * * Return: returns CID ctrl address. */ -void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id); +void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_dec_ctx *ctx, int id); /** * mtk_vdec_h264_fill_dpb_info - get each CID contrl address. @@ -191,7 +191,7 @@ void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id); * @decode_params: slice decode params * @h264_dpb_info: dpb buffer information */ -void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_ctx *ctx, +void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_dec_ctx *ctx, struct slice_api_h264_decode_param *decode_params, struct mtk_h264_dpb_info *h264_dpb_info); diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c index 4bc05ab5afea..5600f1df653d 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c @@ -6,9 +6,8 @@ #include <media/v4l2-h264.h> #include <media/videobuf2-dma-contig.h> -#include "../mtk_vcodec_util.h" #include "../mtk_vcodec_dec.h" -#include "../mtk_vcodec_intr.h" +#include "../../common/mtk_vcodec_intr.h" #include "../vdec_drv_base.h" #include "../vdec_drv_if.h" #include "../vdec_vpu_if.h" @@ -74,7 +73,7 @@ struct vdec_h264_vsi { /** * struct vdec_h264_slice_inst - h264 decoder instance * @num_nalu : how many nalus be decoded - * @ctx : point to mtk_vcodec_ctx + * @ctx : point to mtk_vcodec_dec_ctx * @pred_buf : HW working predication buffer * @mv_buf : HW working motion vector buffer * @vpu : VPU instance @@ -84,7 +83,7 @@ struct vdec_h264_vsi { */ struct vdec_h264_slice_inst { unsigned int num_nalu; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; struct mtk_vcodec_mem pred_buf; struct mtk_vcodec_mem mv_buf[H264_MAX_MV_NUM]; struct vdec_vpu_inst vpu; @@ -162,7 +161,7 @@ static int allocate_predication_buf(struct vdec_h264_slice_inst *inst) inst->pred_buf.size = BUF_PREDICTION_SZ; err = mtk_vcodec_mem_alloc(inst->ctx, &inst->pred_buf); if (err) { - mtk_vcodec_err(inst, "failed to allocate ppl buf"); + mtk_vdec_err(inst->ctx, "failed to allocate ppl buf"); return err; } @@ -174,8 +173,6 @@ static void free_predication_buf(struct vdec_h264_slice_inst *inst) { struct mtk_vcodec_mem *mem = &inst->pred_buf; - mtk_vcodec_debug_enter(inst); - inst->vsi_ctx.pred_buf_dma = 0; if (mem->va) mtk_vcodec_mem_free(inst->ctx, mem); @@ -189,7 +186,7 @@ static int alloc_mv_buf(struct vdec_h264_slice_inst *inst, struct mtk_vcodec_mem *mem = NULL; unsigned int buf_sz = mtk_vdec_h264_get_mv_buf_size(pic->buf_w, pic->buf_h); - mtk_v4l2_debug(3, "size = 0x%x", buf_sz); + mtk_v4l2_vdec_dbg(3, inst->ctx, "size = 0x%x", buf_sz); for (i = 0; i < H264_MAX_MV_NUM; i++) { mem = &inst->mv_buf[i]; if (mem->va) @@ -197,7 +194,7 @@ static int alloc_mv_buf(struct vdec_h264_slice_inst *inst, mem->size = buf_sz; err = mtk_vcodec_mem_alloc(inst->ctx, mem); if (err) { - mtk_vcodec_err(inst, "failed to allocate mv buf"); + mtk_vdec_err(inst->ctx, "failed to allocate mv buf"); return err; } inst->vsi_ctx.mv_buf_dma[i] = mem->dma_addr; @@ -222,7 +219,7 @@ static void free_mv_buf(struct vdec_h264_slice_inst *inst) static void get_pic_info(struct vdec_h264_slice_inst *inst, struct vdec_pic_info *pic) { - struct mtk_vcodec_ctx *ctx = inst->ctx; + struct mtk_vcodec_dec_ctx *ctx = inst->ctx; ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, VCODEC_DEC_ALIGNED_64); ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, VCODEC_DEC_ALIGNED_64); @@ -232,11 +229,11 @@ static void get_pic_info(struct vdec_h264_slice_inst *inst, ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes; *pic = ctx->picinfo; - mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", - ctx->picinfo.pic_w, ctx->picinfo.pic_h, - ctx->picinfo.buf_w, ctx->picinfo.buf_h); - mtk_vcodec_debug(inst, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0], - ctx->picinfo.fb_sz[1]); + mtk_vdec_debug(inst->ctx, "pic(%d, %d), buf(%d, %d)", + ctx->picinfo.pic_w, ctx->picinfo.pic_h, + ctx->picinfo.buf_w, ctx->picinfo.buf_h); + mtk_vdec_debug(inst->ctx, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0], + ctx->picinfo.fb_sz[1]); if (ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w || ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h) { @@ -245,12 +242,12 @@ static void get_pic_info(struct vdec_h264_slice_inst *inst, ctx->last_decoded_picinfo.buf_h != ctx->picinfo.buf_h) inst->vsi_ctx.dec.realloc_mv_buf = true; - mtk_v4l2_debug(1, "ResChg: (%d %d) : old(%d, %d) -> new(%d, %d)", - inst->vsi_ctx.dec.resolution_changed, - inst->vsi_ctx.dec.realloc_mv_buf, - ctx->last_decoded_picinfo.pic_w, - ctx->last_decoded_picinfo.pic_h, - ctx->picinfo.pic_w, ctx->picinfo.pic_h); + mtk_v4l2_vdec_dbg(1, inst->ctx, "ResChg: (%d %d) : old(%d, %d) -> new(%d, %d)", + inst->vsi_ctx.dec.resolution_changed, + inst->vsi_ctx.dec.realloc_mv_buf, + ctx->last_decoded_picinfo.pic_w, + ctx->last_decoded_picinfo.pic_h, + ctx->picinfo.pic_w, ctx->picinfo.pic_h); } } @@ -261,17 +258,17 @@ static void get_crop_info(struct vdec_h264_slice_inst *inst, struct v4l2_rect *c cr->width = inst->vsi_ctx.crop.width; cr->height = inst->vsi_ctx.crop.height; - mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d", - cr->left, cr->top, cr->width, cr->height); + mtk_vdec_debug(inst->ctx, "l=%d, t=%d, w=%d, h=%d", + cr->left, cr->top, cr->width, cr->height); } static void get_dpb_size(struct vdec_h264_slice_inst *inst, unsigned int *dpb_sz) { *dpb_sz = inst->vsi_ctx.dec.dpb_sz; - mtk_vcodec_debug(inst, "sz=%d", *dpb_sz); + mtk_vdec_debug(inst->ctx, "sz=%d", *dpb_sz); } -static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx) +static int vdec_h264_slice_init(struct mtk_vcodec_dec_ctx *ctx) { struct vdec_h264_slice_inst *inst; int err; @@ -287,7 +284,7 @@ static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx) err = vpu_dec_init(&inst->vpu); if (err) { - mtk_vcodec_err(inst, "vdec_h264 init err=%d", err); + mtk_vdec_err(ctx, "vdec_h264 init err=%d", err); goto error_free_inst; } @@ -299,13 +296,13 @@ static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx) if (err) goto error_deinit; - mtk_vcodec_debug(inst, "struct size = %zu,%zu,%zu,%zu\n", - sizeof(struct mtk_h264_sps_param), - sizeof(struct mtk_h264_pps_param), - sizeof(struct mtk_h264_dec_slice_param), - sizeof(struct mtk_h264_dpb_info)); + mtk_vdec_debug(ctx, "struct size = %zu,%zu,%zu,%zu\n", + sizeof(struct mtk_h264_sps_param), + sizeof(struct mtk_h264_pps_param), + sizeof(struct mtk_h264_dec_slice_param), + sizeof(struct mtk_h264_dpb_info)); - mtk_vcodec_debug(inst, "H264 Instance >> %p", inst); + mtk_vdec_debug(ctx, "H264 Instance >> %p", inst); ctx->drv_handle = inst; return 0; @@ -322,8 +319,6 @@ static void vdec_h264_slice_deinit(void *h_vdec) { struct vdec_h264_slice_inst *inst = h_vdec; - mtk_vcodec_debug_enter(inst); - vpu_dec_deinit(&inst->vpu); free_predication_buf(inst); free_mv_buf(inst); @@ -358,8 +353,8 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs, y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; - mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p", - inst->num_nalu, y_fb_dma, c_fb_dma, fb); + mtk_vdec_debug(inst->ctx, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p", + inst->num_nalu, y_fb_dma, c_fb_dma, fb); inst->vsi_ctx.dec.bs_dma = (uint64_t)bs->dma_addr; inst->vsi_ctx.dec.y_fb_dma = y_fb_dma; @@ -384,7 +379,7 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs, *res_chg = inst->vsi_ctx.dec.resolution_changed; if (*res_chg) { - mtk_vcodec_debug(inst, "- resolution changed -"); + mtk_vdec_debug(inst->ctx, "- resolution changed -"); if (inst->vsi_ctx.dec.realloc_mv_buf) { err = alloc_mv_buf(inst, &inst->ctx->picinfo); inst->vsi_ctx.dec.realloc_mv_buf = false; @@ -408,11 +403,11 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs, vpu_dec_end(vpu); memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx)); - mtk_vcodec_debug(inst, "\n - NALU[%d]", inst->num_nalu); + mtk_vdec_debug(inst->ctx, "\n - NALU[%d]", inst->num_nalu); return 0; err_free_fb_out: - mtk_vcodec_err(inst, "\n - NALU[%d] err=%d -\n", inst->num_nalu, err); + mtk_vdec_err(inst->ctx, "\n - NALU[%d] err=%d -\n", inst->num_nalu, err); return err; } @@ -434,7 +429,7 @@ static int vdec_h264_slice_get_param(void *h_vdec, enum vdec_get_param_type type break; default: - mtk_vcodec_err(inst, "invalid get parameter type=%d", type); + mtk_vdec_err(inst->ctx, "invalid get parameter type=%d", type); return -EINVAL; } diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c index a7e8e3257b7f..0e741e0dc8ba 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c @@ -10,9 +10,8 @@ #include <media/v4l2-mem2mem.h> #include <media/videobuf2-dma-contig.h> -#include "../mtk_vcodec_util.h" #include "../mtk_vcodec_dec.h" -#include "../mtk_vcodec_intr.h" +#include "../../common/mtk_vcodec_intr.h" #include "../vdec_drv_base.h" #include "../vdec_drv_if.h" #include "../vdec_vpu_if.h" @@ -133,7 +132,7 @@ struct vdec_h264_slice_share_info { * struct vdec_h264_slice_inst - h264 decoder instance * * @slice_dec_num: how many picture be decoded - * @ctx: point to mtk_vcodec_ctx + * @ctx: point to mtk_vcodec_dec_ctx * @pred_buf: HW working predication buffer * @mv_buf: HW working motion vector buffer * @vpu: VPU instance @@ -153,7 +152,7 @@ struct vdec_h264_slice_share_info { */ struct vdec_h264_slice_inst { unsigned int slice_dec_num; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; struct mtk_vcodec_mem pred_buf; struct mtk_vcodec_mem mv_buf[H264_MAX_MV_NUM]; struct vdec_vpu_inst vpu; @@ -199,7 +198,7 @@ static int vdec_h264_slice_fill_decode_parameters(struct vdec_h264_slice_inst *i return PTR_ERR(pps); if (dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) { - mtk_vcodec_err(inst, "No support for H.264 field decoding."); + mtk_vdec_err(inst->ctx, "No support for H.264 field decoding."); inst->is_field_bitstream = true; return -EINVAL; } @@ -294,7 +293,7 @@ static void vdec_h264_slice_fill_decode_reflist(struct vdec_h264_slice_inst *ins mtk_vdec_h264_fill_dpb_info(inst->ctx, &slice_param->decode_params, slice_param->h264_dpb_info); - mtk_v4l2_debug(3, "cur poc = %d\n", dec_params->bottom_field_order_cnt); + mtk_v4l2_vdec_dbg(3, inst->ctx, "cur poc = %d\n", dec_params->bottom_field_order_cnt); /* Build the reference lists */ v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps, inst->dpb); @@ -314,7 +313,7 @@ static int vdec_h264_slice_alloc_mv_buf(struct vdec_h264_slice_inst *inst, struct mtk_vcodec_mem *mem; int i, err; - mtk_v4l2_debug(3, "size = 0x%x", buf_sz); + mtk_v4l2_vdec_dbg(3, inst->ctx, "size = 0x%x", buf_sz); for (i = 0; i < H264_MAX_MV_NUM; i++) { mem = &inst->mv_buf[i]; if (mem->va) @@ -322,7 +321,7 @@ static int vdec_h264_slice_alloc_mv_buf(struct vdec_h264_slice_inst *inst, mem->size = buf_sz; err = mtk_vcodec_mem_alloc(inst->ctx, mem); if (err) { - mtk_vcodec_err(inst, "failed to allocate mv buf"); + mtk_vdec_err(inst->ctx, "failed to allocate mv buf"); return err; } } @@ -344,7 +343,7 @@ static void vdec_h264_slice_free_mv_buf(struct vdec_h264_slice_inst *inst) static void vdec_h264_slice_get_pic_info(struct vdec_h264_slice_inst *inst) { - struct mtk_vcodec_ctx *ctx = inst->ctx; + struct mtk_vcodec_dec_ctx *ctx = inst->ctx; u32 data[3]; data[0] = ctx->picinfo.pic_w; @@ -359,11 +358,11 @@ static void vdec_h264_slice_get_pic_info(struct vdec_h264_slice_inst *inst) inst->cap_num_planes = ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes; - mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", - ctx->picinfo.pic_w, ctx->picinfo.pic_h, - ctx->picinfo.buf_w, ctx->picinfo.buf_h); - mtk_vcodec_debug(inst, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0], - ctx->picinfo.fb_sz[1]); + mtk_vdec_debug(ctx, "pic(%d, %d), buf(%d, %d)", + ctx->picinfo.pic_w, ctx->picinfo.pic_h, + ctx->picinfo.buf_w, ctx->picinfo.buf_h); + mtk_vdec_debug(ctx, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0], + ctx->picinfo.fb_sz[1]); if (ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w || ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h) { @@ -372,12 +371,12 @@ static void vdec_h264_slice_get_pic_info(struct vdec_h264_slice_inst *inst) ctx->last_decoded_picinfo.buf_h != ctx->picinfo.buf_h) inst->realloc_mv_buf = true; - mtk_v4l2_debug(1, "resChg: (%d %d) : old(%d, %d) -> new(%d, %d)", - inst->resolution_changed, - inst->realloc_mv_buf, - ctx->last_decoded_picinfo.pic_w, - ctx->last_decoded_picinfo.pic_h, - ctx->picinfo.pic_w, ctx->picinfo.pic_h); + mtk_v4l2_vdec_dbg(1, inst->ctx, "resChg: (%d %d) : old(%d, %d) -> new(%d, %d)", + inst->resolution_changed, + inst->realloc_mv_buf, + ctx->last_decoded_picinfo.pic_w, + ctx->last_decoded_picinfo.pic_h, + ctx->picinfo.pic_w, ctx->picinfo.pic_h); } } @@ -389,11 +388,11 @@ static void vdec_h264_slice_get_crop_info(struct vdec_h264_slice_inst *inst, cr->width = inst->ctx->picinfo.pic_w; cr->height = inst->ctx->picinfo.pic_h; - mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d", - cr->left, cr->top, cr->width, cr->height); + mtk_vdec_debug(inst->ctx, "l=%d, t=%d, w=%d, h=%d", + cr->left, cr->top, cr->width, cr->height); } -static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx) +static int vdec_h264_slice_init(struct mtk_vcodec_dec_ctx *ctx) { struct vdec_h264_slice_inst *inst; int err, vsi_size; @@ -412,7 +411,7 @@ static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx) err = vpu_dec_init(&inst->vpu); if (err) { - mtk_vcodec_err(inst, "vdec_h264 init err=%d", err); + mtk_vdec_err(ctx, "vdec_h264 init err=%d", err); goto error_free_inst; } @@ -423,14 +422,14 @@ static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx) inst->resolution_changed = true; inst->realloc_mv_buf = true; - mtk_vcodec_debug(inst, "lat struct size = %d,%d,%d,%d vsi: %d\n", - (int)sizeof(struct mtk_h264_sps_param), - (int)sizeof(struct mtk_h264_pps_param), - (int)sizeof(struct vdec_h264_slice_lat_dec_param), - (int)sizeof(struct mtk_h264_dpb_info), - vsi_size); - mtk_vcodec_debug(inst, "lat H264 instance >> %p, codec_type = 0x%x", - inst, inst->vpu.codec_type); + mtk_vdec_debug(ctx, "lat struct size = %d,%d,%d,%d vsi: %d\n", + (int)sizeof(struct mtk_h264_sps_param), + (int)sizeof(struct mtk_h264_pps_param), + (int)sizeof(struct vdec_h264_slice_lat_dec_param), + (int)sizeof(struct mtk_h264_dpb_info), + vsi_size); + mtk_vdec_debug(ctx, "lat H264 instance >> %p, codec_type = 0x%x", + inst, inst->vpu.codec_type); ctx->drv_handle = inst; return 0; @@ -444,8 +443,6 @@ static void vdec_h264_slice_deinit(void *h_vdec) { struct vdec_h264_slice_inst *inst = h_vdec; - mtk_vcodec_debug_enter(inst); - vpu_dec_deinit(&inst->vpu); vdec_h264_slice_free_mv_buf(inst); vdec_msg_queue_deinit(&inst->ctx->msg_queue, inst->ctx); @@ -459,21 +456,21 @@ static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf) u64 vdec_fb_va; u64 y_fb_dma, c_fb_dma; int err, timeout, i; - struct mtk_vcodec_ctx *ctx = lat_buf->ctx; + struct mtk_vcodec_dec_ctx *ctx = lat_buf->ctx; struct vdec_h264_slice_inst *inst = ctx->drv_handle; struct vb2_v4l2_buffer *vb2_v4l2; struct vdec_h264_slice_share_info *share_info = lat_buf->private_data; struct mtk_vcodec_mem *mem; struct vdec_vpu_inst *vpu = &inst->vpu; - mtk_vcodec_debug(inst, "[h264-core] vdec_h264 core decode"); + mtk_vdec_debug(ctx, "[h264-core] vdec_h264 core decode"); memcpy(&inst->vsi_core->h264_slice_params, &share_info->h264_slice_params, sizeof(share_info->h264_slice_params)); fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx); if (!fb) { err = -EBUSY; - mtk_vcodec_err(inst, "fb buffer is NULL"); + mtk_vdec_err(ctx, "fb buffer is NULL"); goto vdec_dec_end; } @@ -485,8 +482,7 @@ static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf) else c_fb_dma = (u64)fb->base_c.dma_addr; - mtk_vcodec_debug(inst, "[h264-core] y/c addr = 0x%llx 0x%llx", y_fb_dma, - c_fb_dma); + mtk_vdec_debug(ctx, "[h264-core] y/c addr = 0x%llx 0x%llx", y_fb_dma, c_fb_dma); inst->vsi_core->dec.y_fb_dma = y_fb_dma; inst->vsi_core->dec.c_fb_dma = c_fb_dma; @@ -516,7 +512,7 @@ static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf) err = vpu_dec_core(vpu); if (err) { - mtk_vcodec_err(inst, "core decode err=%d", err); + mtk_vdec_err(ctx, "core decode err=%d", err); goto vdec_dec_end; } @@ -524,27 +520,26 @@ static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf) timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED, WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE); if (timeout) - mtk_vcodec_err(inst, "core decode timeout: pic_%d", - ctx->decoded_frame_cnt); + mtk_vdec_err(ctx, "core decode timeout: pic_%d", ctx->decoded_frame_cnt); inst->vsi_core->dec.timeout = !!timeout; vpu_dec_core_end(vpu); - mtk_vcodec_debug(inst, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", - ctx->decoded_frame_cnt, - inst->vsi_core->dec.crc[0], inst->vsi_core->dec.crc[1], - inst->vsi_core->dec.crc[2], inst->vsi_core->dec.crc[3], - inst->vsi_core->dec.crc[4], inst->vsi_core->dec.crc[5], - inst->vsi_core->dec.crc[6], inst->vsi_core->dec.crc[7]); + mtk_vdec_debug(ctx, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", + ctx->decoded_frame_cnt, + inst->vsi_core->dec.crc[0], inst->vsi_core->dec.crc[1], + inst->vsi_core->dec.crc[2], inst->vsi_core->dec.crc[3], + inst->vsi_core->dec.crc[4], inst->vsi_core->dec.crc[5], + inst->vsi_core->dec.crc[6], inst->vsi_core->dec.crc[7]); vdec_dec_end: vdec_msg_queue_update_ube_rptr(&lat_buf->ctx->msg_queue, share_info->trans_end); ctx->dev->vdec_pdata->cap_to_disp(ctx, !!err, lat_buf->src_buf_req); - mtk_vcodec_debug(inst, "core decode done err=%d", err); + mtk_vdec_debug(ctx, "core decode done err=%d", err); ctx->decoded_frame_cnt++; return 0; } -static void vdec_h264_insert_startcode(struct mtk_vcodec_dev *vcodec_dev, unsigned char *buf, +static void vdec_h264_insert_startcode(struct mtk_vcodec_dec_dev *vcodec_dev, unsigned char *buf, size_t *bs_size, struct mtk_h264_pps_param *pps) { struct device *dev = &vcodec_dev->plat_dev->dev; @@ -596,7 +591,7 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, lat_buf = vdec_msg_queue_dqbuf(&inst->ctx->msg_queue.lat_ctx); if (!lat_buf) { - mtk_vcodec_debug(inst, "failed to get lat buffer"); + mtk_vdec_debug(inst->ctx, "failed to get lat buffer"); return -EAGAIN; } share_info = lat_buf->private_data; @@ -625,7 +620,7 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, *res_chg = inst->resolution_changed; if (inst->resolution_changed) { - mtk_vcodec_debug(inst, "- resolution changed -"); + mtk_vdec_debug(inst->ctx, "- resolution changed -"); if (inst->realloc_mv_buf) { err = vdec_h264_slice_alloc_mv_buf(inst, &inst->ctx->picinfo); inst->realloc_mv_buf = false; @@ -648,19 +643,19 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, inst->vsi->trans_end = inst->ctx->msg_queue.wdma_rptr_addr; inst->vsi->trans_start = inst->ctx->msg_queue.wdma_wptr_addr; - mtk_vcodec_debug(inst, "lat:trans(0x%llx 0x%llx) err:0x%llx", - inst->vsi->wdma_start_addr, - inst->vsi->wdma_end_addr, - inst->vsi->wdma_err_addr); - - mtk_vcodec_debug(inst, "slice(0x%llx 0x%llx) rprt((0x%llx 0x%llx))", - inst->vsi->slice_bc_start_addr, - inst->vsi->slice_bc_end_addr, - inst->vsi->trans_start, - inst->vsi->trans_end); + mtk_vdec_debug(inst->ctx, "lat:trans(0x%llx 0x%llx) err:0x%llx", + inst->vsi->wdma_start_addr, + inst->vsi->wdma_end_addr, + inst->vsi->wdma_err_addr); + + mtk_vdec_debug(inst->ctx, "slice(0x%llx 0x%llx) rprt((0x%llx 0x%llx))", + inst->vsi->slice_bc_start_addr, + inst->vsi->slice_bc_end_addr, + inst->vsi->trans_start, + inst->vsi->trans_end); err = vpu_dec_start(vpu, data, 2); if (err) { - mtk_vcodec_debug(inst, "lat decode err: %d", err); + mtk_vdec_debug(inst->ctx, "lat decode err: %d", err); goto err_free_fb_out; } @@ -679,7 +674,7 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED, WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0); if (timeout) - mtk_vcodec_err(inst, "lat decode timeout: pic_%d", inst->slice_dec_num); + mtk_vdec_err(inst->ctx, "lat decode timeout: pic_%d", inst->slice_dec_num); inst->vsi->dec.timeout = !!timeout; err = vpu_dec_end(vpu); @@ -687,7 +682,7 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf); inst->slice_dec_num++; - mtk_vcodec_err(inst, "lat dec fail: pic_%d err:%d", inst->slice_dec_num, err); + mtk_vdec_err(inst->ctx, "lat dec fail: pic_%d err:%d", inst->slice_dec_num, err); return -EINVAL; } @@ -700,14 +695,14 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, sizeof(share_info->h264_slice_params)); vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf); } - mtk_vcodec_debug(inst, "dec num: %d lat crc: 0x%x 0x%x 0x%x", inst->slice_dec_num, - inst->vsi->dec.crc[0], inst->vsi->dec.crc[1], inst->vsi->dec.crc[2]); + mtk_vdec_debug(inst->ctx, "dec num: %d lat crc: 0x%x 0x%x 0x%x", inst->slice_dec_num, + inst->vsi->dec.crc[0], inst->vsi->dec.crc[1], inst->vsi->dec.crc[2]); inst->slice_dec_num++; return 0; err_free_fb_out: vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf); - mtk_vcodec_err(inst, "slice dec number: %d err: %d", inst->slice_dec_num, err); + mtk_vdec_err(inst->ctx, "slice dec number: %d err: %d", inst->slice_dec_num, err); return err; } @@ -734,8 +729,8 @@ static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; - mtk_vcodec_debug(inst, "[h264-dec] [%d] y_dma=%llx c_dma=%llx", - inst->ctx->decoded_frame_cnt, y_fb_dma, c_fb_dma); + mtk_vdec_debug(inst->ctx, "[h264-dec] [%d] y_dma=%llx c_dma=%llx", + inst->ctx->decoded_frame_cnt, y_fb_dma, c_fb_dma); inst->vsi_ctx.dec.bs_buf_addr = (u64)bs->dma_addr; inst->vsi_ctx.dec.bs_buf_size = bs->size; @@ -759,7 +754,7 @@ static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs *res_chg = inst->resolution_changed; if (inst->resolution_changed) { - mtk_vcodec_debug(inst, "- resolution changed -"); + mtk_vdec_debug(inst->ctx, "- resolution changed -"); if (inst->realloc_mv_buf) { err = vdec_h264_slice_alloc_mv_buf(inst, &inst->ctx->picinfo); inst->realloc_mv_buf = false; @@ -783,8 +778,7 @@ static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs err = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED, WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE); if (err) - mtk_vcodec_err(inst, "decode timeout: pic_%d", - inst->ctx->decoded_frame_cnt); + mtk_vdec_err(inst->ctx, "decode timeout: pic_%d", inst->ctx->decoded_frame_cnt); inst->vsi->dec.timeout = !!err; err = vpu_dec_end(vpu); @@ -792,19 +786,18 @@ static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs goto err_free_fb_out; memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx)); - mtk_vcodec_debug(inst, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", - inst->ctx->decoded_frame_cnt, - inst->vsi_ctx.dec.crc[0], inst->vsi_ctx.dec.crc[1], - inst->vsi_ctx.dec.crc[2], inst->vsi_ctx.dec.crc[3], - inst->vsi_ctx.dec.crc[4], inst->vsi_ctx.dec.crc[5], - inst->vsi_ctx.dec.crc[6], inst->vsi_ctx.dec.crc[7]); + mtk_vdec_debug(inst->ctx, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", + inst->ctx->decoded_frame_cnt, + inst->vsi_ctx.dec.crc[0], inst->vsi_ctx.dec.crc[1], + inst->vsi_ctx.dec.crc[2], inst->vsi_ctx.dec.crc[3], + inst->vsi_ctx.dec.crc[4], inst->vsi_ctx.dec.crc[5], + inst->vsi_ctx.dec.crc[6], inst->vsi_ctx.dec.crc[7]); inst->ctx->decoded_frame_cnt++; return 0; err_free_fb_out: - mtk_vcodec_err(inst, "dec frame number: %d err: %d", - inst->ctx->decoded_frame_cnt, err); + mtk_vdec_err(inst->ctx, "dec frame number: %d err: %d", inst->ctx->decoded_frame_cnt, err); return err; } @@ -841,7 +834,7 @@ static int vdec_h264_slice_get_param(void *h_vdec, enum vdec_get_param_type type vdec_h264_slice_get_crop_info(inst, out); break; default: - mtk_vcodec_err(inst, "invalid get parameter type=%d", type); + mtk_vdec_err(inst->ctx, "invalid get parameter type=%d", type); return -EINVAL; } return 0; diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_hevc_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c index 1e6ab138b0bb..06ed47df693b 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_hevc_req_multi_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c @@ -8,9 +8,8 @@ #include <linux/slab.h> #include <media/videobuf2-dma-contig.h> -#include "../mtk_vcodec_util.h" #include "../mtk_vcodec_dec.h" -#include "../mtk_vcodec_intr.h" +#include "../../common/mtk_vcodec_intr.h" #include "../vdec_drv_base.h" #include "../vdec_drv_if.h" #include "../vdec_vpu_if.h" @@ -344,7 +343,7 @@ struct vdec_hevc_slice_share_info { * struct vdec_hevc_slice_inst - hevc decoder instance * * @slice_dec_num: how many picture be decoded - * @ctx: point to mtk_vcodec_ctx + * @ctx: point to mtk_vcodec_dec_ctx * @mv_buf: HW working motion vector buffer * @vpu: VPU instance * @vsi: vsi used for lat @@ -359,7 +358,7 @@ struct vdec_hevc_slice_share_info { */ struct vdec_hevc_slice_inst { unsigned int slice_dec_num; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; struct mtk_vcodec_mem mv_buf[HEVC_MAX_MV_NUM]; struct vdec_vpu_inst vpu; struct vdec_hevc_slice_vsi *vsi; @@ -380,7 +379,7 @@ static unsigned int vdec_hevc_get_mv_buf_size(unsigned int width, unsigned int h return 64 * unit_size; } -static void *vdec_hevc_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id) +static void *vdec_hevc_get_ctrl_ptr(struct mtk_vcodec_dec_ctx *ctx, int id) { struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id); @@ -390,7 +389,7 @@ static void *vdec_hevc_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id) return ctrl->p_cur.p; } -static void vdec_hevc_fill_dpb_info(struct mtk_vcodec_ctx *ctx, +static void vdec_hevc_fill_dpb_info(struct mtk_vcodec_dec_ctx *ctx, struct slice_api_hevc_decode_param *decode_params, struct mtk_hevc_dpb_info *hevc_dpb_info) { @@ -649,7 +648,7 @@ static int vdec_hevc_slice_alloc_mv_buf(struct vdec_hevc_slice_inst *inst, struct mtk_vcodec_mem *mem; int i, err; - mtk_v4l2_debug(3, "allocate mv buffer size = 0x%x", buf_sz); + mtk_v4l2_vdec_dbg(3, inst->ctx, "allocate mv buffer size = 0x%x", buf_sz); for (i = 0; i < HEVC_MAX_MV_NUM; i++) { mem = &inst->mv_buf[i]; if (mem->va) @@ -657,7 +656,7 @@ static int vdec_hevc_slice_alloc_mv_buf(struct vdec_hevc_slice_inst *inst, mem->size = buf_sz; err = mtk_vcodec_mem_alloc(inst->ctx, mem); if (err) { - mtk_vcodec_err(inst, "failed to allocate mv buf"); + mtk_vdec_err(inst->ctx, "failed to allocate mv buf"); return err; } } @@ -679,7 +678,7 @@ static void vdec_hevc_slice_free_mv_buf(struct vdec_hevc_slice_inst *inst) static void vdec_hevc_slice_get_pic_info(struct vdec_hevc_slice_inst *inst) { - struct mtk_vcodec_ctx *ctx = inst->ctx; + struct mtk_vcodec_dec_ctx *ctx = inst->ctx; u32 data[3]; data[0] = ctx->picinfo.pic_w; @@ -694,11 +693,11 @@ static void vdec_hevc_slice_get_pic_info(struct vdec_hevc_slice_inst *inst) inst->cap_num_planes = ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes; - mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", - ctx->picinfo.pic_w, ctx->picinfo.pic_h, - ctx->picinfo.buf_w, ctx->picinfo.buf_h); - mtk_vcodec_debug(inst, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0], - ctx->picinfo.fb_sz[1]); + mtk_vdec_debug(ctx, "pic(%d, %d), buf(%d, %d)", + ctx->picinfo.pic_w, ctx->picinfo.pic_h, + ctx->picinfo.buf_w, ctx->picinfo.buf_h); + mtk_vdec_debug(ctx, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0], + ctx->picinfo.fb_sz[1]); if (ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w || ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h) { @@ -707,12 +706,12 @@ static void vdec_hevc_slice_get_pic_info(struct vdec_hevc_slice_inst *inst) ctx->last_decoded_picinfo.buf_h != ctx->picinfo.buf_h) inst->realloc_mv_buf = true; - mtk_v4l2_debug(1, "resChg: (%d %d) : old(%d, %d) -> new(%d, %d)", - inst->resolution_changed, - inst->realloc_mv_buf, - ctx->last_decoded_picinfo.pic_w, - ctx->last_decoded_picinfo.pic_h, - ctx->picinfo.pic_w, ctx->picinfo.pic_h); + mtk_v4l2_vdec_dbg(1, inst->ctx, "resChg: (%d %d) : old(%d, %d) -> new(%d, %d)", + inst->resolution_changed, + inst->realloc_mv_buf, + ctx->last_decoded_picinfo.pic_w, + ctx->last_decoded_picinfo.pic_h, + ctx->picinfo.pic_w, ctx->picinfo.pic_h); } } @@ -724,8 +723,8 @@ static void vdec_hevc_slice_get_crop_info(struct vdec_hevc_slice_inst *inst, cr->width = inst->ctx->picinfo.pic_w; cr->height = inst->ctx->picinfo.pic_h; - mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d", - cr->left, cr->top, cr->width, cr->height); + mtk_vdec_debug(inst->ctx, "l=%d, t=%d, w=%d, h=%d", + cr->left, cr->top, cr->width, cr->height); } static int vdec_hevc_slice_setup_lat_buffer(struct vdec_hevc_slice_inst *inst, @@ -747,7 +746,7 @@ static int vdec_hevc_slice_setup_lat_buffer(struct vdec_hevc_slice_inst *inst, *res_chg = inst->resolution_changed; if (inst->resolution_changed) { - mtk_vcodec_debug(inst, "- resolution changed -"); + mtk_vdec_debug(inst->ctx, "- resolution changed -"); if (inst->realloc_mv_buf) { err = vdec_hevc_slice_alloc_mv_buf(inst, &inst->ctx->picinfo); inst->realloc_mv_buf = false; @@ -779,16 +778,16 @@ static int vdec_hevc_slice_setup_lat_buffer(struct vdec_hevc_slice_inst *inst, share_info->trans.dma_addr = inst->vsi->trans.dma_addr; share_info->trans.dma_addr_end = inst->vsi->trans.dma_addr_end; - mtk_vcodec_debug(inst, "lat: ube addr/size(0x%llx 0x%llx) err:0x%llx", - inst->vsi->ube.buf, - inst->vsi->ube.padding, - inst->vsi->err_map.buf); + mtk_vdec_debug(inst->ctx, "lat: ube addr/size(0x%llx 0x%llx) err:0x%llx", + inst->vsi->ube.buf, + inst->vsi->ube.padding, + inst->vsi->err_map.buf); - mtk_vcodec_debug(inst, "slice addr/size(0x%llx 0x%llx) trans start/end((0x%llx 0x%llx))", - inst->vsi->slice_bc.buf, - inst->vsi->slice_bc.padding, - inst->vsi->trans.buf, - inst->vsi->trans.padding); + mtk_vdec_debug(inst->ctx, "slice addr/size(0x%llx 0x%llx) trans start/end((0x%llx 0x%llx))", + inst->vsi->slice_bc.buf, + inst->vsi->slice_bc.padding, + inst->vsi->trans.buf, + inst->vsi->trans.padding); return 0; } @@ -798,7 +797,7 @@ static int vdec_hevc_slice_setup_core_buffer(struct vdec_hevc_slice_inst *inst, struct vdec_lat_buf *lat_buf) { struct mtk_vcodec_mem *mem; - struct mtk_vcodec_ctx *ctx = inst->ctx; + struct mtk_vcodec_dec_ctx *ctx = inst->ctx; struct vb2_v4l2_buffer *vb2_v4l2; struct vdec_fb *fb; u64 y_fb_dma, c_fb_dma; @@ -806,7 +805,7 @@ static int vdec_hevc_slice_setup_core_buffer(struct vdec_hevc_slice_inst *inst, fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx); if (!fb) { - mtk_vcodec_err(inst, "fb buffer is NULL"); + mtk_vdec_err(inst->ctx, "fb buffer is NULL"); return -EBUSY; } @@ -817,8 +816,7 @@ static int vdec_hevc_slice_setup_core_buffer(struct vdec_hevc_slice_inst *inst, else c_fb_dma = (u64)fb->base_c.dma_addr; - mtk_vcodec_debug(inst, "[hevc-core] y/c addr = 0x%llx 0x%llx", y_fb_dma, - c_fb_dma); + mtk_vdec_debug(inst->ctx, "[hevc-core] y/c addr = 0x%llx 0x%llx", y_fb_dma, c_fb_dma); inst->vsi_core->fb.y.dma_addr = y_fb_dma; inst->vsi_core->fb.y.size = ctx->picinfo.fb_sz[0]; @@ -854,7 +852,7 @@ static int vdec_hevc_slice_setup_core_buffer(struct vdec_hevc_slice_inst *inst, return 0; } -static int vdec_hevc_slice_init(struct mtk_vcodec_ctx *ctx) +static int vdec_hevc_slice_init(struct mtk_vcodec_dec_ctx *ctx) { struct vdec_hevc_slice_inst *inst; int err, vsi_size; @@ -874,7 +872,7 @@ static int vdec_hevc_slice_init(struct mtk_vcodec_ctx *ctx) ctx->drv_handle = inst; err = vpu_dec_init(&inst->vpu); if (err) { - mtk_vcodec_err(inst, "vdec_hevc init err=%d", err); + mtk_vdec_err(ctx, "vdec_hevc init err=%d", err); goto error_free_inst; } @@ -891,14 +889,14 @@ static int vdec_hevc_slice_init(struct mtk_vcodec_ctx *ctx) if (err) goto error_free_inst; - mtk_vcodec_debug(inst, "lat struct size = %d,%d,%d,%d vsi: %d\n", - (int)sizeof(struct mtk_hevc_sps_param), - (int)sizeof(struct mtk_hevc_pps_param), - (int)sizeof(struct vdec_hevc_slice_lat_dec_param), - (int)sizeof(struct mtk_hevc_dpb_info), + mtk_vdec_debug(ctx, "lat struct size = %d,%d,%d,%d vsi: %d\n", + (int)sizeof(struct mtk_hevc_sps_param), + (int)sizeof(struct mtk_hevc_pps_param), + (int)sizeof(struct vdec_hevc_slice_lat_dec_param), + (int)sizeof(struct mtk_hevc_dpb_info), vsi_size); - mtk_vcodec_debug(inst, "lat hevc instance >> %p, codec_type = 0x%x", - inst, inst->vpu.codec_type); + mtk_vdec_debug(ctx, "lat hevc instance >> %p, codec_type = 0x%x", + inst, inst->vpu.codec_type); return 0; error_free_inst: @@ -911,8 +909,6 @@ static void vdec_hevc_slice_deinit(void *h_vdec) struct vdec_hevc_slice_inst *inst = h_vdec; struct mtk_vcodec_mem *mem; - mtk_vcodec_debug_enter(inst); - vpu_dec_deinit(&inst->vpu); vdec_hevc_slice_free_mv_buf(inst); @@ -927,12 +923,12 @@ static void vdec_hevc_slice_deinit(void *h_vdec) static int vdec_hevc_slice_core_decode(struct vdec_lat_buf *lat_buf) { int err, timeout; - struct mtk_vcodec_ctx *ctx = lat_buf->ctx; + struct mtk_vcodec_dec_ctx *ctx = lat_buf->ctx; struct vdec_hevc_slice_inst *inst = ctx->drv_handle; struct vdec_hevc_slice_share_info *share_info = lat_buf->private_data; struct vdec_vpu_inst *vpu = &inst->vpu; - mtk_vcodec_debug(inst, "[hevc-core] vdec_hevc core decode"); + mtk_vdec_debug(ctx, "[hevc-core] vdec_hevc core decode"); memcpy(&inst->vsi_core->hevc_slice_params, &share_info->hevc_slice_params, sizeof(share_info->hevc_slice_params)); @@ -944,7 +940,7 @@ static int vdec_hevc_slice_core_decode(struct vdec_lat_buf *lat_buf) share_info); err = vpu_dec_core(vpu); if (err) { - mtk_vcodec_err(inst, "core decode err=%d", err); + mtk_vdec_err(ctx, "core decode err=%d", err); goto vdec_dec_end; } @@ -952,22 +948,21 @@ static int vdec_hevc_slice_core_decode(struct vdec_lat_buf *lat_buf) timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED, WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE); if (timeout) - mtk_vcodec_err(inst, "core decode timeout: pic_%d", - ctx->decoded_frame_cnt); + mtk_vdec_err(ctx, "core decode timeout: pic_%d", ctx->decoded_frame_cnt); inst->vsi_core->dec.timeout = !!timeout; vpu_dec_core_end(vpu); - mtk_vcodec_debug(inst, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", - ctx->decoded_frame_cnt, - inst->vsi_core->dec.crc[0], inst->vsi_core->dec.crc[1], - inst->vsi_core->dec.crc[2], inst->vsi_core->dec.crc[3], - inst->vsi_core->dec.crc[4], inst->vsi_core->dec.crc[5], - inst->vsi_core->dec.crc[6], inst->vsi_core->dec.crc[7]); + mtk_vdec_debug(ctx, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", + ctx->decoded_frame_cnt, + inst->vsi_core->dec.crc[0], inst->vsi_core->dec.crc[1], + inst->vsi_core->dec.crc[2], inst->vsi_core->dec.crc[3], + inst->vsi_core->dec.crc[4], inst->vsi_core->dec.crc[5], + inst->vsi_core->dec.crc[6], inst->vsi_core->dec.crc[7]); vdec_dec_end: vdec_msg_queue_update_ube_rptr(&lat_buf->ctx->msg_queue, share_info->trans.dma_addr_end); ctx->dev->vdec_pdata->cap_to_disp(ctx, !!err, lat_buf->src_buf_req); - mtk_vcodec_debug(inst, "core decode done err=%d", err); + mtk_vdec_debug(ctx, "core decode done err=%d", err); ctx->decoded_frame_cnt++; return 0; } @@ -995,7 +990,7 @@ static int vdec_hevc_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, lat_buf = vdec_msg_queue_dqbuf(&inst->ctx->msg_queue.lat_ctx); if (!lat_buf) { - mtk_vcodec_debug(inst, "failed to get lat buffer"); + mtk_vdec_debug(inst->ctx, "failed to get lat buffer"); return -EAGAIN; } @@ -1010,7 +1005,7 @@ static int vdec_hevc_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, err = vpu_dec_start(vpu, data, 2); if (err) { - mtk_vcodec_debug(inst, "lat decode err: %d", err); + mtk_vdec_debug(inst->ctx, "lat decode err: %d", err); goto err_free_fb_out; } @@ -1024,7 +1019,7 @@ static int vdec_hevc_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED, WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0); if (timeout) - mtk_vcodec_err(inst, "lat decode timeout: pic_%d", inst->slice_dec_num); + mtk_vdec_err(inst->ctx, "lat decode timeout: pic_%d", inst->slice_dec_num); inst->vsi->dec.timeout = !!timeout; err = vpu_dec_end(vpu); @@ -1032,7 +1027,7 @@ static int vdec_hevc_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf); inst->slice_dec_num++; - mtk_vcodec_err(inst, "lat dec fail: pic_%d err:%d", inst->slice_dec_num, err); + mtk_vdec_err(inst->ctx, "lat dec fail: pic_%d err:%d", inst->slice_dec_num, err); return -EINVAL; } @@ -1045,14 +1040,14 @@ static int vdec_hevc_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, sizeof(share_info->hevc_slice_params)); vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf); } - mtk_vcodec_debug(inst, "dec num: %d lat crc: 0x%x 0x%x 0x%x", inst->slice_dec_num, - inst->vsi->dec.crc[0], inst->vsi->dec.crc[1], inst->vsi->dec.crc[2]); + mtk_vdec_debug(inst->ctx, "dec num: %d lat crc: 0x%x 0x%x 0x%x", inst->slice_dec_num, + inst->vsi->dec.crc[0], inst->vsi->dec.crc[1], inst->vsi->dec.crc[2]); inst->slice_dec_num++; return 0; err_free_fb_out: vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf); - mtk_vcodec_err(inst, "slice dec number: %d err: %d", inst->slice_dec_num, err); + mtk_vdec_err(inst->ctx, "slice dec number: %d err: %d", inst->slice_dec_num, err); return err; } @@ -1083,7 +1078,7 @@ static int vdec_hevc_slice_get_param(void *h_vdec, enum vdec_get_param_type type vdec_hevc_slice_get_crop_info(inst, out); break; default: - mtk_vcodec_err(inst, "invalid get parameter type=%d", type); + mtk_vdec_err(inst->ctx, "invalid get parameter type=%d", type); return -EINVAL; } return 0; diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp8_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_if.c index 88c046731754..19407f9bc773 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp8_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_if.c @@ -7,9 +7,8 @@ #include <linux/slab.h> #include "../vdec_drv_if.h" -#include "../mtk_vcodec_util.h" #include "../mtk_vcodec_dec.h" -#include "../mtk_vcodec_intr.h" +#include "../../common/mtk_vcodec_intr.h" #include "../vdec_vpu_if.h" #include "../vdec_drv_base.h" @@ -91,7 +90,6 @@ struct vdec_vp8_vsi { /** * struct vdec_vp8_hw_reg_base - HW register base - * @sys : base address for sys * @misc : base address for misc * @ld : base address for ld * @top : base address for top @@ -100,7 +98,6 @@ struct vdec_vp8_vsi { * @hwb : base address for hwb */ struct vdec_vp8_hw_reg_base { - void __iomem *sys; void __iomem *misc; void __iomem *ld; void __iomem *top; @@ -160,20 +157,21 @@ struct vdec_vp8_inst { struct mtk_vcodec_mem working_buf; struct vdec_vp8_hw_reg_base reg_base; unsigned int frm_cnt; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; struct vdec_vpu_inst vpu; struct vdec_vp8_vsi *vsi; }; static void get_hw_reg_base(struct vdec_vp8_inst *inst) { - inst->reg_base.top = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_TOP); - inst->reg_base.cm = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_CM); - inst->reg_base.hwd = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_HWD); - inst->reg_base.sys = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_SYS); - inst->reg_base.misc = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_MISC); - inst->reg_base.ld = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_LD); - inst->reg_base.hwb = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_HWB); + void __iomem **reg_base = inst->ctx->dev->reg_base; + + inst->reg_base.top = mtk_vcodec_get_reg_addr(reg_base, VDEC_TOP); + inst->reg_base.cm = mtk_vcodec_get_reg_addr(reg_base, VDEC_CM); + inst->reg_base.hwd = mtk_vcodec_get_reg_addr(reg_base, VDEC_HWD); + inst->reg_base.misc = mtk_vcodec_get_reg_addr(reg_base, VDEC_MISC); + inst->reg_base.ld = mtk_vcodec_get_reg_addr(reg_base, VDEC_LD); + inst->reg_base.hwb = mtk_vcodec_get_reg_addr(reg_base, VDEC_HWB); } static void write_hw_segmentation_data(struct vdec_vp8_inst *inst) @@ -222,17 +220,16 @@ static void read_hw_segmentation_data(struct vdec_vp8_inst *inst) static void enable_hw_rw_function(struct vdec_vp8_inst *inst) { u32 val = 0; - void __iomem *sys = inst->reg_base.sys; void __iomem *misc = inst->reg_base.misc; void __iomem *ld = inst->reg_base.ld; void __iomem *hwb = inst->reg_base.hwb; void __iomem *hwd = inst->reg_base.hwd; - writel(0x1, sys + VP8_RW_CKEN_SET); + mtk_vcodec_write_vdecsys(inst->ctx, VP8_RW_CKEN_SET, 0x1); writel(0x101, ld + VP8_WO_VLD_SRST); writel(0x101, hwb + VP8_WO_VLD_SRST); - writel(1, sys); + mtk_vcodec_write_vdecsys(inst->ctx, 0, 0x1); val = readl(misc + VP8_RW_MISC_SRST); writel((val & 0xFFFFFFFE), misc + VP8_RW_MISC_SRST); @@ -241,7 +238,7 @@ static void enable_hw_rw_function(struct vdec_vp8_inst *inst) writel(0x71201100, misc + VP8_RW_MISC_FUNC_CON); writel(0x0, ld + VP8_WO_VLD_SRST); writel(0x0, hwb + VP8_WO_VLD_SRST); - writel(0x1, sys + VP8_RW_DCM_CON); + mtk_vcodec_write_vdecsys(inst->ctx, VP8_RW_DCM_CON, 0x1); writel(0x1, misc + VP8_RW_MISC_DCM_CON); writel(0x1, hwd + VP8_RW_VP8_CTRL); } @@ -284,10 +281,10 @@ static void get_pic_info(struct vdec_vp8_inst *inst, struct vdec_pic_info *pic) { *pic = inst->vsi->pic; - mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", - pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); - mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)", - pic->fb_sz[0], pic->fb_sz[1]); + mtk_vdec_debug(inst->ctx, "pic(%d, %d), buf(%d, %d)", + pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); + mtk_vdec_debug(inst->ctx, "fb size: Y(%d), C(%d)", + pic->fb_sz[0], pic->fb_sz[1]); } static void vp8_dec_finish(struct vdec_vp8_inst *inst) @@ -295,7 +292,7 @@ static void vp8_dec_finish(struct vdec_vp8_inst *inst) struct vdec_fb_node *node; uint64_t prev_y_dma = inst->vsi->dec.prev_y_dma; - mtk_vcodec_debug(inst, "prev fb base dma=%llx", prev_y_dma); + mtk_vdec_debug(inst->ctx, "prev fb base dma=%llx", prev_y_dma); /* put last decode ok frame to fb_free_list */ if (prev_y_dma != 0) { @@ -370,7 +367,7 @@ static int alloc_working_buf(struct vdec_vp8_inst *inst) mem->size = VP8_WORKING_BUF_SZ; err = mtk_vcodec_mem_alloc(inst->ctx, mem); if (err) { - mtk_vcodec_err(inst, "Cannot allocate working buffer"); + mtk_vdec_err(inst->ctx, "Cannot allocate working buffer"); return err; } @@ -388,7 +385,7 @@ static void free_working_buf(struct vdec_vp8_inst *inst) inst->vsi->dec.working_buf_dma = 0; } -static int vdec_vp8_init(struct mtk_vcodec_ctx *ctx) +static int vdec_vp8_init(struct mtk_vcodec_dec_ctx *ctx) { struct vdec_vp8_inst *inst; int err; @@ -404,7 +401,7 @@ static int vdec_vp8_init(struct mtk_vcodec_ctx *ctx) err = vpu_dec_init(&inst->vpu); if (err) { - mtk_vcodec_err(inst, "vdec_vp8 init err=%d", err); + mtk_vdec_err(ctx, "vdec_vp8 init err=%d", err); goto error_free_inst; } @@ -415,7 +412,7 @@ static int vdec_vp8_init(struct mtk_vcodec_ctx *ctx) goto error_deinit; get_hw_reg_base(inst); - mtk_vcodec_debug(inst, "VP8 Instance >> %p", inst); + mtk_vdec_debug(ctx, "VP8 Instance >> %p", inst); ctx->drv_handle = inst; return 0; @@ -448,8 +445,8 @@ static int vdec_vp8_decode(void *h_vdec, struct mtk_vcodec_mem *bs, y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; - mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx fb=%p", - inst->frm_cnt, y_fb_dma, c_fb_dma, fb); + mtk_vdec_debug(inst->ctx, "+ [%d] FB y_dma=%llx c_dma=%llx fb=%p", + inst->frm_cnt, y_fb_dma, c_fb_dma, fb); inst->cur_fb = fb; dec->bs_dma = (unsigned long)bs->dma_addr; @@ -457,7 +454,7 @@ static int vdec_vp8_decode(void *h_vdec, struct mtk_vcodec_mem *bs, dec->cur_y_fb_dma = y_fb_dma; dec->cur_c_fb_dma = c_fb_dma; - mtk_vcodec_debug(inst, "\n + FRAME[%d] +\n", inst->frm_cnt); + mtk_vdec_debug(inst->ctx, "\n + FRAME[%d] +\n", inst->frm_cnt); write_hw_segmentation_data(inst); enable_hw_rw_function(inst); @@ -472,7 +469,7 @@ static int vdec_vp8_decode(void *h_vdec, struct mtk_vcodec_mem *bs, if (err) { add_fb_to_free_list(inst, fb); if (dec->wait_key_frame) { - mtk_vcodec_debug(inst, "wait key frame !"); + mtk_vdec_debug(inst->ctx, "wait key frame !"); return 0; } @@ -480,7 +477,7 @@ static int vdec_vp8_decode(void *h_vdec, struct mtk_vcodec_mem *bs, } if (dec->resolution_changed) { - mtk_vcodec_debug(inst, "- resolution_changed -"); + mtk_vdec_debug(inst->ctx, "- resolution_changed -"); *res_chg = true; add_fb_to_free_list(inst, fb); return 0; @@ -500,14 +497,13 @@ static int vdec_vp8_decode(void *h_vdec, struct mtk_vcodec_mem *bs, if (err) goto error; - mtk_vcodec_debug(inst, "\n - FRAME[%d] - show=%d\n", inst->frm_cnt, - dec->show_frame); + mtk_vdec_debug(inst->ctx, "\n - FRAME[%d] - show=%d\n", inst->frm_cnt, dec->show_frame); inst->frm_cnt++; *res_chg = false; return 0; error: - mtk_vcodec_err(inst, "\n - FRAME[%d] - err=%d\n", inst->frm_cnt, err); + mtk_vdec_err(inst->ctx, "\n - FRAME[%d] - err=%d\n", inst->frm_cnt, err); return err; } @@ -522,11 +518,10 @@ static void get_disp_fb(struct vdec_vp8_inst *inst, struct vdec_fb **out_fb) list_move_tail(&node->list, &inst->available_fb_node_list); fb = (struct vdec_fb *)node->fb; fb->status |= FB_ST_DISPLAY; - mtk_vcodec_debug(inst, "[FB] get disp fb %p st=%d", - node->fb, fb->status); + mtk_vdec_debug(inst->ctx, "[FB] get disp fb %p st=%d", node->fb, fb->status); } else { fb = NULL; - mtk_vcodec_debug(inst, "[FB] there is no disp fb"); + mtk_vdec_debug(inst->ctx, "[FB] there is no disp fb"); } *out_fb = fb; @@ -543,11 +538,10 @@ static void get_free_fb(struct vdec_vp8_inst *inst, struct vdec_fb **out_fb) list_move_tail(&node->list, &inst->available_fb_node_list); fb = (struct vdec_fb *)node->fb; fb->status |= FB_ST_FREE; - mtk_vcodec_debug(inst, "[FB] get free fb %p st=%d", - node->fb, fb->status); + mtk_vdec_debug(inst->ctx, "[FB] get free fb %p st=%d", node->fb, fb->status); } else { fb = NULL; - mtk_vcodec_debug(inst, "[FB] there is no free fb"); + mtk_vdec_debug(inst->ctx, "[FB] there is no free fb"); } *out_fb = fb; @@ -559,8 +553,8 @@ static void get_crop_info(struct vdec_vp8_inst *inst, struct v4l2_rect *cr) cr->top = 0; cr->width = inst->vsi->pic.pic_w; cr->height = inst->vsi->pic.pic_h; - mtk_vcodec_debug(inst, "get crop info l=%d, t=%d, w=%d, h=%d", - cr->left, cr->top, cr->width, cr->height); + mtk_vdec_debug(inst->ctx, "get crop info l=%d, t=%d, w=%d, h=%d", + cr->left, cr->top, cr->width, cr->height); } static int vdec_vp8_get_param(void *h_vdec, enum vdec_get_param_type type, @@ -590,7 +584,7 @@ static int vdec_vp8_get_param(void *h_vdec, enum vdec_get_param_type type, break; default: - mtk_vcodec_err(inst, "invalid get parameter type=%d", type); + mtk_vdec_err(inst->ctx, "invalid get parameter type=%d", type); return -EINVAL; } @@ -601,8 +595,6 @@ static void vdec_vp8_deinit(void *h_vdec) { struct vdec_vp8_inst *inst = (struct vdec_vp8_inst *)h_vdec; - mtk_vcodec_debug_enter(inst); - vpu_dec_deinit(&inst->vpu); free_working_buf(inst); kfree(inst); diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp8_req_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c index e1fe2603e92e..f64b21c07169 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp8_req_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c @@ -9,9 +9,8 @@ #include <media/videobuf2-dma-contig.h> #include <uapi/linux/v4l2-controls.h> -#include "../mtk_vcodec_util.h" #include "../mtk_vcodec_dec.h" -#include "../mtk_vcodec_intr.h" +#include "../../common/mtk_vcodec_intr.h" #include "../vdec_drv_base.h" #include "../vdec_drv_if.h" #include "../vdec_vpu_if.h" @@ -101,12 +100,12 @@ struct vdec_vp8_slice_inst { struct mtk_vcodec_mem wrap_y_buf; struct mtk_vcodec_mem wrap_c_buf; struct mtk_vcodec_mem vld_wrapper_buf; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; struct vdec_vpu_inst vpu; struct vdec_vp8_slice_vsi *vsi; }; -static void *vdec_vp8_slice_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id) +static void *vdec_vp8_slice_get_ctrl_ptr(struct mtk_vcodec_dec_ctx *ctx, int id) { struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id); @@ -118,7 +117,7 @@ static void *vdec_vp8_slice_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id) static void vdec_vp8_slice_get_pic_info(struct vdec_vp8_slice_inst *inst) { - struct mtk_vcodec_ctx *ctx = inst->ctx; + struct mtk_vcodec_dec_ctx *ctx = inst->ctx; unsigned int data[3]; data[0] = ctx->picinfo.pic_w; @@ -137,11 +136,11 @@ static void vdec_vp8_slice_get_pic_info(struct vdec_vp8_slice_inst *inst) inst->vsi->pic.buf_h = ctx->picinfo.buf_h; inst->vsi->pic.fb_sz[0] = ctx->picinfo.fb_sz[0]; inst->vsi->pic.fb_sz[1] = ctx->picinfo.fb_sz[1]; - mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", - ctx->picinfo.pic_w, ctx->picinfo.pic_h, - ctx->picinfo.buf_w, ctx->picinfo.buf_h); - mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)", - ctx->picinfo.fb_sz[0], ctx->picinfo.fb_sz[1]); + mtk_vdec_debug(inst->ctx, "pic(%d, %d), buf(%d, %d)", + ctx->picinfo.pic_w, ctx->picinfo.pic_h, + ctx->picinfo.buf_w, ctx->picinfo.buf_h); + mtk_vdec_debug(inst->ctx, "fb size: Y(%d), C(%d)", + ctx->picinfo.fb_sz[0], ctx->picinfo.fb_sz[1]); } static int vdec_vp8_slice_alloc_working_buf(struct vdec_vp8_slice_inst *inst) @@ -153,7 +152,7 @@ static int vdec_vp8_slice_alloc_working_buf(struct vdec_vp8_slice_inst *inst) mem->size = VP8_SEG_ID_SZ; err = mtk_vcodec_mem_alloc(inst->ctx, mem); if (err) { - mtk_vcodec_err(inst, "Cannot allocate working buffer"); + mtk_vdec_err(inst->ctx, "Cannot allocate working buffer"); return err; } inst->vsi->dec.seg_id_buf_dma = (u64)mem->dma_addr; @@ -162,7 +161,7 @@ static int vdec_vp8_slice_alloc_working_buf(struct vdec_vp8_slice_inst *inst) mem->size = VP8_PP_WRAPY_SZ; err = mtk_vcodec_mem_alloc(inst->ctx, mem); if (err) { - mtk_vcodec_err(inst, "cannot allocate WRAP Y buffer"); + mtk_vdec_err(inst->ctx, "cannot allocate WRAP Y buffer"); return err; } inst->vsi->dec.wrap_y_dma = (u64)mem->dma_addr; @@ -171,7 +170,7 @@ static int vdec_vp8_slice_alloc_working_buf(struct vdec_vp8_slice_inst *inst) mem->size = VP8_PP_WRAPC_SZ; err = mtk_vcodec_mem_alloc(inst->ctx, mem); if (err) { - mtk_vcodec_err(inst, "cannot allocate WRAP C buffer"); + mtk_vdec_err(inst->ctx, "cannot allocate WRAP C buffer"); return err; } inst->vsi->dec.wrap_c_dma = (u64)mem->dma_addr; @@ -180,7 +179,7 @@ static int vdec_vp8_slice_alloc_working_buf(struct vdec_vp8_slice_inst *inst) mem->size = VP8_VLD_PRED_SZ; err = mtk_vcodec_mem_alloc(inst->ctx, mem); if (err) { - mtk_vcodec_err(inst, "cannot allocate vld wrapper buffer"); + mtk_vdec_err(inst->ctx, "cannot allocate vld wrapper buffer"); return err; } inst->vsi->dec.vld_wrapper_dma = (u64)mem->dma_addr; @@ -233,7 +232,7 @@ static u64 vdec_vp8_slice_get_ref_by_ts(const struct v4l2_ctrl_vp8_frame *frame_ static int vdec_vp8_slice_get_decode_parameters(struct vdec_vp8_slice_inst *inst) { const struct v4l2_ctrl_vp8_frame *frame_header; - struct mtk_vcodec_ctx *ctx = inst->ctx; + struct mtk_vcodec_dec_ctx *ctx = inst->ctx; struct vb2_queue *vq; struct vb2_buffer *vb; u64 referenct_ts; @@ -249,8 +248,8 @@ static int vdec_vp8_slice_get_decode_parameters(struct vdec_vp8_slice_inst *inst vb = vb2_find_buffer(vq, referenct_ts); if (!vb) { if (!V4L2_VP8_FRAME_IS_KEY_FRAME(frame_header)) - mtk_vcodec_err(inst, "reference invalid: index(%d) ts(%lld)", - index, referenct_ts); + mtk_vdec_err(inst->ctx, "reference invalid: index(%d) ts(%lld)", + index, referenct_ts); inst->vsi->vp8_dpb_info[index].reference_flag = 0; continue; } @@ -272,7 +271,7 @@ static int vdec_vp8_slice_get_decode_parameters(struct vdec_vp8_slice_inst *inst return 0; } -static int vdec_vp8_slice_init(struct mtk_vcodec_ctx *ctx) +static int vdec_vp8_slice_init(struct mtk_vcodec_dec_ctx *ctx) { struct vdec_vp8_slice_inst *inst; int err; @@ -291,7 +290,7 @@ static int vdec_vp8_slice_init(struct mtk_vcodec_ctx *ctx) err = vpu_dec_init(&inst->vpu); if (err) { - mtk_vcodec_err(inst, "vdec_vp8 init err=%d", err); + mtk_vdec_err(ctx, "vdec_vp8 init err=%d", err); goto error_free_inst; } @@ -300,11 +299,11 @@ static int vdec_vp8_slice_init(struct mtk_vcodec_ctx *ctx) if (err) goto error_deinit; - mtk_vcodec_debug(inst, "vp8 struct size = %d vsi: %d\n", - (int)sizeof(struct v4l2_ctrl_vp8_frame), - (int)sizeof(struct vdec_vp8_slice_vsi)); - mtk_vcodec_debug(inst, "vp8:%p, codec_type = 0x%x vsi: 0x%p", - inst, inst->vpu.codec_type, inst->vpu.vsi); + mtk_vdec_debug(ctx, "vp8 struct size = %d vsi: %d\n", + (int)sizeof(struct v4l2_ctrl_vp8_frame), + (int)sizeof(struct vdec_vp8_slice_vsi)); + mtk_vdec_debug(ctx, "vp8:%p, codec_type = 0x%x vsi: 0x%p", + inst, inst->vpu.codec_type, inst->vpu.vsi); ctx->drv_handle = inst; return 0; @@ -350,10 +349,10 @@ static int vdec_vp8_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs, inst->vsi->dec.cur_y_fb_dma = y_fb_dma; inst->vsi->dec.cur_c_fb_dma = c_fb_dma; - mtk_vcodec_debug(inst, "frame[%d] bs(%zu 0x%llx) y/c(0x%llx 0x%llx)", - inst->ctx->decoded_frame_cnt, - bs->size, (u64)bs->dma_addr, - y_fb_dma, c_fb_dma); + mtk_vdec_debug(inst->ctx, "frame[%d] bs(%zu 0x%llx) y/c(0x%llx 0x%llx)", + inst->ctx->decoded_frame_cnt, + bs->size, (u64)bs->dma_addr, + y_fb_dma, c_fb_dma); v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb, &dst_buf_info->m2m_buf.vb, true); @@ -364,12 +363,12 @@ static int vdec_vp8_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs, err = vpu_dec_start(vpu, &data, 1); if (err) { - mtk_vcodec_debug(inst, "vp8 dec start err!"); + mtk_vdec_debug(inst->ctx, "vp8 dec start err!"); goto error; } if (inst->vsi->dec.resolution_changed) { - mtk_vcodec_debug(inst, "- resolution_changed -"); + mtk_vdec_debug(inst->ctx, "- resolution_changed -"); *res_chg = true; return 0; } @@ -380,15 +379,15 @@ static int vdec_vp8_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs, err = vpu_dec_end(vpu); if (err || timeout) - mtk_vcodec_debug(inst, "vp8 dec error timeout:%d err: %d pic_%d", - timeout, err, inst->ctx->decoded_frame_cnt); + mtk_vdec_debug(inst->ctx, "vp8 dec error timeout:%d err: %d pic_%d", + timeout, err, inst->ctx->decoded_frame_cnt); - mtk_vcodec_debug(inst, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", - inst->ctx->decoded_frame_cnt, - inst->vsi->dec.crc[0], inst->vsi->dec.crc[1], - inst->vsi->dec.crc[2], inst->vsi->dec.crc[3], - inst->vsi->dec.crc[4], inst->vsi->dec.crc[5], - inst->vsi->dec.crc[6], inst->vsi->dec.crc[7]); + mtk_vdec_debug(inst->ctx, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", + inst->ctx->decoded_frame_cnt, + inst->vsi->dec.crc[0], inst->vsi->dec.crc[1], + inst->vsi->dec.crc[2], inst->vsi->dec.crc[3], + inst->vsi->dec.crc[4], inst->vsi->dec.crc[5], + inst->vsi->dec.crc[6], inst->vsi->dec.crc[7]); inst->ctx->decoded_frame_cnt++; error: @@ -404,13 +403,13 @@ static int vdec_vp8_slice_get_param(void *h_vdec, enum vdec_get_param_type type, vdec_vp8_slice_get_pic_info(inst); break; case GET_PARAM_CROP_INFO: - mtk_vcodec_debug(inst, "No need to get vp8 crop information."); + mtk_vdec_debug(inst->ctx, "No need to get vp8 crop information."); break; case GET_PARAM_DPB_SIZE: *((unsigned int *)out) = VP8_DPB_SIZE; break; default: - mtk_vcodec_err(inst, "invalid get parameter type=%d", type); + mtk_vdec_err(inst->ctx, "invalid get parameter type=%d", type); return -EINVAL; } @@ -421,8 +420,6 @@ static void vdec_vp8_slice_deinit(void *h_vdec) { struct vdec_vp8_slice_inst *inst = h_vdec; - mtk_vcodec_debug_enter(inst); - vpu_dec_deinit(&inst->vpu); vdec_vp8_slice_free_working_buf(inst); kfree(inst); diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c index 70b8383f7c8e..55355fa70090 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c @@ -12,7 +12,7 @@ #include <linux/delay.h> #include <linux/time.h> -#include "../mtk_vcodec_intr.h" +#include "../../common/mtk_vcodec_intr.h" #include "../vdec_drv_base.h" #include "../vdec_vpu_if.h" @@ -196,7 +196,7 @@ struct vdec_vp9_inst { struct list_head fb_free_list; struct list_head fb_disp_list; struct vdec_fb *cur_fb; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; struct vdec_vpu_inst vpu; struct vdec_vp9_vsi *vsi; unsigned int total_frm_cnt; @@ -226,10 +226,11 @@ static struct vdec_fb *vp9_rm_from_fb_use_list(struct vdec_vp9_inst if (fb->base_y.va == addr) { list_move_tail(&node->list, &inst->available_fb_node_list); - break; + return fb; } } - return fb; + + return NULL; } static void vp9_add_to_fb_free_list(struct vdec_vp9_inst *inst, @@ -246,7 +247,7 @@ static void vp9_add_to_fb_free_list(struct vdec_vp9_inst *inst, list_move_tail(&node->list, &inst->fb_free_list); } } else { - mtk_vcodec_debug(inst, "No free fb node"); + mtk_vdec_debug(inst->ctx, "No free fb node"); } } @@ -330,7 +331,7 @@ static int vp9_get_sf_ref_fb(struct vdec_vp9_inst *inst) } if (idx == ARRAY_SIZE(vsi->sf_ref_fb)) { - mtk_vcodec_err(inst, "List Full"); + mtk_vdec_err(inst->ctx, "List Full"); return -1; } @@ -339,7 +340,7 @@ static int vp9_get_sf_ref_fb(struct vdec_vp9_inst *inst) vsi->buf_len_sz_y; if (mtk_vcodec_mem_alloc(inst->ctx, mem_basy_y)) { - mtk_vcodec_err(inst, "Cannot allocate sf_ref_buf y_buf"); + mtk_vdec_err(inst->ctx, "Cannot allocate sf_ref_buf y_buf"); return -1; } @@ -348,7 +349,7 @@ static int vp9_get_sf_ref_fb(struct vdec_vp9_inst *inst) vsi->buf_len_sz_c; if (mtk_vcodec_mem_alloc(inst->ctx, mem_basy_c)) { - mtk_vcodec_err(inst, "Cannot allocate sf_ref_fb c_buf"); + mtk_vdec_err(inst->ctx, "Cannot allocate sf_ref_fb c_buf"); return -1; } vsi->sf_ref_fb[idx].used = 0; @@ -377,17 +378,13 @@ static bool vp9_alloc_work_buf(struct vdec_vp9_inst *inst) if ((vsi->pic_w > max_pic_w) || (vsi->pic_h > max_pic_h)) { - mtk_vcodec_err(inst, "Invalid w/h %d/%d", - vsi->pic_w, vsi->pic_h); + mtk_vdec_err(inst->ctx, "Invalid w/h %d/%d", vsi->pic_w, vsi->pic_h); return false; } - mtk_vcodec_debug(inst, "BUF CHG(%d): w/h/sb_w/sb_h=%d/%d/%d/%d", - vsi->resolution_changed, - vsi->pic_w, - vsi->pic_h, - vsi->buf_w, - vsi->buf_h); + mtk_vdec_debug(inst->ctx, "BUF CHG(%d): w/h/sb_w/sb_h=%d/%d/%d/%d", + vsi->resolution_changed, vsi->pic_w, + vsi->pic_h, vsi->buf_w, vsi->buf_h); mem = &inst->mv_buf; if (mem->va) @@ -398,7 +395,7 @@ static bool vp9_alloc_work_buf(struct vdec_vp9_inst *inst) result = mtk_vcodec_mem_alloc(inst->ctx, mem); if (result) { mem->size = 0; - mtk_vcodec_err(inst, "Cannot allocate mv_buf"); + mtk_vdec_err(inst->ctx, "Cannot allocate mv_buf"); return false; } /* Set the va again */ @@ -415,7 +412,7 @@ static bool vp9_alloc_work_buf(struct vdec_vp9_inst *inst) result = mtk_vcodec_mem_alloc(inst->ctx, mem); if (result) { mem->size = 0; - mtk_vcodec_err(inst, "Cannot allocate seg_id_buf"); + mtk_vdec_err(inst->ctx, "Cannot allocate seg_id_buf"); return false; } /* Set the va again */ @@ -436,7 +433,7 @@ static bool vp9_add_to_fb_disp_list(struct vdec_vp9_inst *inst, struct vdec_fb_node *node; if (!fb) { - mtk_vcodec_err(inst, "fb == NULL"); + mtk_vdec_err(inst->ctx, "fb == NULL"); return false; } @@ -446,7 +443,7 @@ static bool vp9_add_to_fb_disp_list(struct vdec_vp9_inst *inst, node->fb = fb; list_move_tail(&node->list, &inst->fb_disp_list); } else { - mtk_vcodec_err(inst, "No available fb node"); + mtk_vdec_err(inst->ctx, "No available fb node"); return false; } @@ -492,10 +489,10 @@ static void vp9_swap_frm_bufs(struct vdec_vp9_inst *inst) * size */ if (frm_to_show->fb != NULL) - mtk_vcodec_err(inst, - "inst->cur_fb->base_y.size=%zu, frm_to_show->fb.base_y.size=%zu", - inst->cur_fb->base_y.size, - frm_to_show->fb->base_y.size); + mtk_vdec_err(inst->ctx, + "base_y.size=%zu, frm_to_show: base_y.size=%zu", + inst->cur_fb->base_y.size, + frm_to_show->fb->base_y.size); } if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) { if (vsi->show_frame & BIT(0)) @@ -535,7 +532,7 @@ static void vp9_swap_frm_bufs(struct vdec_vp9_inst *inst) static bool vp9_wait_dec_end(struct vdec_vp9_inst *inst) { - struct mtk_vcodec_ctx *ctx = inst->ctx; + struct mtk_vcodec_dec_ctx *ctx = inst->ctx; mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED, @@ -547,7 +544,7 @@ static bool vp9_wait_dec_end(struct vdec_vp9_inst *inst) return false; } -static struct vdec_vp9_inst *vp9_alloc_inst(struct mtk_vcodec_ctx *ctx) +static struct vdec_vp9_inst *vp9_alloc_inst(struct mtk_vcodec_dec_ctx *ctx) { int result; struct mtk_vcodec_mem mem; @@ -582,20 +579,19 @@ static bool vp9_decode_end_proc(struct vdec_vp9_inst *inst) if (!vsi->show_existing_frame) { ret = vp9_wait_dec_end(inst); if (!ret) { - mtk_vcodec_err(inst, "Decode failed, Decode Timeout @[%d]", - vsi->frm_num); + mtk_vdec_err(inst->ctx, "Decode failed, Decode Timeout @[%d]", + vsi->frm_num); return false; } if (vpu_dec_end(&inst->vpu)) { - mtk_vcodec_err(inst, "vp9_dec_vpu_end failed"); + mtk_vdec_err(inst->ctx, "vp9_dec_vpu_end failed"); return false; } - mtk_vcodec_debug(inst, "Decode Ok @%d (%d/%d)", vsi->frm_num, - vsi->pic_w, vsi->pic_h); + mtk_vdec_debug(inst->ctx, "Decode Ok @%d (%d/%d)", vsi->frm_num, + vsi->pic_w, vsi->pic_h); } else { - mtk_vcodec_debug(inst, "Decode Ok @%d (show_existing_frame)", - vsi->frm_num); + mtk_vdec_debug(inst->ctx, "Decode Ok @%d (show_existing_frame)", vsi->frm_num); } vp9_swap_frm_bufs(inst); @@ -624,10 +620,9 @@ static struct vdec_fb *vp9_rm_from_fb_disp_list(struct vdec_vp9_inst *inst) fb = (struct vdec_fb *)node->fb; fb->status |= FB_ST_DISPLAY; list_move_tail(&node->list, &inst->available_fb_node_list); - mtk_vcodec_debug(inst, "[FB] get disp fb %p st=%d", - node->fb, fb->status); + mtk_vdec_debug(inst->ctx, "[FB] get disp fb %p st=%d", node->fb, fb->status); } else - mtk_vcodec_debug(inst, "[FB] there is no disp fb"); + mtk_vdec_debug(inst->ctx, "[FB] there is no disp fb"); return fb; } @@ -638,7 +633,7 @@ static bool vp9_add_to_fb_use_list(struct vdec_vp9_inst *inst, struct vdec_fb_node *node; if (!fb) { - mtk_vcodec_debug(inst, "fb == NULL"); + mtk_vdec_debug(inst->ctx, "fb == NULL"); return false; } @@ -648,7 +643,7 @@ static bool vp9_add_to_fb_use_list(struct vdec_vp9_inst *inst, node->fb = fb; list_move_tail(&node->list, &inst->fb_use_list); } else { - mtk_vcodec_err(inst, "No free fb node"); + mtk_vdec_err(inst->ctx, "No free fb node"); return false; } return true; @@ -665,7 +660,7 @@ static void vp9_reset(struct vdec_vp9_inst *inst) inst->vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst); if (vpu_dec_reset(&inst->vpu)) - mtk_vcodec_err(inst, "vp9_dec_vpu_reset failed"); + mtk_vdec_err(inst->ctx, "vp9_dec_vpu_reset failed"); /* Set the va again, since vpu_dec_reset will clear mv_buf in vpu */ inst->vsi->mv_buf.va = (unsigned long)inst->mv_buf.va; @@ -706,11 +701,9 @@ static void get_pic_info(struct vdec_vp9_inst *inst, struct vdec_pic_info *pic) pic->buf_w = inst->vsi->buf_w; pic->buf_h = inst->vsi->buf_h; - mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", - pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); - mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)", - pic->fb_sz[0], - pic->fb_sz[1]); + mtk_vdec_debug(inst->ctx, "pic(%d, %d), buf(%d, %d)", + pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); + mtk_vdec_debug(inst->ctx, "fb size: Y(%d), C(%d)", pic->fb_sz[0], pic->fb_sz[1]); } static void get_disp_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb) @@ -732,10 +725,9 @@ static void get_free_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb) list_move_tail(&node->list, &inst->available_fb_node_list); fb = (struct vdec_fb *)node->fb; fb->status |= FB_ST_FREE; - mtk_vcodec_debug(inst, "[FB] get free fb %p st=%d", - node->fb, fb->status); + mtk_vdec_debug(inst->ctx, "[FB] get free fb %p st=%d", node->fb, fb->status); } else { - mtk_vcodec_debug(inst, "[FB] there is no free fb"); + mtk_vdec_debug(inst->ctx, "[FB] there is no free fb"); } *out_fb = fb; @@ -744,18 +736,15 @@ static void get_free_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb) static int validate_vsi_array_indexes(struct vdec_vp9_inst *inst, struct vdec_vp9_vsi *vsi) { if (vsi->sf_frm_idx >= VP9_MAX_FRM_BUF_NUM - 1) { - mtk_vcodec_err(inst, "Invalid vsi->sf_frm_idx=%u.", - vsi->sf_frm_idx); + mtk_vdec_err(inst->ctx, "Invalid vsi->sf_frm_idx=%u.", vsi->sf_frm_idx); return -EIO; } if (vsi->frm_to_show_idx >= VP9_MAX_FRM_BUF_NUM) { - mtk_vcodec_err(inst, "Invalid vsi->frm_to_show_idx=%u.", - vsi->frm_to_show_idx); + mtk_vdec_err(inst->ctx, "Invalid vsi->frm_to_show_idx=%u.", vsi->frm_to_show_idx); return -EIO; } if (vsi->new_fb_idx >= VP9_MAX_FRM_BUF_NUM) { - mtk_vcodec_err(inst, "Invalid vsi->new_fb_idx=%u.", - vsi->new_fb_idx); + mtk_vdec_err(inst->ctx, "Invalid vsi->new_fb_idx=%u.", vsi->new_fb_idx); return -EIO; } return 0; @@ -769,7 +758,7 @@ static void vdec_vp9_deinit(void *h_vdec) ret = vpu_dec_deinit(&inst->vpu); if (ret) - mtk_vcodec_err(inst, "vpu_dec_deinit failed"); + mtk_vdec_err(inst->ctx, "vpu_dec_deinit failed"); mem = &inst->mv_buf; if (mem->va) @@ -783,7 +772,7 @@ static void vdec_vp9_deinit(void *h_vdec) vp9_free_inst(inst); } -static int vdec_vp9_init(struct mtk_vcodec_ctx *ctx) +static int vdec_vp9_init(struct mtk_vcodec_dec_ctx *ctx) { struct vdec_vp9_inst *inst; @@ -798,7 +787,7 @@ static int vdec_vp9_init(struct mtk_vcodec_ctx *ctx) inst->vpu.ctx = ctx; if (vpu_dec_init(&inst->vpu)) { - mtk_vcodec_err(inst, "vp9_dec_vpu_init failed"); + mtk_vdec_err(inst->ctx, "vp9_dec_vpu_init failed"); goto err_deinit_inst; } @@ -829,17 +818,17 @@ static int vdec_vp9_decode(void *h_vdec, struct mtk_vcodec_mem *bs, *res_chg = false; if ((bs == NULL) && (fb == NULL)) { - mtk_vcodec_debug(inst, "[EOS]"); + mtk_vdec_debug(inst->ctx, "[EOS]"); vp9_reset(inst); return ret; } if (bs == NULL) { - mtk_vcodec_err(inst, "bs == NULL"); + mtk_vdec_err(inst->ctx, "bs == NULL"); return -EINVAL; } - mtk_vcodec_debug(inst, "Input BS Size = %zu", bs->size); + mtk_vdec_debug(inst->ctx, "Input BS Size = %zu", bs->size); while (1) { struct vdec_fb *cur_fb = NULL; @@ -882,7 +871,7 @@ static int vdec_vp9_decode(void *h_vdec, struct mtk_vcodec_mem *bs, ret = vpu_dec_start(&inst->vpu, data, 3); if (ret) { - mtk_vcodec_err(inst, "vpu_dec_start failed"); + mtk_vdec_err(inst->ctx, "vpu_dec_start failed"); goto DECODE_ERROR; } @@ -892,7 +881,7 @@ static int vdec_vp9_decode(void *h_vdec, struct mtk_vcodec_mem *bs, if (vsi->show_frame & BIT(2)) { ret = vpu_dec_start(&inst->vpu, NULL, 0); if (ret) { - mtk_vcodec_err(inst, "vpu trig decoder failed"); + mtk_vdec_err(inst->ctx, "vpu trig decoder failed"); goto DECODE_ERROR; } } @@ -900,7 +889,7 @@ static int vdec_vp9_decode(void *h_vdec, struct mtk_vcodec_mem *bs, ret = validate_vsi_array_indexes(inst, vsi); if (ret) { - mtk_vcodec_err(inst, "Invalid values from VPU."); + mtk_vdec_err(inst->ctx, "Invalid values from VPU."); goto DECODE_ERROR; } @@ -926,18 +915,18 @@ static int vdec_vp9_decode(void *h_vdec, struct mtk_vcodec_mem *bs, if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) vp9_add_to_fb_use_list(inst, inst->cur_fb); - mtk_vcodec_debug(inst, "[#pic %d]", vsi->frm_num); + mtk_vdec_debug(inst->ctx, "[#pic %d]", vsi->frm_num); if (vsi->show_existing_frame) - mtk_vcodec_debug(inst, - "drv->new_fb_idx=%d, drv->frm_to_show_idx=%d", - vsi->new_fb_idx, vsi->frm_to_show_idx); + mtk_vdec_debug(inst->ctx, + "drv->new_fb_idx=%d, drv->frm_to_show_idx=%d", + vsi->new_fb_idx, vsi->frm_to_show_idx); if (vsi->show_existing_frame && (vsi->frm_to_show_idx < VP9_MAX_FRM_BUF_NUM)) { - mtk_vcodec_debug(inst, - "Skip Decode drv->new_fb_idx=%d, drv->frm_to_show_idx=%d", - vsi->new_fb_idx, vsi->frm_to_show_idx); + mtk_vdec_debug(inst->ctx, + "Skip Decode drv->new_fb_idx=%d, drv->frm_to_show_idx=%d", + vsi->new_fb_idx, vsi->frm_to_show_idx); vp9_ref_cnt_fb(inst, &vsi->new_fb_idx, vsi->frm_to_show_idx); @@ -954,14 +943,14 @@ static int vdec_vp9_decode(void *h_vdec, struct mtk_vcodec_mem *bs, if (vsi->resolution_changed) { *res_chg = true; - mtk_vcodec_debug(inst, "VDEC_ST_RESOLUTION_CHANGED"); + mtk_vdec_debug(inst->ctx, "VDEC_ST_RESOLUTION_CHANGED"); ret = 0; goto DECODE_ERROR; } if (!vp9_decode_end_proc(inst)) { - mtk_vcodec_err(inst, "vp9_decode_end_proc"); + mtk_vdec_err(inst->ctx, "vp9_decode_end_proc"); ret = -EINVAL; goto DECODE_ERROR; } @@ -985,8 +974,8 @@ static void get_crop_info(struct vdec_vp9_inst *inst, struct v4l2_rect *cr) cr->top = 0; cr->width = inst->vsi->pic_w; cr->height = inst->vsi->pic_h; - mtk_vcodec_debug(inst, "get crop info l=%d, t=%d, w=%d, h=%d\n", - cr->left, cr->top, cr->width, cr->height); + mtk_vdec_debug(inst->ctx, "get crop info l=%d, t=%d, w=%d, h=%d\n", + cr->left, cr->top, cr->width, cr->height); } static int vdec_vp9_get_param(void *h_vdec, enum vdec_get_param_type type, @@ -1012,7 +1001,7 @@ static int vdec_vp9_get_param(void *h_vdec, enum vdec_get_param_type type, get_crop_info(inst, out); break; default: - mtk_vcodec_err(inst, "not supported param type %d", type); + mtk_vdec_err(inst->ctx, "not supported param type %d", type); ret = -EINVAL; break; } diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c index c2f90848f498..e393e3e668f8 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c @@ -9,9 +9,8 @@ #include <media/videobuf2-dma-contig.h> #include <media/v4l2-vp9.h> -#include "../mtk_vcodec_util.h" #include "../mtk_vcodec_dec.h" -#include "../mtk_vcodec_intr.h" +#include "../../common/mtk_vcodec_intr.h" #include "../vdec_drv_base.h" #include "../vdec_drv_if.h" #include "../vdec_vpu_if.h" @@ -445,7 +444,7 @@ struct vdec_vp9_slice_ref { * @counts_helper: counts table according to newest kernel spec */ struct vdec_vp9_slice_instance { - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; struct vdec_vpu_inst vpu; int seq; @@ -506,7 +505,7 @@ static int vdec_vp9_slice_init_default_frame_ctx(struct vdec_vp9_slice_instance { struct vdec_vp9_slice_frame_ctx *remote_frame_ctx; struct vdec_vp9_slice_frame_ctx *frame_ctx; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; struct vdec_vp9_slice_init_vsi *vsi; int ret = 0; @@ -518,7 +517,7 @@ static int vdec_vp9_slice_init_default_frame_ctx(struct vdec_vp9_slice_instance remote_frame_ctx = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler, (u32)vsi->default_frame_ctx); if (!remote_frame_ctx) { - mtk_vcodec_err(instance, "failed to map default frame ctx\n"); + mtk_vdec_err(ctx, "failed to map default frame ctx\n"); return -EINVAL; } @@ -543,7 +542,7 @@ out: static int vdec_vp9_slice_alloc_working_buffer(struct vdec_vp9_slice_instance *instance, struct vdec_vp9_slice_vsi *vsi) { - struct mtk_vcodec_ctx *ctx = instance->ctx; + struct mtk_vcodec_dec_ctx *ctx = instance->ctx; enum vdec_vp9_slice_resolution_level level; /* super blocks */ unsigned int max_sb_w; @@ -577,8 +576,8 @@ static int vdec_vp9_slice_alloc_working_buffer(struct vdec_vp9_slice_instance *i if (level == instance->level) return 0; - mtk_vcodec_debug(instance, "resolution level changed, from %u to %u, %ux%u", - instance->level, level, w, h); + mtk_vdec_debug(ctx, "resolution level changed, from %u to %u, %ux%u", + instance->level, level, w, h); max_sb_w = DIV_ROUND_UP(max_w, 64); max_sb_h = DIV_ROUND_UP(max_h, 64); @@ -635,7 +634,7 @@ err: static void vdec_vp9_slice_free_working_buffer(struct vdec_vp9_slice_instance *instance) { - struct mtk_vcodec_ctx *ctx = instance->ctx; + struct mtk_vcodec_dec_ctx *ctx = instance->ctx; int i; for (i = 0; i < ARRAY_SIZE(instance->mv); i++) { @@ -1025,9 +1024,9 @@ static int vdec_vp9_slice_setup_prob_buffer(struct vdec_vp9_slice_instance *inst uh = &vsi->frame.uh; - mtk_vcodec_debug(instance, "ctx dirty %u idx %d\n", - instance->dirty[uh->frame_context_idx], - uh->frame_context_idx); + mtk_vdec_debug(instance->ctx, "ctx dirty %u idx %d\n", + instance->dirty[uh->frame_context_idx], + uh->frame_context_idx); if (instance->dirty[uh->frame_context_idx]) frame_ctx = &instance->frame_ctx[uh->frame_context_idx]; @@ -1051,7 +1050,7 @@ static void vdec_vp9_slice_setup_seg_buffer(struct vdec_vp9_slice_instance *inst uh->error_resilient_mode || uh->frame_width != instance->width || uh->frame_height != instance->height) { - mtk_vcodec_debug(instance, "reset seg\n"); + mtk_vdec_debug(instance->ctx, "reset seg\n"); memset(buf->va, 0, buf->size); } } @@ -1093,16 +1092,14 @@ static int vdec_vp9_slice_setup_tile_buffer(struct vdec_vp9_slice_instance *inst cols = 1 << cols_log2; if (rows > 4 || cols > 64) { - mtk_vcodec_err(instance, "tile_rows %u tile_cols %u\n", - rows, cols); + mtk_vdec_err(instance->ctx, "tile_rows %u tile_cols %u\n", rows, cols); return -EINVAL; } offset = uh->uncompressed_header_size + uh->header_size_in_bytes; if (bs->size <= offset) { - mtk_vcodec_err(instance, "bs size %zu tile offset %u\n", - bs->size, offset); + mtk_vdec_err(instance->ctx, "bs size %zu tile offset %u\n", bs->size, offset); return -EINVAL; } @@ -1596,14 +1593,12 @@ static int vdec_vp9_slice_update_single(struct vdec_vp9_slice_instance *instance vsi = &pfc->vsi; memcpy(&pfc->state[0], &vsi->state, sizeof(vsi->state)); - mtk_vcodec_debug(instance, "Frame %u Y_CRC %08x %08x %08x %08x\n", - pfc->seq, - vsi->state.crc[0], vsi->state.crc[1], - vsi->state.crc[2], vsi->state.crc[3]); - mtk_vcodec_debug(instance, "Frame %u C_CRC %08x %08x %08x %08x\n", - pfc->seq, - vsi->state.crc[4], vsi->state.crc[5], - vsi->state.crc[6], vsi->state.crc[7]); + mtk_vdec_debug(instance->ctx, "Frame %u Y_CRC %08x %08x %08x %08x\n", + pfc->seq, vsi->state.crc[0], vsi->state.crc[1], + vsi->state.crc[2], vsi->state.crc[3]); + mtk_vdec_debug(instance->ctx, "Frame %u C_CRC %08x %08x %08x %08x\n", + pfc->seq, vsi->state.crc[4], vsi->state.crc[5], + vsi->state.crc[6], vsi->state.crc[7]); vdec_vp9_slice_update_prob(instance, vsi); @@ -1624,10 +1619,10 @@ static int vdec_vp9_slice_update_lat(struct vdec_vp9_slice_instance *instance, vsi = &pfc->vsi; memcpy(&pfc->state[0], &vsi->state, sizeof(vsi->state)); - mtk_vcodec_debug(instance, "Frame %u LAT CRC 0x%08x %lx %lx\n", - pfc->seq, vsi->state.crc[0], - (unsigned long)vsi->trans.dma_addr, - (unsigned long)vsi->trans.dma_addr_end); + mtk_vdec_debug(instance->ctx, "Frame %u LAT CRC 0x%08x %lx %lx\n", + pfc->seq, vsi->state.crc[0], + (unsigned long)vsi->trans.dma_addr, + (unsigned long)vsi->trans.dma_addr_end); /* buffer full, need to re-decode */ if (vsi->state.full) { @@ -1844,19 +1839,17 @@ static int vdec_vp9_slice_update_core(struct vdec_vp9_slice_instance *instance, vsi = &pfc->vsi; memcpy(&pfc->state[1], &vsi->state, sizeof(vsi->state)); - mtk_vcodec_debug(instance, "Frame %u Y_CRC %08x %08x %08x %08x\n", - pfc->seq, - vsi->state.crc[0], vsi->state.crc[1], - vsi->state.crc[2], vsi->state.crc[3]); - mtk_vcodec_debug(instance, "Frame %u C_CRC %08x %08x %08x %08x\n", - pfc->seq, - vsi->state.crc[4], vsi->state.crc[5], - vsi->state.crc[6], vsi->state.crc[7]); + mtk_vdec_debug(instance->ctx, "Frame %u Y_CRC %08x %08x %08x %08x\n", + pfc->seq, vsi->state.crc[0], vsi->state.crc[1], + vsi->state.crc[2], vsi->state.crc[3]); + mtk_vdec_debug(instance->ctx, "Frame %u C_CRC %08x %08x %08x %08x\n", + pfc->seq, vsi->state.crc[4], vsi->state.crc[5], + vsi->state.crc[6], vsi->state.crc[7]); return 0; } -static int vdec_vp9_slice_init(struct mtk_vcodec_ctx *ctx) +static int vdec_vp9_slice_init(struct mtk_vcodec_dec_ctx *ctx) { struct vdec_vp9_slice_instance *instance; struct vdec_vp9_slice_init_vsi *vsi; @@ -1874,7 +1867,7 @@ static int vdec_vp9_slice_init(struct mtk_vcodec_ctx *ctx) ret = vpu_dec_init(&instance->vpu); if (ret) { - mtk_vcodec_err(instance, "failed to init vpu dec, ret %d\n", ret); + mtk_vdec_err(ctx, "failed to init vpu dec, ret %d\n", ret); goto error_vpu_init; } @@ -1882,7 +1875,7 @@ static int vdec_vp9_slice_init(struct mtk_vcodec_ctx *ctx) vsi = instance->vpu.vsi; if (!vsi) { - mtk_vcodec_err(instance, "failed to get VP9 vsi\n"); + mtk_vdec_err(ctx, "failed to get VP9 vsi\n"); ret = -EINVAL; goto error_vsi; } @@ -1890,7 +1883,7 @@ static int vdec_vp9_slice_init(struct mtk_vcodec_ctx *ctx) instance->core_vsi = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler, (u32)vsi->core_vsi); if (!instance->core_vsi) { - mtk_vcodec_err(instance, "failed to get VP9 core vsi\n"); + mtk_vdec_err(ctx, "failed to get VP9 core vsi\n"); ret = -EINVAL; goto error_vsi; } @@ -1931,7 +1924,7 @@ static int vdec_vp9_slice_flush(void *h_vdec, struct mtk_vcodec_mem *bs, { struct vdec_vp9_slice_instance *instance = h_vdec; - mtk_vcodec_debug(instance, "flush ...\n"); + mtk_vdec_debug(instance->ctx, "flush ...\n"); if (instance->ctx->dev->vdec_pdata->hw_arch != MTK_VDEC_PURE_SINGLE_CORE) vdec_msg_queue_wait_lat_buf_full(&instance->ctx->msg_queue); return vpu_dec_reset(&instance->vpu); @@ -1939,11 +1932,10 @@ static int vdec_vp9_slice_flush(void *h_vdec, struct mtk_vcodec_mem *bs, static void vdec_vp9_slice_get_pic_info(struct vdec_vp9_slice_instance *instance) { - struct mtk_vcodec_ctx *ctx = instance->ctx; + struct mtk_vcodec_dec_ctx *ctx = instance->ctx; unsigned int data[3]; - mtk_vcodec_debug(instance, "w %u h %u\n", - ctx->picinfo.pic_w, ctx->picinfo.pic_h); + mtk_vdec_debug(instance->ctx, "w %u h %u\n", ctx->picinfo.pic_w, ctx->picinfo.pic_h); data[0] = ctx->picinfo.pic_w; data[1] = ctx->picinfo.pic_h; @@ -1975,11 +1967,10 @@ static int vdec_vp9_slice_get_param(void *h_vdec, enum vdec_get_param_type type, vdec_vp9_slice_get_dpb_size(instance, out); break; case GET_PARAM_CROP_INFO: - mtk_vcodec_debug(instance, "No need to get vp9 crop information."); + mtk_vdec_debug(instance->ctx, "No need to get vp9 crop information."); break; default: - mtk_vcodec_err(instance, "invalid get parameter type=%d\n", - type); + mtk_vdec_err(instance->ctx, "invalid get parameter type=%d\n", type); return -EINVAL; } @@ -1992,7 +1983,7 @@ static int vdec_vp9_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs, struct vdec_vp9_slice_instance *instance = h_vdec; struct vdec_vp9_slice_pfc *pfc = &instance->sc_pfc; struct vdec_vp9_slice_vsi *vsi; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; int ret; if (!instance || !instance->ctx) @@ -2011,14 +2002,14 @@ static int vdec_vp9_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs, ret = vdec_vp9_slice_setup_single(instance, bs, fb, pfc); if (ret) { - mtk_vcodec_err(instance, "Failed to setup VP9 single ret %d\n", ret); + mtk_vdec_err(ctx, "Failed to setup VP9 single ret %d\n", ret); return ret; } vdec_vp9_slice_vsi_to_remote(vsi, instance->vsi); ret = vpu_dec_start(&instance->vpu, NULL, 0); if (ret) { - mtk_vcodec_err(instance, "Failed to dec VP9 ret %d\n", ret); + mtk_vdec_err(ctx, "Failed to dec VP9 ret %d\n", ret); return ret; } @@ -2026,7 +2017,7 @@ static int vdec_vp9_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs, WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE); /* update remote vsi if decode timeout */ if (ret) { - mtk_vcodec_err(instance, "VP9 decode timeout %d\n", ret); + mtk_vdec_err(ctx, "VP9 decode timeout %d\n", ret); WRITE_ONCE(instance->vsi->state.timeout, 1); } @@ -2035,7 +2026,7 @@ static int vdec_vp9_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs, vdec_vp9_slice_vsi_from_remote(vsi, instance->vsi, 0); ret = vdec_vp9_slice_update_single(instance, pfc); if (ret) { - mtk_vcodec_err(instance, "VP9 decode error: %d\n", ret); + mtk_vdec_err(ctx, "VP9 decode error: %d\n", ret); return ret; } @@ -2050,7 +2041,7 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, struct vdec_lat_buf *lat_buf; struct vdec_vp9_slice_pfc *pfc; struct vdec_vp9_slice_vsi *vsi; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; int ret; if (!instance || !instance->ctx) @@ -2069,7 +2060,7 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, lat_buf = vdec_msg_queue_dqbuf(&instance->ctx->msg_queue.lat_ctx); if (!lat_buf) { - mtk_vcodec_debug(instance, "Failed to get VP9 lat buf\n"); + mtk_vdec_debug(ctx, "Failed to get VP9 lat buf\n"); return -EAGAIN; } pfc = (struct vdec_vp9_slice_pfc *)lat_buf->private_data; @@ -2081,14 +2072,14 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, ret = vdec_vp9_slice_setup_lat(instance, bs, lat_buf, pfc); if (ret) { - mtk_vcodec_err(instance, "Failed to setup VP9 lat ret %d\n", ret); + mtk_vdec_err(ctx, "Failed to setup VP9 lat ret %d\n", ret); goto err_free_fb_out; } vdec_vp9_slice_vsi_to_remote(vsi, instance->vsi); ret = vpu_dec_start(&instance->vpu, NULL, 0); if (ret) { - mtk_vcodec_err(instance, "Failed to dec VP9 ret %d\n", ret); + mtk_vdec_err(ctx, "Failed to dec VP9 ret %d\n", ret); goto err_free_fb_out; } @@ -2097,7 +2088,7 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0); /* update remote vsi if decode timeout */ if (ret) { - mtk_vcodec_err(instance, "VP9 decode timeout %d pic %d\n", ret, pfc->seq); + mtk_vdec_err(ctx, "VP9 decode timeout %d pic %d\n", ret, pfc->seq); WRITE_ONCE(instance->vsi->state.timeout, 1); } vpu_dec_end(&instance->vpu); @@ -2108,13 +2099,13 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, /* LAT trans full, no more UBE or decode timeout */ if (ret) { - mtk_vcodec_err(instance, "VP9 decode error: %d\n", ret); + mtk_vdec_err(ctx, "VP9 decode error: %d\n", ret); goto err_free_fb_out; } - mtk_vcodec_debug(instance, "lat dma addr: 0x%lx 0x%lx\n", - (unsigned long)pfc->vsi.trans.dma_addr, - (unsigned long)pfc->vsi.trans.dma_addr_end); + mtk_vdec_debug(ctx, "lat dma addr: 0x%lx 0x%lx\n", + (unsigned long)pfc->vsi.trans.dma_addr, + (unsigned long)pfc->vsi.trans.dma_addr_end); vdec_msg_queue_update_ube_wptr(&ctx->msg_queue, vsi->trans.dma_addr_end + @@ -2145,7 +2136,7 @@ static int vdec_vp9_slice_core_decode(struct vdec_lat_buf *lat_buf) { struct vdec_vp9_slice_instance *instance; struct vdec_vp9_slice_pfc *pfc; - struct mtk_vcodec_ctx *ctx = NULL; + struct mtk_vcodec_dec_ctx *ctx = NULL; struct vdec_fb *fb = NULL; int ret = -EINVAL; @@ -2169,14 +2160,14 @@ static int vdec_vp9_slice_core_decode(struct vdec_lat_buf *lat_buf) ret = vdec_vp9_slice_setup_core(instance, fb, lat_buf, pfc); if (ret) { - mtk_vcodec_err(instance, "vdec_vp9_slice_setup_core\n"); + mtk_vdec_err(ctx, "vdec_vp9_slice_setup_core\n"); goto err; } vdec_vp9_slice_vsi_to_remote(&pfc->vsi, instance->core_vsi); ret = vpu_dec_core(&instance->vpu); if (ret) { - mtk_vcodec_err(instance, "vpu_dec_core\n"); + mtk_vdec_err(ctx, "vpu_dec_core\n"); goto err; } @@ -2185,7 +2176,7 @@ static int vdec_vp9_slice_core_decode(struct vdec_lat_buf *lat_buf) WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE); /* update remote vsi if decode timeout */ if (ret) { - mtk_vcodec_err(instance, "VP9 core timeout pic %d\n", pfc->seq); + mtk_vdec_err(ctx, "VP9 core timeout pic %d\n", pfc->seq); WRITE_ONCE(instance->core_vsi->state.timeout, 1); } vpu_dec_core_end(&instance->vpu); @@ -2194,13 +2185,13 @@ static int vdec_vp9_slice_core_decode(struct vdec_lat_buf *lat_buf) vdec_vp9_slice_vsi_from_remote(&pfc->vsi, instance->core_vsi, 1); ret = vdec_vp9_slice_update_core(instance, lat_buf, pfc); if (ret) { - mtk_vcodec_err(instance, "vdec_vp9_slice_update_core\n"); + mtk_vdec_err(ctx, "vdec_vp9_slice_update_core\n"); goto err; } pfc->vsi.trans.dma_addr_end += ctx->msg_queue.wdma_addr.dma_addr; - mtk_vcodec_debug(instance, "core dma_addr_end 0x%lx\n", - (unsigned long)pfc->vsi.trans.dma_addr_end); + mtk_vdec_debug(ctx, "core dma_addr_end 0x%lx\n", + (unsigned long)pfc->vsi.trans.dma_addr_end); vdec_msg_queue_update_ube_rptr(&ctx->msg_queue, pfc->vsi.trans.dma_addr_end); ctx->dev->vdec_pdata->cap_to_disp(ctx, 0, lat_buf->src_buf_req); diff --git a/drivers/media/platform/mediatek/vcodec/vdec_drv_base.h b/drivers/media/platform/mediatek/vcodec/decoder/vdec_drv_base.h index e913f963b7db..f6abb9365234 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_drv_base.h +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_drv_base.h @@ -15,7 +15,7 @@ struct vdec_common_if { * @ctx : [in] mtk v4l2 context * @h_vdec : [out] driver handle */ - int (*init)(struct mtk_vcodec_ctx *ctx); + int (*init)(struct mtk_vcodec_dec_ctx *ctx); /** * (*decode)() - trigger decode diff --git a/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec_drv_if.c index 06d393174cc2..d0b459b1603f 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_drv_if.c @@ -14,7 +14,7 @@ #include "vdec_drv_base.h" #include "mtk_vcodec_dec_pm.h" -int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) +int vdec_if_init(struct mtk_vcodec_dec_ctx *ctx, unsigned int fourcc) { enum mtk_vdec_hw_arch hw_arch = ctx->dev->vdec_pdata->hw_arch; int ret = 0; @@ -68,14 +68,14 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) return ret; } -int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs, +int vdec_if_decode(struct mtk_vcodec_dec_ctx *ctx, struct mtk_vcodec_mem *bs, struct vdec_fb *fb, bool *res_chg) { int ret = 0; if (bs) { if ((bs->dma_addr & 63) != 0) { - mtk_v4l2_err("bs dma_addr should 64 byte align"); + mtk_v4l2_vdec_err(ctx, "bs dma_addr should 64 byte align"); return -EINVAL; } } @@ -83,7 +83,7 @@ int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs, if (fb) { if (((fb->base_y.dma_addr & 511) != 0) || ((fb->base_c.dma_addr & 511) != 0)) { - mtk_v4l2_err("frame buffer dma_addr should 512 byte align"); + mtk_v4l2_vdec_err(ctx, "frame buffer dma_addr should 512 byte align"); return -EINVAL; } } @@ -100,7 +100,7 @@ int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs, return ret; } -int vdec_if_get_param(struct mtk_vcodec_ctx *ctx, enum vdec_get_param_type type, +int vdec_if_get_param(struct mtk_vcodec_dec_ctx *ctx, enum vdec_get_param_type type, void *out) { int ret = 0; @@ -115,7 +115,7 @@ int vdec_if_get_param(struct mtk_vcodec_ctx *ctx, enum vdec_get_param_type type, return ret; } -void vdec_if_deinit(struct mtk_vcodec_ctx *ctx) +void vdec_if_deinit(struct mtk_vcodec_dec_ctx *ctx) { if (!ctx->drv_handle) return; diff --git a/drivers/media/platform/mediatek/vcodec/vdec_drv_if.h b/drivers/media/platform/mediatek/vcodec/decoder/vdec_drv_if.h index a8da6a59a6a5..bfd297c96850 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_drv_if.h +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_drv_if.h @@ -8,9 +8,7 @@ #ifndef _VDEC_DRV_IF_H_ #define _VDEC_DRV_IF_H_ -#include "mtk_vcodec_drv.h" #include "mtk_vcodec_dec.h" -#include "mtk_vcodec_util.h" /** @@ -69,14 +67,14 @@ extern const struct vdec_common_if vdec_av1_slice_lat_if; * @ctx : [in] v4l2 context * @fourcc : [in] video format fourcc, V4L2_PIX_FMT_H264/VP8/VP9.. */ -int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc); +int vdec_if_init(struct mtk_vcodec_dec_ctx *ctx, unsigned int fourcc); /** * vdec_if_deinit() - deinitialize decode driver * @ctx : [in] v4l2 context * */ -void vdec_if_deinit(struct mtk_vcodec_ctx *ctx); +void vdec_if_deinit(struct mtk_vcodec_dec_ctx *ctx); /** * vdec_if_decode() - trigger decode @@ -90,7 +88,7 @@ void vdec_if_deinit(struct mtk_vcodec_ctx *ctx); * * Return: 0 on success. -EIO on unrecoverable error. */ -int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs, +int vdec_if_decode(struct mtk_vcodec_dec_ctx *ctx, struct mtk_vcodec_mem *bs, struct vdec_fb *fb, bool *res_chg); /** @@ -99,7 +97,7 @@ int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs, * @type : [in] input parameter type * @out : [out] buffer to store query result */ -int vdec_if_get_param(struct mtk_vcodec_ctx *ctx, enum vdec_get_param_type type, +int vdec_if_get_param(struct mtk_vcodec_dec_ctx *ctx, enum vdec_get_param_type type, void *out); #endif diff --git a/drivers/media/platform/mediatek/vcodec/vdec_ipi_msg.h b/drivers/media/platform/mediatek/vcodec/decoder/vdec_ipi_msg.h index 47070be2a991..47070be2a991 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_ipi_msg.h +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_ipi_msg.h diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.c index 04e6dc6cfa1d..f283c4703dc6 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.c @@ -8,8 +8,8 @@ #include <linux/interrupt.h> #include <linux/kthread.h> +#include "mtk_vcodec_dec_drv.h" #include "mtk_vcodec_dec_pm.h" -#include "mtk_vcodec_drv.h" #include "vdec_msg_queue.h" #define VDEC_MSG_QUEUE_TIMEOUT_MS 1500 @@ -77,7 +77,7 @@ int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf head = vdec_get_buf_list(msg_ctx->hardware_index, buf); if (!head) { - mtk_v4l2_err("fail to qbuf: %d", msg_ctx->hardware_index); + mtk_v4l2_vdec_err(buf->ctx, "fail to qbuf: %d", msg_ctx->hardware_index); return -EINVAL; } @@ -95,8 +95,8 @@ int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf } } - mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d", - msg_ctx->hardware_index, buf, msg_ctx->ready_num); + mtk_v4l2_vdec_dbg(3, buf->ctx, "enqueue buf type: %d addr: 0x%p num: %d", + msg_ctx->hardware_index, buf, msg_ctx->ready_num); spin_unlock(&msg_ctx->ready_lock); return 0; @@ -123,8 +123,6 @@ struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *msg_ctx) spin_lock(&msg_ctx->ready_lock); if (list_empty(&msg_ctx->ready_queue)) { - mtk_v4l2_debug(3, "queue is NULL, type:%d num: %d", - msg_ctx->hardware_index, msg_ctx->ready_num); spin_unlock(&msg_ctx->ready_lock); if (msg_ctx->hardware_index == MTK_VDEC_CORE) @@ -146,15 +144,15 @@ struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *msg_ctx) head = vdec_get_buf_list(msg_ctx->hardware_index, buf); if (!head) { spin_unlock(&msg_ctx->ready_lock); - mtk_v4l2_err("fail to dqbuf: %d", msg_ctx->hardware_index); + mtk_v4l2_vdec_err(buf->ctx, "fail to dqbuf: %d", msg_ctx->hardware_index); return NULL; } list_del(head); vdec_msg_queue_dec(&buf->ctx->msg_queue, msg_ctx->hardware_index); msg_ctx->ready_num--; - mtk_v4l2_debug(3, "dqueue buf type:%d addr: 0x%p num: %d", - msg_ctx->hardware_index, buf, msg_ctx->ready_num); + mtk_v4l2_vdec_dbg(3, buf->ctx, "dqueue buf type:%d addr: 0x%p num: %d", + msg_ctx->hardware_index, buf, msg_ctx->ready_num); spin_unlock(&msg_ctx->ready_lock); return buf; @@ -164,7 +162,7 @@ void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue, uint64_t u { spin_lock(&msg_queue->lat_ctx.ready_lock); msg_queue->wdma_rptr_addr = ube_rptr; - mtk_v4l2_debug(3, "update ube rprt (0x%llx)", ube_rptr); + mtk_v4l2_vdec_dbg(3, msg_queue->ctx, "update ube rprt (0x%llx)", ube_rptr); spin_unlock(&msg_queue->lat_ctx.ready_lock); } @@ -172,20 +170,19 @@ void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue, uint64_t u { spin_lock(&msg_queue->lat_ctx.ready_lock); msg_queue->wdma_wptr_addr = ube_wptr; - mtk_v4l2_debug(3, "update ube wprt: (0x%llx 0x%llx) offset: 0x%llx", - msg_queue->wdma_rptr_addr, msg_queue->wdma_wptr_addr, - ube_wptr); + mtk_v4l2_vdec_dbg(3, msg_queue->ctx, "update ube wprt: (0x%llx 0x%llx) offset: 0x%llx", + msg_queue->wdma_rptr_addr, msg_queue->wdma_wptr_addr, + ube_wptr); spin_unlock(&msg_queue->lat_ctx.ready_lock); } bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue) { if (atomic_read(&msg_queue->lat_list_cnt) == NUM_BUFFER_COUNT) { - mtk_v4l2_debug(3, "wait buf full: list(%d %d) ready_num:%d status:%d", - atomic_read(&msg_queue->lat_list_cnt), - atomic_read(&msg_queue->core_list_cnt), - msg_queue->lat_ctx.ready_num, - msg_queue->status); + mtk_v4l2_vdec_dbg(3, msg_queue->ctx, "wait buf full: (%d %d) ready:%d status:%d", + atomic_read(&msg_queue->lat_list_cnt), + atomic_read(&msg_queue->core_list_cnt), + msg_queue->lat_ctx.ready_num, msg_queue->status); return true; } @@ -193,16 +190,16 @@ bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue) vdec_msg_queue_qbuf(&msg_queue->core_ctx, &msg_queue->empty_lat_buf); wait_event(msg_queue->core_dec_done, msg_queue->flush_done); - mtk_v4l2_debug(3, "flush done => ready_num:%d status:%d list(%d %d)", - msg_queue->lat_ctx.ready_num, msg_queue->status, - atomic_read(&msg_queue->lat_list_cnt), - atomic_read(&msg_queue->core_list_cnt)); + mtk_v4l2_vdec_dbg(3, msg_queue->ctx, "flush done => ready_num:%d status:%d list(%d %d)", + msg_queue->lat_ctx.ready_num, msg_queue->status, + atomic_read(&msg_queue->lat_list_cnt), + atomic_read(&msg_queue->core_list_cnt)); return false; } void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue, - struct mtk_vcodec_ctx *ctx) + struct mtk_vcodec_dec_ctx *ctx) { struct vdec_lat_buf *lat_buf; struct mtk_vcodec_mem *mem; @@ -231,6 +228,7 @@ void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue, mtk_vcodec_mem_free(ctx, mem); kfree(lat_buf->private_data); + lat_buf->private_data = NULL; } if (msg_queue->wdma_addr.size) @@ -241,9 +239,9 @@ static void vdec_msg_queue_core_work(struct work_struct *work) { struct vdec_msg_queue *msg_queue = container_of(work, struct vdec_msg_queue, core_work); - struct mtk_vcodec_ctx *ctx = - container_of(msg_queue, struct mtk_vcodec_ctx, msg_queue); - struct mtk_vcodec_dev *dev = ctx->dev; + struct mtk_vcodec_dec_ctx *ctx = + container_of(msg_queue, struct mtk_vcodec_dec_ctx, msg_queue); + struct mtk_vcodec_dec_dev *dev = ctx->dev; struct vdec_lat_buf *lat_buf; spin_lock(&msg_queue->core_ctx.ready_lock); @@ -282,7 +280,7 @@ static void vdec_msg_queue_core_work(struct work_struct *work) } int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, - struct mtk_vcodec_ctx *ctx, core_decode_cb_t core_decode, + struct mtk_vcodec_dec_ctx *ctx, core_decode_cb_t core_decode, int private_size) { struct vdec_lat_buf *lat_buf; @@ -306,7 +304,8 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, ctx->picinfo.buf_h); err = mtk_vcodec_mem_alloc(ctx, &msg_queue->wdma_addr); if (err) { - mtk_v4l2_err("failed to allocate wdma_addr buf"); + mtk_v4l2_vdec_err(ctx, "failed to allocate wdma_addr buf"); + msg_queue->wdma_addr.size = 0; return -ENOMEM; } msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr; @@ -316,20 +315,21 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, msg_queue->empty_lat_buf.core_decode = NULL; msg_queue->empty_lat_buf.is_last_frame = true; + msg_queue->ctx = ctx; for (i = 0; i < NUM_BUFFER_COUNT; i++) { lat_buf = &msg_queue->lat_buf[i]; lat_buf->wdma_err_addr.size = VDEC_ERR_MAP_SZ_AVC; err = mtk_vcodec_mem_alloc(ctx, &lat_buf->wdma_err_addr); if (err) { - mtk_v4l2_err("failed to allocate wdma_err_addr buf[%d]", i); + mtk_v4l2_vdec_err(ctx, "failed to allocate wdma_err_addr buf[%d]", i); goto mem_alloc_err; } lat_buf->slice_bc_addr.size = VDEC_LAT_SLICE_HEADER_SZ; err = mtk_vcodec_mem_alloc(ctx, &lat_buf->slice_bc_addr); if (err) { - mtk_v4l2_err("failed to allocate wdma_addr buf[%d]", i); + mtk_v4l2_vdec_err(ctx, "failed to allocate wdma_addr buf[%d]", i); goto mem_alloc_err; } @@ -337,15 +337,15 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, lat_buf->rd_mv_addr.size = VDEC_RD_MV_BUFFER_SZ; err = mtk_vcodec_mem_alloc(ctx, &lat_buf->rd_mv_addr); if (err) { - mtk_v4l2_err("failed to allocate rd_mv_addr buf[%d]", i); - return -ENOMEM; + mtk_v4l2_vdec_err(ctx, "failed to allocate rd_mv_addr buf[%d]", i); + goto mem_alloc_err; } lat_buf->tile_addr.size = VDEC_LAT_TILE_SZ; err = mtk_vcodec_mem_alloc(ctx, &lat_buf->tile_addr); if (err) { - mtk_v4l2_err("failed to allocate tile_addr buf[%d]", i); - return -ENOMEM; + mtk_v4l2_vdec_err(ctx, "failed to allocate tile_addr buf[%d]", i); + goto mem_alloc_err; } } @@ -360,7 +360,7 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, lat_buf->is_last_frame = false; err = vdec_msg_queue_qbuf(&msg_queue->lat_ctx, lat_buf); if (err) { - mtk_v4l2_err("failed to qbuf buf[%d]", i); + mtk_v4l2_vdec_err(ctx, "failed to qbuf buf[%d]", i); goto mem_alloc_err; } } diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h b/drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.h index 2a745e902ad1..1d9beb9e4a14 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.h @@ -12,13 +12,11 @@ #include <linux/slab.h> #include <media/videobuf2-v4l2.h> -#include "mtk_vcodec_util.h" - #define NUM_BUFFER_COUNT 3 struct vdec_lat_buf; -struct mtk_vcodec_ctx; -struct mtk_vcodec_dev; +struct mtk_vcodec_dec_ctx; +struct mtk_vcodec_dec_dev; typedef int (*core_decode_cb_t)(struct vdec_lat_buf *lat_buf); /** @@ -76,7 +74,7 @@ struct vdec_lat_buf { struct media_request *src_buf_req; void *private_data; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; core_decode_cb_t core_decode; struct list_head lat_list; struct list_head core_list; @@ -100,6 +98,7 @@ struct vdec_lat_buf { * @empty_lat_buf: the last lat buf used to flush decode * @core_dec_done: core work queue decode done event * @status: current context decode status for core hardware + * @ctx: mtk vcodec context information */ struct vdec_msg_queue { struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT]; @@ -118,6 +117,7 @@ struct vdec_msg_queue { struct vdec_lat_buf empty_lat_buf; wait_queue_head_t core_dec_done; int status; + struct mtk_vcodec_dec_ctx *ctx; }; /** @@ -130,7 +130,7 @@ struct vdec_msg_queue { * Return: returns 0 if init successfully, or fail. */ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, - struct mtk_vcodec_ctx *ctx, core_decode_cb_t core_decode, + struct mtk_vcodec_dec_ctx *ctx, core_decode_cb_t core_decode, int private_size); /** @@ -186,6 +186,6 @@ bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue); * @ctx: v4l2 ctx */ void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue, - struct mtk_vcodec_ctx *ctx); + struct mtk_vcodec_dec_ctx *ctx); #endif diff --git a/drivers/media/platform/mediatek/vcodec/vdec_vpu_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c index df309e8e9379..82e57ae983d5 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_vpu_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c @@ -4,19 +4,17 @@ * Author: PC Chen <pc.chen@mediatek.com> */ -#include "mtk_vcodec_drv.h" -#include "mtk_vcodec_util.h" +#include "mtk_vcodec_dec_drv.h" #include "vdec_drv_if.h" #include "vdec_ipi_msg.h" #include "vdec_vpu_if.h" -#include "mtk_vcodec_fw.h" static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg) { struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *) (unsigned long)msg->ap_inst_addr; - mtk_vcodec_debug(vpu, "+ ap_inst_addr = 0x%llx", msg->ap_inst_addr); + mtk_vdec_debug(vpu->ctx, "+ ap_inst_addr = 0x%llx", msg->ap_inst_addr); /* mapping VPU address to kernel virtual address */ /* the content in vsi is initialized to 0 in VPU */ @@ -24,7 +22,7 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg) msg->vpu_inst_addr); vpu->inst_addr = msg->vpu_inst_addr; - mtk_vcodec_debug(vpu, "- vpu_inst_addr = 0x%x", vpu->inst_addr); + mtk_vdec_debug(vpu->ctx, "- vpu_inst_addr = 0x%x", vpu->inst_addr); /* Set default ABI version if dealing with unversioned firmware. */ vpu->fw_abi_version = 0; @@ -40,7 +38,7 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg) /* Check firmware version. */ vpu->fw_abi_version = msg->vdec_abi_version; - mtk_vcodec_debug(vpu, "firmware version 0x%x\n", vpu->fw_abi_version); + mtk_vdec_debug(vpu->ctx, "firmware version 0x%x\n", vpu->fw_abi_version); switch (vpu->fw_abi_version) { case 1: break; @@ -48,8 +46,7 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg) vpu->inst_id = msg->inst_id; break; default: - mtk_vcodec_err(vpu, "unhandled firmware version 0x%x\n", - vpu->fw_abi_version); + mtk_vdec_err(vpu->ctx, "unhandled firmware version 0x%x\n", vpu->fw_abi_version); vpu->failure = 1; break; } @@ -60,7 +57,7 @@ static void handle_get_param_msg_ack(const struct vdec_vpu_ipi_get_param_ack *ms struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *) (unsigned long)msg->ap_inst_addr; - mtk_vcodec_debug(vpu, "+ ap_inst_addr = 0x%llx", msg->ap_inst_addr); + mtk_vdec_debug(vpu->ctx, "+ ap_inst_addr = 0x%llx", msg->ap_inst_addr); /* param_type is enum vdec_get_param_type */ switch (msg->param_type) { @@ -69,12 +66,27 @@ static void handle_get_param_msg_ack(const struct vdec_vpu_ipi_get_param_ack *ms vpu->fb_sz[1] = msg->data[1]; break; default: - mtk_vcodec_err(vpu, "invalid get param type=%d", msg->param_type); + mtk_vdec_err(vpu->ctx, "invalid get param type=%d", msg->param_type); vpu->failure = 1; break; } } +static bool vpu_dec_check_ap_inst(struct mtk_vcodec_dec_dev *dec_dev, struct vdec_vpu_inst *vpu) +{ + struct mtk_vcodec_dec_ctx *ctx; + int ret = false; + + list_for_each_entry(ctx, &dec_dev->ctx_list, list) { + if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) { + ret = true; + break; + } + } + + return ret; +} + /* * vpu_dec_ipi_handler - Handler for VPU ipi message. * @@ -87,44 +99,51 @@ static void handle_get_param_msg_ack(const struct vdec_vpu_ipi_get_param_ack *ms */ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv) { + struct mtk_vcodec_dec_dev *dec_dev; const struct vdec_vpu_ipi_ack *msg = data; - struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *) - (unsigned long)msg->ap_inst_addr; + struct vdec_vpu_inst *vpu; - if (!vpu) { - mtk_v4l2_err("ap_inst_addr is NULL, did the SCP hang or crash?"); + dec_dev = (struct mtk_vcodec_dec_dev *)priv; + vpu = (struct vdec_vpu_inst *)(unsigned long)msg->ap_inst_addr; + if (!priv || !vpu) { + pr_err(MTK_DBG_V4L2_STR "ap_inst_addr is NULL, did the SCP hang or crash?"); return; } - mtk_vcodec_debug(vpu, "+ id=%X", msg->msg_id); + if (!vpu_dec_check_ap_inst(dec_dev, vpu) || msg->msg_id < VPU_IPIMSG_DEC_INIT_ACK || + msg->msg_id > VPU_IPIMSG_DEC_GET_PARAM_ACK) { + mtk_v4l2_vdec_err(vpu->ctx, "vdec msg id not correctly => 0x%x", msg->msg_id); + vpu->failure = -EINVAL; + goto error; + } vpu->failure = msg->status; - vpu->signaled = 1; + if (msg->status != 0) + goto error; - if (msg->status == 0) { - switch (msg->msg_id) { - case VPU_IPIMSG_DEC_INIT_ACK: - handle_init_ack_msg(data); - break; + switch (msg->msg_id) { + case VPU_IPIMSG_DEC_INIT_ACK: + handle_init_ack_msg(data); + break; - case VPU_IPIMSG_DEC_START_ACK: - case VPU_IPIMSG_DEC_END_ACK: - case VPU_IPIMSG_DEC_DEINIT_ACK: - case VPU_IPIMSG_DEC_RESET_ACK: - case VPU_IPIMSG_DEC_CORE_ACK: - case VPU_IPIMSG_DEC_CORE_END_ACK: - break; + case VPU_IPIMSG_DEC_START_ACK: + case VPU_IPIMSG_DEC_END_ACK: + case VPU_IPIMSG_DEC_DEINIT_ACK: + case VPU_IPIMSG_DEC_RESET_ACK: + case VPU_IPIMSG_DEC_CORE_ACK: + case VPU_IPIMSG_DEC_CORE_END_ACK: + break; - case VPU_IPIMSG_DEC_GET_PARAM_ACK: - handle_get_param_msg_ack(data); - break; - default: - mtk_vcodec_err(vpu, "invalid msg=%X", msg->msg_id); - break; - } + case VPU_IPIMSG_DEC_GET_PARAM_ACK: + handle_get_param_msg_ack(data); + break; + default: + mtk_vdec_err(vpu->ctx, "invalid msg=%X", msg->msg_id); + break; } - mtk_vcodec_debug(vpu, "- id=%X", msg->msg_id); +error: + vpu->signaled = 1; } static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len) @@ -132,7 +151,7 @@ static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len) int err, id, msgid; msgid = *(uint32_t *)msg; - mtk_vcodec_debug(vpu, "id=%X", msgid); + mtk_vdec_debug(vpu->ctx, "id=%X", msgid); vpu->failure = 0; vpu->signaled = 0; @@ -150,8 +169,8 @@ static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len) err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, id, msg, len, 2000); if (err) { - mtk_vcodec_err(vpu, "send fail vpu_id=%d msg_id=%X status=%d", - id, msgid, err); + mtk_vdec_err(vpu->ctx, "send fail vpu_id=%d msg_id=%X status=%d", + id, msgid, err); return err; } @@ -163,7 +182,7 @@ static int vcodec_send_ap_ipi(struct vdec_vpu_inst *vpu, unsigned int msg_id) struct vdec_ap_ipi_cmd msg; int err = 0; - mtk_vcodec_debug(vpu, "+ id=%X", msg_id); + mtk_vdec_debug(vpu->ctx, "+ id=%X", msg_id); memset(&msg, 0, sizeof(msg)); msg.msg_id = msg_id; @@ -174,7 +193,7 @@ static int vcodec_send_ap_ipi(struct vdec_vpu_inst *vpu, unsigned int msg_id) msg.codec_type = vpu->codec_type; err = vcodec_vpu_send_msg(vpu, &msg, sizeof(msg)); - mtk_vcodec_debug(vpu, "- id=%X ret=%d", msg_id, err); + mtk_vdec_debug(vpu->ctx, "- id=%X ret=%d", msg_id, err); return err; } @@ -183,24 +202,23 @@ int vpu_dec_init(struct vdec_vpu_inst *vpu) struct vdec_ap_ipi_init msg; int err; - mtk_vcodec_debug_enter(vpu); - init_waitqueue_head(&vpu->wq); vpu->handler = vpu_dec_ipi_handler; + vpu->ctx->vpu_inst = vpu; err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler, vpu->id, - vpu->handler, "vdec", NULL); + vpu->handler, "vdec", vpu->ctx->dev); if (err) { - mtk_vcodec_err(vpu, "vpu_ipi_register fail status=%d", err); + mtk_vdec_err(vpu->ctx, "vpu_ipi_register fail status=%d", err); return err; } if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) { err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler, vpu->core_id, vpu->handler, - "vdec", NULL); + "vdec", vpu->ctx->dev); if (err) { - mtk_vcodec_err(vpu, "vpu_ipi_register core fail status=%d", err); + mtk_vdec_err(vpu->ctx, "vpu_ipi_register core fail status=%d", err); return err; } } @@ -210,10 +228,10 @@ int vpu_dec_init(struct vdec_vpu_inst *vpu) msg.ap_inst_addr = (unsigned long)vpu; msg.codec_type = vpu->codec_type; - mtk_vcodec_debug(vpu, "vdec_inst=%p", vpu); + mtk_vdec_debug(vpu->ctx, "vdec_inst=%p", vpu); err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg)); - mtk_vcodec_debug(vpu, "- ret=%d", err); + mtk_vdec_debug(vpu->ctx, "- ret=%d", err); return err; } @@ -223,10 +241,8 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len) int i; int err = 0; - mtk_vcodec_debug_enter(vpu); - if (len > ARRAY_SIZE(msg.data)) { - mtk_vcodec_err(vpu, "invalid len = %d\n", len); + mtk_vdec_err(vpu->ctx, "invalid len = %d\n", len); return -EINVAL; } @@ -242,7 +258,7 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len) msg.codec_type = vpu->codec_type; err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg)); - mtk_vcodec_debug(vpu, "- ret=%d", err); + mtk_vdec_debug(vpu->ctx, "- ret=%d", err); return err; } @@ -252,10 +268,8 @@ int vpu_dec_get_param(struct vdec_vpu_inst *vpu, uint32_t *data, struct vdec_ap_ipi_get_param msg; int err; - mtk_vcodec_debug_enter(vpu); - if (len > ARRAY_SIZE(msg.data)) { - mtk_vcodec_err(vpu, "invalid len = %d\n", len); + mtk_vdec_err(vpu->ctx, "invalid len = %d\n", len); return -EINVAL; } @@ -267,7 +281,7 @@ int vpu_dec_get_param(struct vdec_vpu_inst *vpu, uint32_t *data, msg.codec_type = vpu->codec_type; err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg)); - mtk_vcodec_debug(vpu, "- ret=%d", err); + mtk_vdec_debug(vpu->ctx, "- ret=%d", err); return err; } diff --git a/drivers/media/platform/mediatek/vcodec/vdec_vpu_if.h b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h index 0436bba91457..fbb3f34a73f0 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_vpu_if.h +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h @@ -7,9 +7,7 @@ #ifndef _VDEC_VPU_IF_H_ #define _VDEC_VPU_IF_H_ -#include "mtk_vcodec_fw.h" - -struct mtk_vcodec_ctx; +struct mtk_vcodec_dec_ctx; /** * struct vdec_vpu_inst - VPU instance for video codec @@ -40,7 +38,7 @@ struct vdec_vpu_inst { uint32_t fw_abi_version; uint32_t inst_id; unsigned int signaled; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_dec_ctx *ctx; wait_queue_head_t wq; mtk_vcodec_ipi_handler handler; unsigned int codec_type; diff --git a/drivers/media/platform/mediatek/vcodec/encoder/Makefile b/drivers/media/platform/mediatek/vcodec/encoder/Makefile new file mode 100644 index 000000000000..e621b5b7e5e6 --- /dev/null +++ b/drivers/media/platform/mediatek/vcodec/encoder/Makefile @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-enc.o + +mtk-vcodec-enc-y := venc/venc_vp8_if.o \ + venc/venc_h264_if.o \ + mtk_vcodec_enc.o \ + mtk_vcodec_enc_drv.o \ + mtk_vcodec_enc_pm.o \ + venc_drv_if.o \ + venc_vpu_if.o \ diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c index 315e97a2450e..04948d3eb011 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c @@ -10,10 +10,7 @@ #include <media/videobuf2-dma-contig.h> #include <linux/pm_runtime.h> -#include "mtk_vcodec_drv.h" #include "mtk_vcodec_enc.h" -#include "mtk_vcodec_intr.h" -#include "mtk_vcodec_util.h" #include "venc_drv_if.h" #define MTK_VENC_MIN_W 160U @@ -45,69 +42,59 @@ static const struct v4l2_frmsize_stepwise mtk_venc_4k_framesizes = { static int vidioc_venc_s_ctrl(struct v4l2_ctrl *ctrl) { - struct mtk_vcodec_ctx *ctx = ctrl_to_ctx(ctrl); + struct mtk_vcodec_enc_ctx *ctx = ctrl_to_enc_ctx(ctrl); struct mtk_enc_params *p = &ctx->enc_params; int ret = 0; switch (ctrl->id) { case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_BITRATE_MODE val= %d", - ctrl->val); + mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_BITRATE_MODE val= %d", ctrl->val); if (ctrl->val != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) { - mtk_v4l2_err("Unsupported bitrate mode =%d", ctrl->val); + mtk_v4l2_venc_err(ctx, "Unsupported bitrate mode =%d", ctrl->val); ret = -EINVAL; } break; case V4L2_CID_MPEG_VIDEO_BITRATE: - mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_BITRATE val = %d", - ctrl->val); + mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_BITRATE val = %d", ctrl->val); p->bitrate = ctrl->val; ctx->param_change |= MTK_ENCODE_PARAM_BITRATE; break; case V4L2_CID_MPEG_VIDEO_B_FRAMES: - mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_B_FRAMES val = %d", - ctrl->val); + mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_B_FRAMES val = %d", ctrl->val); p->num_b_frame = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: - mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE val = %d", - ctrl->val); + mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE val = %d", + ctrl->val); p->rc_frame = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: - mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_MAX_QP val = %d", - ctrl->val); + mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_H264_MAX_QP val = %d", ctrl->val); p->h264_max_qp = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_HEADER_MODE: - mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_HEADER_MODE val = %d", - ctrl->val); + mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_HEADER_MODE val = %d", ctrl->val); p->seq_hdr_mode = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: - mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE val = %d", - ctrl->val); + mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE val = %d", ctrl->val); p->rc_mb = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_H264_PROFILE: - mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_PROFILE val = %d", - ctrl->val); + mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_H264_PROFILE val = %d", ctrl->val); p->h264_profile = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_H264_LEVEL: - mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_LEVEL val = %d", - ctrl->val); + mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_H264_LEVEL val = %d", ctrl->val); p->h264_level = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: - mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_I_PERIOD val = %d", - ctrl->val); + mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_H264_I_PERIOD val = %d", ctrl->val); p->intra_period = ctrl->val; ctx->param_change |= MTK_ENCODE_PARAM_INTRA_PERIOD; break; case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_GOP_SIZE val = %d", - ctrl->val); + mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_GOP_SIZE val = %d", ctrl->val); p->gop_size = ctrl->val; ctx->param_change |= MTK_ENCODE_PARAM_GOP_SIZE; break; @@ -116,10 +103,10 @@ static int vidioc_venc_s_ctrl(struct v4l2_ctrl *ctrl) * FIXME - what vp8 profiles are actually supported? * The ctrl is added (with only profile 0 supported) for now. */ - mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_VP8_PROFILE val = %d", ctrl->val); + mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_VP8_PROFILE val = %d", ctrl->val); break; case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: - mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME"); + mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME"); p->force_intra = 1; ctx->param_change |= MTK_ENCODE_PARAM_FORCE_INTRA; break; @@ -172,7 +159,7 @@ static int vidioc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize) { const struct mtk_video_fmt *fmt; - struct mtk_vcodec_ctx *ctx = fh_to_ctx(fh); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(fh); if (fsize->index != 0) return -EINVAL; @@ -196,7 +183,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { const struct mtk_vcodec_enc_pdata *pdata = - fh_to_ctx(priv)->dev->venc_pdata; + fh_to_enc_ctx(priv)->dev->venc_pdata; return vidioc_enum_fmt(f, pdata->capture_formats, pdata->num_capture_formats); @@ -206,7 +193,7 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, struct v4l2_fmtdesc *f) { const struct mtk_vcodec_enc_pdata *pdata = - fh_to_ctx(priv)->dev->venc_pdata; + fh_to_enc_ctx(priv)->dev->venc_pdata; return vidioc_enum_fmt(f, pdata->output_formats, pdata->num_output_formats); @@ -214,7 +201,7 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, static int mtk_vcodec_enc_get_chip_name(void *priv) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv); struct device *dev = &ctx->dev->plat_dev->dev; if (of_device_is_compatible(dev->of_node, "mediatek,mt8173-vcodec-enc")) @@ -234,7 +221,7 @@ static int mtk_vcodec_enc_get_chip_name(void *priv) static int vidioc_venc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv); struct device *dev = &ctx->dev->plat_dev->dev; int platform_name = mtk_vcodec_enc_get_chip_name(priv); @@ -247,7 +234,7 @@ static int vidioc_venc_querycap(struct file *file, void *priv, static int vidioc_venc_s_parm(struct file *file, void *priv, struct v4l2_streamparm *a) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv); struct v4l2_fract *timeperframe = &a->parm.output.timeperframe; if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) @@ -270,7 +257,7 @@ static int vidioc_venc_s_parm(struct file *file, void *priv, static int vidioc_venc_g_parm(struct file *file, void *priv, struct v4l2_streamparm *a) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv); if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) return -EINVAL; @@ -284,7 +271,7 @@ static int vidioc_venc_g_parm(struct file *file, void *priv, return 0; } -static struct mtk_q_data *mtk_venc_get_q_data(struct mtk_vcodec_ctx *ctx, +static struct mtk_q_data *mtk_venc_get_q_data(struct mtk_vcodec_enc_ctx *ctx, enum v4l2_buf_type type) { if (V4L2_TYPE_IS_OUTPUT(type)) @@ -304,7 +291,7 @@ static void vidioc_try_fmt_cap(struct v4l2_format *f) /* V4L2 specification suggests the driver corrects the format struct if any of * the dimensions is unsupported */ -static int vidioc_try_fmt_out(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f, +static int vidioc_try_fmt_out(struct mtk_vcodec_enc_ctx *ctx, struct v4l2_format *f, const struct mtk_video_fmt *fmt) { struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; @@ -341,11 +328,12 @@ static int vidioc_try_fmt_out(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f, if (pix_fmt_mp->height < tmp_h && (pix_fmt_mp->height + 32) <= max_height) pix_fmt_mp->height += 32; - mtk_v4l2_debug(0, "before resize w=%d, h=%d, after resize w=%d, h=%d, sizeimage=%d %d", - tmp_w, tmp_h, pix_fmt_mp->width, - pix_fmt_mp->height, - pix_fmt_mp->plane_fmt[0].sizeimage, - pix_fmt_mp->plane_fmt[1].sizeimage); + mtk_v4l2_venc_dbg(0, ctx, + "before resize wxh=%dx%d, after resize wxh=%dx%d, sizeimage=%d %d", + tmp_w, tmp_h, pix_fmt_mp->width, + pix_fmt_mp->height, + pix_fmt_mp->plane_fmt[0].sizeimage, + pix_fmt_mp->plane_fmt[1].sizeimage); pix_fmt_mp->num_planes = fmt->num_planes; pix_fmt_mp->plane_fmt[0].sizeimage = @@ -376,8 +364,8 @@ static int vidioc_try_fmt_out(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f, return 0; } -static void mtk_venc_set_param(struct mtk_vcodec_ctx *ctx, - struct venc_enc_param *param) +static void mtk_venc_set_param(struct mtk_vcodec_enc_ctx *ctx, + struct venc_enc_param *param) { struct mtk_q_data *q_data_src = &ctx->q_data[MTK_Q_DATA_SRC]; struct mtk_enc_params *enc_params = &ctx->enc_params; @@ -396,7 +384,7 @@ static void mtk_venc_set_param(struct mtk_vcodec_ctx *ctx, param->input_yuv_fmt = VENC_YUV_FORMAT_NV21; break; default: - mtk_v4l2_err("Unsupported fourcc =%d", q_data_src->fmt->fourcc); + mtk_v4l2_venc_err(ctx, "Unsupported fourcc =%d", q_data_src->fmt->fourcc); break; } param->h264_profile = enc_params->h264_profile; @@ -414,19 +402,19 @@ static void mtk_venc_set_param(struct mtk_vcodec_ctx *ctx, param->gop_size = enc_params->gop_size; param->bitrate = enc_params->bitrate; - mtk_v4l2_debug(0, - "fmt 0x%x, P/L %d/%d, w/h %d/%d, buf %d/%d, fps/bps %d/%d, gop %d, i_period %d", - param->input_yuv_fmt, param->h264_profile, - param->h264_level, param->width, param->height, - param->buf_width, param->buf_height, - param->frm_rate, param->bitrate, - param->gop_size, param->intra_period); + mtk_v4l2_venc_dbg(0, ctx, + "fmt 0x%x, P/L %d/%d w/h %d/%d buf %d/%d fps/bps %d/%d gop %d i_per %d", + param->input_yuv_fmt, param->h264_profile, + param->h264_level, param->width, param->height, + param->buf_width, param->buf_height, + param->frm_rate, param->bitrate, + param->gop_size, param->intra_period); } static int vidioc_venc_s_fmt_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv); const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata; struct vb2_queue *vq; struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type); @@ -435,12 +423,12 @@ static int vidioc_venc_s_fmt_cap(struct file *file, void *priv, vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); if (!vq) { - mtk_v4l2_err("fail to get vq"); + mtk_v4l2_venc_err(ctx, "fail to get vq"); return -EINVAL; } if (vb2_is_busy(vq)) { - mtk_v4l2_err("queue busy"); + mtk_v4l2_venc_err(ctx, "queue busy"); return -EBUSY; } @@ -468,8 +456,8 @@ static int vidioc_venc_s_fmt_cap(struct file *file, void *priv, if (ctx->state == MTK_STATE_FREE) { ret = venc_if_init(ctx, q_data->fmt->fourcc); if (ret) { - mtk_v4l2_err("venc_if_init failed=%d, codec type=%x", - ret, q_data->fmt->fourcc); + mtk_v4l2_venc_err(ctx, "venc_if_init failed=%d, codec type=%x", + ret, q_data->fmt->fourcc); return -EBUSY; } ctx->state = MTK_STATE_INIT; @@ -481,7 +469,7 @@ static int vidioc_venc_s_fmt_cap(struct file *file, void *priv, static int vidioc_venc_s_fmt_out(struct file *file, void *priv, struct v4l2_format *f) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv); const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata; struct vb2_queue *vq; struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type); @@ -490,12 +478,12 @@ static int vidioc_venc_s_fmt_out(struct file *file, void *priv, vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); if (!vq) { - mtk_v4l2_err("fail to get vq"); + mtk_v4l2_venc_err(ctx, "fail to get vq"); return -EINVAL; } if (vb2_is_busy(vq)) { - mtk_v4l2_err("queue busy"); + mtk_v4l2_venc_err(ctx, "queue busy"); return -EBUSY; } @@ -536,7 +524,7 @@ static int vidioc_venc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) { struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv); struct vb2_queue *vq; struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type); int i; @@ -569,7 +557,7 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv, struct v4l2_format *f) { const struct mtk_video_fmt *fmt; - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv); const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata; fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata); @@ -591,7 +579,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, struct v4l2_format *f) { const struct mtk_video_fmt *fmt; - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv); const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata; fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata); @@ -612,7 +600,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, static int vidioc_venc_g_selection(struct file *file, void *priv, struct v4l2_selection *s) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv); struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, s->type); if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) @@ -642,7 +630,7 @@ static int vidioc_venc_g_selection(struct file *file, void *priv, static int vidioc_venc_s_selection(struct file *file, void *priv, struct v4l2_selection *s) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv); struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, s->type); if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) @@ -667,11 +655,11 @@ static int vidioc_venc_s_selection(struct file *file, void *priv, static int vidioc_venc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv); if (ctx->state == MTK_STATE_ABORT) { - mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error", - ctx->id); + mtk_v4l2_venc_err(ctx, "[%d] Call on QBUF after unrecoverable error", + ctx->id); return -EIO; } @@ -681,12 +669,12 @@ static int vidioc_venc_qbuf(struct file *file, void *priv, static int vidioc_venc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv); int ret; if (ctx->state == MTK_STATE_ABORT) { - mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error", - ctx->id); + mtk_v4l2_venc_err(ctx, "[%d] Call on QBUF after unrecoverable error", + ctx->id); return -EIO; } @@ -719,13 +707,13 @@ static int vidioc_venc_dqbuf(struct file *file, void *priv, static int vidioc_encoder_cmd(struct file *file, void *priv, struct v4l2_encoder_cmd *cmd) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv); struct vb2_queue *src_vq, *dst_vq; int ret; if (ctx->state == MTK_STATE_ABORT) { - mtk_v4l2_err("[%d] Call to CMD after unrecoverable error", - ctx->id); + mtk_v4l2_venc_err(ctx, "[%d] Call to CMD after unrecoverable error", + ctx->id); return -EIO; } @@ -737,7 +725,7 @@ static int vidioc_encoder_cmd(struct file *file, void *priv, if (ctx->is_flushing) return -EBUSY; - mtk_v4l2_debug(1, "encoder cmd=%u", cmd->cmd); + mtk_v4l2_venc_dbg(1, ctx, "encoder cmd=%u", cmd->cmd); dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); @@ -746,11 +734,11 @@ static int vidioc_encoder_cmd(struct file *file, void *priv, src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); if (!vb2_is_streaming(src_vq)) { - mtk_v4l2_debug(1, "Output stream is off. No need to flush."); + mtk_v4l2_venc_dbg(1, ctx, "Output stream is off. No need to flush."); return 0; } if (!vb2_is_streaming(dst_vq)) { - mtk_v4l2_debug(1, "Capture stream is off. No need to flush."); + mtk_v4l2_venc_dbg(1, ctx, "Capture stream is off. No need to flush."); return 0; } ctx->is_flushing = true; @@ -813,7 +801,7 @@ static int vb2ops_venc_queue_setup(struct vb2_queue *vq, unsigned int sizes[], struct device *alloc_devs[]) { - struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq); + struct mtk_vcodec_enc_ctx *ctx = vb2_get_drv_priv(vq); struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, vq->type); unsigned int i; @@ -837,15 +825,14 @@ static int vb2ops_venc_queue_setup(struct vb2_queue *vq, static int vb2ops_venc_buf_prepare(struct vb2_buffer *vb) { - struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct mtk_vcodec_enc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, vb->vb2_queue->type); int i; for (i = 0; i < q_data->fmt->num_planes; i++) { if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) { - mtk_v4l2_err("data will not fit into plane %d (%lu < %d)", - i, vb2_plane_size(vb, i), - q_data->sizeimage[i]); + mtk_v4l2_venc_err(ctx, "data will not fit into plane %d (%lu < %d)", + i, vb2_plane_size(vb, i), q_data->sizeimage[i]); return -EINVAL; } } @@ -855,7 +842,7 @@ static int vb2ops_venc_buf_prepare(struct vb2_buffer *vb) static void vb2ops_venc_buf_queue(struct vb2_buffer *vb) { - struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct mtk_vcodec_enc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf); @@ -865,10 +852,8 @@ static void vb2ops_venc_buf_queue(struct vb2_buffer *vb) if ((vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) && (ctx->param_change != MTK_ENCODE_PARAM_NONE)) { - mtk_v4l2_debug(1, "[%d] Before id=%d encode parameter change %x", - ctx->id, - vb2_v4l2->vb2_buf.index, - ctx->param_change); + mtk_v4l2_venc_dbg(1, ctx, "[%d] Before id=%d encode parameter change %x", + ctx->id, vb2_v4l2->vb2_buf.index, ctx->param_change); mtk_buf->param_change = ctx->param_change; mtk_buf->enc_params = ctx->enc_params; ctx->param_change = MTK_ENCODE_PARAM_NONE; @@ -879,7 +864,7 @@ static void vb2ops_venc_buf_queue(struct vb2_buffer *vb) static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count) { - struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q); + struct mtk_vcodec_enc_ctx *ctx = vb2_get_drv_priv(q); struct venc_enc_param param; int ret, pm_ret; int i; @@ -903,14 +888,14 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count) ret = pm_runtime_resume_and_get(&ctx->dev->plat_dev->dev); if (ret < 0) { - mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret); + mtk_v4l2_venc_err(ctx, "pm_runtime_resume_and_get fail %d", ret); goto err_start_stream; } mtk_venc_set_param(ctx, ¶m); ret = venc_if_set_param(ctx, VENC_SET_PARAM_ENC, ¶m); if (ret) { - mtk_v4l2_err("venc_if_set_param failed=%d", ret); + mtk_v4l2_venc_err(ctx, "venc_if_set_param failed=%d", ret); ctx->state = MTK_STATE_ABORT; goto err_set_param; } @@ -923,7 +908,7 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count) VENC_SET_PARAM_PREPEND_HEADER, NULL); if (ret) { - mtk_v4l2_err("venc_if_set_param failed=%d", ret); + mtk_v4l2_venc_err(ctx, "venc_if_set_param failed=%d", ret); ctx->state = MTK_STATE_ABORT; goto err_set_param; } @@ -935,7 +920,7 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count) err_set_param: pm_ret = pm_runtime_put(&ctx->dev->plat_dev->dev); if (pm_ret < 0) - mtk_v4l2_err("pm_runtime_put fail %d", pm_ret); + mtk_v4l2_venc_err(ctx, "pm_runtime_put fail %d", pm_ret); err_start_stream: for (i = 0; i < q->num_buffers; ++i) { @@ -946,9 +931,8 @@ err_start_stream: * can be marked as done. */ if (buf && buf->state == VB2_BUF_STATE_ACTIVE) { - mtk_v4l2_debug(0, "[%d] id=%d, type=%d, %d -> VB2_BUF_STATE_QUEUED", - ctx->id, i, q->type, - (int)buf->state); + mtk_v4l2_venc_dbg(0, ctx, "[%d] id=%d, type=%d, %d->VB2_BUF_STATE_QUEUED", + ctx->id, i, q->type, (int)buf->state); v4l2_m2m_buf_done(to_vb2_v4l2_buffer(buf), VB2_BUF_STATE_QUEUED); } @@ -959,11 +943,11 @@ err_start_stream: static void vb2ops_venc_stop_streaming(struct vb2_queue *q) { - struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q); + struct mtk_vcodec_enc_ctx *ctx = vb2_get_drv_priv(q); struct vb2_v4l2_buffer *src_buf, *dst_buf; int ret; - mtk_v4l2_debug(2, "[%d]-> type=%d", ctx->id, q->type); + mtk_v4l2_venc_dbg(2, ctx, "[%d]-> type=%d", ctx->id, q->type); if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) { @@ -974,7 +958,7 @@ static void vb2ops_venc_stop_streaming(struct vb2_queue *q) if (ctx->is_flushing) { struct v4l2_m2m_buffer *b, *n; - mtk_v4l2_debug(1, "STREAMOFF called while flushing"); + mtk_v4l2_venc_dbg(1, ctx, "STREAMOFF called while flushing"); /* * STREAMOFF could be called before the flush buffer is * dequeued. Check whether empty flush buf is still in @@ -1008,21 +992,21 @@ static void vb2ops_venc_stop_streaming(struct vb2_queue *q) vb2_is_streaming(&ctx->m2m_ctx->out_q_ctx.q)) || (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && vb2_is_streaming(&ctx->m2m_ctx->cap_q_ctx.q))) { - mtk_v4l2_debug(1, "[%d]-> q type %d out=%d cap=%d", - ctx->id, q->type, - vb2_is_streaming(&ctx->m2m_ctx->out_q_ctx.q), - vb2_is_streaming(&ctx->m2m_ctx->cap_q_ctx.q)); + mtk_v4l2_venc_dbg(1, ctx, "[%d]-> q type %d out=%d cap=%d", + ctx->id, q->type, + vb2_is_streaming(&ctx->m2m_ctx->out_q_ctx.q), + vb2_is_streaming(&ctx->m2m_ctx->cap_q_ctx.q)); return; } /* Release the encoder if both streams are stopped. */ ret = venc_if_deinit(ctx); if (ret) - mtk_v4l2_err("venc_if_deinit failed=%d", ret); + mtk_v4l2_venc_err(ctx, "venc_if_deinit failed=%d", ret); ret = pm_runtime_put(&ctx->dev->plat_dev->dev); if (ret < 0) - mtk_v4l2_err("pm_runtime_put fail %d", ret); + mtk_v4l2_venc_err(ctx, "pm_runtime_put fail %d", ret); ctx->state = MTK_STATE_FREE; } @@ -1048,7 +1032,7 @@ static const struct vb2_ops mtk_venc_vb2_ops = { static int mtk_venc_encode_header(void *priv) { - struct mtk_vcodec_ctx *ctx = priv; + struct mtk_vcodec_enc_ctx *ctx = priv; int ret; struct vb2_v4l2_buffer *src_buf, *dst_buf; struct mtk_vcodec_mem bs_buf; @@ -1056,7 +1040,7 @@ static int mtk_venc_encode_header(void *priv) dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); if (!dst_buf) { - mtk_v4l2_debug(1, "No dst buffer"); + mtk_v4l2_venc_dbg(1, ctx, "No dst buffer"); return -EINVAL; } @@ -1064,12 +1048,10 @@ static int mtk_venc_encode_header(void *priv) bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); bs_buf.size = (size_t)dst_buf->vb2_buf.planes[0].length; - mtk_v4l2_debug(1, - "[%d] buf id=%d va=0x%p dma_addr=0x%llx size=%zu", - ctx->id, - dst_buf->vb2_buf.index, bs_buf.va, - (u64)bs_buf.dma_addr, - bs_buf.size); + mtk_v4l2_venc_dbg(1, ctx, + "[%d] buf id=%d va=0x%p dma_addr=0x%llx size=%zu", + ctx->id, dst_buf->vb2_buf.index, bs_buf.va, + (u64)bs_buf.dma_addr, bs_buf.size); ret = venc_if_encode(ctx, VENC_START_OPT_ENCODE_SEQUENCE_HEADER, @@ -1079,7 +1061,7 @@ static int mtk_venc_encode_header(void *priv) vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0); ctx->state = MTK_STATE_ABORT; v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); - mtk_v4l2_err("venc_if_encode failed=%d", ret); + mtk_v4l2_venc_err(ctx, "venc_if_encode failed=%d", ret); return -EINVAL; } src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); @@ -1087,7 +1069,7 @@ static int mtk_venc_encode_header(void *priv) dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp; dst_buf->timecode = src_buf->timecode; } else { - mtk_v4l2_err("No timestamp for the header buffer."); + mtk_v4l2_venc_err(ctx, "No timestamp for the header buffer."); } ctx->state = MTK_STATE_HEADER; @@ -1097,7 +1079,7 @@ static int mtk_venc_encode_header(void *priv) return 0; } -static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx) +static int mtk_venc_param_change(struct mtk_vcodec_enc_ctx *ctx) { struct venc_enc_param enc_prm; struct vb2_v4l2_buffer *vb2_v4l2 = v4l2_m2m_next_src_buf(ctx->m2m_ctx); @@ -1116,10 +1098,8 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx) if (mtk_buf->param_change & MTK_ENCODE_PARAM_BITRATE) { enc_prm.bitrate = mtk_buf->enc_params.bitrate; - mtk_v4l2_debug(1, "[%d] id=%d, change param br=%d", - ctx->id, - vb2_v4l2->vb2_buf.index, - enc_prm.bitrate); + mtk_v4l2_venc_dbg(1, ctx, "[%d] id=%d, change param br=%d", + ctx->id, vb2_v4l2->vb2_buf.index, enc_prm.bitrate); ret |= venc_if_set_param(ctx, VENC_SET_PARAM_ADJUST_BITRATE, &enc_prm); @@ -1127,27 +1107,23 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx) if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_FRAMERATE) { enc_prm.frm_rate = mtk_buf->enc_params.framerate_num / mtk_buf->enc_params.framerate_denom; - mtk_v4l2_debug(1, "[%d] id=%d, change param fr=%d", - ctx->id, - vb2_v4l2->vb2_buf.index, - enc_prm.frm_rate); + mtk_v4l2_venc_dbg(1, ctx, "[%d] id=%d, change param fr=%d", + ctx->id, vb2_v4l2->vb2_buf.index, enc_prm.frm_rate); ret |= venc_if_set_param(ctx, VENC_SET_PARAM_ADJUST_FRAMERATE, &enc_prm); } if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_GOP_SIZE) { enc_prm.gop_size = mtk_buf->enc_params.gop_size; - mtk_v4l2_debug(1, "change param intra period=%d", - enc_prm.gop_size); + mtk_v4l2_venc_dbg(1, ctx, "change param intra period=%d", enc_prm.gop_size); ret |= venc_if_set_param(ctx, VENC_SET_PARAM_GOP_SIZE, &enc_prm); } if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_FORCE_INTRA) { - mtk_v4l2_debug(1, "[%d] id=%d, change param force I=%d", - ctx->id, - vb2_v4l2->vb2_buf.index, - mtk_buf->enc_params.force_intra); + mtk_v4l2_venc_dbg(1, ctx, "[%d] id=%d, change param force I=%d", + ctx->id, vb2_v4l2->vb2_buf.index, + mtk_buf->enc_params.force_intra); if (mtk_buf->enc_params.force_intra) ret |= venc_if_set_param(ctx, VENC_SET_PARAM_FORCE_INTRA, @@ -1158,8 +1134,8 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx) if (ret) { ctx->state = MTK_STATE_ABORT; - mtk_v4l2_err("venc_if_set_param %d failed=%d", - mtk_buf->param_change, ret); + mtk_v4l2_venc_err(ctx, "venc_if_set_param %d failed=%d", + mtk_buf->param_change, ret); return -1; } @@ -1176,7 +1152,7 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx) */ static void mtk_venc_worker(struct work_struct *work) { - struct mtk_vcodec_ctx *ctx = container_of(work, struct mtk_vcodec_ctx, + struct mtk_vcodec_enc_ctx *ctx = container_of(work, struct mtk_vcodec_enc_ctx, encode_work); struct vb2_v4l2_buffer *src_buf, *dst_buf; struct venc_frm_buf frm_buf; @@ -1220,14 +1196,11 @@ static void mtk_venc_worker(struct work_struct *work) bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); bs_buf.size = (size_t)dst_buf->vb2_buf.planes[0].length; - mtk_v4l2_debug(2, - "Framebuf PA=%llx Size=0x%zx;PA=0x%llx Size=0x%zx;PA=0x%llx Size=%zu", - (u64)frm_buf.fb_addr[0].dma_addr, - frm_buf.fb_addr[0].size, - (u64)frm_buf.fb_addr[1].dma_addr, - frm_buf.fb_addr[1].size, - (u64)frm_buf.fb_addr[2].dma_addr, - frm_buf.fb_addr[2].size); + mtk_v4l2_venc_dbg(2, ctx, + "Framebuf PA=%llx Size=0x%zx;PA=0x%llx Size=0x%zx;PA=0x%llx Size=%zu", + (u64)frm_buf.fb_addr[0].dma_addr, frm_buf.fb_addr[0].size, + (u64)frm_buf.fb_addr[1].dma_addr, frm_buf.fb_addr[1].size, + (u64)frm_buf.fb_addr[2].dma_addr, frm_buf.fb_addr[2].size); ret = venc_if_encode(ctx, VENC_START_OPT_ENCODE_FRAME, &frm_buf, &bs_buf, &enc_result); @@ -1242,25 +1215,24 @@ static void mtk_venc_worker(struct work_struct *work) v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0); v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); - mtk_v4l2_err("venc_if_encode failed=%d", ret); + mtk_v4l2_venc_err(ctx, "venc_if_encode failed=%d", ret); } else { v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); vb2_set_plane_payload(&dst_buf->vb2_buf, 0, enc_result.bs_size); v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); - mtk_v4l2_debug(2, "venc_if_encode bs size=%d", - enc_result.bs_size); + mtk_v4l2_venc_dbg(2, ctx, "venc_if_encode bs size=%d", + enc_result.bs_size); } v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx); - mtk_v4l2_debug(1, "<=== src_buf[%d] dst_buf[%d] venc_if_encode ret=%d Size=%u===>", - src_buf->vb2_buf.index, dst_buf->vb2_buf.index, ret, - enc_result.bs_size); + mtk_v4l2_venc_dbg(1, ctx, "<=== src_buf[%d] dst_buf[%d] venc_if_encode ret=%d Size=%u===>", + src_buf->vb2_buf.index, dst_buf->vb2_buf.index, ret, enc_result.bs_size); } static void m2mops_venc_device_run(void *priv) { - struct mtk_vcodec_ctx *ctx = priv; + struct mtk_vcodec_enc_ctx *ctx = priv; if ((ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_H264) && (ctx->state != MTK_STATE_HEADER)) { @@ -1276,11 +1248,10 @@ static void m2mops_venc_device_run(void *priv) static int m2mops_venc_job_ready(void *m2m_priv) { - struct mtk_vcodec_ctx *ctx = m2m_priv; + struct mtk_vcodec_enc_ctx *ctx = m2m_priv; if (ctx->state == MTK_STATE_ABORT || ctx->state == MTK_STATE_FREE) { - mtk_v4l2_debug(3, "[%d]Not ready: state=0x%x.", - ctx->id, ctx->state); + mtk_v4l2_venc_dbg(3, ctx, "[%d]Not ready: state=0x%x.", ctx->id, ctx->state); return 0; } @@ -1289,7 +1260,7 @@ static int m2mops_venc_job_ready(void *m2m_priv) static void m2mops_venc_job_abort(void *priv) { - struct mtk_vcodec_ctx *ctx = priv; + struct mtk_vcodec_enc_ctx *ctx = priv; ctx->state = MTK_STATE_ABORT; } @@ -1300,7 +1271,7 @@ const struct v4l2_m2m_ops mtk_venc_m2m_ops = { .job_abort = m2mops_venc_job_abort, }; -void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx) +void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_enc_ctx *ctx) { struct mtk_q_data *q_data; @@ -1361,7 +1332,7 @@ void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx) ctx->enc_params.framerate_denom = MTK_DEFAULT_FRAMERATE_DENOM; } -int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx) +int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_enc_ctx *ctx) { const struct v4l2_ctrl_ops *ops = &mtk_vcodec_enc_ctrl_ops; struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl; @@ -1415,8 +1386,7 @@ int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx) if (handler->error) { - mtk_v4l2_err("Init control handler fail %d", - handler->error); + mtk_v4l2_venc_err(ctx, "Init control handler fail %d", handler->error); return handler->error; } @@ -1428,7 +1398,7 @@ int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx) int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) { - struct mtk_vcodec_ctx *ctx = priv; + struct mtk_vcodec_enc_ctx *ctx = priv; int ret; /* Note: VB2_USERPTR works with dma-contig because mt8173 @@ -1463,28 +1433,28 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq, return vb2_queue_init(dst_vq); } -int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx) +int mtk_venc_unlock(struct mtk_vcodec_enc_ctx *ctx) { - struct mtk_vcodec_dev *dev = ctx->dev; + struct mtk_vcodec_enc_dev *dev = ctx->dev; mutex_unlock(&dev->enc_mutex); return 0; } -int mtk_venc_lock(struct mtk_vcodec_ctx *ctx) +int mtk_venc_lock(struct mtk_vcodec_enc_ctx *ctx) { - struct mtk_vcodec_dev *dev = ctx->dev; + struct mtk_vcodec_enc_dev *dev = ctx->dev; mutex_lock(&dev->enc_mutex); return 0; } -void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx) +void mtk_vcodec_enc_release(struct mtk_vcodec_enc_ctx *ctx) { int ret = venc_if_deinit(ctx); if (ret) - mtk_v4l2_err("venc_if_deinit failed=%d", ret); + mtk_v4l2_venc_err(ctx, "venc_if_deinit failed=%d", ret); ctx->state = MTK_STATE_FREE; } diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h index 513ee7993e34..82246401ed4a 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.h +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h @@ -11,6 +11,8 @@ #include <media/videobuf2-core.h> #include <media/v4l2-mem2mem.h> +#include "mtk_vcodec_enc_drv.h" + #define MTK_VENC_IRQ_STATUS_SPS 0x1 #define MTK_VENC_IRQ_STATUS_PPS 0x2 #define MTK_VENC_IRQ_STATUS_FRM 0x4 @@ -39,12 +41,12 @@ struct mtk_video_enc_buf { extern const struct v4l2_ioctl_ops mtk_venc_ioctl_ops; extern const struct v4l2_m2m_ops mtk_venc_m2m_ops; -int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx); -int mtk_venc_lock(struct mtk_vcodec_ctx *ctx); +int mtk_venc_unlock(struct mtk_vcodec_enc_ctx *ctx); +int mtk_venc_lock(struct mtk_vcodec_enc_ctx *ctx); int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq); -void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx); -int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx); -void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx); +void mtk_vcodec_enc_release(struct mtk_vcodec_enc_ctx *ctx); +int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_enc_ctx *ctx); +void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_enc_ctx *ctx); #endif /* _MTK_VCODEC_ENC_H_ */ diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c index 5df0a22ff3b5..6319f24bc714 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_drv.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c @@ -9,19 +9,16 @@ #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/module.h> -#include <linux/of_device.h> #include <linux/of.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <media/v4l2-event.h> #include <media/v4l2-mem2mem.h> #include <media/videobuf2-dma-contig.h> -#include "mtk_vcodec_drv.h" #include "mtk_vcodec_enc.h" #include "mtk_vcodec_enc_pm.h" -#include "mtk_vcodec_intr.h" -#include "mtk_vcodec_util.h" -#include "mtk_vcodec_fw.h" +#include "../common/mtk_vcodec_intr.h" static const struct mtk_video_fmt mtk_video_formats_output[] = { { @@ -85,8 +82,8 @@ static void clean_irq_status(unsigned int irq_status, void __iomem *addr) } static irqreturn_t mtk_vcodec_enc_irq_handler(int irq, void *priv) { - struct mtk_vcodec_dev *dev = priv; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_enc_dev *dev = priv; + struct mtk_vcodec_enc_ctx *ctx; unsigned long flags; void __iomem *addr; int core_id; @@ -97,12 +94,11 @@ static irqreturn_t mtk_vcodec_enc_irq_handler(int irq, void *priv) core_id = dev->venc_pdata->core_id; if (core_id < 0 || core_id >= NUM_MAX_VCODEC_REG_BASE) { - mtk_v4l2_err("Invalid core id: %d, ctx id: %d", - core_id, ctx->id); + mtk_v4l2_venc_err(ctx, "Invalid core id: %d, ctx id: %d", core_id, ctx->id); return IRQ_HANDLED; } - mtk_v4l2_debug(1, "id: %d, core id: %d", ctx->id, core_id); + mtk_v4l2_venc_dbg(1, ctx, "id: %d, core id: %d", ctx->id, core_id); addr = dev->reg_base[core_id] + MTK_VENC_IRQ_ACK_OFFSET; @@ -111,14 +107,14 @@ static irqreturn_t mtk_vcodec_enc_irq_handler(int irq, void *priv) clean_irq_status(ctx->irq_status, addr); - wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0); + wake_up_enc_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0); return IRQ_HANDLED; } static int fops_vcodec_open(struct file *file) { - struct mtk_vcodec_dev *dev = video_drvdata(file); - struct mtk_vcodec_ctx *ctx = NULL; + struct mtk_vcodec_enc_dev *dev = video_drvdata(file); + struct mtk_vcodec_enc_ctx *ctx = NULL; int ret = 0; struct vb2_queue *src_vq; @@ -143,16 +139,14 @@ static int fops_vcodec_open(struct file *file) ctx->type = MTK_INST_ENCODER; ret = mtk_vcodec_enc_ctrls_setup(ctx); if (ret) { - mtk_v4l2_err("Failed to setup controls() (%d)", - ret); + mtk_v4l2_venc_err(ctx, "Failed to setup controls() (%d)", ret); goto err_ctrls_setup; } ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev_enc, ctx, &mtk_vcodec_enc_queue_init); if (IS_ERR((__force void *)ctx->m2m_ctx)) { ret = PTR_ERR((__force void *)ctx->m2m_ctx); - mtk_v4l2_err("Failed to v4l2_m2m_ctx_init() (%d)", - ret); + mtk_v4l2_venc_err(ctx, "Failed to v4l2_m2m_ctx_init() (%d)", ret); goto err_m2m_ctx_init; } src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, @@ -171,23 +165,23 @@ static int fops_vcodec_open(struct file *file) * Return 0 if downloading firmware successfully, * otherwise it is failed */ - mtk_v4l2_err("vpu_load_firmware failed!"); + mtk_v4l2_venc_err(ctx, "vpu_load_firmware failed!"); goto err_load_fw; } dev->enc_capability = mtk_vcodec_fw_get_venc_capa(dev->fw_handler); - mtk_v4l2_debug(0, "encoder capability %x", dev->enc_capability); + mtk_v4l2_venc_dbg(0, ctx, "encoder capability %x", dev->enc_capability); } - mtk_v4l2_debug(2, "Create instance [%d]@%p m2m_ctx=%p ", - ctx->id, ctx, ctx->m2m_ctx); + mtk_v4l2_venc_dbg(2, ctx, "Create instance [%d]@%p m2m_ctx=%p ", + ctx->id, ctx, ctx->m2m_ctx); list_add(&ctx->list, &dev->ctx_list); mutex_unlock(&dev->dev_mutex); - mtk_v4l2_debug(0, "%s encoder [%d]", dev_name(&dev->plat_dev->dev), - ctx->id); + mtk_v4l2_venc_dbg(0, ctx, "%s encoder [%d]", dev_name(&dev->plat_dev->dev), + ctx->id); return ret; /* Deinit when failure occurred */ @@ -206,10 +200,10 @@ err_ctrls_setup: static int fops_vcodec_release(struct file *file) { - struct mtk_vcodec_dev *dev = video_drvdata(file); - struct mtk_vcodec_ctx *ctx = fh_to_ctx(file->private_data); + struct mtk_vcodec_enc_dev *dev = video_drvdata(file); + struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(file->private_data); - mtk_v4l2_debug(1, "[%d] encoder", ctx->id); + mtk_v4l2_venc_dbg(1, ctx, "[%d] encoder", ctx->id); mutex_lock(&dev->dev_mutex); v4l2_m2m_ctx_release(ctx->m2m_ctx); @@ -235,7 +229,7 @@ static const struct v4l2_file_operations mtk_vcodec_fops = { static int mtk_vcodec_probe(struct platform_device *pdev) { - struct mtk_vcodec_dev *dev; + struct mtk_vcodec_enc_dev *dev; struct video_device *vfd_enc; phandle rproc_phandle; enum mtk_vcodec_fw_type fw_type; @@ -255,7 +249,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) &rproc_phandle)) { fw_type = SCP; } else { - mtk_v4l2_err("Could not get venc IPI device"); + dev_err(&pdev->dev, "[MTK VCODEC] Could not get venc IPI device"); return -ENODEV; } dma_set_max_seg_size(&pdev->dev, UINT_MAX); @@ -267,7 +261,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) dev->venc_pdata = of_device_get_match_data(&pdev->dev); ret = mtk_vcodec_init_enc_clk(dev); if (ret < 0) { - dev_err(&pdev->dev, "Failed to get mtk vcodec clock source!"); + dev_err(&pdev->dev, "[MTK VCODEC] Failed to get mtk vcodec clock source!"); goto err_enc_pm; } @@ -292,7 +286,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) 0, pdev->name, dev); if (ret) { dev_err(&pdev->dev, - "Failed to install dev->enc_irq %d (%d) core_id (%d)", + "[MTK VCODEC] Failed to install dev->enc_irq %d (%d) core_id (%d)", dev->enc_irq, ret, dev->venc_pdata->core_id); ret = -EINVAL; goto err_res; @@ -307,16 +301,14 @@ static int mtk_vcodec_probe(struct platform_device *pdev) ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); if (ret) { - mtk_v4l2_err("v4l2_device_register err=%d", ret); + dev_err(&pdev->dev, "[MTK VCODEC] v4l2_device_register err=%d", ret); goto err_res; } - init_waitqueue_head(&dev->queue); - /* allocate video device for encoder and register it */ vfd_enc = video_device_alloc(); if (!vfd_enc) { - mtk_v4l2_err("Failed to allocate video device"); + dev_err(&pdev->dev, "[MTK VCODEC] Failed to allocate video device"); ret = -ENOMEM; goto err_enc_alloc; } @@ -337,7 +329,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) dev->m2m_dev_enc = v4l2_m2m_init(&mtk_venc_m2m_ops); if (IS_ERR((__force void *)dev->m2m_dev_enc)) { - mtk_v4l2_err("Failed to init mem2mem enc device"); + dev_err(&pdev->dev, "[MTK VCODEC] Failed to init mem2mem enc device"); ret = PTR_ERR((__force void *)dev->m2m_dev_enc); goto err_enc_mem_init; } @@ -347,20 +339,20 @@ static int mtk_vcodec_probe(struct platform_device *pdev) WQ_MEM_RECLAIM | WQ_FREEZABLE); if (!dev->encode_workqueue) { - mtk_v4l2_err("Failed to create encode workqueue"); + dev_err(&pdev->dev, "[MTK VCODEC] Failed to create encode workqueue"); ret = -EINVAL; goto err_event_workq; } ret = video_register_device(vfd_enc, VFL_TYPE_VIDEO, -1); if (ret) { - mtk_v4l2_err("Failed to register video device"); + dev_err(&pdev->dev, "[MTK VCODEC] Failed to register video device"); goto err_enc_reg; } mtk_vcodec_dbgfs_init(dev, true); - mtk_v4l2_debug(0, "encoder %d registered as /dev/video%d", - dev->venc_pdata->core_id, vfd_enc->num); + dev_dbg(&pdev->dev, "[MTK VCODEC] encoder %d registered as /dev/video%d", + dev->venc_pdata->core_id, vfd_enc->num); return 0; @@ -459,9 +451,8 @@ MODULE_DEVICE_TABLE(of, mtk_vcodec_enc_match); static void mtk_vcodec_enc_remove(struct platform_device *pdev) { - struct mtk_vcodec_dev *dev = platform_get_drvdata(pdev); + struct mtk_vcodec_enc_dev *dev = platform_get_drvdata(pdev); - mtk_v4l2_debug_enter(); destroy_workqueue(dev->encode_workqueue); if (dev->m2m_dev_enc) v4l2_m2m_release(dev->m2m_dev_enc); @@ -469,7 +460,7 @@ static void mtk_vcodec_enc_remove(struct platform_device *pdev) if (dev->vfd_enc) video_unregister_device(dev->vfd_enc); - mtk_vcodec_dbgfs_deinit(dev); + mtk_vcodec_dbgfs_deinit(&dev->dbgfs); v4l2_device_unregister(&dev->v4l2_dev); pm_runtime_disable(dev->pm.dev); mtk_vcodec_fw_release(dev->fw_handler); diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h new file mode 100644 index 000000000000..a042f607ed8d --- /dev/null +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h @@ -0,0 +1,248 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2023 MediaTek Inc. + * Author: Yunfei Dong <yunfei.dong@mediatek.com> + */ + +#ifndef _MTK_VCODEC_ENC_DRV_H_ +#define _MTK_VCODEC_ENC_DRV_H_ + +#include "../common/mtk_vcodec_cmn_drv.h" +#include "../common/mtk_vcodec_dbgfs.h" +#include "../common/mtk_vcodec_fw_priv.h" +#include "../common/mtk_vcodec_util.h" + +#define MTK_VCODEC_ENC_NAME "mtk-vcodec-enc" + +#define MTK_ENC_CTX_IS_EXT(ctx) ((ctx)->dev->venc_pdata->uses_ext) +#define MTK_ENC_IOVA_IS_34BIT(ctx) ((ctx)->dev->venc_pdata->uses_34bit) + +/** + * struct mtk_vcodec_enc_pdata - compatible data for each IC + * + * @uses_ext: whether the encoder uses the extended firmware messaging format + * @min_bitrate: minimum supported encoding bitrate + * @max_bitrate: maximum supported encoding bitrate + * @capture_formats: array of supported capture formats + * @num_capture_formats: number of entries in capture_formats + * @output_formats: array of supported output formats + * @num_output_formats: number of entries in output_formats + * @core_id: stand for h264 or vp8 encode index + * @uses_34bit: whether the encoder uses 34-bit iova + */ +struct mtk_vcodec_enc_pdata { + bool uses_ext; + u64 min_bitrate; + u64 max_bitrate; + const struct mtk_video_fmt *capture_formats; + size_t num_capture_formats; + const struct mtk_video_fmt *output_formats; + size_t num_output_formats; + u8 core_id; + bool uses_34bit; +}; + +/* + * enum mtk_encode_param - General encoding parameters type + */ +enum mtk_encode_param { + MTK_ENCODE_PARAM_NONE = 0, + MTK_ENCODE_PARAM_BITRATE = (1 << 0), + MTK_ENCODE_PARAM_FRAMERATE = (1 << 1), + MTK_ENCODE_PARAM_INTRA_PERIOD = (1 << 2), + MTK_ENCODE_PARAM_FORCE_INTRA = (1 << 3), + MTK_ENCODE_PARAM_GOP_SIZE = (1 << 4), +}; + +/** + * struct mtk_enc_params - General encoding parameters + * @bitrate: target bitrate in bits per second + * @num_b_frame: number of b frames between p-frame + * @rc_frame: frame based rate control + * @rc_mb: macroblock based rate control + * @seq_hdr_mode: H.264 sequence header is encoded separately or joined + * with the first frame + * @intra_period: I frame period + * @gop_size: group of picture size, it's used as the intra frame period + * @framerate_num: frame rate numerator. ex: framerate_num=30 and + * framerate_denom=1 means FPS is 30 + * @framerate_denom: frame rate denominator. ex: framerate_num=30 and + * framerate_denom=1 means FPS is 30 + * @h264_max_qp: Max value for H.264 quantization parameter + * @h264_profile: V4L2 defined H.264 profile + * @h264_level: V4L2 defined H.264 level + * @force_intra: force/insert intra frame + */ +struct mtk_enc_params { + unsigned int bitrate; + unsigned int num_b_frame; + unsigned int rc_frame; + unsigned int rc_mb; + unsigned int seq_hdr_mode; + unsigned int intra_period; + unsigned int gop_size; + unsigned int framerate_num; + unsigned int framerate_denom; + unsigned int h264_max_qp; + unsigned int h264_profile; + unsigned int h264_level; + unsigned int force_intra; +}; + +/** + * struct mtk_vcodec_enc_ctx - Context (instance) private data. + * + * @type: type of encoder instance + * @dev: pointer to the mtk_vcodec_enc_dev of the device + * @list: link to ctx_list of mtk_vcodec_enc_dev + * + * @fh: struct v4l2_fh + * @m2m_ctx: pointer to the v4l2_m2m_ctx of the context + * @q_data: store information of input and output queue of the context + * @id: index of the context that this structure describes + * @state: state of the context + * @param_change: indicate encode parameter type + * @enc_params: encoding parameters + * + * @enc_if: hooked encoder driver interface + * @drv_handle: driver handle for specific decode/encode instance + * + * @int_cond: variable used by the waitqueue + * @int_type: type of the last interrupt + * @queue: waitqueue that can be used to wait for this context to finish + * @irq_status: irq status + * + * @ctrl_hdl: handler for v4l2 framework + * @encode_work: worker for the encoding + * @empty_flush_buf: a fake size-0 capture buffer that indicates flush. Used for encoder. + * @is_flushing: set to true if flushing is in progress. + * + * @colorspace: enum v4l2_colorspace; supplemental to pixelformat + * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding + * @quantization: enum v4l2_quantization, colorspace quantization + * @xfer_func: enum v4l2_xfer_func, colorspace transfer function + * + * @q_mutex: vb2_queue mutex. + * @vpu_inst: vpu instance pointer. + */ +struct mtk_vcodec_enc_ctx { + enum mtk_instance_type type; + struct mtk_vcodec_enc_dev *dev; + struct list_head list; + + struct v4l2_fh fh; + struct v4l2_m2m_ctx *m2m_ctx; + struct mtk_q_data q_data[2]; + int id; + enum mtk_instance_state state; + enum mtk_encode_param param_change; + struct mtk_enc_params enc_params; + + const struct venc_common_if *enc_if; + void *drv_handle; + + int int_cond[MTK_VDEC_HW_MAX]; + int int_type[MTK_VDEC_HW_MAX]; + wait_queue_head_t queue[MTK_VDEC_HW_MAX]; + unsigned int irq_status; + + struct v4l2_ctrl_handler ctrl_hdl; + struct work_struct encode_work; + struct v4l2_m2m_buffer empty_flush_buf; + bool is_flushing; + + enum v4l2_colorspace colorspace; + enum v4l2_ycbcr_encoding ycbcr_enc; + enum v4l2_quantization quantization; + enum v4l2_xfer_func xfer_func; + + struct mutex q_mutex; + void *vpu_inst; +}; + +/** + * struct mtk_vcodec_enc_dev - driver data + * @v4l2_dev: V4L2 device to register video devices for. + * @vfd_enc: Video device for encoder. + * + * @m2m_dev_enc: m2m device for encoder. + * @plat_dev: platform device + * @ctx_list: list of struct mtk_vcodec_ctx + * @curr_ctx: The context that is waiting for codec hardware + * + * @reg_base: Mapped address of MTK Vcodec registers. + * @venc_pdata: encoder IC-specific data + * + * @fw_handler: used to communicate with the firmware. + * @id_counter: used to identify current opened instance + * + * @enc_mutex: encoder hardware lock. + * @dev_mutex: video_device lock + * @encode_workqueue: encode work queue + * + * @enc_irq: h264 encoder irq resource + * @irqlock: protect data access by irq handler and work thread + * + * @pm: power management control + * @enc_capability: used to identify encode capability + * @dbgfs: debug log related information + */ +struct mtk_vcodec_enc_dev { + struct v4l2_device v4l2_dev; + struct video_device *vfd_enc; + + struct v4l2_m2m_dev *m2m_dev_enc; + struct platform_device *plat_dev; + struct list_head ctx_list; + struct mtk_vcodec_enc_ctx *curr_ctx; + + void __iomem *reg_base[NUM_MAX_VCODEC_REG_BASE]; + const struct mtk_vcodec_enc_pdata *venc_pdata; + + struct mtk_vcodec_fw *fw_handler; + u64 id_counter; + + /* encoder hardware mutex lock */ + struct mutex enc_mutex; + struct mutex dev_mutex; + struct workqueue_struct *encode_workqueue; + + int enc_irq; + spinlock_t irqlock; + + struct mtk_vcodec_pm pm; + unsigned int enc_capability; + struct mtk_vcodec_dbgfs dbgfs; +}; + +static inline struct mtk_vcodec_enc_ctx *fh_to_enc_ctx(struct v4l2_fh *fh) +{ + return container_of(fh, struct mtk_vcodec_enc_ctx, fh); +} + +static inline struct mtk_vcodec_enc_ctx *ctrl_to_enc_ctx(struct v4l2_ctrl *ctrl) +{ + return container_of(ctrl->handler, struct mtk_vcodec_enc_ctx, ctrl_hdl); +} + +/* Wake up context wait_queue */ +static inline void +wake_up_enc_ctx(struct mtk_vcodec_enc_ctx *ctx, unsigned int reason, unsigned int hw_id) +{ + ctx->int_cond[hw_id] = 1; + ctx->int_type[hw_id] = reason; + wake_up_interruptible(&ctx->queue[hw_id]); +} + +#define mtk_venc_err(ctx, fmt, args...) \ + mtk_vcodec_err((ctx)->id, (ctx)->dev->plat_dev, fmt, ##args) + +#define mtk_venc_debug(ctx, fmt, args...) \ + mtk_vcodec_debug((ctx)->id, (ctx)->dev->plat_dev, fmt, ##args) + +#define mtk_v4l2_venc_err(ctx, fmt, args...) mtk_v4l2_err((ctx)->dev->plat_dev, fmt, ##args) + +#define mtk_v4l2_venc_dbg(level, ctx, fmt, args...) \ + mtk_v4l2_debug((ctx)->dev->plat_dev, level, fmt, ##args) + +#endif /* _MTK_VCODEC_ENC_DRV_H_ */ diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c index 7055954eb2af..3fce936e61b9 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_pm.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c @@ -5,14 +5,13 @@ */ #include <linux/clk.h> -#include <linux/of_address.h> -#include <linux/of_platform.h> +#include <linux/of.h> #include <linux/pm_runtime.h> +#include "mtk_vcodec_enc_drv.h" #include "mtk_vcodec_enc_pm.h" -#include "mtk_vcodec_util.h" -int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev) +int mtk_vcodec_init_enc_clk(struct mtk_vcodec_enc_dev *mtkdev) { struct platform_device *pdev; struct mtk_vcodec_pm *pm; @@ -35,7 +34,7 @@ int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev) if (!enc_clk->clk_info) return -ENOMEM; } else { - mtk_v4l2_err("Failed to get venc clock count"); + dev_err(pm->dev, "[MTK VCODEC] Failed to get venc clock count"); return -EINVAL; } @@ -44,13 +43,13 @@ int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev) ret = of_property_read_string_index(pdev->dev.of_node, "clock-names", i, &clk_info->clk_name); if (ret) { - mtk_v4l2_err("venc failed to get clk name %d", i); + dev_err(pm->dev, "[MTK VCODEC] venc failed to get clk name %d", i); return ret; } clk_info->vcodec_clk = devm_clk_get(&pdev->dev, clk_info->clk_name); if (IS_ERR(clk_info->vcodec_clk)) { - mtk_v4l2_err("venc devm_clk_get (%d)%s fail", i, + dev_err(pm->dev, "[MTK VCODEC] venc devm_clk_get (%d)%s fail", i, clk_info->clk_name); return PTR_ERR(clk_info->vcodec_clk); } @@ -67,7 +66,7 @@ void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm) for (i = 0; i < enc_clk->clk_num; i++) { ret = clk_prepare_enable(enc_clk->clk_info[i].vcodec_clk); if (ret) { - mtk_v4l2_err("venc clk_prepare_enable %d %s fail %d", i, + dev_err(pm->dev, "[MTK VCODEC] venc clk_prepare_enable %d %s fail %d", i, enc_clk->clk_info[i].clk_name, ret); goto clkerr; } diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_pm.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h index bc455cefc0cd..e50be0575190 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_pm.h +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h @@ -7,9 +7,9 @@ #ifndef _MTK_VCODEC_ENC_PM_H_ #define _MTK_VCODEC_ENC_PM_H_ -#include "mtk_vcodec_drv.h" +#include "mtk_vcodec_enc_drv.h" -int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *dev); +int mtk_vcodec_init_enc_clk(struct mtk_vcodec_enc_dev *dev); void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm); void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm); diff --git a/drivers/media/platform/mediatek/vcodec/venc/venc_h264_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c index 60fd165c0d94..a68dac72c4e4 100644 --- a/drivers/media/platform/mediatek/vcodec/venc/venc_h264_if.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c @@ -10,9 +10,8 @@ #include <linux/kernel.h> #include <linux/slab.h> -#include "../mtk_vcodec_drv.h" -#include "../mtk_vcodec_util.h" -#include "../mtk_vcodec_intr.h" +#include "../mtk_vcodec_enc_drv.h" +#include "../../common/mtk_vcodec_intr.h" #include "../mtk_vcodec_enc.h" #include "../mtk_vcodec_enc_pm.h" #include "../venc_drv_base.h" @@ -221,7 +220,7 @@ struct venc_h264_inst { struct venc_vpu_inst vpu_inst; struct venc_h264_vsi *vsi; struct venc_h264_vsi_34 *vsi_34; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_enc_ctx *ctx; }; static inline u32 h264_read_reg(struct venc_h264_inst *inst, u32 addr) @@ -240,13 +239,13 @@ static unsigned int h264_get_profile(struct venc_h264_inst *inst, case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: return 100; case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: - mtk_vcodec_err(inst, "unsupported CONSTRAINED_BASELINE"); + mtk_venc_err(inst->ctx, "unsupported CONSTRAINED_BASELINE"); return 0; case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: - mtk_vcodec_err(inst, "unsupported EXTENDED"); + mtk_venc_err(inst->ctx, "unsupported EXTENDED"); return 0; default: - mtk_vcodec_debug(inst, "unsupported profile %d", profile); + mtk_venc_debug(inst->ctx, "unsupported profile %d", profile); return 100; } } @@ -256,7 +255,7 @@ static unsigned int h264_get_level(struct venc_h264_inst *inst, { switch (level) { case V4L2_MPEG_VIDEO_H264_LEVEL_1B: - mtk_vcodec_err(inst, "unsupported 1B"); + mtk_venc_err(inst->ctx, "unsupported 1B"); return 0; case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: return 10; @@ -289,7 +288,7 @@ static unsigned int h264_get_level(struct venc_h264_inst *inst, case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: return 51; default: - mtk_vcodec_debug(inst, "unsupported level %d", level); + mtk_venc_debug(inst->ctx, "unsupported level %d", level); return 31; } } @@ -298,8 +297,6 @@ static void h264_enc_free_work_buf(struct venc_h264_inst *inst) { int i; - mtk_vcodec_debug_enter(inst); - /* Except the SKIP_FRAME buffers, * other buffers need to be freed by AP. */ @@ -309,8 +306,6 @@ static void h264_enc_free_work_buf(struct venc_h264_inst *inst) } mtk_vcodec_mem_free(inst->ctx, &inst->pps_buf); - - mtk_vcodec_debug_leave(inst); } static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst, bool is_34bit) @@ -321,8 +316,6 @@ static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst, bool is_34bit) u32 vpua, wb_size; int ret = 0; - mtk_vcodec_debug_enter(inst); - if (is_34bit) wb_34 = inst->vsi_34->work_bufs; else @@ -366,8 +359,7 @@ static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst, bool is_34bit) ret = mtk_vcodec_mem_alloc(inst->ctx, &inst->work_bufs[i]); if (ret) { - mtk_vcodec_err(inst, - "cannot allocate buf %d", i); + mtk_venc_err(inst->ctx, "cannot allocate buf %d", i); goto err_alloc; } /* @@ -391,23 +383,20 @@ static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst, bool is_34bit) else wb[i].iova = inst->work_bufs[i].dma_addr; - mtk_vcodec_debug(inst, - "work_buf[%d] va=0x%p iova=%pad size=%zu", - i, inst->work_bufs[i].va, - &inst->work_bufs[i].dma_addr, - inst->work_bufs[i].size); + mtk_venc_debug(inst->ctx, "work_buf[%d] va=0x%p iova=%pad size=%zu", + i, inst->work_bufs[i].va, + &inst->work_bufs[i].dma_addr, + inst->work_bufs[i].size); } /* the pps_buf is used by AP side only */ inst->pps_buf.size = 128; ret = mtk_vcodec_mem_alloc(inst->ctx, &inst->pps_buf); if (ret) { - mtk_vcodec_err(inst, "cannot allocate pps_buf"); + mtk_venc_err(inst->ctx, "cannot allocate pps_buf"); goto err_alloc; } - mtk_vcodec_debug_leave(inst); - return ret; err_alloc: @@ -419,12 +408,12 @@ err_alloc: static unsigned int h264_enc_wait_venc_done(struct venc_h264_inst *inst) { unsigned int irq_status = 0; - struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx; + struct mtk_vcodec_enc_ctx *ctx = (struct mtk_vcodec_enc_ctx *)inst->ctx; if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED, WAIT_INTR_TIMEOUT_MS, 0)) { irq_status = ctx->irq_status; - mtk_vcodec_debug(inst, "irq_status %x <-", irq_status); + mtk_venc_debug(ctx, "irq_status %x <-", irq_status); } return irq_status; } @@ -452,21 +441,18 @@ static int h264_encode_sps(struct venc_h264_inst *inst, int ret = 0; unsigned int irq_status; - mtk_vcodec_debug_enter(inst); - ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_SPS, NULL, bs_buf, NULL); if (ret) return ret; irq_status = h264_enc_wait_venc_done(inst); if (irq_status != MTK_VENC_IRQ_STATUS_SPS) { - mtk_vcodec_err(inst, "expect irq status %d", - MTK_VENC_IRQ_STATUS_SPS); + mtk_venc_err(inst->ctx, "expect irq status %d", MTK_VENC_IRQ_STATUS_SPS); return -EINVAL; } *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT); - mtk_vcodec_debug(inst, "bs size %d <-", *bs_size); + mtk_venc_debug(inst->ctx, "bs size %d <-", *bs_size); return ret; } @@ -478,21 +464,18 @@ static int h264_encode_pps(struct venc_h264_inst *inst, int ret = 0; unsigned int irq_status; - mtk_vcodec_debug_enter(inst); - ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_PPS, NULL, bs_buf, NULL); if (ret) return ret; irq_status = h264_enc_wait_venc_done(inst); if (irq_status != MTK_VENC_IRQ_STATUS_PPS) { - mtk_vcodec_err(inst, "expect irq status %d", - MTK_VENC_IRQ_STATUS_PPS); + mtk_venc_err(inst->ctx, "expect irq status %d", MTK_VENC_IRQ_STATUS_PPS); return -EINVAL; } *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT); - mtk_vcodec_debug(inst, "bs size %d <-", *bs_size); + mtk_venc_debug(inst->ctx, "bs size %d <-", *bs_size); return ret; } @@ -529,10 +512,9 @@ static int h264_encode_frame(struct venc_h264_inst *inst, unsigned int intra_period; unsigned int irq_status; struct venc_frame_info frame_info; - struct mtk_vcodec_ctx *ctx = inst->ctx; + struct mtk_vcodec_enc_ctx *ctx = inst->ctx; - mtk_vcodec_debug_enter(inst); - mtk_vcodec_debug(inst, "frm_cnt = %d\n ", inst->frm_cnt); + mtk_venc_debug(ctx, "frm_cnt = %d\n ", inst->frm_cnt); if (MTK_ENC_IOVA_IS_34BIT(ctx)) { gop_size = inst->vsi_34->config.gop_size; @@ -545,9 +527,9 @@ static int h264_encode_frame(struct venc_h264_inst *inst, frame_info.skip_frm_count = inst->skip_frm_cnt; frame_info.frm_type = h264_frame_type(inst->frm_cnt, gop_size, intra_period); - mtk_vcodec_debug(inst, "frm_count = %d,skip_frm_count =%d,frm_type=%d.\n", - frame_info.frm_count, frame_info.skip_frm_count, - frame_info.frm_type); + mtk_venc_debug(ctx, "frm_count = %d,skip_frm_count =%d,frm_type=%d.\n", + frame_info.frm_count, frame_info.skip_frm_count, + frame_info.frm_type); ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_FRAME, frm_buf, bs_buf, &frame_info); @@ -570,15 +552,15 @@ static int h264_encode_frame(struct venc_h264_inst *inst, irq_status = h264_enc_wait_venc_done(inst); if (irq_status != MTK_VENC_IRQ_STATUS_FRM) { - mtk_vcodec_err(inst, "irq_status=%d failed", irq_status); + mtk_venc_err(ctx, "irq_status=%d failed", irq_status); return -EIO; } *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT); ++inst->frm_cnt; - mtk_vcodec_debug(inst, "frm %d bs_size %d key_frm %d <-", - inst->frm_cnt, *bs_size, inst->vpu_inst.is_key_frm); + mtk_venc_debug(ctx, "frm %d bs_size %d key_frm %d <-", + inst->frm_cnt, *bs_size, inst->vpu_inst.is_key_frm); return 0; } @@ -589,7 +571,7 @@ static void h264_encode_filler(struct venc_h264_inst *inst, void *buf, unsigned char *p = buf; if (size < H264_FILLER_MARKER_SIZE) { - mtk_vcodec_err(inst, "filler size too small %d", size); + mtk_venc_err(inst->ctx, "filler size too small %d", size); return; } @@ -599,7 +581,7 @@ static void h264_encode_filler(struct venc_h264_inst *inst, void *buf, memset(p, 0xff, size); } -static int h264_enc_init(struct mtk_vcodec_ctx *ctx) +static int h264_enc_init(struct mtk_vcodec_enc_ctx *ctx) { const bool is_ext = MTK_ENC_CTX_IS_EXT(ctx); int ret = 0; @@ -612,9 +594,7 @@ static int h264_enc_init(struct mtk_vcodec_ctx *ctx) inst->ctx = ctx; inst->vpu_inst.ctx = ctx; inst->vpu_inst.id = is_ext ? SCP_IPI_VENC_H264 : IPI_VENC_H264; - inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx, VENC_SYS); - - mtk_vcodec_debug_enter(inst); + inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx->dev->reg_base, VENC_SYS); ret = vpu_enc_init(&inst->vpu_inst); @@ -623,8 +603,6 @@ static int h264_enc_init(struct mtk_vcodec_ctx *ctx) else inst->vsi = (struct venc_h264_vsi *)inst->vpu_inst.vsi; - mtk_vcodec_debug_leave(inst); - if (ret) kfree(inst); else @@ -641,9 +619,9 @@ static int h264_enc_encode(void *handle, { int ret = 0; struct venc_h264_inst *inst = (struct venc_h264_inst *)handle; - struct mtk_vcodec_ctx *ctx = inst->ctx; + struct mtk_vcodec_enc_ctx *ctx = inst->ctx; - mtk_vcodec_debug(inst, "opt %d ->", opt); + mtk_venc_debug(ctx, "opt %d ->", opt); enable_irq(ctx->dev->enc_irq); @@ -678,7 +656,7 @@ static int h264_enc_encode(void *handle, break; } - mtk_vcodec_debug(inst, "h264_encode_frame prepend SPS/PPS"); + mtk_venc_debug(ctx, "h264_encode_frame prepend SPS/PPS"); ret = h264_encode_header(inst, bs_buf, &bs_size_hdr); if (ret) @@ -705,9 +683,8 @@ static int h264_enc_encode(void *handle, result->bs_size = hdr_sz + filler_sz + bs_size_frm; - mtk_vcodec_debug(inst, "hdr %d filler %d frame %d bs %d", - hdr_sz, filler_sz, bs_size_frm, - result->bs_size); + mtk_venc_debug(ctx, "hdr %d filler %d frame %d bs %d", + hdr_sz, filler_sz, bs_size_frm, result->bs_size); inst->prepend_hdr = 0; result->is_key_frm = inst->vpu_inst.is_key_frm; @@ -715,7 +692,7 @@ static int h264_enc_encode(void *handle, } default: - mtk_vcodec_err(inst, "venc_start_opt %d not supported", opt); + mtk_venc_err(ctx, "venc_start_opt %d not supported", opt); ret = -EINVAL; break; } @@ -723,7 +700,7 @@ static int h264_enc_encode(void *handle, encode_err: disable_irq(ctx->dev->enc_irq); - mtk_vcodec_debug(inst, "opt %d <-", opt); + mtk_venc_debug(ctx, "opt %d <-", opt); return ret; } @@ -772,10 +749,10 @@ static int h264_enc_set_param(void *handle, { int ret = 0; struct venc_h264_inst *inst = (struct venc_h264_inst *)handle; - struct mtk_vcodec_ctx *ctx = inst->ctx; + struct mtk_vcodec_enc_ctx *ctx = inst->ctx; const bool is_34bit = MTK_ENC_IOVA_IS_34BIT(ctx); - mtk_vcodec_debug(inst, "->type=%d", type); + mtk_venc_debug(ctx, "->type=%d", type); switch (type) { case VENC_SET_PARAM_ENC: @@ -798,7 +775,7 @@ static int h264_enc_set_param(void *handle, case VENC_SET_PARAM_PREPEND_HEADER: inst->prepend_hdr = 1; - mtk_vcodec_debug(inst, "set prepend header mode"); + mtk_venc_debug(ctx, "set prepend header mode"); break; case VENC_SET_PARAM_FORCE_INTRA: case VENC_SET_PARAM_GOP_SIZE: @@ -811,8 +788,6 @@ static int h264_enc_set_param(void *handle, break; } - mtk_vcodec_debug_leave(inst); - return ret; } @@ -821,14 +796,11 @@ static int h264_enc_deinit(void *handle) int ret = 0; struct venc_h264_inst *inst = (struct venc_h264_inst *)handle; - mtk_vcodec_debug_enter(inst); - ret = vpu_enc_deinit(&inst->vpu_inst); if (inst->work_buf_allocated) h264_enc_free_work_buf(inst); - mtk_vcodec_debug_leave(inst); kfree(inst); return ret; diff --git a/drivers/media/platform/mediatek/vcodec/venc/venc_vp8_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_vp8_if.c index 56ce58f761f1..05abca91e742 100644 --- a/drivers/media/platform/mediatek/vcodec/venc/venc_vp8_if.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_vp8_if.c @@ -9,9 +9,8 @@ #include <linux/kernel.h> #include <linux/slab.h> -#include "../mtk_vcodec_drv.h" -#include "../mtk_vcodec_util.h" -#include "../mtk_vcodec_intr.h" +#include "../mtk_vcodec_enc_drv.h" +#include "../../common/mtk_vcodec_intr.h" #include "../mtk_vcodec_enc.h" #include "../mtk_vcodec_enc_pm.h" #include "../venc_drv_base.h" @@ -129,7 +128,7 @@ struct venc_vp8_inst { unsigned int ts_mode; struct venc_vpu_inst vpu_inst; struct venc_vp8_vsi *vsi; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_enc_ctx *ctx; }; static inline u32 vp8_enc_read_reg(struct venc_vp8_inst *inst, u32 addr) @@ -141,16 +140,12 @@ static void vp8_enc_free_work_buf(struct venc_vp8_inst *inst) { int i; - mtk_vcodec_debug_enter(inst); - /* Buffers need to be freed by AP. */ for (i = 0; i < VENC_VP8_VPU_WORK_BUF_MAX; i++) { if (inst->work_bufs[i].size == 0) continue; mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]); } - - mtk_vcodec_debug_leave(inst); } static int vp8_enc_alloc_work_buf(struct venc_vp8_inst *inst) @@ -159,8 +154,6 @@ static int vp8_enc_alloc_work_buf(struct venc_vp8_inst *inst) int ret = 0; struct venc_vp8_vpu_buf *wb = inst->vsi->work_bufs; - mtk_vcodec_debug_enter(inst); - for (i = 0; i < VENC_VP8_VPU_WORK_BUF_MAX; i++) { if (wb[i].size == 0) continue; @@ -177,8 +170,7 @@ static int vp8_enc_alloc_work_buf(struct venc_vp8_inst *inst) inst->work_bufs[i].size = wb[i].size; ret = mtk_vcodec_mem_alloc(inst->ctx, &inst->work_bufs[i]); if (ret) { - mtk_vcodec_err(inst, - "cannot alloc work_bufs[%d]", i); + mtk_venc_err(inst->ctx, "cannot alloc work_bufs[%d]", i); goto err_alloc; } /* @@ -199,15 +191,12 @@ static int vp8_enc_alloc_work_buf(struct venc_vp8_inst *inst) } wb[i].iova = inst->work_bufs[i].dma_addr; - mtk_vcodec_debug(inst, - "work_bufs[%d] va=0x%p,iova=%pad,size=%zu", - i, inst->work_bufs[i].va, - &inst->work_bufs[i].dma_addr, - inst->work_bufs[i].size); + mtk_venc_debug(inst->ctx, "work_bufs[%d] va=0x%p,iova=%pad,size=%zu", + i, inst->work_bufs[i].va, + &inst->work_bufs[i].dma_addr, + inst->work_bufs[i].size); } - mtk_vcodec_debug_leave(inst); - return ret; err_alloc: @@ -219,12 +208,12 @@ err_alloc: static unsigned int vp8_enc_wait_venc_done(struct venc_vp8_inst *inst) { unsigned int irq_status = 0; - struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx; + struct mtk_vcodec_enc_ctx *ctx = (struct mtk_vcodec_enc_ctx *)inst->ctx; if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED, WAIT_INTR_TIMEOUT_MS, 0)) { irq_status = ctx->irq_status; - mtk_vcodec_debug(inst, "isr return %x", irq_status); + mtk_venc_debug(ctx, "isr return %x", irq_status); } return irq_status; } @@ -269,8 +258,7 @@ static int vp8_enc_compose_one_frame(struct venc_vp8_inst *inst, } if (bs_buf->size < bs_hdr_len + bs_frm_size + ac_tag_size) { - mtk_vcodec_err(inst, "bitstream buf size is too small(%zu)", - bs_buf->size); + mtk_venc_err(inst->ctx, "bitstream buf size is too small(%zu)", bs_buf->size); return -EINVAL; } @@ -300,7 +288,7 @@ static int vp8_enc_encode_frame(struct venc_vp8_inst *inst, int ret = 0; unsigned int irq_status; - mtk_vcodec_debug(inst, "->frm_cnt=%d", inst->frm_cnt); + mtk_venc_debug(inst->ctx, "->frm_cnt=%d", inst->frm_cnt); ret = vpu_enc_encode(&inst->vpu_inst, 0, frm_buf, bs_buf, NULL); if (ret) @@ -308,23 +296,22 @@ static int vp8_enc_encode_frame(struct venc_vp8_inst *inst, irq_status = vp8_enc_wait_venc_done(inst); if (irq_status != MTK_VENC_IRQ_STATUS_FRM) { - mtk_vcodec_err(inst, "irq_status=%d failed", irq_status); + mtk_venc_err(inst->ctx, "irq_status=%d failed", irq_status); return -EIO; } if (vp8_enc_compose_one_frame(inst, bs_buf, bs_size)) { - mtk_vcodec_err(inst, "vp8_enc_compose_one_frame failed"); + mtk_venc_err(inst->ctx, "vp8_enc_compose_one_frame failed"); return -EINVAL; } inst->frm_cnt++; - mtk_vcodec_debug(inst, "<-size=%d key_frm=%d", *bs_size, - inst->vpu_inst.is_key_frm); + mtk_venc_debug(inst->ctx, "<-size=%d key_frm=%d", *bs_size, inst->vpu_inst.is_key_frm); return ret; } -static int vp8_enc_init(struct mtk_vcodec_ctx *ctx) +static int vp8_enc_init(struct mtk_vcodec_enc_ctx *ctx) { int ret = 0; struct venc_vp8_inst *inst; @@ -336,16 +323,12 @@ static int vp8_enc_init(struct mtk_vcodec_ctx *ctx) inst->ctx = ctx; inst->vpu_inst.ctx = ctx; inst->vpu_inst.id = IPI_VENC_VP8; - inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx, VENC_LT_SYS); - - mtk_vcodec_debug_enter(inst); + inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx->dev->reg_base, VENC_LT_SYS); ret = vpu_enc_init(&inst->vpu_inst); inst->vsi = (struct venc_vp8_vsi *)inst->vpu_inst.vsi; - mtk_vcodec_debug_leave(inst); - if (ret) kfree(inst); else @@ -362,9 +345,7 @@ static int vp8_enc_encode(void *handle, { int ret = 0; struct venc_vp8_inst *inst = (struct venc_vp8_inst *)handle; - struct mtk_vcodec_ctx *ctx = inst->ctx; - - mtk_vcodec_debug_enter(inst); + struct mtk_vcodec_enc_ctx *ctx = inst->ctx; enable_irq(ctx->dev->enc_irq); @@ -378,7 +359,7 @@ static int vp8_enc_encode(void *handle, break; default: - mtk_vcodec_err(inst, "opt not support:%d", opt); + mtk_venc_err(ctx, "opt not support:%d", opt); ret = -EINVAL; break; } @@ -386,8 +367,6 @@ static int vp8_enc_encode(void *handle, encode_err: disable_irq(ctx->dev->enc_irq); - mtk_vcodec_debug_leave(inst); - return ret; } @@ -398,7 +377,7 @@ static int vp8_enc_set_param(void *handle, int ret = 0; struct venc_vp8_inst *inst = (struct venc_vp8_inst *)handle; - mtk_vcodec_debug(inst, "->type=%d", type); + mtk_venc_debug(inst->ctx, "->type=%d", type); switch (type) { case VENC_SET_PARAM_ENC: @@ -429,7 +408,7 @@ static int vp8_enc_set_param(void *handle, */ case VENC_SET_PARAM_TS_MODE: inst->ts_mode = 1; - mtk_vcodec_debug(inst, "set ts_mode"); + mtk_venc_debug(inst->ctx, "set ts_mode"); break; default: @@ -437,8 +416,6 @@ static int vp8_enc_set_param(void *handle, break; } - mtk_vcodec_debug_leave(inst); - return ret; } @@ -447,16 +424,12 @@ static int vp8_enc_deinit(void *handle) int ret = 0; struct venc_vp8_inst *inst = (struct venc_vp8_inst *)handle; - mtk_vcodec_debug_enter(inst); - ret = vpu_enc_deinit(&inst->vpu_inst); if (inst->work_buf_allocated) vp8_enc_free_work_buf(inst); - mtk_vcodec_debug_leave(inst); kfree(inst); - return ret; } diff --git a/drivers/media/platform/mediatek/vcodec/venc_drv_base.h b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_base.h index 3d718411dc73..856d50151bf6 100644 --- a/drivers/media/platform/mediatek/vcodec/venc_drv_base.h +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_base.h @@ -9,7 +9,7 @@ #ifndef _VENC_DRV_BASE_ #define _VENC_DRV_BASE_ -#include "mtk_vcodec_drv.h" +#include "mtk_vcodec_enc_drv.h" #include "venc_drv_if.h" @@ -19,7 +19,7 @@ struct venc_common_if { * @ctx: [in] mtk v4l2 context * @handle: [out] driver handle */ - int (*init)(struct mtk_vcodec_ctx *ctx); + int (*init)(struct mtk_vcodec_enc_ctx *ctx); /** * (*encode)() - trigger encode diff --git a/drivers/media/platform/mediatek/vcodec/venc_drv_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c index ce0bce811615..1bdaecdd64a7 100644 --- a/drivers/media/platform/mediatek/vcodec/venc_drv_if.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c @@ -16,7 +16,7 @@ #include "mtk_vcodec_enc.h" #include "mtk_vcodec_enc_pm.h" -int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) +int venc_if_init(struct mtk_vcodec_enc_ctx *ctx, unsigned int fourcc) { int ret = 0; @@ -40,8 +40,8 @@ int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) return ret; } -int venc_if_set_param(struct mtk_vcodec_ctx *ctx, - enum venc_set_param_type type, struct venc_enc_param *in) +int venc_if_set_param(struct mtk_vcodec_enc_ctx *ctx, + enum venc_set_param_type type, struct venc_enc_param *in) { int ret = 0; @@ -54,7 +54,7 @@ int venc_if_set_param(struct mtk_vcodec_ctx *ctx, return ret; } -int venc_if_encode(struct mtk_vcodec_ctx *ctx, +int venc_if_encode(struct mtk_vcodec_enc_ctx *ctx, enum venc_start_opt opt, struct venc_frm_buf *frm_buf, struct mtk_vcodec_mem *bs_buf, struct venc_done_result *result) @@ -81,7 +81,7 @@ int venc_if_encode(struct mtk_vcodec_ctx *ctx, return ret; } -int venc_if_deinit(struct mtk_vcodec_ctx *ctx) +int venc_if_deinit(struct mtk_vcodec_enc_ctx *ctx) { int ret = 0; diff --git a/drivers/media/platform/mediatek/vcodec/venc_drv_if.h b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.h index 0b04a1020873..d00fb68b8235 100644 --- a/drivers/media/platform/mediatek/vcodec/venc_drv_if.h +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.h @@ -9,8 +9,7 @@ #ifndef _VENC_DRV_IF_H_ #define _VENC_DRV_IF_H_ -#include "mtk_vcodec_drv.h" -#include "mtk_vcodec_util.h" +#include "mtk_vcodec_enc_drv.h" /* * enum venc_yuv_fmt - The type of input yuv format @@ -132,14 +131,14 @@ extern const struct venc_common_if venc_vp8_if; * @fourcc: encoder input format * Return: 0 if creating handle successfully, otherwise it is failed. */ -int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc); +int venc_if_init(struct mtk_vcodec_enc_ctx *ctx, unsigned int fourcc); /* * venc_if_deinit - Release the driver handle * @ctx: device context * Return: 0 if releasing handle successfully, otherwise it is failed. */ -int venc_if_deinit(struct mtk_vcodec_ctx *ctx); +int venc_if_deinit(struct mtk_vcodec_enc_ctx *ctx); /* * venc_if_set_param - Set parameter to driver @@ -148,7 +147,7 @@ int venc_if_deinit(struct mtk_vcodec_ctx *ctx); * @in: input parameter * Return: 0 if setting param successfully, otherwise it is failed. */ -int venc_if_set_param(struct mtk_vcodec_ctx *ctx, +int venc_if_set_param(struct mtk_vcodec_enc_ctx *ctx, enum venc_set_param_type type, struct venc_enc_param *in); @@ -161,7 +160,7 @@ int venc_if_set_param(struct mtk_vcodec_ctx *ctx, * @result: encode result * Return: 0 if encoding frame successfully, otherwise it is failed. */ -int venc_if_encode(struct mtk_vcodec_ctx *ctx, +int venc_if_encode(struct mtk_vcodec_enc_ctx *ctx, enum venc_start_opt opt, struct venc_frm_buf *frm_buf, struct mtk_vcodec_mem *bs_buf, diff --git a/drivers/media/platform/mediatek/vcodec/venc_ipi_msg.h b/drivers/media/platform/mediatek/vcodec/encoder/venc_ipi_msg.h index bb16d96a7f57..bb16d96a7f57 100644 --- a/drivers/media/platform/mediatek/vcodec/venc_ipi_msg.h +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_ipi_msg.h diff --git a/drivers/media/platform/mediatek/vcodec/venc_vpu_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c index 09e7eaa25aab..d299cc2962a5 100644 --- a/drivers/media/platform/mediatek/vcodec/venc_vpu_if.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c @@ -4,8 +4,7 @@ * Author: PoChun Lin <pochun.lin@mediatek.com> */ -#include "mtk_vcodec_drv.h" -#include "mtk_vcodec_fw.h" +#include "mtk_vcodec_enc_drv.h" #include "venc_ipi_msg.h" #include "venc_vpu_if.h" @@ -22,14 +21,13 @@ static void handle_enc_init_msg(struct venc_vpu_inst *vpu, const void *data) return; /* Check firmware version. */ - mtk_vcodec_debug(vpu, "firmware version: 0x%x\n", - msg->venc_abi_version); + mtk_venc_debug(vpu->ctx, "firmware version: 0x%x\n", msg->venc_abi_version); switch (msg->venc_abi_version) { case 1: break; default: - mtk_vcodec_err(vpu, "unhandled firmware version 0x%x\n", - msg->venc_abi_version); + mtk_venc_err(vpu->ctx, "unhandled firmware version 0x%x\n", + msg->venc_abi_version); vpu->failure = 1; break; } @@ -44,19 +42,47 @@ static void handle_enc_encode_msg(struct venc_vpu_inst *vpu, const void *data) vpu->is_key_frm = msg->is_key_frm; } +static bool vpu_enc_check_ap_inst(struct mtk_vcodec_enc_dev *enc_dev, struct venc_vpu_inst *vpu) +{ + struct mtk_vcodec_enc_ctx *ctx; + int ret = false; + + list_for_each_entry(ctx, &enc_dev->ctx_list, list) { + if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) { + ret = true; + break; + } + } + + return ret; +} + static void vpu_enc_ipi_handler(void *data, unsigned int len, void *priv) { + struct mtk_vcodec_enc_dev *enc_dev; const struct venc_vpu_ipi_msg_common *msg = data; - struct venc_vpu_inst *vpu = - (struct venc_vpu_inst *)(unsigned long)msg->venc_inst; + struct venc_vpu_inst *vpu; - mtk_vcodec_debug(vpu, "msg_id %x inst %p status %d", - msg->msg_id, vpu, msg->status); + enc_dev = (struct mtk_vcodec_enc_dev *)priv; + vpu = (struct venc_vpu_inst *)(unsigned long)msg->venc_inst; + if (!priv || !vpu) { + pr_err(MTK_DBG_V4L2_STR "venc_inst is NULL, did the SCP hang or crash?"); + return; + } + + mtk_venc_debug(vpu->ctx, "msg_id %x inst %p status %d", msg->msg_id, vpu, msg->status); + if (!vpu_enc_check_ap_inst(enc_dev, vpu) || msg->msg_id < VPU_IPIMSG_ENC_INIT_DONE || + msg->msg_id > VPU_IPIMSG_ENC_DEINIT_DONE) { + mtk_v4l2_venc_err(vpu->ctx, "venc msg id not correctly => 0x%x", msg->msg_id); + vpu->failure = -EINVAL; + goto error; + } - vpu->signaled = 1; vpu->failure = (msg->status != VENC_IPI_MSG_STATUS_OK); - if (vpu->failure) - goto failure; + if (vpu->failure) { + mtk_venc_err(vpu->ctx, "vpu enc status failure %d", vpu->failure); + goto error; + } switch (msg->msg_id) { case VPU_IPIMSG_ENC_INIT_DONE: @@ -70,12 +96,12 @@ static void vpu_enc_ipi_handler(void *data, unsigned int len, void *priv) case VPU_IPIMSG_ENC_DEINIT_DONE: break; default: - mtk_vcodec_err(vpu, "unknown msg id %x", msg->msg_id); + mtk_venc_err(vpu->ctx, "unknown msg id %x", msg->msg_id); break; } -failure: - mtk_vcodec_debug_leave(vpu); +error: + vpu->signaled = 1; } static int vpu_enc_send_msg(struct venc_vpu_inst *vpu, void *msg, @@ -83,25 +109,21 @@ static int vpu_enc_send_msg(struct venc_vpu_inst *vpu, void *msg, { int status; - mtk_vcodec_debug_enter(vpu); - if (!vpu->ctx->dev->fw_handler) { - mtk_vcodec_err(vpu, "inst dev is NULL"); + mtk_venc_err(vpu->ctx, "inst dev is NULL"); return -EINVAL; } status = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, vpu->id, msg, len, 2000); if (status) { - mtk_vcodec_err(vpu, "vpu_ipi_send msg_id %x len %d fail %d", - *(uint32_t *)msg, len, status); + mtk_venc_err(vpu->ctx, "vpu_ipi_send msg_id %x len %d fail %d", + *(uint32_t *)msg, len, status); return -EINVAL; } if (vpu->failure) return -EINVAL; - mtk_vcodec_debug_leave(vpu); - return 0; } @@ -110,17 +132,16 @@ int vpu_enc_init(struct venc_vpu_inst *vpu) int status; struct venc_ap_ipi_msg_init out; - mtk_vcodec_debug_enter(vpu); - init_waitqueue_head(&vpu->wq_hd); vpu->signaled = 0; vpu->failure = 0; + vpu->ctx->vpu_inst = vpu; status = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler, vpu->id, vpu_enc_ipi_handler, "venc", NULL); if (status) { - mtk_vcodec_err(vpu, "vpu_ipi_register fail %d", status); + mtk_venc_err(vpu->ctx, "vpu_ipi_register fail %d", status); return -EINVAL; } @@ -128,12 +149,10 @@ int vpu_enc_init(struct venc_vpu_inst *vpu) out.msg_id = AP_IPIMSG_ENC_INIT; out.venc_inst = (unsigned long)vpu; if (vpu_enc_send_msg(vpu, &out, sizeof(out))) { - mtk_vcodec_err(vpu, "AP_IPIMSG_ENC_INIT fail"); + mtk_venc_err(vpu->ctx, "AP_IPIMSG_ENC_INIT fail"); return -EINVAL; } - mtk_vcodec_debug_leave(vpu); - return 0; } @@ -166,7 +185,7 @@ int vpu_enc_set_param(struct venc_vpu_inst *vpu, sizeof(struct venc_ap_ipi_msg_set_param); struct venc_ap_ipi_msg_set_param_ext out; - mtk_vcodec_debug(vpu, "id %d ->", id); + mtk_venc_debug(vpu->ctx, "id %d ->", id); memset(&out, 0, sizeof(out)); out.base.msg_id = AP_IPIMSG_ENC_SET_PARAM; @@ -208,16 +227,15 @@ int vpu_enc_set_param(struct venc_vpu_inst *vpu, out.base.data_item = 0; break; default: - mtk_vcodec_err(vpu, "id %d not supported", id); + mtk_venc_err(vpu->ctx, "id %d not supported", id); return -EINVAL; } if (vpu_enc_send_msg(vpu, &out, msg_size)) { - mtk_vcodec_err(vpu, - "AP_IPIMSG_ENC_SET_PARAM %d fail", id); + mtk_venc_err(vpu->ctx, "AP_IPIMSG_ENC_SET_PARAM %d fail", id); return -EINVAL; } - mtk_vcodec_debug(vpu, "id %d <-", id); + mtk_venc_debug(vpu->ctx, "id %d <-", id); return 0; } @@ -234,7 +252,7 @@ static int vpu_enc_encode_32bits(struct venc_vpu_inst *vpu, sizeof(struct venc_ap_ipi_msg_enc); struct venc_ap_ipi_msg_enc_ext out; - mtk_vcodec_debug(vpu, "bs_mode %d ->", bs_mode); + mtk_venc_debug(vpu->ctx, "bs_mode %d ->", bs_mode); memset(&out, 0, sizeof(out)); out.base.msg_id = AP_IPIMSG_ENC_ENCODE; @@ -248,7 +266,7 @@ static int vpu_enc_encode_32bits(struct venc_vpu_inst *vpu, out.base.input_addr[1] = frm_buf->fb_addr[1].dma_addr; out.base.input_addr[2] = frm_buf->fb_addr[2].dma_addr; } else { - mtk_vcodec_err(vpu, "dma_addr not align to 16"); + mtk_venc_err(vpu->ctx, "dma_addr not align to 16"); return -EINVAL; } } @@ -263,8 +281,7 @@ static int vpu_enc_encode_32bits(struct venc_vpu_inst *vpu, out.data[2] = frame_info->frm_type; } if (vpu_enc_send_msg(vpu, &out, msg_size)) { - mtk_vcodec_err(vpu, "AP_IPIMSG_ENC_ENCODE %d fail", - bs_mode); + mtk_venc_err(vpu->ctx, "AP_IPIMSG_ENC_ENCODE %d fail", bs_mode); return -EINVAL; } @@ -280,7 +297,7 @@ static int vpu_enc_encode_34bits(struct venc_vpu_inst *vpu, struct venc_ap_ipi_msg_enc_ext_34 out; size_t msg_size = sizeof(struct venc_ap_ipi_msg_enc_ext_34); - mtk_vcodec_debug(vpu, "bs_mode %d ->", bs_mode); + mtk_venc_debug(vpu->ctx, "bs_mode %d ->", bs_mode); memset(&out, 0, sizeof(out)); out.msg_id = AP_IPIMSG_ENC_ENCODE; @@ -295,7 +312,7 @@ static int vpu_enc_encode_34bits(struct venc_vpu_inst *vpu, out.input_addr[1] = frm_buf->fb_addr[1].dma_addr; out.input_addr[2] = frm_buf->fb_addr[2].dma_addr; } else { - mtk_vcodec_err(vpu, "dma_addr not align to 16"); + mtk_venc_err(vpu->ctx, "dma_addr not align to 16"); return -EINVAL; } } @@ -310,8 +327,7 @@ static int vpu_enc_encode_34bits(struct venc_vpu_inst *vpu, out.data[2] = frame_info->frm_type; } if (vpu_enc_send_msg(vpu, &out, msg_size)) { - mtk_vcodec_err(vpu, "AP_IPIMSG_ENC_ENCODE %d fail", - bs_mode); + mtk_venc_err(vpu->ctx, "AP_IPIMSG_ENC_ENCODE %d fail", bs_mode); return -EINVAL; } @@ -335,8 +351,8 @@ int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode, if (ret) return ret; - mtk_vcodec_debug(vpu, "bs_mode %d state %d size %d key_frm %d <-", - bs_mode, vpu->state, vpu->bs_size, vpu->is_key_frm); + mtk_venc_debug(vpu->ctx, "bs_mode %d state %d size %d key_frm %d <-", + bs_mode, vpu->state, vpu->bs_size, vpu->is_key_frm); return 0; } @@ -345,17 +361,13 @@ int vpu_enc_deinit(struct venc_vpu_inst *vpu) { struct venc_ap_ipi_msg_deinit out; - mtk_vcodec_debug_enter(vpu); - memset(&out, 0, sizeof(out)); out.msg_id = AP_IPIMSG_ENC_DEINIT; out.vpu_inst_addr = vpu->inst_addr; if (vpu_enc_send_msg(vpu, &out, sizeof(out))) { - mtk_vcodec_err(vpu, "AP_IPIMSG_ENC_DEINIT fail"); + mtk_venc_err(vpu->ctx, "AP_IPIMSG_ENC_DEINIT fail"); return -EINVAL; } - mtk_vcodec_debug_leave(vpu); - return 0; } diff --git a/drivers/media/platform/mediatek/vcodec/venc_vpu_if.h b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.h index f83bc1b3f2bf..ede55fc3bd07 100644 --- a/drivers/media/platform/mediatek/vcodec/venc_vpu_if.h +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.h @@ -7,7 +7,6 @@ #ifndef _VENC_VPU_IF_H_ #define _VENC_VPU_IF_H_ -#include "mtk_vcodec_fw.h" #include "venc_drv_if.h" /* @@ -35,7 +34,7 @@ struct venc_vpu_inst { unsigned int inst_addr; void *vsi; int id; - struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_enc_ctx *ctx; }; int vpu_enc_init(struct venc_vpu_inst *vpu); diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h deleted file mode 100644 index f17d67e781c9..000000000000 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h +++ /dev/null @@ -1,548 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* -* Copyright (c) 2016 MediaTek Inc. -* Author: PC Chen <pc.chen@mediatek.com> -* Tiffany Lin <tiffany.lin@mediatek.com> -*/ - -#ifndef _MTK_VCODEC_DRV_H_ -#define _MTK_VCODEC_DRV_H_ - -#include <linux/platform_device.h> -#include <linux/videodev2.h> -#include <media/v4l2-ctrls.h> -#include <media/v4l2-device.h> -#include <media/v4l2-ioctl.h> -#include <media/v4l2-mem2mem.h> -#include <media/videobuf2-core.h> - -#include "mtk_vcodec_dbgfs.h" -#include "mtk_vcodec_util.h" -#include "vdec_msg_queue.h" - -#define MTK_VCODEC_DEC_NAME "mtk-vcodec-dec" -#define MTK_VCODEC_ENC_NAME "mtk-vcodec-enc" - -#define MTK_VCODEC_MAX_PLANES 3 -#define MTK_V4L2_BENCHMARK 0 -#define WAIT_INTR_TIMEOUT_MS 1000 -#define IS_VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE) -#define IS_VDEC_INNER_RACING(capability) ((capability) & MTK_VCODEC_INNER_RACING) - -/* - * enum mtk_hw_reg_idx - MTK hw register base index - */ -enum mtk_hw_reg_idx { - VDEC_SYS, - VDEC_MISC, - VDEC_LD, - VDEC_TOP, - VDEC_CM, - VDEC_AD, - VDEC_AV, - VDEC_PP, - VDEC_HWD, - VDEC_HWQ, - VDEC_HWB, - VDEC_HWG, - NUM_MAX_VDEC_REG_BASE, - /* h264 encoder */ - VENC_SYS = NUM_MAX_VDEC_REG_BASE, - /* vp8 encoder */ - VENC_LT_SYS, - NUM_MAX_VCODEC_REG_BASE -}; - -/* - * enum mtk_instance_type - The type of an MTK Vcodec instance. - */ -enum mtk_instance_type { - MTK_INST_DECODER = 0, - MTK_INST_ENCODER = 1, -}; - -/** - * enum mtk_instance_state - The state of an MTK Vcodec instance. - * @MTK_STATE_FREE: default state when instance is created - * @MTK_STATE_INIT: vcodec instance is initialized - * @MTK_STATE_HEADER: vdec had sps/pps header parsed or venc - * had sps/pps header encoded - * @MTK_STATE_FLUSH: vdec is flushing. Only used by decoder - * @MTK_STATE_ABORT: vcodec should be aborted - */ -enum mtk_instance_state { - MTK_STATE_FREE = 0, - MTK_STATE_INIT = 1, - MTK_STATE_HEADER = 2, - MTK_STATE_FLUSH = 3, - MTK_STATE_ABORT = 4, -}; - -/* - * enum mtk_encode_param - General encoding parameters type - */ -enum mtk_encode_param { - MTK_ENCODE_PARAM_NONE = 0, - MTK_ENCODE_PARAM_BITRATE = (1 << 0), - MTK_ENCODE_PARAM_FRAMERATE = (1 << 1), - MTK_ENCODE_PARAM_INTRA_PERIOD = (1 << 2), - MTK_ENCODE_PARAM_FORCE_INTRA = (1 << 3), - MTK_ENCODE_PARAM_GOP_SIZE = (1 << 4), -}; - -enum mtk_fmt_type { - MTK_FMT_DEC = 0, - MTK_FMT_ENC = 1, - MTK_FMT_FRAME = 2, -}; - -/* - * enum mtk_vdec_hw_id - Hardware index used to separate - * different hardware - */ -enum mtk_vdec_hw_id { - MTK_VDEC_CORE, - MTK_VDEC_LAT0, - MTK_VDEC_LAT1, - MTK_VDEC_LAT_SOC, - MTK_VDEC_HW_MAX, -}; - -/* - * enum mtk_vdec_hw_count - Supported hardware count - */ -enum mtk_vdec_hw_count { - MTK_VDEC_NO_HW = 0, - MTK_VDEC_ONE_CORE, - MTK_VDEC_ONE_LAT_ONE_CORE, - MTK_VDEC_MAX_HW_COUNT, -}; - -/* - * struct mtk_video_fmt - Structure used to store information about pixelformats - */ -struct mtk_video_fmt { - u32 fourcc; - enum mtk_fmt_type type; - u32 num_planes; - u32 flags; - struct v4l2_frmsize_stepwise frmsize; -}; - -/* - * enum mtk_q_type - Type of queue - */ -enum mtk_q_type { - MTK_Q_DATA_SRC = 0, - MTK_Q_DATA_DST = 1, -}; - -/* - * struct mtk_q_data - Structure used to store information about queue - */ -struct mtk_q_data { - unsigned int visible_width; - unsigned int visible_height; - unsigned int coded_width; - unsigned int coded_height; - enum v4l2_field field; - unsigned int bytesperline[MTK_VCODEC_MAX_PLANES]; - unsigned int sizeimage[MTK_VCODEC_MAX_PLANES]; - const struct mtk_video_fmt *fmt; -}; - -/** - * struct mtk_enc_params - General encoding parameters - * @bitrate: target bitrate in bits per second - * @num_b_frame: number of b frames between p-frame - * @rc_frame: frame based rate control - * @rc_mb: macroblock based rate control - * @seq_hdr_mode: H.264 sequence header is encoded separately or joined - * with the first frame - * @intra_period: I frame period - * @gop_size: group of picture size, it's used as the intra frame period - * @framerate_num: frame rate numerator. ex: framerate_num=30 and - * framerate_denom=1 means FPS is 30 - * @framerate_denom: frame rate denominator. ex: framerate_num=30 and - * framerate_denom=1 means FPS is 30 - * @h264_max_qp: Max value for H.264 quantization parameter - * @h264_profile: V4L2 defined H.264 profile - * @h264_level: V4L2 defined H.264 level - * @force_intra: force/insert intra frame - */ -struct mtk_enc_params { - unsigned int bitrate; - unsigned int num_b_frame; - unsigned int rc_frame; - unsigned int rc_mb; - unsigned int seq_hdr_mode; - unsigned int intra_period; - unsigned int gop_size; - unsigned int framerate_num; - unsigned int framerate_denom; - unsigned int h264_max_qp; - unsigned int h264_profile; - unsigned int h264_level; - unsigned int force_intra; -}; - -/* - * struct mtk_vcodec_clk_info - Structure used to store clock name - */ -struct mtk_vcodec_clk_info { - const char *clk_name; - struct clk *vcodec_clk; -}; - -/* - * struct mtk_vcodec_clk - Structure used to store vcodec clock information - */ -struct mtk_vcodec_clk { - struct mtk_vcodec_clk_info *clk_info; - int clk_num; -}; - -/* - * struct mtk_vcodec_pm - Power management data structure - */ -struct mtk_vcodec_pm { - struct mtk_vcodec_clk vdec_clk; - struct mtk_vcodec_clk venc_clk; - struct device *dev; -}; - -/** - * struct vdec_pic_info - picture size information - * @pic_w: picture width - * @pic_h: picture height - * @buf_w: picture buffer width (64 aligned up from pic_w) - * @buf_h: picture buffer heiht (64 aligned up from pic_h) - * @fb_sz: bitstream size of each plane - * E.g. suppose picture size is 176x144, - * buffer size will be aligned to 176x160. - * @cap_fourcc: fourcc number(may changed when resolution change) - * @reserved: align struct to 64-bit in order to adjust 32-bit and 64-bit os. - */ -struct vdec_pic_info { - unsigned int pic_w; - unsigned int pic_h; - unsigned int buf_w; - unsigned int buf_h; - unsigned int fb_sz[VIDEO_MAX_PLANES]; - unsigned int cap_fourcc; - unsigned int reserved; -}; - -/** - * struct mtk_vcodec_ctx - Context (instance) private data. - * - * @type: type of the instance - decoder or encoder - * @dev: pointer to the mtk_vcodec_dev of the device - * @list: link to ctx_list of mtk_vcodec_dev - * @fh: struct v4l2_fh - * @m2m_ctx: pointer to the v4l2_m2m_ctx of the context - * @q_data: store information of input and output queue - * of the context - * @id: index of the context that this structure describes - * @state: state of the context - * @param_change: indicate encode parameter type - * @enc_params: encoding parameters - * @dec_if: hooked decoder driver interface - * @enc_if: hooked encoder driver interface - * @drv_handle: driver handle for specific decode/encode instance - * - * @picinfo: store picture info after header parsing - * @dpb_size: store dpb count after header parsing - * @int_cond: variable used by the waitqueue - * @int_type: type of the last interrupt - * @queue: waitqueue that can be used to wait for this context to - * finish - * @irq_status: irq status - * - * @ctrl_hdl: handler for v4l2 framework - * @decode_work: worker for the decoding - * @encode_work: worker for the encoding - * @last_decoded_picinfo: pic information get from latest decode - * @empty_flush_buf: a fake size-0 capture buffer that indicates flush. Only - * to be used with encoder and stateful decoder. - * @is_flushing: set to true if flushing is in progress. - * @current_codec: current set input codec, in V4L2 pixel format - * @capture_fourcc: capture queue type in V4L2 pixel format - * - * @colorspace: enum v4l2_colorspace; supplemental to pixelformat - * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding - * @quantization: enum v4l2_quantization, colorspace quantization - * @xfer_func: enum v4l2_xfer_func, colorspace transfer function - * @decoded_frame_cnt: number of decoded frames - * @lock: protect variables accessed by V4L2 threads and worker thread such as - * mtk_video_dec_buf. - * @hw_id: hardware index used to identify different hardware. - * - * @msg_queue: msg queue used to store lat buffer information. - * @q_mutex: vb2_queue mutex. - */ -struct mtk_vcodec_ctx { - enum mtk_instance_type type; - struct mtk_vcodec_dev *dev; - struct list_head list; - - struct v4l2_fh fh; - struct v4l2_m2m_ctx *m2m_ctx; - struct mtk_q_data q_data[2]; - int id; - enum mtk_instance_state state; - enum mtk_encode_param param_change; - struct mtk_enc_params enc_params; - - const struct vdec_common_if *dec_if; - const struct venc_common_if *enc_if; - void *drv_handle; - - struct vdec_pic_info picinfo; - int dpb_size; - - int int_cond[MTK_VDEC_HW_MAX]; - int int_type[MTK_VDEC_HW_MAX]; - wait_queue_head_t queue[MTK_VDEC_HW_MAX]; - unsigned int irq_status; - - struct v4l2_ctrl_handler ctrl_hdl; - struct work_struct decode_work; - struct work_struct encode_work; - struct vdec_pic_info last_decoded_picinfo; - struct v4l2_m2m_buffer empty_flush_buf; - bool is_flushing; - - u32 current_codec; - u32 capture_fourcc; - - enum v4l2_colorspace colorspace; - enum v4l2_ycbcr_encoding ycbcr_enc; - enum v4l2_quantization quantization; - enum v4l2_xfer_func xfer_func; - - int decoded_frame_cnt; - struct mutex lock; - int hw_id; - - struct vdec_msg_queue msg_queue; - - struct mutex q_mutex; -}; - -/* - * enum mtk_vdec_hw_arch - Used to separate different hardware architecture - */ -enum mtk_vdec_hw_arch { - MTK_VDEC_PURE_SINGLE_CORE, - MTK_VDEC_LAT_SINGLE_CORE, -}; - -/* - * struct mtk_vdec_format_types - Structure used to get supported - * format types according to decoder capability - */ -enum mtk_vdec_format_types { - MTK_VDEC_FORMAT_MM21 = 0x20, - MTK_VDEC_FORMAT_MT21C = 0x40, - MTK_VDEC_FORMAT_H264_SLICE = 0x100, - MTK_VDEC_FORMAT_VP8_FRAME = 0x200, - MTK_VDEC_FORMAT_VP9_FRAME = 0x400, - MTK_VDEC_FORMAT_AV1_FRAME = 0x800, - MTK_VDEC_FORMAT_HEVC_FRAME = 0x1000, - MTK_VCODEC_INNER_RACING = 0x20000, -}; - -/** - * struct mtk_vcodec_dec_pdata - compatible data for each IC - * @init_vdec_params: init vdec params - * @ctrls_setup: init vcodec dec ctrls - * @worker: worker to start a decode job - * @flush_decoder: function that flushes the decoder - * @get_cap_buffer: get capture buffer from capture queue - * @cap_to_disp: put capture buffer to disp list for lat and core arch - * @vdec_vb2_ops: struct vb2_ops - * - * @vdec_formats: supported video decoder formats - * @num_formats: count of video decoder formats - * @default_out_fmt: default output buffer format - * @default_cap_fmt: default capture buffer format - * - * @hw_arch: hardware arch is used to separate pure_sin_core and lat_sin_core - * - * @is_subdev_supported: whether support parent-node architecture(subdev) - * @uses_stateless_api: whether the decoder uses the stateless API with requests - */ - -struct mtk_vcodec_dec_pdata { - void (*init_vdec_params)(struct mtk_vcodec_ctx *ctx); - int (*ctrls_setup)(struct mtk_vcodec_ctx *ctx); - void (*worker)(struct work_struct *work); - int (*flush_decoder)(struct mtk_vcodec_ctx *ctx); - struct vdec_fb *(*get_cap_buffer)(struct mtk_vcodec_ctx *ctx); - void (*cap_to_disp)(struct mtk_vcodec_ctx *ctx, int error, - struct media_request *src_buf_req); - - struct vb2_ops *vdec_vb2_ops; - - const struct mtk_video_fmt *vdec_formats; - const int *num_formats; - const struct mtk_video_fmt *default_out_fmt; - const struct mtk_video_fmt *default_cap_fmt; - - enum mtk_vdec_hw_arch hw_arch; - - bool is_subdev_supported; - bool uses_stateless_api; -}; - -/** - * struct mtk_vcodec_enc_pdata - compatible data for each IC - * - * @uses_ext: whether the encoder uses the extended firmware messaging format - * @min_bitrate: minimum supported encoding bitrate - * @max_bitrate: maximum supported encoding bitrate - * @capture_formats: array of supported capture formats - * @num_capture_formats: number of entries in capture_formats - * @output_formats: array of supported output formats - * @num_output_formats: number of entries in output_formats - * @core_id: stand for h264 or vp8 encode index - * @uses_34bit: whether the encoder uses 34-bit iova - */ -struct mtk_vcodec_enc_pdata { - bool uses_ext; - unsigned long min_bitrate; - unsigned long max_bitrate; - const struct mtk_video_fmt *capture_formats; - size_t num_capture_formats; - const struct mtk_video_fmt *output_formats; - size_t num_output_formats; - int core_id; - bool uses_34bit; -}; - -#define MTK_ENC_CTX_IS_EXT(ctx) ((ctx)->dev->venc_pdata->uses_ext) -#define MTK_ENC_IOVA_IS_34BIT(ctx) ((ctx)->dev->venc_pdata->uses_34bit) - -/** - * struct mtk_vcodec_dev - driver data - * @v4l2_dev: V4L2 device to register video devices for. - * @vfd_dec: Video device for decoder - * @mdev_dec: Media device for decoder - * @vfd_enc: Video device for encoder. - * - * @m2m_dev_dec: m2m device for decoder - * @m2m_dev_enc: m2m device for encoder. - * @plat_dev: platform device - * @ctx_list: list of struct mtk_vcodec_ctx - * @irqlock: protect data access by irq handler and work thread - * @curr_ctx: The context that is waiting for codec hardware - * - * @reg_base: Mapped address of MTK Vcodec registers. - * @vdec_pdata: decoder IC-specific data - * @venc_pdata: encoder IC-specific data - * - * @fw_handler: used to communicate with the firmware. - * @id_counter: used to identify current opened instance - * - * @decode_workqueue: decode work queue - * @encode_workqueue: encode work queue - * - * @int_cond: used to identify interrupt condition happen - * @int_type: used to identify what kind of interrupt condition happen - * @dev_mutex: video_device lock - * @queue: waitqueue for waiting for completion of device commands - * - * @dec_irq: decoder irq resource - * @enc_irq: h264 encoder irq resource - * - * @dec_mutex: decoder hardware lock - * @enc_mutex: encoder hardware lock. - * - * @pm: power management control - * @dec_capability: used to identify decode capability, ex: 4k - * @enc_capability: used to identify encode capability - * - * @core_workqueue: queue used for core hardware decode - * - * @subdev_dev: subdev hardware device - * @subdev_prob_done: check whether all used hw device is prob done - * @subdev_bitmap: used to record hardware is ready or not - * - * @dec_active_cnt: used to mark whether need to record register value - * @vdec_racing_info: record register value - * @dec_racing_info_mutex: mutex lock used for inner racing mode - * @dbgfs: debug log related information - */ -struct mtk_vcodec_dev { - struct v4l2_device v4l2_dev; - struct video_device *vfd_dec; - struct media_device mdev_dec; - struct video_device *vfd_enc; - - struct v4l2_m2m_dev *m2m_dev_dec; - struct v4l2_m2m_dev *m2m_dev_enc; - struct platform_device *plat_dev; - struct list_head ctx_list; - spinlock_t irqlock; - struct mtk_vcodec_ctx *curr_ctx; - void __iomem *reg_base[NUM_MAX_VCODEC_REG_BASE]; - const struct mtk_vcodec_dec_pdata *vdec_pdata; - const struct mtk_vcodec_enc_pdata *venc_pdata; - - struct mtk_vcodec_fw *fw_handler; - - unsigned long id_counter; - - struct workqueue_struct *decode_workqueue; - struct workqueue_struct *encode_workqueue; - int int_cond; - int int_type; - struct mutex dev_mutex; - wait_queue_head_t queue; - - int dec_irq; - int enc_irq; - - /* decoder hardware mutex lock */ - struct mutex dec_mutex[MTK_VDEC_HW_MAX]; - struct mutex enc_mutex; - - struct mtk_vcodec_pm pm; - unsigned int dec_capability; - unsigned int enc_capability; - - struct workqueue_struct *core_workqueue; - - void *subdev_dev[MTK_VDEC_HW_MAX]; - int (*subdev_prob_done)(struct mtk_vcodec_dev *vdec_dev); - DECLARE_BITMAP(subdev_bitmap, MTK_VDEC_HW_MAX); - - atomic_t dec_active_cnt; - u32 vdec_racing_info[132]; - /* Protects access to vdec_racing_info data */ - struct mutex dec_racing_info_mutex; - - struct mtk_vcodec_dbgfs dbgfs; -}; - -static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh) -{ - return container_of(fh, struct mtk_vcodec_ctx, fh); -} - -static inline struct mtk_vcodec_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl) -{ - return container_of(ctrl->handler, struct mtk_vcodec_ctx, ctrl_hdl); -} - -/* Wake up context wait_queue */ -static inline void -wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason, unsigned int hw_id) -{ - ctx->int_cond[hw_id] = 1; - ctx->int_type[hw_id] = reason; - wake_up_interruptible(&ctx->queue[hw_id]); -} - -#endif /* _MTK_VCODEC_DRV_H_ */ diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_intr.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_intr.c deleted file mode 100644 index 552b4c93d972..000000000000 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_intr.c +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* -* Copyright (c) 2016 MediaTek Inc. -* Author: Tiffany Lin <tiffany.lin@mediatek.com> -*/ - -#include <linux/errno.h> -#include <linux/wait.h> - -#include "mtk_vcodec_drv.h" -#include "mtk_vcodec_intr.h" -#include "mtk_vcodec_util.h" - -int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx, - int command, unsigned int timeout_ms, - unsigned int hw_id) -{ - long timeout_jiff, ret; - int status = 0; - - timeout_jiff = msecs_to_jiffies(timeout_ms); - ret = wait_event_interruptible_timeout(ctx->queue[hw_id], - ctx->int_cond[hw_id], - timeout_jiff); - - if (!ret) { - status = -1; /* timeout */ - mtk_v4l2_err("[%d] cmd=%d, type=%d, dec timeout=%ums (%d %d)", - ctx->id, command, ctx->type, timeout_ms, - ctx->int_cond[hw_id], ctx->int_type[hw_id]); - } else if (-ERESTARTSYS == ret) { - status = -1; - mtk_v4l2_err("[%d] cmd=%d, type=%d, dec inter fail (%d %d)", - ctx->id, command, ctx->type, - ctx->int_cond[hw_id], ctx->int_type[hw_id]); - } - - ctx->int_cond[hw_id] = 0; - ctx->int_type[hw_id] = 0; - - return status; -} -EXPORT_SYMBOL(mtk_vcodec_wait_for_done_ctx); diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_util.h b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_util.h deleted file mode 100644 index 88d389b65f13..000000000000 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_util.h +++ /dev/null @@ -1,83 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* -* Copyright (c) 2016 MediaTek Inc. -* Author: PC Chen <pc.chen@mediatek.com> -* Tiffany Lin <tiffany.lin@mediatek.com> -*/ - -#ifndef _MTK_VCODEC_UTIL_H_ -#define _MTK_VCODEC_UTIL_H_ - -#include <linux/types.h> -#include <linux/dma-direction.h> - -struct mtk_vcodec_mem { - size_t size; - void *va; - dma_addr_t dma_addr; -}; - -struct mtk_vcodec_fb { - size_t size; - dma_addr_t dma_addr; -}; - -struct mtk_vcodec_ctx; -struct mtk_vcodec_dev; - -#undef pr_fmt -#define pr_fmt(fmt) "%s(),%d: " fmt, __func__, __LINE__ - -#define mtk_v4l2_err(fmt, args...) \ - pr_err("[MTK_V4L2][ERROR] " fmt "\n", ##args) - -#define mtk_vcodec_err(h, fmt, args...) \ - pr_err("[MTK_VCODEC][ERROR][%d]: " fmt "\n", \ - ((struct mtk_vcodec_ctx *)(h)->ctx)->id, ##args) - -#if defined(CONFIG_DEBUG_FS) -extern int mtk_v4l2_dbg_level; -extern int mtk_vcodec_dbg; - -#define mtk_v4l2_debug(level, fmt, args...) \ - do { \ - if (mtk_v4l2_dbg_level >= (level)) \ - pr_debug("[MTK_V4L2] %s, %d: " fmt "\n", \ - __func__, __LINE__, ##args); \ - } while (0) - -#define mtk_vcodec_debug(h, fmt, args...) \ - do { \ - if (mtk_vcodec_dbg) \ - dev_dbg(&(((struct mtk_vcodec_ctx *)(h)->ctx)->dev->plat_dev->dev), \ - "[MTK_VCODEC][%d]: %s, %d " fmt "\n", \ - ((struct mtk_vcodec_ctx *)(h)->ctx)->id, \ - __func__, __LINE__, ##args); \ - } while (0) -#else -#define mtk_v4l2_debug(level, fmt, args...) pr_debug(fmt, ##args) - -#define mtk_vcodec_debug(h, fmt, args...) \ - pr_debug("[MTK_VCODEC][%d]: " fmt "\n", \ - ((struct mtk_vcodec_ctx *)(h)->ctx)->id, ##args) -#endif - -#define mtk_v4l2_debug_enter() mtk_v4l2_debug(3, "+") -#define mtk_v4l2_debug_leave() mtk_v4l2_debug(3, "-") - -#define mtk_vcodec_debug_enter(h) mtk_vcodec_debug(h, "+") -#define mtk_vcodec_debug_leave(h) mtk_vcodec_debug(h, "-") - -void __iomem *mtk_vcodec_get_reg_addr(struct mtk_vcodec_ctx *data, - unsigned int reg_idx); -int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data, - struct mtk_vcodec_mem *mem); -void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data, - struct mtk_vcodec_mem *mem); -void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev, - struct mtk_vcodec_ctx *ctx, int hw_idx); -struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev, - unsigned int hw_idx); -void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int hw_idx); - -#endif /* _MTK_VCODEC_UTIL_H_ */ diff --git a/drivers/media/platform/mediatek/vpu/mtk_vpu.c b/drivers/media/platform/mediatek/vpu/mtk_vpu.c index 4c8f5296d120..7243604a82a5 100644 --- a/drivers/media/platform/mediatek/vpu/mtk_vpu.c +++ b/drivers/media/platform/mediatek/vpu/mtk_vpu.c @@ -9,10 +9,10 @@ #include <linux/interrupt.h> #include <linux/iommu.h> #include <linux/module.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> +#include <linux/of.h> #include <linux/of_platform.h> #include <linux/of_reserved_mem.h> +#include <linux/platform_device.h> #include <linux/sched.h> #include <linux/sizes.h> #include <linux/dma-mapping.h> diff --git a/drivers/media/platform/microchip/microchip-csi2dc.c b/drivers/media/platform/microchip/microchip-csi2dc.c index bfb3edcf018a..988c1cc1d8b6 100644 --- a/drivers/media/platform/microchip/microchip-csi2dc.c +++ b/drivers/media/platform/microchip/microchip-csi2dc.c @@ -476,7 +476,7 @@ static const struct v4l2_subdev_ops csi2dc_subdev_ops = { static int csi2dc_async_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct csi2dc_device *csi2dc = container_of(notifier, struct csi2dc_device, notifier); @@ -520,14 +520,14 @@ static const struct v4l2_async_notifier_operations csi2dc_async_ops = { static int csi2dc_prepare_notifier(struct csi2dc_device *csi2dc, struct fwnode_handle *input_fwnode) { - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; int ret = 0; - v4l2_async_nf_init(&csi2dc->notifier); + v4l2_async_subdev_nf_init(&csi2dc->notifier, &csi2dc->csi2dc_sd); asd = v4l2_async_nf_add_fwnode_remote(&csi2dc->notifier, input_fwnode, - struct v4l2_async_subdev); + struct v4l2_async_connection); fwnode_handle_put(input_fwnode); @@ -542,8 +542,7 @@ static int csi2dc_prepare_notifier(struct csi2dc_device *csi2dc, csi2dc->notifier.ops = &csi2dc_async_ops; - ret = v4l2_async_subdev_nf_register(&csi2dc->csi2dc_sd, - &csi2dc->notifier); + ret = v4l2_async_nf_register(&csi2dc->notifier); if (ret) { dev_err(csi2dc->dev, "fail to register async notifier: %d\n", ret); diff --git a/drivers/media/platform/microchip/microchip-isc-base.c b/drivers/media/platform/microchip/microchip-isc-base.c index 4e657fad33d0..8dbf7bc1e863 100644 --- a/drivers/media/platform/microchip/microchip-isc-base.c +++ b/drivers/media/platform/microchip/microchip-isc-base.c @@ -1712,7 +1712,7 @@ static int isc_ctrl_init(struct isc_device *isc) static int isc_async_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct isc_device *isc = container_of(notifier->v4l2_dev, struct isc_device, v4l2_dev); @@ -1741,7 +1741,7 @@ static int isc_async_bound(struct v4l2_async_notifier *notifier, static void isc_async_unbind(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct isc_device *isc = container_of(notifier->v4l2_dev, struct isc_device, v4l2_dev); diff --git a/drivers/media/platform/microchip/microchip-isc.h b/drivers/media/platform/microchip/microchip-isc.h index e3a6c7367e70..ad4e98a1dd8f 100644 --- a/drivers/media/platform/microchip/microchip-isc.h +++ b/drivers/media/platform/microchip/microchip-isc.h @@ -44,7 +44,7 @@ struct isc_buffer { struct isc_subdev_entity { struct v4l2_subdev *sd; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct device_node *epn; struct v4l2_async_notifier notifier; diff --git a/drivers/media/platform/microchip/microchip-sama5d2-isc.c b/drivers/media/platform/microchip/microchip-sama5d2-isc.c index 746f4a2fa9f6..5ac149cf3647 100644 --- a/drivers/media/platform/microchip/microchip-sama5d2-isc.c +++ b/drivers/media/platform/microchip/microchip-sama5d2-isc.c @@ -409,7 +409,6 @@ static int microchip_isc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct isc_device *isc; - struct resource *res; void __iomem *io_base; struct isc_subdev_entity *subdev_entity; int irq; @@ -423,8 +422,7 @@ static int microchip_isc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, isc); isc->dev = dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - io_base = devm_ioremap_resource(dev, res); + io_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(io_base)) return PTR_ERR(io_base); @@ -525,15 +523,15 @@ static int microchip_isc_probe(struct platform_device *pdev) } list_for_each_entry(subdev_entity, &isc->subdev_entities, list) { - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct fwnode_handle *fwnode = of_fwnode_handle(subdev_entity->epn); - v4l2_async_nf_init(&subdev_entity->notifier); + v4l2_async_nf_init(&subdev_entity->notifier, &isc->v4l2_dev); asd = v4l2_async_nf_add_fwnode_remote(&subdev_entity->notifier, fwnode, - struct v4l2_async_subdev); + struct v4l2_async_connection); of_node_put(subdev_entity->epn); subdev_entity->epn = NULL; @@ -545,8 +543,7 @@ static int microchip_isc_probe(struct platform_device *pdev) subdev_entity->notifier.ops = µchip_isc_async_ops; - ret = v4l2_async_nf_register(&isc->v4l2_dev, - &subdev_entity->notifier); + ret = v4l2_async_nf_register(&subdev_entity->notifier); if (ret) { dev_err(dev, "fail to register async notifier\n"); goto cleanup_subdev; diff --git a/drivers/media/platform/microchip/microchip-sama7g5-isc.c b/drivers/media/platform/microchip/microchip-sama7g5-isc.c index 79ae696764d0..73445f33d26b 100644 --- a/drivers/media/platform/microchip/microchip-sama7g5-isc.c +++ b/drivers/media/platform/microchip/microchip-sama7g5-isc.c @@ -398,7 +398,6 @@ static int microchip_xisc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct isc_device *isc; - struct resource *res; void __iomem *io_base; struct isc_subdev_entity *subdev_entity; int irq; @@ -412,8 +411,7 @@ static int microchip_xisc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, isc); isc->dev = dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - io_base = devm_ioremap_resource(dev, res); + io_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(io_base)) return PTR_ERR(io_base); @@ -515,15 +513,15 @@ static int microchip_xisc_probe(struct platform_device *pdev) } list_for_each_entry(subdev_entity, &isc->subdev_entities, list) { - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct fwnode_handle *fwnode = of_fwnode_handle(subdev_entity->epn); - v4l2_async_nf_init(&subdev_entity->notifier); + v4l2_async_nf_init(&subdev_entity->notifier, &isc->v4l2_dev); asd = v4l2_async_nf_add_fwnode_remote(&subdev_entity->notifier, fwnode, - struct v4l2_async_subdev); + struct v4l2_async_connection); of_node_put(subdev_entity->epn); subdev_entity->epn = NULL; @@ -535,8 +533,7 @@ static int microchip_xisc_probe(struct platform_device *pdev) subdev_entity->notifier.ops = µchip_isc_async_ops; - ret = v4l2_async_nf_register(&isc->v4l2_dev, - &subdev_entity->notifier); + ret = v4l2_async_nf_register(&subdev_entity->notifier); if (ret) { dev_err(dev, "fail to register async notifier\n"); goto cleanup_subdev; diff --git a/drivers/media/platform/nvidia/tegra-vde/vde.c b/drivers/media/platform/nvidia/tegra-vde/vde.c index 7157734a1550..81a0d3b76b88 100644 --- a/drivers/media/platform/nvidia/tegra-vde/vde.c +++ b/drivers/media/platform/nvidia/tegra-vde/vde.c @@ -12,7 +12,8 @@ #include <linux/interrupt.h> #include <linux/list.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> #include <linux/slab.h> diff --git a/drivers/media/platform/nxp/Kconfig b/drivers/media/platform/nxp/Kconfig index a0ca6b297fb8..40e3436669e2 100644 --- a/drivers/media/platform/nxp/Kconfig +++ b/drivers/media/platform/nxp/Kconfig @@ -17,6 +17,17 @@ config VIDEO_IMX7_CSI Driver for the NXP Camera Sensor Interface (CSI) Bridge. This device is found in the i.MX6UL/L, i.MX7 and i.MX8M[MQ] SoCs. +config VIDEO_IMX8MQ_MIPI_CSI2 + tristate "NXP i.MX8MQ MIPI CSI-2 receiver" + depends on ARCH_MXC || COMPILE_TEST + depends on VIDEO_DEV + select MEDIA_CONTROLLER + select V4L2_FWNODE + select VIDEO_V4L2_SUBDEV_API + help + Video4Linux2 driver for the MIPI CSI-2 receiver found on the i.MX8MQ + SoC. + config VIDEO_IMX_MIPI_CSIS tristate "NXP MIPI CSI-2 CSIS receiver found on i.MX7 and i.MX8 models" depends on ARCH_MXC || COMPILE_TEST diff --git a/drivers/media/platform/nxp/Makefile b/drivers/media/platform/nxp/Makefile index b8e672b75fed..4d90eb713652 100644 --- a/drivers/media/platform/nxp/Makefile +++ b/drivers/media/platform/nxp/Makefile @@ -5,6 +5,7 @@ obj-y += imx-jpeg/ obj-y += imx8-isi/ obj-$(CONFIG_VIDEO_IMX7_CSI) += imx7-media-csi.o +obj-$(CONFIG_VIDEO_IMX8MQ_MIPI_CSI2) += imx8mq-mipi-csi2.o obj-$(CONFIG_VIDEO_IMX_MIPI_CSIS) += imx-mipi-csis.o obj-$(CONFIG_VIDEO_IMX_PXP) += imx-pxp.o obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index 9512c0a61966..b7a720198ce5 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -2742,7 +2742,6 @@ static int mxc_jpeg_probe(struct platform_device *pdev) dev_info(&pdev->dev, "choose slot %d\n", jpeg->slot_data.slot); dec_irq = platform_get_irq(pdev, 0); if (dec_irq < 0) { - dev_err(&pdev->dev, "Failed to get irq %d\n", dec_irq); ret = dec_irq; goto err_irq; } diff --git a/drivers/media/platform/nxp/imx-mipi-csis.c b/drivers/media/platform/nxp/imx-mipi-csis.c index 05d52762e792..16f19a640130 100644 --- a/drivers/media/platform/nxp/imx-mipi-csis.c +++ b/drivers/media/platform/nxp/imx-mipi-csis.c @@ -22,7 +22,6 @@ #include <linux/module.h> #include <linux/mutex.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/regulator/consumer.h> @@ -1230,7 +1229,7 @@ mipi_notifier_to_csis_state(struct v4l2_async_notifier *n) static int mipi_csis_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct mipi_csis_device *csis = mipi_notifier_to_csis_state(notifier); struct media_pad *sink = &csis->sd.entity.pads[CSIS_PAD_SINK]; @@ -1247,12 +1246,12 @@ static int mipi_csis_async_register(struct mipi_csis_device *csis) struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_CSI2_DPHY, }; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct fwnode_handle *ep; unsigned int i; int ret; - v4l2_async_nf_init(&csis->notifier); + v4l2_async_subdev_nf_init(&csis->notifier, &csis->sd); ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csis->dev), 0, 0, FWNODE_GRAPH_ENDPOINT_NEXT); @@ -1278,7 +1277,7 @@ static int mipi_csis_async_register(struct mipi_csis_device *csis) dev_dbg(csis->dev, "flags: 0x%08x\n", csis->bus.flags); asd = v4l2_async_nf_add_fwnode_remote(&csis->notifier, ep, - struct v4l2_async_subdev); + struct v4l2_async_connection); if (IS_ERR(asd)) { ret = PTR_ERR(asd); goto err_parse; @@ -1288,7 +1287,7 @@ static int mipi_csis_async_register(struct mipi_csis_device *csis) csis->notifier.ops = &mipi_csis_notify_ops; - ret = v4l2_async_subdev_nf_register(&csis->sd, &csis->notifier); + ret = v4l2_async_nf_register(&csis->notifier); if (ret) return ret; @@ -1365,13 +1364,6 @@ static int mipi_csis_subdev_init(struct mipi_csis_device *csis) sd->dev = csis->dev; - sd->fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(csis->dev), - 1, 0, 0); - if (!sd->fwnode) { - dev_err(csis->dev, "Unable to retrieve endpoint for port@1\n"); - return -ENOENT; - } - csis->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; csis->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE diff --git a/drivers/media/platform/nxp/imx-pxp.c b/drivers/media/platform/nxp/imx-pxp.c index 90f319857c23..e62dc5c1a4ae 100644 --- a/drivers/media/platform/nxp/imx-pxp.c +++ b/drivers/media/platform/nxp/imx-pxp.c @@ -19,7 +19,6 @@ #include <linux/iopoll.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/sched.h> diff --git a/drivers/media/platform/nxp/imx7-media-csi.c b/drivers/media/platform/nxp/imx7-media-csi.c index 791bde67f439..15049c6aab37 100644 --- a/drivers/media/platform/nxp/imx7-media-csi.c +++ b/drivers/media/platform/nxp/imx7-media-csi.c @@ -13,7 +13,7 @@ #include <linux/mfd/syscon.h> #include <linux/minmax.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/of_graph.h> #include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> @@ -1076,6 +1076,7 @@ static int imx7_csi_video_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize) { const struct imx7_csi_pixfmt *cc; + u32 walign; if (fsize->index > 0) return -EINVAL; @@ -1085,16 +1086,17 @@ static int imx7_csi_video_enum_framesizes(struct file *file, void *fh, return -EINVAL; /* - * TODO: The constraints are hardware-specific and may depend on the - * pixel format. This should come from the driver using - * imx_media_capture. + * The width alignment is 8 bytes as indicated by the + * CSI_IMAG_PARA.IMAGE_WIDTH documentation. Convert it to pixels. */ + walign = 8 * 8 / cc->bpp; + fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; - fsize->stepwise.min_width = 1; - fsize->stepwise.max_width = 65535; + fsize->stepwise.min_width = walign; + fsize->stepwise.max_width = round_down(65535U, walign); fsize->stepwise.min_height = 1; fsize->stepwise.max_height = 65535; - fsize->stepwise.step_width = 1; + fsize->stepwise.step_width = walign; fsize->stepwise.step_height = 1; return 0; @@ -2035,7 +2037,7 @@ static const struct media_entity_operations imx7_csi_entity_ops = { static int imx7_csi_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct imx7_csi *csi = imx7_csi_notifier_to_dev(notifier); struct media_pad *sink = &csi->sd.entity.pads[IMX7_CSI_PAD_SINK]; @@ -2060,11 +2062,11 @@ static const struct v4l2_async_notifier_operations imx7_csi_notify_ops = { static int imx7_csi_async_register(struct imx7_csi *csi) { - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct fwnode_handle *ep; int ret; - v4l2_async_nf_init(&csi->notifier); + v4l2_async_nf_init(&csi->notifier, &csi->v4l2_dev); ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0, FWNODE_GRAPH_ENDPOINT_NEXT); @@ -2075,7 +2077,7 @@ static int imx7_csi_async_register(struct imx7_csi *csi) } asd = v4l2_async_nf_add_fwnode_remote(&csi->notifier, ep, - struct v4l2_async_subdev); + struct v4l2_async_connection); fwnode_handle_put(ep); @@ -2087,7 +2089,7 @@ static int imx7_csi_async_register(struct imx7_csi *csi) csi->notifier.ops = &imx7_csi_notify_ops; - ret = v4l2_async_nf_register(&csi->v4l2_dev, &csi->notifier); + ret = v4l2_async_nf_register(&csi->notifier); if (ret) goto error; diff --git a/drivers/media/platform/nxp/imx8-isi/Makefile b/drivers/media/platform/nxp/imx8-isi/Makefile index 9bff9297686d..4713c4e8b64b 100644 --- a/drivers/media/platform/nxp/imx8-isi/Makefile +++ b/drivers/media/platform/nxp/imx8-isi/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only -imx8-isi-y := imx8-isi-core.o imx8-isi-crossbar.o imx8-isi-hw.o \ - imx8-isi-pipe.o imx8-isi-video.o +imx8-isi-y := imx8-isi-core.o imx8-isi-crossbar.o imx8-isi-gasket.o \ + imx8-isi-hw.o imx8-isi-pipe.o imx8-isi-video.o imx8-isi-$(CONFIG_DEBUG_FS) += imx8-isi-debug.o imx8-isi-$(CONFIG_VIDEO_IMX8_ISI_M2M) += imx8-isi-m2m.o diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c index 253e77189b69..81be744e9f1b 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c @@ -9,7 +9,7 @@ #include <linux/kernel.h> #include <linux/mfd/syscon.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm.h> #include <linux/pm_runtime.h> @@ -30,12 +30,12 @@ */ struct mxc_isi_async_subdev { - struct v4l2_async_subdev asd; + struct v4l2_async_connection asd; unsigned int port; }; static inline struct mxc_isi_async_subdev * -asd_to_mxc_isi_async_subdev(struct v4l2_async_subdev *asd) +asd_to_mxc_isi_async_subdev(struct v4l2_async_connection *asd) { return container_of(asd, struct mxc_isi_async_subdev, asd); }; @@ -48,12 +48,12 @@ notifier_to_mxc_isi_dev(struct v4l2_async_notifier *n) static int mxc_isi_async_notifier_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asc) { const unsigned int link_flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED; struct mxc_isi_dev *isi = notifier_to_mxc_isi_dev(notifier); - struct mxc_isi_async_subdev *masd = asd_to_mxc_isi_async_subdev(asd); + struct mxc_isi_async_subdev *masd = asd_to_mxc_isi_async_subdev(asc); struct media_pad *pad = &isi->crossbar.pads[masd->port]; struct device_link *link; @@ -175,7 +175,7 @@ static int mxc_isi_v4l2_init(struct mxc_isi_dev *isi) } /* Initialize, fill and register the async notifier. */ - v4l2_async_nf_init(&isi->notifier); + v4l2_async_nf_init(&isi->notifier, v4l2_dev); isi->notifier.ops = &mxc_isi_async_notifier_ops; for (i = 0; i < isi->pdata->num_ports; ++i) { @@ -200,7 +200,7 @@ static int mxc_isi_v4l2_init(struct mxc_isi_dev *isi) masd->port = i; } - ret = v4l2_async_nf_register(v4l2_dev, &isi->notifier); + ret = v4l2_async_nf_register(&isi->notifier); if (ret < 0) { dev_err(isi->dev, "Failed to register async notifier: %d\n", ret); @@ -289,7 +289,7 @@ static const struct mxc_isi_plat_data mxc_imx8mn_data = { .clks = mxc_imx8mn_clks, .num_clks = ARRAY_SIZE(mxc_imx8mn_clks), .buf_active_reverse = false, - .has_gasket = true, + .gasket_ops = &mxc_imx8_gasket_ops, .has_36bit_dma = false, }; @@ -303,10 +303,24 @@ static const struct mxc_isi_plat_data mxc_imx8mp_data = { .clks = mxc_imx8mn_clks, .num_clks = ARRAY_SIZE(mxc_imx8mn_clks), .buf_active_reverse = true, - .has_gasket = true, + .gasket_ops = &mxc_imx8_gasket_ops, .has_36bit_dma = true, }; +static const struct mxc_isi_plat_data mxc_imx93_data = { + .model = MXC_ISI_IMX93, + .num_ports = 1, + .num_channels = 1, + .reg_offset = 0, + .ier_reg = &mxc_imx8_isi_ier_v2, + .set_thd = &mxc_imx8_isi_thd_v1, + .clks = mxc_imx8mn_clks, + .num_clks = ARRAY_SIZE(mxc_imx8mn_clks), + .buf_active_reverse = true, + .gasket_ops = &mxc_imx93_gasket_ops, + .has_36bit_dma = false, +}; + /* ----------------------------------------------------------------------------- * Power management */ @@ -443,7 +457,7 @@ static int mxc_isi_probe(struct platform_device *pdev) return PTR_ERR(isi->regs); } - if (isi->pdata->has_gasket) { + if (isi->pdata->gasket_ops) { isi->gasket = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,blk-ctrl"); if (IS_ERR(isi->gasket)) { @@ -518,6 +532,7 @@ static int mxc_isi_remove(struct platform_device *pdev) static const struct of_device_id mxc_isi_of_match[] = { { .compatible = "fsl,imx8mn-isi", .data = &mxc_imx8mn_data }, { .compatible = "fsl,imx8mp-isi", .data = &mxc_imx8mp_data }, + { .compatible = "fsl,imx93-isi", .data = &mxc_imx93_data }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, mxc_isi_of_match); diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h index e469788a9e6c..2810ebe9b5f7 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h @@ -147,9 +147,18 @@ struct mxc_isi_set_thd { struct mxc_isi_panic_thd panic_set_thd_v; }; +struct mxc_gasket_ops { + void (*enable)(struct mxc_isi_dev *isi, + const struct v4l2_mbus_frame_desc *fd, + const struct v4l2_mbus_framefmt *fmt, + const unsigned int port); + void (*disable)(struct mxc_isi_dev *isi, const unsigned int port); +}; + enum model { MXC_ISI_IMX8MN, MXC_ISI_IMX8MP, + MXC_ISI_IMX93, }; struct mxc_isi_plat_data { @@ -159,10 +168,10 @@ struct mxc_isi_plat_data { unsigned int reg_offset; const struct mxc_isi_ier_reg *ier_reg; const struct mxc_isi_set_thd *set_thd; + const struct mxc_gasket_ops *gasket_ops; const struct clk_bulk_data *clks; unsigned int num_clks; bool buf_active_reverse; - bool has_gasket; bool has_36bit_dma; }; @@ -286,6 +295,9 @@ struct mxc_isi_dev { struct dentry *debugfs_root; }; +extern const struct mxc_gasket_ops mxc_imx8_gasket_ops; +extern const struct mxc_gasket_ops mxc_imx93_gasket_ops; + int mxc_isi_crossbar_init(struct mxc_isi_dev *isi); void mxc_isi_crossbar_cleanup(struct mxc_isi_crossbar *xbar); int mxc_isi_crossbar_register(struct mxc_isi_crossbar *xbar); diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c index f7447b2f4d77..792f031e032a 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c @@ -15,7 +15,6 @@ #include <linux/types.h> #include <media/media-entity.h> -#include <media/mipi-csi2.h> #include <media/v4l2-subdev.h> #include "imx8-isi-core.h" @@ -25,32 +24,18 @@ static inline struct mxc_isi_crossbar *to_isi_crossbar(struct v4l2_subdev *sd) return container_of(sd, struct mxc_isi_crossbar, sd); } -/* ----------------------------------------------------------------------------- - * Media block control (i.MX8MN and i.MX8MP only) - */ -#define GASKET_BASE(n) (0x0060 + (n) * 0x30) - -#define GASKET_CTRL 0x0000 -#define GASKET_CTRL_DATA_TYPE(dt) ((dt) << 8) -#define GASKET_CTRL_DATA_TYPE_MASK (0x3f << 8) -#define GASKET_CTRL_DUAL_COMP_ENABLE BIT(1) -#define GASKET_CTRL_ENABLE BIT(0) - -#define GASKET_HSIZE 0x0004 -#define GASKET_VSIZE 0x0008 - static int mxc_isi_crossbar_gasket_enable(struct mxc_isi_crossbar *xbar, struct v4l2_subdev_state *state, struct v4l2_subdev *remote_sd, u32 remote_pad, unsigned int port) { struct mxc_isi_dev *isi = xbar->isi; + const struct mxc_gasket_ops *gasket_ops = isi->pdata->gasket_ops; const struct v4l2_mbus_framefmt *fmt; struct v4l2_mbus_frame_desc fd; - u32 val; int ret; - if (!isi->pdata->has_gasket) + if (!gasket_ops) return 0; /* @@ -77,17 +62,7 @@ static int mxc_isi_crossbar_gasket_enable(struct mxc_isi_crossbar *xbar, if (!fmt) return -EINVAL; - regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_HSIZE, fmt->width); - regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_VSIZE, fmt->height); - - val = GASKET_CTRL_DATA_TYPE(fd.entry[0].bus.csi2.dt) - | GASKET_CTRL_ENABLE; - - if (fd.entry[0].bus.csi2.dt == MIPI_CSI2_DT_YUV422_8B) - val |= GASKET_CTRL_DUAL_COMP_ENABLE; - - regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_CTRL, val); - + gasket_ops->enable(isi, &fd, fmt, port); return 0; } @@ -95,11 +70,12 @@ static void mxc_isi_crossbar_gasket_disable(struct mxc_isi_crossbar *xbar, unsigned int port) { struct mxc_isi_dev *isi = xbar->isi; + const struct mxc_gasket_ops *gasket_ops = isi->pdata->gasket_ops; - if (!isi->pdata->has_gasket) + if (!gasket_ops) return; - regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_CTRL, 0); + gasket_ops->disable(isi, port); } /* ----------------------------------------------------------------------------- @@ -483,7 +459,7 @@ int mxc_isi_crossbar_init(struct mxc_isi_dev *isi) xbar->inputs = kcalloc(xbar->num_sinks, sizeof(*xbar->inputs), GFP_KERNEL); - if (!xbar->pads) { + if (!xbar->inputs) { ret = -ENOMEM; goto err_free; } diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-gasket.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-gasket.c new file mode 100644 index 000000000000..f69c3b5d4782 --- /dev/null +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-gasket.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019-2023 NXP + */ + +#include <linux/regmap.h> + +#include <media/mipi-csi2.h> + +#include "imx8-isi-core.h" + +/* ----------------------------------------------------------------------------- + * i.MX8MN and i.MX8MP gasket + */ + +#define GASKET_BASE(n) (0x0060 + (n) * 0x30) + +#define GASKET_CTRL 0x0000 +#define GASKET_CTRL_DATA_TYPE(dt) ((dt) << 8) +#define GASKET_CTRL_DATA_TYPE_MASK (0x3f << 8) +#define GASKET_CTRL_DUAL_COMP_ENABLE BIT(1) +#define GASKET_CTRL_ENABLE BIT(0) + +#define GASKET_HSIZE 0x0004 +#define GASKET_VSIZE 0x0008 + +static void mxc_imx8_gasket_enable(struct mxc_isi_dev *isi, + const struct v4l2_mbus_frame_desc *fd, + const struct v4l2_mbus_framefmt *fmt, + const unsigned int port) +{ + u32 val; + + regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_HSIZE, fmt->width); + regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_VSIZE, fmt->height); + + val = GASKET_CTRL_DATA_TYPE(fd->entry[0].bus.csi2.dt); + if (fd->entry[0].bus.csi2.dt == MIPI_CSI2_DT_YUV422_8B) + val |= GASKET_CTRL_DUAL_COMP_ENABLE; + + val |= GASKET_CTRL_ENABLE; + regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_CTRL, val); +} + +static void mxc_imx8_gasket_disable(struct mxc_isi_dev *isi, + const unsigned int port) +{ + regmap_write(isi->gasket, GASKET_BASE(port) + GASKET_CTRL, 0); +} + +const struct mxc_gasket_ops mxc_imx8_gasket_ops = { + .enable = mxc_imx8_gasket_enable, + .disable = mxc_imx8_gasket_disable, +}; + +/* ----------------------------------------------------------------------------- + * i.MX93 gasket + */ + +#define DISP_MIX_CAMERA_MUX 0x30 +#define DISP_MIX_CAMERA_MUX_DATA_TYPE(x) (((x) & 0x3f) << 3) +#define DISP_MIX_CAMERA_MUX_GASKET_ENABLE BIT(16) + +static void mxc_imx93_gasket_enable(struct mxc_isi_dev *isi, + const struct v4l2_mbus_frame_desc *fd, + const struct v4l2_mbus_framefmt *fmt, + const unsigned int port) +{ + u32 val; + + val = DISP_MIX_CAMERA_MUX_DATA_TYPE(fd->entry[0].bus.csi2.dt); + val |= DISP_MIX_CAMERA_MUX_GASKET_ENABLE; + regmap_write(isi->gasket, DISP_MIX_CAMERA_MUX, val); +} + +static void mxc_imx93_gasket_disable(struct mxc_isi_dev *isi, + unsigned int port) +{ + regmap_write(isi->gasket, DISP_MIX_CAMERA_MUX, 0); +} + +const struct mxc_gasket_ops mxc_imx93_gasket_ops = { + .enable = mxc_imx93_gasket_enable, + .disable = mxc_imx93_gasket_disable, +}; diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c index c4454aa1cb34..65d20e9bae69 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c @@ -791,7 +791,6 @@ int mxc_isi_pipe_init(struct mxc_isi_dev *isi, unsigned int id) irq = platform_get_irq(to_platform_device(isi->dev), id); if (irq < 0) { - dev_err(pipe->isi->dev, "Failed to get IRQ (%d)\n", irq); ret = irq; goto error; } diff --git a/drivers/media/platform/nxp/imx8mq-mipi-csi2.c b/drivers/media/platform/nxp/imx8mq-mipi-csi2.c new file mode 100644 index 000000000000..ed048f73c982 --- /dev/null +++ b/drivers/media/platform/nxp/imx8mq-mipi-csi2.c @@ -0,0 +1,965 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * NXP i.MX8MQ SoC series MIPI-CSI2 receiver driver + * + * Copyright (C) 2021 Purism SPC + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/interconnect.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> +#include <linux/reset.h> +#include <linux/spinlock.h> + +#include <media/v4l2-common.h> +#include <media/v4l2-device.h> +#include <media/v4l2-fwnode.h> +#include <media/v4l2-mc.h> +#include <media/v4l2-subdev.h> + +#define MIPI_CSI2_DRIVER_NAME "imx8mq-mipi-csi2" +#define MIPI_CSI2_SUBDEV_NAME MIPI_CSI2_DRIVER_NAME + +#define MIPI_CSI2_PAD_SINK 0 +#define MIPI_CSI2_PAD_SOURCE 1 +#define MIPI_CSI2_PADS_NUM 2 + +#define MIPI_CSI2_DEF_PIX_WIDTH 640 +#define MIPI_CSI2_DEF_PIX_HEIGHT 480 + +/* Register map definition */ + +/* i.MX8MQ CSI-2 controller CSR */ +#define CSI2RX_CFG_NUM_LANES 0x100 +#define CSI2RX_CFG_DISABLE_DATA_LANES 0x104 +#define CSI2RX_BIT_ERR 0x108 +#define CSI2RX_IRQ_STATUS 0x10c +#define CSI2RX_IRQ_MASK 0x110 +#define CSI2RX_IRQ_MASK_ALL 0x1ff +#define CSI2RX_IRQ_MASK_ULPS_STATUS_CHANGE 0x8 +#define CSI2RX_ULPS_STATUS 0x114 +#define CSI2RX_PPI_ERRSOT_HS 0x118 +#define CSI2RX_PPI_ERRSOTSYNC_HS 0x11c +#define CSI2RX_PPI_ERRESC 0x120 +#define CSI2RX_PPI_ERRSYNCESC 0x124 +#define CSI2RX_PPI_ERRCONTROL 0x128 +#define CSI2RX_CFG_DISABLE_PAYLOAD_0 0x12c +#define CSI2RX_CFG_VID_VC_IGNORE 0x180 +#define CSI2RX_CFG_VID_VC 0x184 +#define CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL 0x188 +#define CSI2RX_CFG_DISABLE_PAYLOAD_1 0x130 + +enum { + ST_POWERED = 1, + ST_STREAMING = 2, + ST_SUSPENDED = 4, +}; + +enum imx8mq_mipi_csi_clk { + CSI2_CLK_CORE, + CSI2_CLK_ESC, + CSI2_CLK_UI, + CSI2_NUM_CLKS, +}; + +static const char * const imx8mq_mipi_csi_clk_id[CSI2_NUM_CLKS] = { + [CSI2_CLK_CORE] = "core", + [CSI2_CLK_ESC] = "esc", + [CSI2_CLK_UI] = "ui", +}; + +#define CSI2_NUM_CLKS ARRAY_SIZE(imx8mq_mipi_csi_clk_id) + +#define GPR_CSI2_1_RX_ENABLE BIT(13) +#define GPR_CSI2_1_VID_INTFC_ENB BIT(12) +#define GPR_CSI2_1_HSEL BIT(10) +#define GPR_CSI2_1_CONT_CLK_MODE BIT(8) +#define GPR_CSI2_1_S_PRG_RXHS_SETTLE(x) (((x) & 0x3f) << 2) + +/* + * The send level configures the number of entries that must accumulate in + * the Pixel FIFO before the data will be transferred to the video output. + * The exact value needed for this configuration is dependent on the rate at + * which the sensor transfers data to the CSI-2 Controller and the user + * video clock. + * + * The calculation is the classical rate-in rate-out type of problem: If the + * video bandwidth is 10% faster than the incoming mipi data and the video + * line length is 500 pixels, then the fifo should be allowed to fill + * 10% of the line length or 50 pixels. If the gap data is ok, then the level + * can be set to 16 and ignored. + */ +#define CSI2RX_SEND_LEVEL 64 + +struct csi_state { + struct device *dev; + void __iomem *regs; + struct clk_bulk_data clks[CSI2_NUM_CLKS]; + struct reset_control *rst; + struct regulator *mipi_phy_regulator; + + struct v4l2_subdev sd; + struct media_pad pads[MIPI_CSI2_PADS_NUM]; + struct v4l2_async_notifier notifier; + struct v4l2_subdev *src_sd; + + struct v4l2_mbus_config_mipi_csi2 bus; + + struct mutex lock; /* Protect state */ + u32 state; + + struct regmap *phy_gpr; + u8 phy_gpr_reg; + + struct icc_path *icc_path; + s32 icc_path_bw; +}; + +/* ----------------------------------------------------------------------------- + * Format helpers + */ + +struct csi2_pix_format { + u32 code; + u8 width; +}; + +static const struct csi2_pix_format imx8mq_mipi_csi_formats[] = { + /* RAW (Bayer and greyscale) formats. */ + { + .code = MEDIA_BUS_FMT_SBGGR8_1X8, + .width = 8, + }, { + .code = MEDIA_BUS_FMT_SGBRG8_1X8, + .width = 8, + }, { + .code = MEDIA_BUS_FMT_SGRBG8_1X8, + .width = 8, + }, { + .code = MEDIA_BUS_FMT_SRGGB8_1X8, + .width = 8, + }, { + .code = MEDIA_BUS_FMT_Y8_1X8, + .width = 8, + }, { + .code = MEDIA_BUS_FMT_SBGGR10_1X10, + .width = 10, + }, { + .code = MEDIA_BUS_FMT_SGBRG10_1X10, + .width = 10, + }, { + .code = MEDIA_BUS_FMT_SGRBG10_1X10, + .width = 10, + }, { + .code = MEDIA_BUS_FMT_SRGGB10_1X10, + .width = 10, + }, { + .code = MEDIA_BUS_FMT_Y10_1X10, + .width = 10, + }, { + .code = MEDIA_BUS_FMT_SBGGR12_1X12, + .width = 12, + }, { + .code = MEDIA_BUS_FMT_SGBRG12_1X12, + .width = 12, + }, { + .code = MEDIA_BUS_FMT_SGRBG12_1X12, + .width = 12, + }, { + .code = MEDIA_BUS_FMT_SRGGB12_1X12, + .width = 12, + }, { + .code = MEDIA_BUS_FMT_Y12_1X12, + .width = 12, + }, { + .code = MEDIA_BUS_FMT_SBGGR14_1X14, + .width = 14, + }, { + .code = MEDIA_BUS_FMT_SGBRG14_1X14, + .width = 14, + }, { + .code = MEDIA_BUS_FMT_SGRBG14_1X14, + .width = 14, + }, { + .code = MEDIA_BUS_FMT_SRGGB14_1X14, + .width = 14, + }, + /* YUV formats */ + { + .code = MEDIA_BUS_FMT_YUYV8_1X16, + .width = 16, + }, { + .code = MEDIA_BUS_FMT_UYVY8_1X16, + .width = 16, + } +}; + +static const struct csi2_pix_format *find_csi2_format(u32 code) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(imx8mq_mipi_csi_formats); i++) + if (code == imx8mq_mipi_csi_formats[i].code) + return &imx8mq_mipi_csi_formats[i]; + return NULL; +} + +/* ----------------------------------------------------------------------------- + * Hardware configuration + */ + +static inline void imx8mq_mipi_csi_write(struct csi_state *state, u32 reg, u32 val) +{ + writel(val, state->regs + reg); +} + +static int imx8mq_mipi_csi_sw_reset(struct csi_state *state) +{ + int ret; + + /* + * these are most likely self-clearing reset bits. to make it + * more clear, the reset-imx7 driver should implement the + * .reset() operation. + */ + ret = reset_control_assert(state->rst); + if (ret < 0) { + dev_err(state->dev, "Failed to assert resets: %d\n", ret); + return ret; + } + + return 0; +} + +static void imx8mq_mipi_csi_set_params(struct csi_state *state) +{ + int lanes = state->bus.num_data_lanes; + + imx8mq_mipi_csi_write(state, CSI2RX_CFG_NUM_LANES, lanes - 1); + imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES, + (0xf << lanes) & 0xf); + imx8mq_mipi_csi_write(state, CSI2RX_IRQ_MASK, CSI2RX_IRQ_MASK_ALL); + /* + * 0x180 bit 0 controls the Virtual Channel behaviour: when set the + * interface ignores the Virtual Channel (VC) field in received packets; + * when cleared it causes the interface to only accept packets whose VC + * matches the value to which VC is set at offset 0x184. + */ + imx8mq_mipi_csi_write(state, CSI2RX_CFG_VID_VC_IGNORE, 1); + imx8mq_mipi_csi_write(state, CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL, + CSI2RX_SEND_LEVEL); +} + +static int imx8mq_mipi_csi_clk_enable(struct csi_state *state) +{ + return clk_bulk_prepare_enable(CSI2_NUM_CLKS, state->clks); +} + +static void imx8mq_mipi_csi_clk_disable(struct csi_state *state) +{ + clk_bulk_disable_unprepare(CSI2_NUM_CLKS, state->clks); +} + +static int imx8mq_mipi_csi_clk_get(struct csi_state *state) +{ + unsigned int i; + + for (i = 0; i < CSI2_NUM_CLKS; i++) + state->clks[i].id = imx8mq_mipi_csi_clk_id[i]; + + return devm_clk_bulk_get(state->dev, CSI2_NUM_CLKS, state->clks); +} + +static int imx8mq_mipi_csi_calc_hs_settle(struct csi_state *state, + struct v4l2_subdev_state *sd_state, + u32 *hs_settle) +{ + s64 link_freq; + u32 lane_rate; + unsigned long esc_clk_rate; + u32 min_ths_settle, max_ths_settle, ths_settle_ns, esc_clk_period_ns; + const struct v4l2_mbus_framefmt *fmt; + const struct csi2_pix_format *csi2_fmt; + + /* Calculate the line rate from the pixel rate. */ + + fmt = v4l2_subdev_get_pad_format(&state->sd, sd_state, MIPI_CSI2_PAD_SINK); + csi2_fmt = find_csi2_format(fmt->code); + + link_freq = v4l2_get_link_freq(state->src_sd->ctrl_handler, + csi2_fmt->width, + state->bus.num_data_lanes * 2); + if (link_freq < 0) { + dev_err(state->dev, "Unable to obtain link frequency: %d\n", + (int)link_freq); + return link_freq; + } + + lane_rate = link_freq * 2; + if (lane_rate < 80000000 || lane_rate > 1500000000) { + dev_dbg(state->dev, "Out-of-bound lane rate %u\n", lane_rate); + return -EINVAL; + } + + /* + * The D-PHY specification requires Ths-settle to be in the range + * 85ns + 6*UI to 140ns + 10*UI, with the unit interval UI being half + * the clock period. + * + * The Ths-settle value is expressed in the hardware as a multiple of + * the Esc clock period: + * + * Ths-settle = (PRG_RXHS_SETTLE + 1) * Tperiod of RxClkInEsc + * + * Due to the one cycle inaccuracy introduced by rounding, the + * documentation recommends picking a value away from the boundaries. + * Let's pick the average. + */ + esc_clk_rate = clk_get_rate(state->clks[CSI2_CLK_ESC].clk); + if (!esc_clk_rate) { + dev_err(state->dev, "Could not get esc clock rate.\n"); + return -EINVAL; + } + + dev_dbg(state->dev, "esc clk rate: %lu\n", esc_clk_rate); + esc_clk_period_ns = 1000000000 / esc_clk_rate; + + min_ths_settle = 85 + 6 * 1000000 / (lane_rate / 1000); + max_ths_settle = 140 + 10 * 1000000 / (lane_rate / 1000); + ths_settle_ns = (min_ths_settle + max_ths_settle) / 2; + + *hs_settle = ths_settle_ns / esc_clk_period_ns - 1; + + dev_dbg(state->dev, "lane rate %u Ths_settle %u hs_settle %u\n", + lane_rate, ths_settle_ns, *hs_settle); + + return 0; +} + +static int imx8mq_mipi_csi_start_stream(struct csi_state *state, + struct v4l2_subdev_state *sd_state) +{ + int ret; + u32 hs_settle = 0; + + ret = imx8mq_mipi_csi_sw_reset(state); + if (ret) + return ret; + + imx8mq_mipi_csi_set_params(state); + ret = imx8mq_mipi_csi_calc_hs_settle(state, sd_state, &hs_settle); + if (ret) + return ret; + + regmap_update_bits(state->phy_gpr, + state->phy_gpr_reg, + 0x3fff, + GPR_CSI2_1_RX_ENABLE | + GPR_CSI2_1_VID_INTFC_ENB | + GPR_CSI2_1_HSEL | + GPR_CSI2_1_CONT_CLK_MODE | + GPR_CSI2_1_S_PRG_RXHS_SETTLE(hs_settle)); + + return 0; +} + +static void imx8mq_mipi_csi_stop_stream(struct csi_state *state) +{ + imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES, 0xf); +} + +/* ----------------------------------------------------------------------------- + * V4L2 subdev operations + */ + +static struct csi_state *mipi_sd_to_csi2_state(struct v4l2_subdev *sdev) +{ + return container_of(sdev, struct csi_state, sd); +} + +static int imx8mq_mipi_csi_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct csi_state *state = mipi_sd_to_csi2_state(sd); + struct v4l2_subdev_state *sd_state; + int ret = 0; + + if (enable) { + ret = pm_runtime_resume_and_get(state->dev); + if (ret < 0) + return ret; + } + + mutex_lock(&state->lock); + + if (enable) { + if (state->state & ST_SUSPENDED) { + ret = -EBUSY; + goto unlock; + } + + sd_state = v4l2_subdev_lock_and_get_active_state(sd); + ret = imx8mq_mipi_csi_start_stream(state, sd_state); + v4l2_subdev_unlock_state(sd_state); + + if (ret < 0) + goto unlock; + + ret = v4l2_subdev_call(state->src_sd, video, s_stream, 1); + if (ret < 0) + goto unlock; + + state->state |= ST_STREAMING; + } else { + v4l2_subdev_call(state->src_sd, video, s_stream, 0); + imx8mq_mipi_csi_stop_stream(state); + state->state &= ~ST_STREAMING; + } + +unlock: + mutex_unlock(&state->lock); + + if (!enable || ret < 0) + pm_runtime_put(state->dev); + + return ret; +} + +static int imx8mq_mipi_csi_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state) +{ + struct v4l2_mbus_framefmt *fmt_sink; + struct v4l2_mbus_framefmt *fmt_source; + + fmt_sink = v4l2_subdev_get_pad_format(sd, sd_state, MIPI_CSI2_PAD_SINK); + fmt_source = v4l2_subdev_get_pad_format(sd, sd_state, MIPI_CSI2_PAD_SOURCE); + + fmt_sink->code = MEDIA_BUS_FMT_SGBRG10_1X10; + fmt_sink->width = MIPI_CSI2_DEF_PIX_WIDTH; + fmt_sink->height = MIPI_CSI2_DEF_PIX_HEIGHT; + fmt_sink->field = V4L2_FIELD_NONE; + + fmt_sink->colorspace = V4L2_COLORSPACE_RAW; + fmt_sink->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt_sink->colorspace); + fmt_sink->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt_sink->colorspace); + fmt_sink->quantization = + V4L2_MAP_QUANTIZATION_DEFAULT(false, fmt_sink->colorspace, + fmt_sink->ycbcr_enc); + + *fmt_source = *fmt_sink; + + return 0; +} + +static int imx8mq_mipi_csi_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_mbus_code_enum *code) +{ + /* + * We can't transcode in any way, the source format is identical + * to the sink format. + */ + if (code->pad == MIPI_CSI2_PAD_SOURCE) { + struct v4l2_mbus_framefmt *fmt; + + if (code->index > 0) + return -EINVAL; + + fmt = v4l2_subdev_get_pad_format(sd, sd_state, code->pad); + code->code = fmt->code; + return 0; + } + + if (code->pad != MIPI_CSI2_PAD_SINK) + return -EINVAL; + + if (code->index >= ARRAY_SIZE(imx8mq_mipi_csi_formats)) + return -EINVAL; + + code->code = imx8mq_mipi_csi_formats[code->index].code; + + return 0; +} + +static int imx8mq_mipi_csi_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *sdformat) +{ + const struct csi2_pix_format *csi2_fmt; + struct v4l2_mbus_framefmt *fmt; + + /* + * The device can't transcode in any way, the source format can't be + * modified. + */ + if (sdformat->pad == MIPI_CSI2_PAD_SOURCE) + return v4l2_subdev_get_fmt(sd, sd_state, sdformat); + + if (sdformat->pad != MIPI_CSI2_PAD_SINK) + return -EINVAL; + + csi2_fmt = find_csi2_format(sdformat->format.code); + if (!csi2_fmt) + csi2_fmt = &imx8mq_mipi_csi_formats[0]; + + fmt = v4l2_subdev_get_pad_format(sd, sd_state, sdformat->pad); + + fmt->code = csi2_fmt->code; + fmt->width = sdformat->format.width; + fmt->height = sdformat->format.height; + + sdformat->format = *fmt; + + /* Propagate the format from sink to source. */ + fmt = v4l2_subdev_get_pad_format(sd, sd_state, MIPI_CSI2_PAD_SOURCE); + *fmt = sdformat->format; + + return 0; +} + +static const struct v4l2_subdev_video_ops imx8mq_mipi_csi_video_ops = { + .s_stream = imx8mq_mipi_csi_s_stream, +}; + +static const struct v4l2_subdev_pad_ops imx8mq_mipi_csi_pad_ops = { + .init_cfg = imx8mq_mipi_csi_init_cfg, + .enum_mbus_code = imx8mq_mipi_csi_enum_mbus_code, + .get_fmt = v4l2_subdev_get_fmt, + .set_fmt = imx8mq_mipi_csi_set_fmt, +}; + +static const struct v4l2_subdev_ops imx8mq_mipi_csi_subdev_ops = { + .video = &imx8mq_mipi_csi_video_ops, + .pad = &imx8mq_mipi_csi_pad_ops, +}; + +/* ----------------------------------------------------------------------------- + * Media entity operations + */ + +static const struct media_entity_operations imx8mq_mipi_csi_entity_ops = { + .link_validate = v4l2_subdev_link_validate, + .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1, +}; + +/* ----------------------------------------------------------------------------- + * Async subdev notifier + */ + +static struct csi_state * +mipi_notifier_to_csi2_state(struct v4l2_async_notifier *n) +{ + return container_of(n, struct csi_state, notifier); +} + +static int imx8mq_mipi_csi_notify_bound(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *sd, + struct v4l2_async_connection *asd) +{ + struct csi_state *state = mipi_notifier_to_csi2_state(notifier); + struct media_pad *sink = &state->sd.entity.pads[MIPI_CSI2_PAD_SINK]; + + state->src_sd = sd; + + return v4l2_create_fwnode_links_to_pad(sd, sink, MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); +} + +static const struct v4l2_async_notifier_operations imx8mq_mipi_csi_notify_ops = { + .bound = imx8mq_mipi_csi_notify_bound, +}; + +static int imx8mq_mipi_csi_async_register(struct csi_state *state) +{ + struct v4l2_fwnode_endpoint vep = { + .bus_type = V4L2_MBUS_CSI2_DPHY, + }; + struct v4l2_async_connection *asd; + struct fwnode_handle *ep; + unsigned int i; + int ret; + + v4l2_async_subdev_nf_init(&state->notifier, &state->sd); + + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(state->dev), 0, 0, + FWNODE_GRAPH_ENDPOINT_NEXT); + if (!ep) + return -ENOTCONN; + + ret = v4l2_fwnode_endpoint_parse(ep, &vep); + if (ret) + goto err_parse; + + for (i = 0; i < vep.bus.mipi_csi2.num_data_lanes; ++i) { + if (vep.bus.mipi_csi2.data_lanes[i] != i + 1) { + dev_err(state->dev, + "data lanes reordering is not supported"); + ret = -EINVAL; + goto err_parse; + } + } + + state->bus = vep.bus.mipi_csi2; + + dev_dbg(state->dev, "data lanes: %d flags: 0x%08x\n", + state->bus.num_data_lanes, + state->bus.flags); + + asd = v4l2_async_nf_add_fwnode_remote(&state->notifier, ep, + struct v4l2_async_connection); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + goto err_parse; + } + + fwnode_handle_put(ep); + + state->notifier.ops = &imx8mq_mipi_csi_notify_ops; + + ret = v4l2_async_nf_register(&state->notifier); + if (ret) + return ret; + + return v4l2_async_register_subdev(&state->sd); + +err_parse: + fwnode_handle_put(ep); + + return ret; +} + +/* ----------------------------------------------------------------------------- + * Suspend/resume + */ + +static void imx8mq_mipi_csi_pm_suspend(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct csi_state *state = mipi_sd_to_csi2_state(sd); + + mutex_lock(&state->lock); + + if (state->state & ST_POWERED) { + imx8mq_mipi_csi_stop_stream(state); + imx8mq_mipi_csi_clk_disable(state); + state->state &= ~ST_POWERED; + } + + mutex_unlock(&state->lock); +} + +static int imx8mq_mipi_csi_pm_resume(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct csi_state *state = mipi_sd_to_csi2_state(sd); + struct v4l2_subdev_state *sd_state; + int ret = 0; + + mutex_lock(&state->lock); + + if (!(state->state & ST_POWERED)) { + state->state |= ST_POWERED; + ret = imx8mq_mipi_csi_clk_enable(state); + } + if (state->state & ST_STREAMING) { + sd_state = v4l2_subdev_lock_and_get_active_state(sd); + ret = imx8mq_mipi_csi_start_stream(state, sd_state); + v4l2_subdev_unlock_state(sd_state); + if (ret) + goto unlock; + } + + state->state &= ~ST_SUSPENDED; + +unlock: + mutex_unlock(&state->lock); + + return ret ? -EAGAIN : 0; +} + +static int __maybe_unused imx8mq_mipi_csi_suspend(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct csi_state *state = mipi_sd_to_csi2_state(sd); + + imx8mq_mipi_csi_pm_suspend(dev); + + state->state |= ST_SUSPENDED; + + return 0; +} + +static int __maybe_unused imx8mq_mipi_csi_resume(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct csi_state *state = mipi_sd_to_csi2_state(sd); + + if (!(state->state & ST_SUSPENDED)) + return 0; + + return imx8mq_mipi_csi_pm_resume(dev); +} + +static int __maybe_unused imx8mq_mipi_csi_runtime_suspend(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct csi_state *state = mipi_sd_to_csi2_state(sd); + int ret; + + imx8mq_mipi_csi_pm_suspend(dev); + + ret = icc_set_bw(state->icc_path, 0, 0); + if (ret) + dev_err(dev, "icc_set_bw failed with %d\n", ret); + + return ret; +} + +static int __maybe_unused imx8mq_mipi_csi_runtime_resume(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct csi_state *state = mipi_sd_to_csi2_state(sd); + int ret; + + ret = icc_set_bw(state->icc_path, 0, state->icc_path_bw); + if (ret) { + dev_err(dev, "icc_set_bw failed with %d\n", ret); + return ret; + } + + return imx8mq_mipi_csi_pm_resume(dev); +} + +static const struct dev_pm_ops imx8mq_mipi_csi_pm_ops = { + SET_RUNTIME_PM_OPS(imx8mq_mipi_csi_runtime_suspend, + imx8mq_mipi_csi_runtime_resume, + NULL) + SET_SYSTEM_SLEEP_PM_OPS(imx8mq_mipi_csi_suspend, imx8mq_mipi_csi_resume) +}; + +/* ----------------------------------------------------------------------------- + * Probe/remove & platform driver + */ + +static int imx8mq_mipi_csi_subdev_init(struct csi_state *state) +{ + struct v4l2_subdev *sd = &state->sd; + int ret; + + v4l2_subdev_init(sd, &imx8mq_mipi_csi_subdev_ops); + sd->owner = THIS_MODULE; + snprintf(sd->name, sizeof(sd->name), "%s %s", + MIPI_CSI2_SUBDEV_NAME, dev_name(state->dev)); + + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + + sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; + sd->entity.ops = &imx8mq_mipi_csi_entity_ops; + + sd->dev = state->dev; + + state->pads[MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK + | MEDIA_PAD_FL_MUST_CONNECT; + state->pads[MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE + | MEDIA_PAD_FL_MUST_CONNECT; + ret = media_entity_pads_init(&sd->entity, MIPI_CSI2_PADS_NUM, + state->pads); + if (ret) + return ret; + + ret = v4l2_subdev_init_finalize(sd); + if (ret) { + media_entity_cleanup(&sd->entity); + return ret; + } + + return 0; +} + +static void imx8mq_mipi_csi_release_icc(struct platform_device *pdev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev); + struct csi_state *state = mipi_sd_to_csi2_state(sd); + + icc_put(state->icc_path); +} + +static int imx8mq_mipi_csi_init_icc(struct platform_device *pdev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev); + struct csi_state *state = mipi_sd_to_csi2_state(sd); + + /* Optional interconnect request */ + state->icc_path = of_icc_get(&pdev->dev, "dram"); + if (IS_ERR_OR_NULL(state->icc_path)) + return PTR_ERR_OR_ZERO(state->icc_path); + + state->icc_path_bw = MBps_to_icc(700); + + return 0; +} + +static int imx8mq_mipi_csi_parse_dt(struct csi_state *state) +{ + struct device *dev = state->dev; + struct device_node *np = state->dev->of_node; + struct device_node *node; + phandle ph; + u32 out_val[2]; + int ret = 0; + + state->rst = devm_reset_control_array_get_exclusive(dev); + if (IS_ERR(state->rst)) { + dev_err(dev, "Failed to get reset: %pe\n", state->rst); + return PTR_ERR(state->rst); + } + + ret = of_property_read_u32_array(np, "fsl,mipi-phy-gpr", out_val, + ARRAY_SIZE(out_val)); + if (ret) { + dev_err(dev, "no fsl,mipi-phy-gpr property found: %d\n", ret); + return ret; + } + + ph = *out_val; + + node = of_find_node_by_phandle(ph); + if (!node) { + dev_err(dev, "Error finding node by phandle\n"); + return -ENODEV; + } + state->phy_gpr = syscon_node_to_regmap(node); + of_node_put(node); + if (IS_ERR(state->phy_gpr)) { + dev_err(dev, "failed to get gpr regmap: %pe\n", state->phy_gpr); + return PTR_ERR(state->phy_gpr); + } + + state->phy_gpr_reg = out_val[1]; + dev_dbg(dev, "phy gpr register set to 0x%x\n", state->phy_gpr_reg); + + return ret; +} + +static int imx8mq_mipi_csi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct csi_state *state; + int ret; + + state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; + + state->dev = dev; + + ret = imx8mq_mipi_csi_parse_dt(state); + if (ret < 0) { + dev_err(dev, "Failed to parse device tree: %d\n", ret); + return ret; + } + + /* Acquire resources. */ + state->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(state->regs)) + return PTR_ERR(state->regs); + + ret = imx8mq_mipi_csi_clk_get(state); + if (ret < 0) + return ret; + + platform_set_drvdata(pdev, &state->sd); + + mutex_init(&state->lock); + + ret = imx8mq_mipi_csi_subdev_init(state); + if (ret < 0) + goto mutex; + + ret = imx8mq_mipi_csi_init_icc(pdev); + if (ret) + goto mutex; + + /* Enable runtime PM. */ + pm_runtime_enable(dev); + if (!pm_runtime_enabled(dev)) { + ret = imx8mq_mipi_csi_runtime_resume(dev); + if (ret < 0) + goto icc; + } + + ret = imx8mq_mipi_csi_async_register(state); + if (ret < 0) + goto cleanup; + + return 0; + +cleanup: + pm_runtime_disable(&pdev->dev); + imx8mq_mipi_csi_runtime_suspend(&pdev->dev); + + media_entity_cleanup(&state->sd.entity); + v4l2_subdev_cleanup(&state->sd); + v4l2_async_nf_unregister(&state->notifier); + v4l2_async_nf_cleanup(&state->notifier); + v4l2_async_unregister_subdev(&state->sd); +icc: + imx8mq_mipi_csi_release_icc(pdev); +mutex: + mutex_destroy(&state->lock); + + return ret; +} + +static void imx8mq_mipi_csi_remove(struct platform_device *pdev) +{ + struct v4l2_subdev *sd = platform_get_drvdata(pdev); + struct csi_state *state = mipi_sd_to_csi2_state(sd); + + v4l2_async_nf_unregister(&state->notifier); + v4l2_async_nf_cleanup(&state->notifier); + v4l2_async_unregister_subdev(&state->sd); + + pm_runtime_disable(&pdev->dev); + imx8mq_mipi_csi_runtime_suspend(&pdev->dev); + media_entity_cleanup(&state->sd.entity); + v4l2_subdev_cleanup(&state->sd); + mutex_destroy(&state->lock); + pm_runtime_set_suspended(&pdev->dev); + imx8mq_mipi_csi_release_icc(pdev); +} + +static const struct of_device_id imx8mq_mipi_csi_of_match[] = { + { .compatible = "fsl,imx8mq-mipi-csi2", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, imx8mq_mipi_csi_of_match); + +static struct platform_driver imx8mq_mipi_csi_driver = { + .probe = imx8mq_mipi_csi_probe, + .remove_new = imx8mq_mipi_csi_remove, + .driver = { + .of_match_table = imx8mq_mipi_csi_of_match, + .name = MIPI_CSI2_DRIVER_NAME, + .pm = &imx8mq_mipi_csi_pm_ops, + }, +}; + +module_platform_driver(imx8mq_mipi_csi_driver); + +MODULE_DESCRIPTION("i.MX8MQ MIPI CSI-2 receiver driver"); +MODULE_AUTHOR("Martin Kepplinger <martin.kepplinger@puri.sm>"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:imx8mq-mipi-csi2"); diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 1ef26aea3eae..f11dc59135a5 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -1383,7 +1383,7 @@ static void camss_unregister_entities(struct camss *camss) static int camss_subdev_notifier_bound(struct v4l2_async_notifier *async, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct camss *camss = container_of(async, struct camss, notifier); struct camss_async_subdev *csd = @@ -1615,14 +1615,6 @@ static int camss_probe(struct platform_device *pdev) if (!camss->vfe) return -ENOMEM; - v4l2_async_nf_init(&camss->notifier); - - num_subdevs = camss_of_parse_ports(camss); - if (num_subdevs < 0) { - ret = num_subdevs; - goto err_cleanup; - } - ret = camss_icc_get(camss); if (ret < 0) goto err_cleanup; @@ -1648,15 +1640,22 @@ static int camss_probe(struct platform_device *pdev) goto err_cleanup; } + v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev); + + num_subdevs = camss_of_parse_ports(camss); + if (num_subdevs < 0) { + ret = num_subdevs; + goto err_cleanup; + } + ret = camss_register_entities(camss); if (ret < 0) - goto err_register_entities; + goto err_cleanup; if (num_subdevs) { camss->notifier.ops = &camss_subdev_notifier_ops; - ret = v4l2_async_nf_register(&camss->v4l2_dev, - &camss->notifier); + ret = v4l2_async_nf_register(&camss->notifier); if (ret) { dev_err(dev, "Failed to register async subdev nodes: %d\n", @@ -1691,9 +1690,8 @@ static int camss_probe(struct platform_device *pdev) err_register_subdevs: camss_unregister_entities(camss); -err_register_entities: - v4l2_device_unregister(&camss->v4l2_dev); err_cleanup: + v4l2_device_unregister(&camss->v4l2_dev); v4l2_async_nf_cleanup(&camss->notifier); return ret; diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index 3acd2b3403e8..f6c326cb853b 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -113,7 +113,7 @@ struct camss_camera_interface { }; struct camss_async_subdev { - struct v4l2_async_subdev asd; /* must be first */ + struct v4l2_async_connection asd; /* must be first */ struct camss_camera_interface interface; }; diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index 2ae867cb4c48..054b8e74ba4f 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -11,7 +11,8 @@ #include <linux/devcoredump.h> #include <linux/list.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/types.h> @@ -246,7 +247,7 @@ err: static void venus_assign_register_offsets(struct venus_core *core) { - if (IS_V6(core)) { + if (IS_IRIS2(core) || IS_IRIS2_1(core)) { core->vbif_base = core->base + VBIF_BASE; core->cpu_base = core->base + CPU_BASE_V6; core->cpu_cs_base = core->base + CPU_CS_BASE_V6; @@ -684,6 +685,7 @@ static const struct venus_resources sdm845_res = { .vcodec_clks_num = 2, .max_load = 3110400, /* 4096x2160@90 */ .hfi_version = HFI_VERSION_4XX, + .vpu_version = VPU_VERSION_AR50, .vmem_id = VIDC_RESOURCE_NONE, .vmem_size = 0, .vmem_addr = 0, @@ -709,6 +711,7 @@ static const struct venus_resources sdm845_res_v2 = { .vcodec_num = 2, .max_load = 3110400, /* 4096x2160@90 */ .hfi_version = HFI_VERSION_4XX, + .vpu_version = VPU_VERSION_AR50, .vmem_id = VIDC_RESOURCE_NONE, .vmem_size = 0, .vmem_addr = 0, @@ -756,10 +759,15 @@ static const struct venus_resources sc7180_res = { .opp_pmdomain = (const char *[]) { "cx", NULL }, .vcodec_num = 1, .hfi_version = HFI_VERSION_4XX, + .vpu_version = VPU_VERSION_AR50, .vmem_id = VIDC_RESOURCE_NONE, .vmem_size = 0, .vmem_addr = 0, .dma_mask = 0xe0000000 - 1, + .cp_start = 0, + .cp_size = 0x70800000, + .cp_nonpixel_start = 0x1000000, + .cp_nonpixel_size = 0x24800000, .fwname = "qcom/venus-5.4/venus.mdt", }; @@ -809,12 +817,13 @@ static const struct venus_resources sm8250_res = { .vcodec_num = 1, .max_load = 7833600, .hfi_version = HFI_VERSION_6XX, + .vpu_version = VPU_VERSION_IRIS2, .num_vpp_pipes = 4, .vmem_id = VIDC_RESOURCE_NONE, .vmem_size = 0, .vmem_addr = 0, .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu-1.0/venus.mdt", + .fwname = "qcom/vpu-1.0/venus.mbn", }; static const struct freq_tbl sc7280_freq_table[] = { @@ -866,6 +875,7 @@ static const struct venus_resources sc7280_res = { .opp_pmdomain = (const char *[]) { "cx", NULL }, .vcodec_num = 1, .hfi_version = HFI_VERSION_6XX, + .vpu_version = VPU_VERSION_IRIS2_1, .num_vpp_pipes = 1, .vmem_id = VIDC_RESOURCE_NONE, .vmem_size = 0, diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index 320bde0f83cb..4a633261ece4 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -48,6 +48,14 @@ struct bw_tbl { u32 peak_10bit; }; +enum vpu_version { + VPU_VERSION_AR50, + VPU_VERSION_AR50_LITE, + VPU_VERSION_IRIS1, + VPU_VERSION_IRIS2, + VPU_VERSION_IRIS2_1, +}; + struct venus_resources { u64 dma_mask; const struct freq_tbl *freq_tbl; @@ -71,6 +79,7 @@ struct venus_resources { const char * const resets[VIDC_RESETS_NUM_MAX]; unsigned int resets_num; enum hfi_version hfi_version; + enum vpu_version vpu_version; u8 num_vpp_pipes; u32 max_load; unsigned int vmem_id; @@ -160,6 +169,7 @@ struct venus_format { * @core0_usage_count: usage counter for core0 * @core1_usage_count: usage counter for core1 * @root: debugfs root directory + * @venus_ver: the venus firmware version */ struct venus_core { void __iomem *base; @@ -386,7 +396,8 @@ enum venus_inst_modes { * @ycbcr_enc: current YCbCr encoding * @quantization: current quantization * @xfer_func: current xfer function - * @codec_state: current codec API state (see DEC/ENC_STATE_) + * @codec_state: current decoder API state (see DEC_STATE_) + * @enc_state: current encoder API state (see ENC_STATE_) * @reconf_wait: wait queue for resolution change event * @subscriptions: used to hold current events subscriptions * @buf_count: used to count number of buffers (reqbuf(0)) @@ -505,6 +516,12 @@ struct venus_inst { #define IS_V4(core) ((core)->res->hfi_version == HFI_VERSION_4XX) #define IS_V6(core) ((core)->res->hfi_version == HFI_VERSION_6XX) +#define IS_AR50(core) ((core)->res->vpu_version == VPU_VERSION_AR50) +#define IS_AR50_LITE(core) ((core)->res->vpu_version == VPU_VERSION_AR50_LITE) +#define IS_IRIS1(core) ((core)->res->vpu_version == VPU_VERSION_IRIS1) +#define IS_IRIS2(core) ((core)->res->vpu_version == VPU_VERSION_IRIS2) +#define IS_IRIS2_1(core) ((core)->res->vpu_version == VPU_VERSION_IRIS2_1) + #define ctrl_to_inst(ctrl) \ container_of((ctrl)->handler, struct venus_inst, ctrl_handler) diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c index cfb11c551167..fe7da2b30482 100644 --- a/drivers/media/platform/qcom/venus/firmware.c +++ b/drivers/media/platform/qcom/venus/firmware.c @@ -10,6 +10,7 @@ #include <linux/io.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/of_reserved_mem.h> #include <linux/platform_device.h> #include <linux/of_device.h> #include <linux/firmware/qcom/qcom_scm.h> @@ -29,7 +30,7 @@ static void venus_reset_cpu(struct venus_core *core) u32 fw_size = core->fw.mapped_mem_size; void __iomem *wrapper_base; - if (IS_V6(core)) + if (IS_IRIS2_1(core)) wrapper_base = core->wrapper_tz_base; else wrapper_base = core->wrapper_base; @@ -41,7 +42,7 @@ static void venus_reset_cpu(struct venus_core *core) writel(fw_size, wrapper_base + WRAPPER_NONPIX_START_ADDR); writel(fw_size, wrapper_base + WRAPPER_NONPIX_END_ADDR); - if (IS_V6(core)) { + if (IS_IRIS2_1(core)) { /* Bring XTSS out of reset */ writel(0, wrapper_base + WRAPPER_TZ_XTSS_SW_RESET); } else { @@ -67,7 +68,7 @@ int venus_set_hw_state(struct venus_core *core, bool resume) if (resume) { venus_reset_cpu(core); } else { - if (IS_V6(core)) + if (IS_IRIS2_1(core)) writel(WRAPPER_XTSS_SW_RESET_BIT, core->wrapper_tz_base + WRAPPER_TZ_XTSS_SW_RESET); else @@ -82,9 +83,9 @@ static int venus_load_fw(struct venus_core *core, const char *fwname, phys_addr_t *mem_phys, size_t *mem_size) { const struct firmware *mdt; + struct reserved_mem *rmem; struct device_node *node; struct device *dev; - struct resource r; ssize_t fw_size; void *mem_va; int ret; @@ -99,13 +100,16 @@ static int venus_load_fw(struct venus_core *core, const char *fwname, return -EINVAL; } - ret = of_address_to_resource(node, 0, &r); - if (ret) - goto err_put_node; + rmem = of_reserved_mem_lookup(node); + of_node_put(node); + if (!rmem) { + dev_err(dev, "failed to lookup reserved memory-region\n"); + return -EINVAL; + } ret = request_firmware(&mdt, fwname, dev); if (ret < 0) - goto err_put_node; + return ret; fw_size = qcom_mdt_get_size(mdt); if (fw_size < 0) { @@ -113,17 +117,17 @@ static int venus_load_fw(struct venus_core *core, const char *fwname, goto err_release_fw; } - *mem_phys = r.start; - *mem_size = resource_size(&r); + *mem_phys = rmem->base; + *mem_size = rmem->size; if (*mem_size < fw_size || fw_size > VENUS_FW_MEM_SIZE) { ret = -EINVAL; goto err_release_fw; } - mem_va = memremap(r.start, *mem_size, MEMREMAP_WC); + mem_va = memremap(*mem_phys, *mem_size, MEMREMAP_WC); if (!mem_va) { - dev_err(dev, "unable to map memory region: %pR\n", &r); + dev_err(dev, "unable to map memory region %pa size %#zx\n", mem_phys, *mem_size); ret = -ENOMEM; goto err_release_fw; } @@ -138,8 +142,6 @@ static int venus_load_fw(struct venus_core *core, const char *fwname, memunmap(mem_va); err_release_fw: release_firmware(mdt); -err_put_node: - of_node_put(node); return ret; } @@ -179,7 +181,7 @@ static int venus_shutdown_no_tz(struct venus_core *core) void __iomem *wrapper_base = core->wrapper_base; void __iomem *wrapper_tz_base = core->wrapper_tz_base; - if (IS_V6(core)) { + if (IS_IRIS2_1(core)) { /* Assert the reset to XTSS */ reg = readl(wrapper_tz_base + WRAPPER_TZ_XTSS_SW_RESET); reg |= WRAPPER_XTSS_SW_RESET_BIT; @@ -241,6 +243,16 @@ int venus_boot(struct venus_core *core) return ret; if (core->use_tz && res->cp_size) { + /* + * Clues for porting using downstream data: + * cp_start = 0 + * cp_size = venus_ns/virtual-addr-pool[0] - yes, address and not size! + * This works, as the non-secure context bank is placed + * contiguously right after the Content Protection region. + * + * cp_nonpixel_start = venus_sec_non_pixel/virtual-addr-pool[0] + * cp_nonpixel_size = venus_sec_non_pixel/virtual-addr-pool[1] + */ ret = qcom_scm_mem_protect_video_var(res->cp_start, res->cp_size, res->cp_nonpixel_start, diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 1822e85ab6bf..8295542e1a7c 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -189,7 +189,7 @@ int venus_helper_alloc_dpb_bufs(struct venus_inst *inst) if (ret) return ret; - count = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); + count = hfi_bufreq_get_count_min(&bufreq, ver); for (i = 0; i < count; i++) { buf = kzalloc(sizeof(*buf), GFP_KERNEL); @@ -668,6 +668,7 @@ int venus_helper_get_bufreq(struct venus_inst *inst, u32 type, struct hfi_buffer_requirements *req) { u32 ptype = HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS; + enum hfi_version ver = inst->core->res->hfi_version; union hfi_get_property hprop; unsigned int i; int ret; @@ -675,12 +676,12 @@ int venus_helper_get_bufreq(struct venus_inst *inst, u32 type, memset(req, 0, sizeof(*req)); if (type == HFI_BUFFER_OUTPUT || type == HFI_BUFFER_OUTPUT2) - req->count_min = inst->fw_min_cnt; + hfi_bufreq_set_count_min(req, ver, inst->fw_min_cnt); ret = platform_get_bufreq(inst, type, req); if (!ret) { if (type == HFI_BUFFER_OUTPUT || type == HFI_BUFFER_OUTPUT2) - inst->fw_min_cnt = req->count_min; + inst->fw_min_cnt = hfi_bufreq_get_count_min(req, ver); return 0; } diff --git a/drivers/media/platform/qcom/venus/hfi_helper.h b/drivers/media/platform/qcom/venus/hfi_helper.h index 0abbc50c5864..e4c05d62cfc7 100644 --- a/drivers/media/platform/qcom/venus/hfi_helper.h +++ b/drivers/media/platform/qcom/venus/hfi_helper.h @@ -1170,14 +1170,6 @@ struct hfi_buffer_display_hold_count_actual { u32 hold_count; }; -/* HFI 4XX reorder the fields, use these macros */ -#define HFI_BUFREQ_HOLD_COUNT(bufreq, ver) \ - ((ver) == HFI_VERSION_4XX ? 0 : (bufreq)->hold_count) -#define HFI_BUFREQ_COUNT_MIN(bufreq, ver) \ - ((ver) == HFI_VERSION_4XX ? (bufreq)->hold_count : (bufreq)->count_min) -#define HFI_BUFREQ_COUNT_MIN_HOST(bufreq, ver) \ - ((ver) == HFI_VERSION_4XX ? (bufreq)->count_min : 0) - struct hfi_buffer_requirements { u32 type; u32 size; @@ -1189,6 +1181,59 @@ struct hfi_buffer_requirements { u32 alignment; }; +/* On HFI 4XX, some of the struct members have been swapped. */ +static inline u32 hfi_bufreq_get_hold_count(struct hfi_buffer_requirements *req, + u32 ver) +{ + if (ver == HFI_VERSION_4XX) + return 0; + + return req->hold_count; +}; + +static inline u32 hfi_bufreq_get_count_min(struct hfi_buffer_requirements *req, + u32 ver) +{ + if (ver == HFI_VERSION_4XX) + return req->hold_count; + + return req->count_min; +}; + +static inline u32 hfi_bufreq_get_count_min_host(struct hfi_buffer_requirements *req, + u32 ver) +{ + if (ver == HFI_VERSION_4XX) + return req->count_min; + + return 0; +}; + +static inline void hfi_bufreq_set_hold_count(struct hfi_buffer_requirements *req, + u32 ver, u32 val) +{ + if (ver == HFI_VERSION_4XX) + return; + + req->hold_count = val; +}; + +static inline void hfi_bufreq_set_count_min(struct hfi_buffer_requirements *req, + u32 ver, u32 val) +{ + if (ver == HFI_VERSION_4XX) + req->hold_count = val; + + req->count_min = val; +}; + +static inline void hfi_bufreq_set_count_min_host(struct hfi_buffer_requirements *req, + u32 ver, u32 val) +{ + if (ver == HFI_VERSION_4XX) + req->count_min = val; +}; + struct hfi_data_payload { u32 size; u8 data[1]; diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c index 3d5dadfa1900..7cab685a2ec8 100644 --- a/drivers/media/platform/qcom/venus/hfi_msgs.c +++ b/drivers/media/platform/qcom/venus/hfi_msgs.c @@ -99,7 +99,7 @@ static void event_seq_changed(struct venus_core *core, struct venus_inst *inst, case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS: data_ptr += sizeof(u32); bufreq = (struct hfi_buffer_requirements *)data_ptr; - event.buf_count = HFI_BUFREQ_COUNT_MIN(bufreq, ver); + event.buf_count = hfi_bufreq_get_count_min(bufreq, ver); data_ptr += sizeof(*bufreq); break; case HFI_INDEX_EXTRADATA_INPUT_CROP: diff --git a/drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c b/drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c index e97ff8cf6d64..f5a655973c08 100644 --- a/drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c +++ b/drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c @@ -1215,24 +1215,24 @@ static int bufreq_dec(struct hfi_plat_buffers_params *params, u32 buftype, out_min_count = output_buffer_count(VIDC_SESSION_TYPE_DEC, codec); /* Max of driver and FW count */ - out_min_count = max(out_min_count, bufreq->count_min); + out_min_count = max(out_min_count, hfi_bufreq_get_count_min(bufreq, version)); bufreq->type = buftype; bufreq->region_size = 0; - bufreq->count_min = 1; bufreq->count_actual = 1; - bufreq->hold_count = 1; + hfi_bufreq_set_count_min(bufreq, version, 1); + hfi_bufreq_set_hold_count(bufreq, version, 1); bufreq->contiguous = 1; bufreq->alignment = 256; if (buftype == HFI_BUFFER_INPUT) { - bufreq->count_min = MIN_INPUT_BUFFERS; + hfi_bufreq_set_count_min(bufreq, version, MIN_INPUT_BUFFERS); bufreq->size = calculate_dec_input_frame_size(width, height, codec, max_mbs_per_frame, buffer_size_limit); } else if (buftype == HFI_BUFFER_OUTPUT || buftype == HFI_BUFFER_OUTPUT2) { - bufreq->count_min = out_min_count; + hfi_bufreq_set_count_min(bufreq, version, out_min_count); bufreq->size = venus_helper_get_framesz_raw(params->hfi_color_fmt, out_width, out_height); @@ -1269,7 +1269,7 @@ static int bufreq_enc(struct hfi_plat_buffers_params *params, u32 buftype, u32 work_mode = params->enc.work_mode; u32 rc_type = params->enc.rc_type; u32 num_vpp_pipes = params->num_vpp_pipes; - u32 num_ref; + u32 num_ref, count_min; switch (codec) { case V4L2_PIX_FMT_H264: @@ -1289,21 +1289,21 @@ static int bufreq_enc(struct hfi_plat_buffers_params *params, u32 buftype, bufreq->type = buftype; bufreq->region_size = 0; - bufreq->count_min = 1; bufreq->count_actual = 1; - bufreq->hold_count = 1; + hfi_bufreq_set_count_min(bufreq, version, 1); + hfi_bufreq_set_hold_count(bufreq, version, 1); bufreq->contiguous = 1; bufreq->alignment = 256; if (buftype == HFI_BUFFER_INPUT) { - bufreq->count_min = MIN_INPUT_BUFFERS; + hfi_bufreq_set_count_min(bufreq, version, MIN_INPUT_BUFFERS); bufreq->size = venus_helper_get_framesz_raw(params->hfi_color_fmt, width, height); } else if (buftype == HFI_BUFFER_OUTPUT || buftype == HFI_BUFFER_OUTPUT2) { - bufreq->count_min = - output_buffer_count(VIDC_SESSION_TYPE_ENC, codec); + count_min = output_buffer_count(VIDC_SESSION_TYPE_ENC, codec); + hfi_bufreq_set_count_min(bufreq, version, count_min); bufreq->size = calculate_enc_output_frame_size(width, height, rc_type); } else if (buftype == HFI_BUFFER_INTERNAL_SCRATCH(version)) { diff --git a/drivers/media/platform/qcom/venus/hfi_platform.c b/drivers/media/platform/qcom/venus/hfi_platform.c index f07f554bc5fe..643e5aa138f5 100644 --- a/drivers/media/platform/qcom/venus/hfi_platform.c +++ b/drivers/media/platform/qcom/venus/hfi_platform.c @@ -2,7 +2,7 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. */ -#include <linux/of_device.h> +#include <linux/of.h> #include "hfi_platform.h" #include "core.h" @@ -80,7 +80,7 @@ hfi_platform_get_codecs(struct venus_core *core, u32 *enc_codecs, u32 *dec_codec if (plat->codecs) plat->codecs(enc_codecs, dec_codecs, count); - if (of_device_is_compatible(core->dev->of_node, "qcom,sc7280-venus")) { + if (IS_IRIS2_1(core)) { *enc_codecs &= ~HFI_VIDEO_CODEC_VP8; *dec_codecs &= ~HFI_VIDEO_CODEC_VP8; } diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c index f0b46389e8d5..19fc6575a489 100644 --- a/drivers/media/platform/qcom/venus/hfi_venus.c +++ b/drivers/media/platform/qcom/venus/hfi_venus.c @@ -131,7 +131,6 @@ struct venus_hfi_device { static bool venus_pkt_debug; int venus_fw_debug = HFI_DEBUG_MSG_ERROR | HFI_DEBUG_MSG_FATAL; -static bool venus_sys_idle_indicator; static bool venus_fw_low_power_mode = true; static int venus_hw_rsp_timeout = 1000; static bool venus_fw_coverage; @@ -448,23 +447,25 @@ static int venus_boot_core(struct venus_hfi_device *hdev) { struct device *dev = hdev->core->dev; static const unsigned int max_tries = 100; - u32 ctrl_status = 0, mask_val; + u32 ctrl_status = 0, mask_val = 0; unsigned int count = 0; void __iomem *cpu_cs_base = hdev->core->cpu_cs_base; void __iomem *wrapper_base = hdev->core->wrapper_base; int ret = 0; - writel(BIT(VIDC_CTRL_INIT_CTRL_SHIFT), cpu_cs_base + VIDC_CTRL_INIT); - if (IS_V6(hdev->core)) { + if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core)) { mask_val = readl(wrapper_base + WRAPPER_INTR_MASK); mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BASK_V6 | WRAPPER_INTR_MASK_A2HCPU_MASK); } else { mask_val = WRAPPER_INTR_MASK_A2HVCODEC_MASK; } + writel(mask_val, wrapper_base + WRAPPER_INTR_MASK); - writel(1, cpu_cs_base + CPU_CS_SCIACMDARG3); + if (IS_V1(hdev->core)) + writel(1, cpu_cs_base + CPU_CS_SCIACMDARG3); + writel(BIT(VIDC_CTRL_INIT_CTRL_SHIFT), cpu_cs_base + VIDC_CTRL_INIT); while (!ctrl_status && count < max_tries) { ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0); if ((ctrl_status & CPU_CS_SCIACMDARG0_ERROR_STATUS_MASK) == 4) { @@ -480,7 +481,7 @@ static int venus_boot_core(struct venus_hfi_device *hdev) if (count >= max_tries) ret = -ETIMEDOUT; - if (IS_V6(hdev->core)) { + if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core)) { writel(0x1, cpu_cs_base + CPU_CS_H2XSOFTINTEN_V6); writel(0x0, cpu_cs_base + CPU_CS_X2RPMH_V6); } @@ -548,10 +549,10 @@ static int venus_halt_axi(struct venus_hfi_device *hdev) u32 mask_val; int ret; - if (IS_V6(hdev->core)) { + if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core)) { writel(0x3, cpu_cs_base + CPU_CS_X2RPMH_V6); - if (hdev->core->res->num_vpp_pipes == 1) + if (IS_IRIS2_1(hdev->core)) goto skip_aon_mvp_noc; writel(0x1, aon_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); @@ -927,17 +928,12 @@ static int venus_sys_set_default_properties(struct venus_hfi_device *hdev) if (ret) dev_warn(dev, "setting fw debug msg ON failed (%d)\n", ret); - /* - * Idle indicator is disabled by default on some 4xx firmware versions, - * enable it explicitly in order to make suspend functional by checking - * WFI (wait-for-interrupt) bit. - */ - if (IS_V4(hdev->core) || IS_V6(hdev->core)) - venus_sys_idle_indicator = true; - - ret = venus_sys_set_idle_message(hdev, venus_sys_idle_indicator); - if (ret) - dev_warn(dev, "setting idle response ON failed (%d)\n", ret); + /* HFI_PROPERTY_SYS_IDLE_INDICATOR is not supported beyond 8916 (HFI V1) */ + if (IS_V1(hdev->core)) { + ret = venus_sys_set_idle_message(hdev, false); + if (ret) + dev_warn(dev, "setting idle response ON failed (%d)\n", ret); + } ret = venus_sys_set_power_control(hdev, venus_fw_low_power_mode); if (ret) @@ -1114,7 +1110,7 @@ static irqreturn_t venus_isr(struct venus_core *core) wrapper_base = hdev->core->wrapper_base; status = readl(wrapper_base + WRAPPER_INTR_STATUS); - if (IS_V6(core)) { + if (IS_IRIS2(core) || IS_IRIS2_1(core)) { if (status & WRAPPER_INTR_STATUS_A2H_MASK || status & WRAPPER_INTR_STATUS_A2HWD_MASK_V6 || status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK) @@ -1126,7 +1122,7 @@ static irqreturn_t venus_isr(struct venus_core *core) hdev->irq_status = status; } writel(1, cpu_cs_base + CPU_CS_A2HSOFTINTCLR); - if (!IS_V6(core)) + if (!(IS_IRIS2(core) || IS_IRIS2_1(core))) writel(status, wrapper_base + WRAPPER_INTR_CLEAR); return IRQ_WAKE_THREAD; @@ -1521,7 +1517,7 @@ static bool venus_cpu_and_video_core_idle(struct venus_hfi_device *hdev) void __iomem *cpu_cs_base = hdev->core->cpu_cs_base; u32 ctrl_status, cpu_status; - if (IS_V6(hdev->core)) + if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core)) cpu_status = readl(wrapper_tz_base + WRAPPER_TZ_CPU_STATUS_V6); else cpu_status = readl(wrapper_base + WRAPPER_CPU_STATUS); @@ -1541,7 +1537,7 @@ static bool venus_cpu_idle_and_pc_ready(struct venus_hfi_device *hdev) void __iomem *cpu_cs_base = hdev->core->cpu_cs_base; u32 ctrl_status, cpu_status; - if (IS_V6(hdev->core)) + if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core)) cpu_status = readl(wrapper_tz_base + WRAPPER_TZ_CPU_STATUS_V6); else cpu_status = readl(wrapper_base + WRAPPER_CPU_STATUS); diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index f5676440dd36..dbf305cec120 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -727,7 +727,7 @@ static int vdec_set_work_route(struct venus_inst *inst) u32 ptype = HFI_PROPERTY_PARAM_WORK_ROUTE; struct hfi_video_work_route wr; - if (!IS_V6(inst->core)) + if (!(IS_IRIS2(inst->core) || IS_IRIS2_1(inst->core))) return 0; wr.video_work_route = inst->core->res->num_vpp_pipes; @@ -899,13 +899,13 @@ static int vdec_num_buffers(struct venus_inst *inst, unsigned int *in_num, if (ret) return ret; - *in_num = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); + *in_num = hfi_bufreq_get_count_min(&bufreq, ver); ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq); if (ret) return ret; - *out_num = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); + *out_num = hfi_bufreq_get_count_min(&bufreq, ver); return 0; } @@ -1019,14 +1019,14 @@ static int vdec_verify_conf(struct venus_inst *inst) return ret; if (inst->num_output_bufs < bufreq.count_actual || - inst->num_output_bufs < HFI_BUFREQ_COUNT_MIN(&bufreq, ver)) + inst->num_output_bufs < hfi_bufreq_get_count_min(&bufreq, ver)) return -EINVAL; ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); if (ret) return ret; - if (inst->num_input_bufs < HFI_BUFREQ_COUNT_MIN(&bufreq, ver)) + if (inst->num_input_bufs < hfi_bufreq_get_count_min(&bufreq, ver)) return -EINVAL; return 0; diff --git a/drivers/media/platform/qcom/venus/vdec_ctrls.c b/drivers/media/platform/qcom/venus/vdec_ctrls.c index fbe12a608b21..7e0f29bf7fae 100644 --- a/drivers/media/platform/qcom/venus/vdec_ctrls.c +++ b/drivers/media/platform/qcom/venus/vdec_ctrls.c @@ -79,7 +79,7 @@ static int vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq); if (!ret) - ctrl->val = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); + ctrl->val = hfi_bufreq_get_count_min(&bufreq, ver); break; default: return -EINVAL; diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 6d773b000e8a..44b13696cf82 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -1207,7 +1207,7 @@ static int venc_verify_conf(struct venus_inst *inst) return ret; if (inst->num_output_bufs < bufreq.count_actual || - inst->num_output_bufs < HFI_BUFREQ_COUNT_MIN(&bufreq, ver)) + inst->num_output_bufs < hfi_bufreq_get_count_min(&bufreq, ver)) return -EINVAL; ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); @@ -1215,7 +1215,7 @@ static int venc_verify_conf(struct venus_inst *inst) return ret; if (inst->num_input_bufs < bufreq.count_actual || - inst->num_input_bufs < HFI_BUFREQ_COUNT_MIN(&bufreq, ver)) + inst->num_input_bufs < hfi_bufreq_get_count_min(&bufreq, ver)) return -EINVAL; return 0; diff --git a/drivers/media/platform/qcom/venus/venc_ctrls.c b/drivers/media/platform/qcom/venus/venc_ctrls.c index 7468e43800a9..d9d2a293f3ef 100644 --- a/drivers/media/platform/qcom/venus/venc_ctrls.c +++ b/drivers/media/platform/qcom/venus/venc_ctrls.c @@ -358,7 +358,7 @@ static int venc_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); if (!ret) - ctrl->val = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); + ctrl->val = hfi_bufreq_get_count_min(&bufreq, ver); break; default: return -EINVAL; diff --git a/drivers/media/platform/renesas/rcar-isp.c b/drivers/media/platform/renesas/rcar-isp.c index fee1a066f56b..7360cf3863f2 100644 --- a/drivers/media/platform/renesas/rcar-isp.c +++ b/drivers/media/platform/renesas/rcar-isp.c @@ -12,7 +12,7 @@ #include <linux/module.h> #include <linux/mutex.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> @@ -326,7 +326,7 @@ static const struct v4l2_subdev_ops rcar_isp_subdev_ops = { static int risp_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct rcar_isp *isp = notifier_to_isp(notifier); int pad; @@ -350,7 +350,7 @@ static int risp_notify_bound(struct v4l2_async_notifier *notifier, static void risp_notify_unbind(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct rcar_isp *isp = notifier_to_isp(notifier); @@ -366,7 +366,7 @@ static const struct v4l2_async_notifier_operations risp_notify_ops = { static int risp_parse_dt(struct rcar_isp *isp) { - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct fwnode_handle *fwnode; struct fwnode_handle *ep; unsigned int id; @@ -392,16 +392,16 @@ static int risp_parse_dt(struct rcar_isp *isp) dev_dbg(isp->dev, "Found '%pOF'\n", to_of_node(fwnode)); - v4l2_async_nf_init(&isp->notifier); + v4l2_async_subdev_nf_init(&isp->notifier, &isp->subdev); isp->notifier.ops = &risp_notify_ops; asd = v4l2_async_nf_add_fwnode(&isp->notifier, fwnode, - struct v4l2_async_subdev); + struct v4l2_async_connection); fwnode_handle_put(fwnode); if (IS_ERR(asd)) return PTR_ERR(asd); - ret = v4l2_async_subdev_nf_register(&isp->subdev, &isp->notifier); + ret = v4l2_async_nf_register(&isp->notifier); if (ret) v4l2_async_nf_cleanup(&isp->notifier); diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-core.c b/drivers/media/platform/renesas/rcar-vin/rcar-core.c index 3c4f5eb93be1..809c3a38cc4a 100644 --- a/drivers/media/platform/renesas/rcar-vin/rcar-core.c +++ b/drivers/media/platform/renesas/rcar-vin/rcar-core.c @@ -12,7 +12,6 @@ #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/of_graph.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -252,7 +251,7 @@ static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier) static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asc) { struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); unsigned int i; @@ -264,7 +263,7 @@ static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier, mutex_lock(&vin->group->lock); for (i = 0; i < RVIN_CSI_MAX; i++) { - if (vin->group->remotes[i].asd != asd) + if (vin->group->remotes[i].asc != asc) continue; vin->group->remotes[i].subdev = NULL; vin_dbg(vin, "Unbind %s from slot %u\n", subdev->name, i); @@ -278,7 +277,7 @@ static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier, static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asc) { struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); unsigned int i; @@ -286,7 +285,7 @@ static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier, mutex_lock(&vin->group->lock); for (i = 0; i < RVIN_CSI_MAX; i++) { - if (vin->group->remotes[i].asd != asd) + if (vin->group->remotes[i].asc != asc) continue; vin->group->remotes[i].subdev = subdev; vin_dbg(vin, "Bound %s to slot %u\n", subdev->name, i); @@ -311,7 +310,7 @@ static int rvin_group_parse_of(struct rvin_dev *vin, unsigned int port, struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_CSI2_DPHY, }; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asc; int ret; ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), port, id, 0); @@ -327,14 +326,14 @@ static int rvin_group_parse_of(struct rvin_dev *vin, unsigned int port, goto out; } - asd = v4l2_async_nf_add_fwnode(&vin->group->notifier, fwnode, - struct v4l2_async_subdev); - if (IS_ERR(asd)) { - ret = PTR_ERR(asd); + asc = v4l2_async_nf_add_fwnode(&vin->group->notifier, fwnode, + struct v4l2_async_connection); + if (IS_ERR(asc)) { + ret = PTR_ERR(asc); goto out; } - vin->group->remotes[vep.base.id].asd = asd; + vin->group->remotes[vep.base.id].asc = asc; vin_dbg(vin, "Add group OF device %pOF to slot %u\n", to_of_node(fwnode), vep.base.id); @@ -376,7 +375,7 @@ static int rvin_group_notifier_init(struct rvin_dev *vin, unsigned int port, mutex_unlock(&vin->group->lock); - v4l2_async_nf_init(&vin->group->notifier); + v4l2_async_nf_init(&vin->group->notifier, &vin->v4l2_dev); /* * Some subdevices may overlap but the parser function can handle it and @@ -387,7 +386,7 @@ static int rvin_group_notifier_init(struct rvin_dev *vin, unsigned int port, continue; for (id = 0; id < max_id; id++) { - if (vin->group->remotes[id].asd) + if (vin->group->remotes[id].asc) continue; ret = rvin_group_parse_of(vin->group->vin[i], port, id); @@ -396,11 +395,11 @@ static int rvin_group_notifier_init(struct rvin_dev *vin, unsigned int port, } } - if (list_empty(&vin->group->notifier.asd_list)) + if (list_empty(&vin->group->notifier.waiting_list)) return 0; vin->group->notifier.ops = &rvin_group_notify_ops; - ret = v4l2_async_nf_register(&vin->v4l2_dev, &vin->group->notifier); + ret = v4l2_async_nf_register(&vin->group->notifier); if (ret < 0) { vin_err(vin, "Notifier registration failed\n"); v4l2_async_nf_cleanup(&vin->group->notifier); @@ -611,7 +610,7 @@ static int rvin_parallel_notify_complete(struct v4l2_async_notifier *notifier) static void rvin_parallel_notify_unbind(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asc) { struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); @@ -624,7 +623,7 @@ static void rvin_parallel_notify_unbind(struct v4l2_async_notifier *notifier, static int rvin_parallel_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asc) { struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); int ret; @@ -656,7 +655,7 @@ static int rvin_parallel_parse_of(struct rvin_dev *vin) struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_UNKNOWN, }; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asc; int ret; ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), 0, 0, 0); @@ -687,14 +686,14 @@ static int rvin_parallel_parse_of(struct rvin_dev *vin) goto out; } - asd = v4l2_async_nf_add_fwnode(&vin->notifier, fwnode, - struct v4l2_async_subdev); - if (IS_ERR(asd)) { - ret = PTR_ERR(asd); + asc = v4l2_async_nf_add_fwnode(&vin->notifier, fwnode, + struct v4l2_async_connection); + if (IS_ERR(asc)) { + ret = PTR_ERR(asc); goto out; } - vin->parallel.asd = asd; + vin->parallel.asc = asc; vin_dbg(vin, "Add parallel OF device %pOF\n", to_of_node(fwnode)); out: @@ -713,20 +712,20 @@ static int rvin_parallel_init(struct rvin_dev *vin) { int ret; - v4l2_async_nf_init(&vin->notifier); + v4l2_async_nf_init(&vin->notifier, &vin->v4l2_dev); ret = rvin_parallel_parse_of(vin); if (ret) return ret; - if (!vin->parallel.asd) + if (!vin->parallel.asc) return -ENODEV; vin_dbg(vin, "Found parallel subdevice %pOF\n", - to_of_node(vin->parallel.asd->match.fwnode)); + to_of_node(vin->parallel.asc->match.fwnode)); vin->notifier.ops = &rvin_parallel_notify_ops; - ret = v4l2_async_nf_register(&vin->v4l2_dev, &vin->notifier); + ret = v4l2_async_nf_register(&vin->notifier); if (ret < 0) { vin_err(vin, "Notifier registration failed\n"); v4l2_async_nf_cleanup(&vin->notifier); diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c index 7a134c0eff57..f6326df0b09b 100644 --- a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c @@ -10,7 +10,6 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/of_graph.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -133,6 +132,111 @@ struct rcar_csi2; #define PHYFRX_FORCERX_MODE_1 BIT(1) #define PHYFRX_FORCERX_MODE_0 BIT(0) +/* V4H BASE registers */ +#define V4H_N_LANES_REG 0x0004 +#define V4H_CSI2_RESETN_REG 0x0008 +#define V4H_PHY_MODE_REG 0x001c +#define V4H_PHY_SHUTDOWNZ_REG 0x0040 +#define V4H_DPHY_RSTZ_REG 0x0044 +#define V4H_FLDC_REG 0x0804 +#define V4H_FLDD_REG 0x0808 +#define V4H_IDIC_REG 0x0810 +#define V4H_PHY_EN_REG 0x2000 + +#define V4H_ST_PHYST_REG 0x2814 +#define V4H_ST_PHYST_ST_PHY_READY BIT(31) +#define V4H_ST_PHYST_ST_STOPSTATE_3 BIT(3) +#define V4H_ST_PHYST_ST_STOPSTATE_2 BIT(2) +#define V4H_ST_PHYST_ST_STOPSTATE_1 BIT(1) +#define V4H_ST_PHYST_ST_STOPSTATE_0 BIT(0) + +/* V4H PPI registers */ +#define V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(n) (0x21800 + ((n) * 2)) /* n = 0 - 9 */ +#define V4H_PPI_STARTUP_RW_COMMON_STARTUP_1_1_REG 0x21822 +#define V4H_PPI_CALIBCTRL_RW_COMMON_BG_0_REG 0x2184c +#define V4H_PPI_RW_LPDCOCAL_TIMEBASE_REG 0x21c02 +#define V4H_PPI_RW_LPDCOCAL_NREF_REG 0x21c04 +#define V4H_PPI_RW_LPDCOCAL_NREF_RANGE_REG 0x21c06 +#define V4H_PPI_RW_LPDCOCAL_TWAIT_CONFIG_REG 0x21c0a +#define V4H_PPI_RW_LPDCOCAL_VT_CONFIG_REG 0x21c0c +#define V4H_PPI_RW_LPDCOCAL_COARSE_CFG_REG 0x21c10 +#define V4H_PPI_RW_COMMON_CFG_REG 0x21c6c +#define V4H_PPI_RW_TERMCAL_CFG_0_REG 0x21c80 +#define V4H_PPI_RW_OFFSETCAL_CFG_0_REG 0x21ca0 + +/* V4H CORE registers */ +#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(n) (0x22040 + ((n) * 2)) /* n = 0 - 15 */ +#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_REG(n) (0x22440 + ((n) * 2)) /* n = 0 - 15 */ +#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_REG(n) (0x22840 + ((n) * 2)) /* n = 0 - 15 */ +#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_REG(n) (0x22c40 + ((n) * 2)) /* n = 0 - 15 */ +#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_REG(n) (0x23040 + ((n) * 2)) /* n = 0 - 15 */ +#define V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(n) (0x23840 + ((n) * 2)) /* n = 0 - 11 */ +#define V4H_CORE_DIG_RW_COMMON_REG(n) (0x23880 + ((n) * 2)) /* n = 0 - 15 */ +#define V4H_CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_REG(n) (0x239e0 + ((n) * 2)) /* n = 0 - 3 */ +#define V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG 0x2a400 +#define V4H_CORE_DIG_CLANE_1_RW_HS_TX_6_REG 0x2a60c + +/* V4H C-PHY */ +#define V4H_CORE_DIG_RW_TRIO0_REG(n) (0x22100 + ((n) * 2)) /* n = 0 - 3 */ +#define V4H_CORE_DIG_RW_TRIO1_REG(n) (0x22500 + ((n) * 2)) /* n = 0 - 3 */ +#define V4H_CORE_DIG_RW_TRIO2_REG(n) (0x22900 + ((n) * 2)) /* n = 0 - 3 */ +#define V4H_CORE_DIG_CLANE_0_RW_LP_0_REG 0x2a080 +#define V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(n) (0x2a100 + ((n) * 2)) /* n = 0 - 6 */ +#define V4H_CORE_DIG_CLANE_1_RW_LP_0_REG 0x2a480 +#define V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(n) (0x2a500 + ((n) * 2)) /* n = 0 - 6 */ +#define V4H_CORE_DIG_CLANE_2_RW_LP_0_REG 0x2a880 +#define V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(n) (0x2a900 + ((n) * 2)) /* n = 0 - 6 */ + +struct rcsi2_cphy_setting { + u16 msps; + u16 rx2; + u16 trio0; + u16 trio1; + u16 trio2; + u16 lane27; + u16 lane29; +}; + +static const struct rcsi2_cphy_setting cphy_setting_table_r8a779g0[] = { + { .msps = 80, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0134, .trio2 = 0x6a, .lane27 = 0x0000, .lane29 = 0x0a24 }, + { .msps = 100, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x00f5, .trio2 = 0x55, .lane27 = 0x0000, .lane29 = 0x0a24 }, + { .msps = 200, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0077, .trio2 = 0x2b, .lane27 = 0x0000, .lane29 = 0x0a44 }, + { .msps = 300, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x004d, .trio2 = 0x1d, .lane27 = 0x0000, .lane29 = 0x0a44 }, + { .msps = 400, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0038, .trio2 = 0x16, .lane27 = 0x0000, .lane29 = 0x0a64 }, + { .msps = 500, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x002b, .trio2 = 0x12, .lane27 = 0x0000, .lane29 = 0x0a64 }, + { .msps = 600, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0023, .trio2 = 0x0f, .lane27 = 0x0000, .lane29 = 0x0a64 }, + { .msps = 700, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x001d, .trio2 = 0x0d, .lane27 = 0x0000, .lane29 = 0x0a84 }, + { .msps = 800, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0018, .trio2 = 0x0c, .lane27 = 0x0000, .lane29 = 0x0a84 }, + { .msps = 900, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0015, .trio2 = 0x0b, .lane27 = 0x0000, .lane29 = 0x0a84 }, + { .msps = 1000, .rx2 = 0x3e, .trio0 = 0x024a, .trio1 = 0x0012, .trio2 = 0x0a, .lane27 = 0x0400, .lane29 = 0x0a84 }, + { .msps = 1100, .rx2 = 0x44, .trio0 = 0x024a, .trio1 = 0x000f, .trio2 = 0x09, .lane27 = 0x0800, .lane29 = 0x0a84 }, + { .msps = 1200, .rx2 = 0x4a, .trio0 = 0x024a, .trio1 = 0x000e, .trio2 = 0x08, .lane27 = 0x0c00, .lane29 = 0x0a84 }, + { .msps = 1300, .rx2 = 0x51, .trio0 = 0x024a, .trio1 = 0x000c, .trio2 = 0x08, .lane27 = 0x0c00, .lane29 = 0x0aa4 }, + { .msps = 1400, .rx2 = 0x57, .trio0 = 0x024a, .trio1 = 0x000b, .trio2 = 0x07, .lane27 = 0x1000, .lane29 = 0x0aa4 }, + { .msps = 1500, .rx2 = 0x5d, .trio0 = 0x044a, .trio1 = 0x0009, .trio2 = 0x07, .lane27 = 0x1000, .lane29 = 0x0aa4 }, + { .msps = 1600, .rx2 = 0x63, .trio0 = 0x044a, .trio1 = 0x0008, .trio2 = 0x07, .lane27 = 0x1400, .lane29 = 0x0aa4 }, + { .msps = 1700, .rx2 = 0x6a, .trio0 = 0x044a, .trio1 = 0x0007, .trio2 = 0x06, .lane27 = 0x1400, .lane29 = 0x0aa4 }, + { .msps = 1800, .rx2 = 0x70, .trio0 = 0x044a, .trio1 = 0x0007, .trio2 = 0x06, .lane27 = 0x1400, .lane29 = 0x0aa4 }, + { .msps = 1900, .rx2 = 0x76, .trio0 = 0x044a, .trio1 = 0x0006, .trio2 = 0x06, .lane27 = 0x1400, .lane29 = 0x0aa4 }, + { .msps = 2000, .rx2 = 0x7c, .trio0 = 0x044a, .trio1 = 0x0005, .trio2 = 0x06, .lane27 = 0x1800, .lane29 = 0x0aa4 }, + { .msps = 2100, .rx2 = 0x83, .trio0 = 0x044a, .trio1 = 0x0005, .trio2 = 0x05, .lane27 = 0x1800, .lane29 = 0x0aa4 }, + { .msps = 2200, .rx2 = 0x89, .trio0 = 0x064a, .trio1 = 0x0004, .trio2 = 0x05, .lane27 = 0x1800, .lane29 = 0x0aa4 }, + { .msps = 2300, .rx2 = 0x8f, .trio0 = 0x064a, .trio1 = 0x0003, .trio2 = 0x05, .lane27 = 0x1800, .lane29 = 0x0aa4 }, + { .msps = 2400, .rx2 = 0x95, .trio0 = 0x064a, .trio1 = 0x0003, .trio2 = 0x05, .lane27 = 0x1800, .lane29 = 0x0aa4 }, + { .msps = 2500, .rx2 = 0x9c, .trio0 = 0x064a, .trio1 = 0x0003, .trio2 = 0x05, .lane27 = 0x1c00, .lane29 = 0x0aa4 }, + { .msps = 2600, .rx2 = 0xa2, .trio0 = 0x064a, .trio1 = 0x0002, .trio2 = 0x05, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 2700, .rx2 = 0xa8, .trio0 = 0x064a, .trio1 = 0x0002, .trio2 = 0x05, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 2800, .rx2 = 0xae, .trio0 = 0x064a, .trio1 = 0x0002, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 2900, .rx2 = 0xb5, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 3000, .rx2 = 0xbb, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 3100, .rx2 = 0xc1, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 3200, .rx2 = 0xc7, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 3300, .rx2 = 0xce, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 3400, .rx2 = 0xd4, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 3500, .rx2 = 0xda, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { /* sentinel */ }, +}; + struct phtw_value { u16 data; u16 code; @@ -538,6 +642,11 @@ static void rcsi2_write(struct rcar_csi2 *priv, unsigned int reg, u32 data) iowrite32(data, priv->base + reg); } +static void rcsi2_write16(struct rcar_csi2 *priv, unsigned int reg, u16 data) +{ + iowrite16(data, priv->base + reg); +} + static void rcsi2_enter_standby_gen3(struct rcar_csi2 *priv) { rcsi2_write(priv, PHYCNT_REG, 0); @@ -645,6 +754,10 @@ static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp, mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * bpp; do_div(mbps, lanes * 1000000); + /* Adjust for C-PHY, divide by 2.8. */ + if (priv->cphy) + mbps = div_u64(mbps * 5, 14); + return mbps; } @@ -834,6 +947,173 @@ static int rcsi2_start_receiver_gen3(struct rcar_csi2 *priv) return 0; } +static int rcsi2_wait_phy_start_v4h(struct rcar_csi2 *priv, u32 match) +{ + unsigned int timeout; + u32 status; + + for (timeout = 0; timeout <= 10; timeout++) { + status = rcsi2_read(priv, V4H_ST_PHYST_REG); + if ((status & match) == match) + return 0; + + usleep_range(1000, 2000); + } + + return -ETIMEDOUT; +} + +static int rcsi2_c_phy_setting_v4h(struct rcar_csi2 *priv, int msps) +{ + const struct rcsi2_cphy_setting *conf; + + for (conf = cphy_setting_table_r8a779g0; conf->msps != 0; conf++) { + if (conf->msps > msps) + break; + } + + if (!conf->msps) { + dev_err(priv->dev, "Unsupported PHY speed for msps setting (%u Msps)", msps); + return -ERANGE; + } + + /* C-PHY specific */ + rcsi2_write16(priv, V4H_CORE_DIG_RW_COMMON_REG(7), 0x0155); + rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(7), 0x0068); + rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(8), 0x0010); + + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_LP_0_REG, 0x463c); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_LP_0_REG, 0x463c); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_LP_0_REG, 0x463c); + + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(0), 0x00d5); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(0), 0x00d5); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(0), 0x00d5); + + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(1), 0x0013); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(1), 0x0013); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(1), 0x0013); + + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(5), 0x0013); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(5), 0x0013); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(5), 0x0013); + + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(6), 0x000a); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(6), 0x000a); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(6), 0x000a); + + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(2), conf->rx2); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(2), conf->rx2); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(2), conf->rx2); + + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(2), 0x0001); + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_REG(2), 0); + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_REG(2), 0x0001); + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_REG(2), 0x0001); + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_REG(2), 0); + + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO0_REG(0), conf->trio0); + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO1_REG(0), conf->trio0); + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO2_REG(0), conf->trio0); + + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO0_REG(2), conf->trio2); + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO1_REG(2), conf->trio2); + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO2_REG(2), conf->trio2); + + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO0_REG(1), conf->trio1); + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO1_REG(1), conf->trio1); + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO2_REG(1), conf->trio1); + + /* + * Configure pin-swap. + * TODO: This registers is not documented yet, the values should depend + * on the 'clock-lanes' and 'data-lanes' devicetree properties. + */ + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG, 0xf5); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_TX_6_REG, 0x5000); + + /* Leave Shutdown mode */ + rcsi2_write(priv, V4H_DPHY_RSTZ_REG, BIT(0)); + rcsi2_write(priv, V4H_PHY_SHUTDOWNZ_REG, BIT(0)); + + /* Wait for calibration */ + if (rcsi2_wait_phy_start_v4h(priv, V4H_ST_PHYST_ST_PHY_READY)) { + dev_err(priv->dev, "PHY calibration failed\n"); + return -ETIMEDOUT; + } + + /* C-PHY setting - analog programing*/ + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(9), conf->lane29); + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(7), conf->lane27); + + return 0; +} + +static int rcsi2_start_receiver_v4h(struct rcar_csi2 *priv) +{ + const struct rcar_csi2_format *format; + unsigned int lanes; + int msps; + int ret; + + /* Calculate parameters */ + format = rcsi2_code_to_fmt(priv->mf.code); + if (!format) + return -EINVAL; + + ret = rcsi2_get_active_lanes(priv, &lanes); + if (ret) + return ret; + + msps = rcsi2_calc_mbps(priv, format->bpp, lanes); + if (msps < 0) + return msps; + + /* Reset LINK and PHY*/ + rcsi2_write(priv, V4H_CSI2_RESETN_REG, 0); + rcsi2_write(priv, V4H_DPHY_RSTZ_REG, 0); + rcsi2_write(priv, V4H_PHY_SHUTDOWNZ_REG, 0); + + /* PHY static setting */ + rcsi2_write(priv, V4H_PHY_EN_REG, BIT(0)); + rcsi2_write(priv, V4H_FLDC_REG, 0); + rcsi2_write(priv, V4H_FLDD_REG, 0); + rcsi2_write(priv, V4H_IDIC_REG, 0); + rcsi2_write(priv, V4H_PHY_MODE_REG, BIT(0)); + rcsi2_write(priv, V4H_N_LANES_REG, lanes - 1); + + /* Reset CSI2 */ + rcsi2_write(priv, V4H_CSI2_RESETN_REG, BIT(0)); + + /* Registers static setting through APB */ + /* Common setting */ + rcsi2_write16(priv, V4H_CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_REG(0), 0x1bfd); + rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_STARTUP_1_1_REG, 0x0233); + rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(6), 0x0027); + rcsi2_write16(priv, V4H_PPI_CALIBCTRL_RW_COMMON_BG_0_REG, 0x01f4); + rcsi2_write16(priv, V4H_PPI_RW_TERMCAL_CFG_0_REG, 0x0013); + rcsi2_write16(priv, V4H_PPI_RW_OFFSETCAL_CFG_0_REG, 0x0003); + rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_TIMEBASE_REG, 0x004f); + rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_NREF_REG, 0x0320); + rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_NREF_RANGE_REG, 0x000f); + rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_TWAIT_CONFIG_REG, 0xfe18); + rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_VT_CONFIG_REG, 0x0c3c); + rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_COARSE_CFG_REG, 0x0105); + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(6), 0x1000); + rcsi2_write16(priv, V4H_PPI_RW_COMMON_CFG_REG, 0x0003); + + /* C-PHY settings */ + ret = rcsi2_c_phy_setting_v4h(priv, msps); + if (ret) + return ret; + + rcsi2_wait_phy_start_v4h(priv, V4H_ST_PHYST_ST_STOPSTATE_0 | + V4H_ST_PHYST_ST_STOPSTATE_1 | + V4H_ST_PHYST_ST_STOPSTATE_2); + + return 0; +} + static int rcsi2_start(struct rcar_csi2 *priv) { int ret; @@ -989,12 +1269,12 @@ static irqreturn_t rcsi2_irq_thread(int irq, void *data) static int rcsi2_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asc) { struct rcar_csi2 *priv = notifier_to_csi2(notifier); int pad; - pad = media_entity_get_fwnode_pad(&subdev->entity, asd->match.fwnode, + pad = media_entity_get_fwnode_pad(&subdev->entity, asc->match.fwnode, MEDIA_PAD_FL_SOURCE); if (pad < 0) { dev_err(priv->dev, "Failed to find pad for %s\n", subdev->name); @@ -1014,7 +1294,7 @@ static int rcsi2_notify_bound(struct v4l2_async_notifier *notifier, static void rcsi2_notify_unbind(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asc) { struct rcar_csi2 *priv = notifier_to_csi2(notifier); @@ -1091,7 +1371,7 @@ static int rcsi2_parse_v4l2(struct rcar_csi2 *priv, static int rcsi2_parse_dt(struct rcar_csi2 *priv) { - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asc; struct fwnode_handle *fwnode; struct fwnode_handle *ep; struct v4l2_fwnode_endpoint v4l2_ep = { @@ -1123,16 +1403,16 @@ static int rcsi2_parse_dt(struct rcar_csi2 *priv) dev_dbg(priv->dev, "Found '%pOF'\n", to_of_node(fwnode)); - v4l2_async_nf_init(&priv->notifier); + v4l2_async_subdev_nf_init(&priv->notifier, &priv->subdev); priv->notifier.ops = &rcar_csi2_notify_ops; - asd = v4l2_async_nf_add_fwnode(&priv->notifier, fwnode, - struct v4l2_async_subdev); + asc = v4l2_async_nf_add_fwnode(&priv->notifier, fwnode, + struct v4l2_async_connection); fwnode_handle_put(fwnode); - if (IS_ERR(asd)) - return PTR_ERR(asd); + if (IS_ERR(asc)) + return PTR_ERR(asc); - ret = v4l2_async_subdev_nf_register(&priv->subdev, &priv->notifier); + ret = v4l2_async_nf_register(&priv->notifier); if (ret) v4l2_async_nf_cleanup(&priv->notifier); @@ -1496,6 +1776,12 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a779a0 = { .support_dphy = true, }; +static const struct rcar_csi2_info rcar_csi2_info_r8a779g0 = { + .start_receiver = rcsi2_start_receiver_v4h, + .use_isp = true, + .support_cphy = true, +}; + static const struct of_device_id rcar_csi2_of_table[] = { { .compatible = "renesas,r8a774a1-csi2", @@ -1545,6 +1831,10 @@ static const struct of_device_id rcar_csi2_of_table[] = { .compatible = "renesas,r8a779a0-csi2", .data = &rcar_csi2_info_r8a779a0, }, + { + .compatible = "renesas,r8a779g0-csi2", + .data = &rcar_csi2_info_r8a779g0, + }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, rcar_csi2_of_table); diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-vin.h b/drivers/media/platform/renesas/rcar-vin/rcar-vin.h index cb206d3976dd..792336dada44 100644 --- a/drivers/media/platform/renesas/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/renesas/rcar-vin/rcar-vin.h @@ -106,7 +106,7 @@ struct rvin_video_format { /** * struct rvin_parallel_entity - Parallel video input endpoint descriptor - * @asd: sub-device descriptor for async framework + * @asc: async connection descriptor for async framework * @subdev: subdevice matched using async framework * @mbus_type: media bus type * @bus: media bus parallel configuration @@ -115,7 +115,7 @@ struct rvin_video_format { * */ struct rvin_parallel_entity { - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asc; struct v4l2_subdev *subdev; enum v4l2_mbus_type mbus_type; @@ -272,10 +272,10 @@ struct rvin_dev { * * @lock: protects the count, notifier, vin and csi members * @count: number of enabled VIN instances found in DT - * @notifier: group notifier for CSI-2 async subdevices + * @notifier: group notifier for CSI-2 async connections * @vin: VIN instances which are part of the group * @link_setup: Callback to create all links for the media graph - * @remotes: array of pairs of fwnode and subdev pointers + * @remotes: array of pairs of async connection and subdev pointers * to all remote subdevices. */ struct rvin_group { @@ -291,7 +291,7 @@ struct rvin_group { int (*link_setup)(struct rvin_dev *vin); struct { - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asc; struct v4l2_subdev *subdev; } remotes[RVIN_REMOTES_MAX]; }; diff --git a/drivers/media/platform/renesas/rcar_drif.c b/drivers/media/platform/renesas/rcar_drif.c index 3a92f4535c18..163a4ba61c17 100644 --- a/drivers/media/platform/renesas/rcar_drif.c +++ b/drivers/media/platform/renesas/rcar_drif.c @@ -44,8 +44,9 @@ #include <linux/ioctl.h> #include <linux/iopoll.h> #include <linux/module.h> +#include <linux/of.h> #include <linux/of_graph.h> -#include <linux/of_device.h> +#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/sched.h> #include <media/v4l2-async.h> @@ -1097,7 +1098,7 @@ static void rcar_drif_sdr_unregister(struct rcar_drif_sdr *sdr) /* Sub-device bound callback */ static int rcar_drif_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct rcar_drif_sdr *sdr = container_of(notifier, struct rcar_drif_sdr, notifier); @@ -1112,7 +1113,7 @@ static int rcar_drif_notify_bound(struct v4l2_async_notifier *notifier, /* Sub-device unbind callback */ static void rcar_drif_notify_unbind(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct rcar_drif_sdr *sdr = container_of(notifier, struct rcar_drif_sdr, notifier); @@ -1205,9 +1206,9 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr) { struct v4l2_async_notifier *notifier = &sdr->notifier; struct fwnode_handle *fwnode, *ep; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; - v4l2_async_nf_init(notifier); + v4l2_async_nf_init(&sdr->notifier, &sdr->v4l2_dev); ep = fwnode_graph_get_next_endpoint(of_fwnode_handle(sdr->dev->of_node), NULL); @@ -1225,7 +1226,7 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr) } asd = v4l2_async_nf_add_fwnode(notifier, fwnode, - struct v4l2_async_subdev); + struct v4l2_async_connection); fwnode_handle_put(fwnode); if (IS_ERR(asd)) return PTR_ERR(asd); @@ -1341,7 +1342,7 @@ static int rcar_drif_sdr_probe(struct rcar_drif_sdr *sdr) sdr->notifier.ops = &rcar_drif_notify_ops; /* Register notifier */ - ret = v4l2_async_nf_register(&sdr->v4l2_dev, &sdr->notifier); + ret = v4l2_async_nf_register(&sdr->notifier); if (ret < 0) { dev_err(sdr->dev, "failed: notifier register ret %d\n", ret); goto cleanup; diff --git a/drivers/media/platform/renesas/rcar_fdp1.c b/drivers/media/platform/renesas/rcar_fdp1.c index ab39cd2201c8..a2565b269f3b 100644 --- a/drivers/media/platform/renesas/rcar_fdp1.c +++ b/drivers/media/platform/renesas/rcar_fdp1.c @@ -18,7 +18,6 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/sched.h> diff --git a/drivers/media/platform/renesas/rcar_jpu.c b/drivers/media/platform/renesas/rcar_jpu.c index 2b8cb50f54de..fff349e45067 100644 --- a/drivers/media/platform/renesas/rcar_jpu.c +++ b/drivers/media/platform/renesas/rcar_jpu.c @@ -22,7 +22,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/spinlock.h> @@ -1601,10 +1600,8 @@ static int jpu_probe(struct platform_device *pdev) /* interrupt service routine registration */ jpu->irq = ret = platform_get_irq(pdev, 0); - if (ret < 0) { - dev_err(&pdev->dev, "cannot find IRQ\n"); + if (ret < 0) return ret; - } ret = devm_request_irq(&pdev->dev, jpu->irq, jpu_irq_handler, 0, dev_name(&pdev->dev), jpu); diff --git a/drivers/media/platform/renesas/renesas-ceu.c b/drivers/media/platform/renesas/renesas-ceu.c index 5c9e27f8c94b..ec631c6e2a57 100644 --- a/drivers/media/platform/renesas/renesas-ceu.c +++ b/drivers/media/platform/renesas/renesas-ceu.c @@ -22,7 +22,6 @@ #include <linux/mm.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/of_graph.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -152,7 +151,7 @@ static inline struct ceu_buffer *vb2_to_ceu(struct vb2_v4l2_buffer *vbuf) * ceu_subdev - Wraps v4l2 sub-device and provides async subdevice. */ struct ceu_subdev { - struct v4l2_async_subdev asd; + struct v4l2_async_connection asd; struct v4l2_subdev *v4l2_sd; /* per-subdevice mbus configuration options */ @@ -160,7 +159,7 @@ struct ceu_subdev { struct ceu_mbus_fmt mbus_fmt; }; -static struct ceu_subdev *to_ceu_subdev(struct v4l2_async_subdev *asd) +static struct ceu_subdev *to_ceu_subdev(struct v4l2_async_connection *asd) { return container_of(asd, struct ceu_subdev, asd); } @@ -1375,7 +1374,7 @@ static void ceu_vdev_release(struct video_device *vdev) static int ceu_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *v4l2_sd, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct v4l2_device *v4l2_dev = notifier->v4l2_dev; struct ceu_device *ceudev = v4l2_to_ceu(v4l2_dev); @@ -1658,7 +1657,7 @@ static int ceu_probe(struct platform_device *pdev) if (ret) goto error_pm_disable; - v4l2_async_nf_init(&ceudev->notifier); + v4l2_async_nf_init(&ceudev->notifier, &ceudev->v4l2_dev); if (IS_ENABLED(CONFIG_OF) && dev->of_node) { ceu_data = of_device_get_match_data(dev); @@ -1680,7 +1679,7 @@ static int ceu_probe(struct platform_device *pdev) ceudev->notifier.v4l2_dev = &ceudev->v4l2_dev; ceudev->notifier.ops = &ceu_notify_ops; - ret = v4l2_async_nf_register(&ceudev->v4l2_dev, &ceudev->notifier); + ret = v4l2_async_nf_register(&ceudev->notifier); if (ret) goto error_cleanup; diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c index 7a71370fcc32..280efd2a8185 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c @@ -14,7 +14,6 @@ #include <linux/module.h> #include <linux/mod_devicetable.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/of_graph.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -93,7 +92,7 @@ static int rzg2l_cru_group_notify_complete(struct v4l2_async_notifier *notifier) static void rzg2l_cru_group_notify_unbind(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct rzg2l_cru_dev *cru = notifier_to_cru(notifier); @@ -111,7 +110,7 @@ static void rzg2l_cru_group_notify_unbind(struct v4l2_async_notifier *notifier, static int rzg2l_cru_group_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct rzg2l_cru_dev *cru = notifier_to_cru(notifier); @@ -139,7 +138,7 @@ static int rzg2l_cru_mc_parse_of(struct rzg2l_cru_dev *cru) .bus_type = V4L2_MBUS_CSI2_DPHY, }; struct fwnode_handle *ep, *fwnode; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; int ret; ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(cru->dev), 1, 0, 0); @@ -163,7 +162,7 @@ static int rzg2l_cru_mc_parse_of(struct rzg2l_cru_dev *cru) } asd = v4l2_async_nf_add_fwnode(&cru->notifier, fwnode, - struct v4l2_async_subdev); + struct v4l2_async_connection); if (IS_ERR(asd)) { ret = PTR_ERR(asd); goto out; @@ -183,7 +182,7 @@ static int rzg2l_cru_mc_parse_of_graph(struct rzg2l_cru_dev *cru) { int ret; - v4l2_async_nf_init(&cru->notifier); + v4l2_async_nf_init(&cru->notifier, &cru->v4l2_dev); ret = rzg2l_cru_mc_parse_of(cru); if (ret) @@ -191,10 +190,10 @@ static int rzg2l_cru_mc_parse_of_graph(struct rzg2l_cru_dev *cru) cru->notifier.ops = &rzg2l_cru_async_ops; - if (list_empty(&cru->notifier.asd_list)) + if (list_empty(&cru->notifier.waiting_list)) return 0; - ret = v4l2_async_nf_register(&cru->v4l2_dev, &cru->notifier); + ret = v4l2_async_nf_register(&cru->notifier); if (ret < 0) { dev_err(cru->dev, "Notifier registration failed\n"); v4l2_async_nf_cleanup(&cru->notifier); diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h index 0b682cbae3eb..811603f18af0 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h @@ -45,7 +45,7 @@ enum rzg2l_cru_dma_state { }; struct rzg2l_cru_csi { - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct v4l2_subdev *subdev; u32 channel; }; diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c index d6489c62b081..ad2bd71037ab 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c @@ -11,7 +11,6 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/of_graph.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -600,7 +599,7 @@ static const struct v4l2_subdev_ops rzg2l_csi2_subdev_ops = { static int rzg2l_csi2_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct rzg2l_csi2 *csi2 = notifier_to_csi2(notifier); @@ -616,7 +615,7 @@ static int rzg2l_csi2_notify_bound(struct v4l2_async_notifier *notifier, static void rzg2l_csi2_notify_unbind(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct rzg2l_csi2 *csi2 = notifier_to_csi2(notifier); @@ -647,7 +646,7 @@ static int rzg2l_csi2_parse_dt(struct rzg2l_csi2 *csi2) struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = V4L2_MBUS_CSI2_DPHY }; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct fwnode_handle *fwnode; struct fwnode_handle *ep; int ret; @@ -674,16 +673,16 @@ static int rzg2l_csi2_parse_dt(struct rzg2l_csi2 *csi2) fwnode = fwnode_graph_get_remote_endpoint(ep); fwnode_handle_put(ep); - v4l2_async_nf_init(&csi2->notifier); + v4l2_async_subdev_nf_init(&csi2->notifier, &csi2->subdev); csi2->notifier.ops = &rzg2l_csi2_notify_ops; asd = v4l2_async_nf_add_fwnode(&csi2->notifier, fwnode, - struct v4l2_async_subdev); + struct v4l2_async_connection); fwnode_handle_put(fwnode); if (IS_ERR(asd)) return PTR_ERR(asd); - ret = v4l2_async_subdev_nf_register(&csi2->subdev, &csi2->notifier); + ret = v4l2_async_nf_register(&csi2->notifier); if (ret) v4l2_async_nf_cleanup(&csi2->notifier); diff --git a/drivers/media/platform/renesas/sh_vou.c b/drivers/media/platform/renesas/sh_vou.c index 8fe3272a541f..f792aedc9d82 100644 --- a/drivers/media/platform/renesas/sh_vou.c +++ b/drivers/media/platform/renesas/sh_vou.c @@ -1223,19 +1223,19 @@ static int sh_vou_probe(struct platform_device *pdev) struct i2c_adapter *i2c_adap; struct video_device *vdev; struct sh_vou_device *vou_dev; - struct resource *reg_res; struct v4l2_subdev *subdev; struct vb2_queue *q; int irq, ret; - reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - - if (!vou_pdata || !reg_res || irq <= 0) { + if (!vou_pdata) { dev_err(&pdev->dev, "Insufficient VOU platform information.\n"); return -ENODEV; } + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + vou_dev = devm_kzalloc(&pdev->dev, sizeof(*vou_dev), GFP_KERNEL); if (!vou_dev) return -ENOMEM; @@ -1264,7 +1264,7 @@ static int sh_vou_probe(struct platform_device *pdev) pix->sizeimage = VOU_MAX_IMAGE_WIDTH * 2 * 480; pix->colorspace = V4L2_COLORSPACE_SMPTE170M; - vou_dev->base = devm_ioremap_resource(&pdev->dev, reg_res); + vou_dev->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(vou_dev->base)) return PTR_ERR(vou_dev->base); diff --git a/drivers/media/platform/renesas/vsp1/vsp1_drv.c b/drivers/media/platform/renesas/vsp1/vsp1_drv.c index a9db84be4822..1aac44d68731 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_drv.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_drv.c @@ -13,7 +13,6 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h index a1293c45aae1..d30f0ecb1bfd 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h @@ -148,7 +148,7 @@ struct rkisp1_info { * @port: port number (0: MIPI, 1: Parallel) */ struct rkisp1_sensor_async { - struct v4l2_async_subdev asd; + struct v4l2_async_connection asd; unsigned int index; struct fwnode_handle *source_ep; unsigned int lanes; diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c index d7acc94e10f8..fdff3d0da4e5 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c @@ -381,6 +381,7 @@ static int rkisp1_csi_s_stream(struct v4l2_subdev *sd, int enable) struct rkisp1_csi *csi = to_rkisp1_csi(sd); struct rkisp1_device *rkisp1 = csi->rkisp1; struct rkisp1_sensor_async *source_asd; + struct v4l2_async_connection *asc; struct media_pad *source_pad; struct v4l2_subdev *source; int ret; @@ -406,7 +407,11 @@ static int rkisp1_csi_s_stream(struct v4l2_subdev *sd, int enable) return -EPIPE; } - source_asd = container_of(source->asd, struct rkisp1_sensor_async, asd); + asc = v4l2_async_connection_unique(source); + if (!asc) + return -EPIPE; + + source_asd = container_of(asc, struct rkisp1_sensor_async, asd); if (source_asd->mbus_type != V4L2_MBUS_CSI2_DPHY) return -EINVAL; diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c index 4762cb32353d..c41abd2833f1 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c @@ -13,7 +13,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_graph.h> -#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <linux/pinctrl/consumer.h> #include <linux/pm_runtime.h> #include <media/v4l2-fwnode.h> @@ -122,12 +122,12 @@ struct rkisp1_isr_data { static int rkisp1_subdev_notifier_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asc) { struct rkisp1_device *rkisp1 = container_of(notifier, struct rkisp1_device, notifier); struct rkisp1_sensor_async *s_asd = - container_of(asd, struct rkisp1_sensor_async, asd); + container_of(asc, struct rkisp1_sensor_async, asd); int source_pad; int ret; @@ -165,10 +165,10 @@ static int rkisp1_subdev_notifier_complete(struct v4l2_async_notifier *notifier) return v4l2_device_register_subdev_nodes(&rkisp1->v4l2_dev); } -static void rkisp1_subdev_notifier_destroy(struct v4l2_async_subdev *asd) +static void rkisp1_subdev_notifier_destroy(struct v4l2_async_connection *asc) { struct rkisp1_sensor_async *rk_asd = - container_of(asd, struct rkisp1_sensor_async, asd); + container_of(asc, struct rkisp1_sensor_async, asd); fwnode_handle_put(rk_asd->source_ep); } @@ -187,7 +187,7 @@ static int rkisp1_subdev_notifier_register(struct rkisp1_device *rkisp1) unsigned int index = 0; int ret = 0; - v4l2_async_nf_init(ntf); + v4l2_async_nf_init(ntf, &rkisp1->v4l2_dev); ntf->ops = &rkisp1_subdev_notifier_ops; @@ -287,7 +287,7 @@ static int rkisp1_subdev_notifier_register(struct rkisp1_device *rkisp1) if (!index) dev_dbg(rkisp1->dev, "no remote subdevice found\n"); - ret = v4l2_async_nf_register(&rkisp1->v4l2_dev, ntf); + ret = v4l2_async_nf_register(ntf); if (ret) { v4l2_async_nf_cleanup(ntf); return ret; diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c index 585cf3f53469..07fbb77ce234 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c @@ -868,9 +868,13 @@ static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable) mbus_flags = 0; } else { const struct rkisp1_sensor_async *asd; + struct v4l2_async_connection *asc; - asd = container_of(rkisp1->source->asd, - struct rkisp1_sensor_async, asd); + asc = v4l2_async_connection_unique(rkisp1->source); + if (!asc) + return -EPIPE; + + asd = container_of(asc, struct rkisp1_sensor_async, asd); mbus_type = asd->mbus_type; mbus_flags = asd->mbus_flags; diff --git a/drivers/media/platform/samsung/exynos-gsc/gsc-core.c b/drivers/media/platform/samsung/exynos-gsc/gsc-core.c index 1fb34de70649..618ae55fe396 100644 --- a/drivers/media/platform/samsung/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/samsung/exynos-gsc/gsc-core.c @@ -20,7 +20,6 @@ #include <linux/slab.h> #include <linux/clk.h> #include <linux/of.h> -#include <linux/of_device.h> #include <media/v4l2-ioctl.h> #include "gsc-core.h" diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.c b/drivers/media/platform/samsung/exynos4-is/fimc-core.c index 976b4f747ad4..97908778e1c8 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-core.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.c @@ -19,7 +19,6 @@ #include <linux/mfd/syscon.h> #include <linux/io.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/slab.h> #include <linux/clk.h> #include <media/v4l2-ioctl.h> @@ -924,7 +923,6 @@ static int fimc_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; u32 lclk_freq = 0; struct fimc_dev *fimc; - struct resource *res; int ret = 0; int irq; @@ -961,8 +959,7 @@ static int fimc_probe(struct platform_device *pdev) return PTR_ERR(fimc->sysreg); } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - fimc->regs = devm_ioremap_resource(dev, res); + fimc->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(fimc->regs)) return PTR_ERR(fimc->regs); diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-lite.c b/drivers/media/platform/samsung/exynos4-is/fimc-lite.c index c3146ae08447..9396b10b5b1c 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-lite.c @@ -1450,7 +1450,6 @@ static int fimc_lite_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; const struct of_device_id *of_id; struct fimc_lite *fimc; - struct resource *res; int ret; int irq; @@ -1479,8 +1478,7 @@ static int fimc_lite_probe(struct platform_device *pdev) spin_lock_init(&fimc->slock); mutex_init(&fimc->lock); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - fimc->regs = devm_ioremap_resource(dev, res); + fimc->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(fimc->regs)) return PTR_ERR(fimc->regs); diff --git a/drivers/media/platform/samsung/exynos4-is/media-dev.c b/drivers/media/platform/samsung/exynos4-is/media-dev.c index c9cb9a216fae..5f10bb4eb4f7 100644 --- a/drivers/media/platform/samsung/exynos4-is/media-dev.c +++ b/drivers/media/platform/samsung/exynos4-is/media-dev.c @@ -17,7 +17,6 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_platform.h> -#include <linux/of_device.h> #include <linux/of_graph.h> #include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> @@ -401,7 +400,7 @@ static int fimc_md_parse_one_endpoint(struct fimc_md *fmd, int index = fmd->num_sensors; struct fimc_source_info *pd = &fmd->sensor[index].pdata; struct device_node *rem, *np; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 }; int ret; @@ -466,7 +465,7 @@ static int fimc_md_parse_one_endpoint(struct fimc_md *fmd, asd = v4l2_async_nf_add_fwnode_remote(&fmd->subdev_notifier, of_fwnode_handle(ep), - struct v4l2_async_subdev); + struct v4l2_async_connection); of_node_put(ep); @@ -1372,7 +1371,7 @@ err: static int subdev_notifier_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct fimc_md *fmd = notifier_to_fimc_md(notifier); struct fimc_sensor_info *si = NULL; @@ -1479,7 +1478,7 @@ static int fimc_md_probe(struct platform_device *pdev) platform_set_drvdata(pdev, fmd); - v4l2_async_nf_init(&fmd->subdev_notifier); + v4l2_async_nf_init(&fmd->subdev_notifier, &fmd->v4l2_dev); ret = fimc_md_register_platform_entities(fmd, dev->of_node); if (ret) @@ -1507,8 +1506,7 @@ static int fimc_md_probe(struct platform_device *pdev) fmd->subdev_notifier.ops = &subdev_notifier_ops; fmd->num_sensors = 0; - ret = v4l2_async_nf_register(&fmd->v4l2_dev, - &fmd->subdev_notifier); + ret = v4l2_async_nf_register(&fmd->subdev_notifier); if (ret) goto err_clk_p; } diff --git a/drivers/media/platform/samsung/exynos4-is/media-dev.h b/drivers/media/platform/samsung/exynos4-is/media-dev.h index 079105d88bab..786264cf79dc 100644 --- a/drivers/media/platform/samsung/exynos4-is/media-dev.h +++ b/drivers/media/platform/samsung/exynos4-is/media-dev.h @@ -82,7 +82,7 @@ struct fimc_camclk_info { */ struct fimc_sensor_info { struct fimc_source_info pdata; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct v4l2_subdev *subdev; struct fimc_dev *host; }; diff --git a/drivers/media/platform/samsung/s3c-camif/camif-core.c b/drivers/media/platform/samsung/s3c-camif/camif-core.c index afe1fcc37354..e4529f666e20 100644 --- a/drivers/media/platform/samsung/s3c-camif/camif-core.c +++ b/drivers/media/platform/samsung/s3c-camif/camif-core.c @@ -381,8 +381,8 @@ static int camif_request_irqs(struct platform_device *pdev, init_waitqueue_head(&vp->irq_queue); irq = platform_get_irq(pdev, i); - if (irq <= 0) - return -ENXIO; + if (irq < 0) + return irq; ret = devm_request_irq(&pdev->dev, irq, s3c_camif_irq_handler, 0, dev_name(&pdev->dev), vp); diff --git a/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c b/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c index c3c7e48f1b6e..d2c4a0178b3c 100644 --- a/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c @@ -2870,10 +2870,8 @@ static int s5p_jpeg_probe(struct platform_device *pdev) /* interrupt service routine registration */ jpeg->irq = ret = platform_get_irq(pdev, 0); - if (ret < 0) { - dev_err(&pdev->dev, "cannot find IRQ\n"); + if (ret < 0) return ret; - } ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq, 0, dev_name(&pdev->dev), jpeg); @@ -3164,7 +3162,7 @@ static struct platform_driver s5p_jpeg_driver = { .probe = s5p_jpeg_probe, .remove_new = s5p_jpeg_remove, .driver = { - .of_match_table = of_match_ptr(samsung_jpeg_match), + .of_match_table = samsung_jpeg_match, .name = S5P_JPEG_M2M_NAME, .pm = &s5p_jpeg_pm_ops, }, diff --git a/drivers/media/platform/st/stm32/stm32-dcmi.c b/drivers/media/platform/st/stm32/stm32-dcmi.c index dad6e22e4ce4..8cb4fdcae137 100644 --- a/drivers/media/platform/st/stm32/stm32-dcmi.c +++ b/drivers/media/platform/st/stm32/stm32-dcmi.c @@ -134,6 +134,7 @@ struct stm32_dcmi { struct video_device *vdev; struct v4l2_async_notifier notifier; struct v4l2_subdev *source; + struct v4l2_subdev *s_subdev; struct v4l2_format fmt; struct v4l2_rect crop; bool do_crop; @@ -692,51 +693,6 @@ static int dcmi_pipeline_s_fmt(struct stm32_dcmi *dcmi, return 0; } -static int dcmi_pipeline_s_stream(struct stm32_dcmi *dcmi, int state) -{ - struct media_entity *entity = &dcmi->vdev->entity; - struct v4l2_subdev *subdev; - struct media_pad *pad; - int ret; - - /* Start/stop all entities within pipeline */ - while (1) { - pad = &entity->pads[0]; - if (!(pad->flags & MEDIA_PAD_FL_SINK)) - break; - - pad = media_pad_remote_pad_first(pad); - if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) - break; - - entity = pad->entity; - subdev = media_entity_to_v4l2_subdev(entity); - - ret = v4l2_subdev_call(subdev, video, s_stream, state); - if (ret < 0 && ret != -ENOIOCTLCMD) { - dev_err(dcmi->dev, "%s: \"%s\" failed to %s streaming (%d)\n", - __func__, subdev->name, - state ? "start" : "stop", ret); - return ret; - } - - dev_dbg(dcmi->dev, "\"%s\" is %s\n", - subdev->name, state ? "started" : "stopped"); - } - - return 0; -} - -static int dcmi_pipeline_start(struct stm32_dcmi *dcmi) -{ - return dcmi_pipeline_s_stream(dcmi, 1); -} - -static void dcmi_pipeline_stop(struct stm32_dcmi *dcmi) -{ - dcmi_pipeline_s_stream(dcmi, 0); -} - static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) { struct stm32_dcmi *dcmi = vb2_get_drv_priv(vq); @@ -758,9 +714,12 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) goto err_pm_put; } - ret = dcmi_pipeline_start(dcmi); - if (ret) + ret = v4l2_subdev_call(dcmi->s_subdev, video, s_stream, 1); + if (ret < 0) { + dev_err(dcmi->dev, "%s: Failed to start source subdev, error (%d)\n", + __func__, ret); goto err_media_pipeline_stop; + } spin_lock_irq(&dcmi->irqlock); @@ -862,7 +821,7 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) return 0; err_pipeline_stop: - dcmi_pipeline_stop(dcmi); + v4l2_subdev_call(dcmi->s_subdev, video, s_stream, 0); err_media_pipeline_stop: video_device_pipeline_stop(dcmi->vdev); @@ -889,8 +848,12 @@ static void dcmi_stop_streaming(struct vb2_queue *vq) { struct stm32_dcmi *dcmi = vb2_get_drv_priv(vq); struct dcmi_buf *buf, *node; + int ret; - dcmi_pipeline_stop(dcmi); + ret = v4l2_subdev_call(dcmi->s_subdev, video, s_stream, 0); + if (ret < 0) + dev_err(dcmi->dev, "%s: Failed to stop source subdev, error (%d)\n", + __func__, ret); video_device_pipeline_stop(dcmi->vdev); @@ -1837,7 +1800,7 @@ static int dcmi_graph_notify_complete(struct v4l2_async_notifier *notifier) static void dcmi_graph_notify_unbind(struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct stm32_dcmi *dcmi = notifier_to_dcmi(notifier); @@ -1849,7 +1812,7 @@ static void dcmi_graph_notify_unbind(struct v4l2_async_notifier *notifier, static int dcmi_graph_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct stm32_dcmi *dcmi = notifier_to_dcmi(notifier); unsigned int ret; @@ -1876,6 +1839,8 @@ static int dcmi_graph_notify_bound(struct v4l2_async_notifier *notifier, dev_dbg(dcmi->dev, "DCMI is now linked to \"%s\"\n", subdev->name); + dcmi->s_subdev = subdev; + return ret; } @@ -1887,7 +1852,7 @@ static const struct v4l2_async_notifier_operations dcmi_graph_notify_ops = { static int dcmi_graph_init(struct stm32_dcmi *dcmi) { - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct device_node *ep; int ret; @@ -1897,11 +1862,11 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi) return -EINVAL; } - v4l2_async_nf_init(&dcmi->notifier); + v4l2_async_nf_init(&dcmi->notifier, &dcmi->v4l2_dev); asd = v4l2_async_nf_add_fwnode_remote(&dcmi->notifier, of_fwnode_handle(ep), - struct v4l2_async_subdev); + struct v4l2_async_connection); of_node_put(ep); @@ -1912,7 +1877,7 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi) dcmi->notifier.ops = &dcmi_graph_notify_ops; - ret = v4l2_async_nf_register(&dcmi->v4l2_dev, &dcmi->notifier); + ret = v4l2_async_nf_register(&dcmi->notifier); if (ret < 0) { dev_err(dcmi->dev, "Failed to register notifier\n"); v4l2_async_nf_cleanup(&dcmi->notifier); @@ -1932,7 +1897,6 @@ static int dcmi_probe(struct platform_device *pdev) struct dma_chan *chan; struct dma_slave_caps caps; struct clk *mclk; - int irq; int ret = 0; match = of_match_device(of_match_ptr(stm32_dcmi_of_match), &pdev->dev); @@ -1981,19 +1945,11 @@ static int dcmi_probe(struct platform_device *pdev) dcmi->bus.data_shift = ep.bus.parallel.data_shift; dcmi->bus_type = ep.bus_type; - irq = platform_get_irq(pdev, 0); - if (irq <= 0) - return irq ? irq : -ENXIO; - - dcmi->irq = irq; - - dcmi->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!dcmi->res) { - dev_err(&pdev->dev, "Could not get resource\n"); - return -ENODEV; - } + dcmi->irq = platform_get_irq(pdev, 0); + if (dcmi->irq < 0) + return dcmi->irq; - dcmi->regs = devm_ioremap_resource(&pdev->dev, dcmi->res); + dcmi->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &dcmi->res); if (IS_ERR(dcmi->regs)) return PTR_ERR(dcmi->regs); diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c index d6e7d1b36083..ad13d447d483 100644 --- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c +++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c @@ -12,7 +12,6 @@ #include <linux/module.h> #include <linux/mutex.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/of_graph.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -42,7 +41,7 @@ static const struct media_entity_operations sun4i_csi_video_entity_ops = { static int sun4i_csi_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct sun4i_csi *csi = container_of(notifier, struct sun4i_csi, notifier); @@ -118,11 +117,11 @@ static int sun4i_csi_notifier_init(struct sun4i_csi *csi) struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_PARALLEL, }; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct fwnode_handle *ep; int ret; - v4l2_async_nf_init(&csi->notifier); + v4l2_async_nf_init(&csi->notifier, &csi->v4l); ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0, FWNODE_GRAPH_ENDPOINT_NEXT); @@ -136,7 +135,7 @@ static int sun4i_csi_notifier_init(struct sun4i_csi *csi) csi->bus = vep.bus.parallel; asd = v4l2_async_nf_add_fwnode_remote(&csi->notifier, ep, - struct v4l2_async_subdev); + struct v4l2_async_connection); if (IS_ERR(asd)) { ret = PTR_ERR(asd); goto out; @@ -240,7 +239,7 @@ static int sun4i_csi_probe(struct platform_device *pdev) if (ret) goto err_unregister_media; - ret = v4l2_async_nf_register(&csi->v4l, &csi->notifier); + ret = v4l2_async_nf_register(&csi->notifier); if (ret) { dev_err(csi->dev, "Couldn't register our notifier.\n"); goto err_unregister_media; diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index e2723cfa4515..c6ba385c0c86 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -11,7 +11,6 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> @@ -427,7 +426,7 @@ static struct platform_driver sun6i_csi_platform_driver = { .remove_new = sun6i_csi_remove, .driver = { .name = SUN6I_CSI_NAME, - .of_match_table = of_match_ptr(sun6i_csi_of_match), + .of_match_table = sun6i_csi_of_match, .pm = &sun6i_csi_pm_ops, }, }; diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c index 4db950973ce2..e573413123b9 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c @@ -642,7 +642,7 @@ static int sun6i_csi_bridge_link(struct sun6i_csi_device *csi_dev, static int sun6i_csi_bridge_notifier_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *remote_subdev, - struct v4l2_async_subdev *async_subdev) + struct v4l2_async_connection *async_subdev) { struct sun6i_csi_device *csi_dev = container_of(notifier, struct sun6i_csi_device, @@ -819,7 +819,10 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev) /* V4L2 Async */ - v4l2_async_nf_init(notifier); + if (csi_dev->isp_available) + v4l2_async_subdev_nf_init(notifier, subdev); + else + v4l2_async_nf_init(notifier, v4l2_dev); notifier->ops = &sun6i_csi_bridge_notifier_ops; sun6i_csi_bridge_source_setup(csi_dev, &bridge->source_parallel, @@ -828,10 +831,7 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev) sun6i_csi_bridge_source_setup(csi_dev, &bridge->source_mipi_csi2, SUN6I_CSI_PORT_MIPI_CSI2, NULL); - if (csi_dev->isp_available) - ret = v4l2_async_subdev_nf_register(subdev, notifier); - else - ret = v4l2_async_nf_register(v4l2_dev, notifier); + ret = v4l2_async_nf_register(notifier); if (ret) { dev_err(dev, "failed to register v4l2 async notifier: %d\n", ret); diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h index ee592a14b9c5..44653b38f722 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h @@ -34,7 +34,7 @@ struct sun6i_csi_bridge_source { }; struct sun6i_csi_bridge_async_subdev { - struct v4l2_async_subdev async_subdev; + struct v4l2_async_connection async_subdev; struct sun6i_csi_bridge_source *source; }; diff --git a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c index dce130b4c9f6..08d86c17b284 100644 --- a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c +++ b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c @@ -7,7 +7,6 @@ #include <linux/clk.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/phy/phy.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -408,7 +407,7 @@ static const struct media_entity_operations sun6i_mipi_csi2_entity_ops = { static int sun6i_mipi_csi2_notifier_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *remote_subdev, - struct v4l2_async_subdev *async_subdev) + struct v4l2_async_connection *async_subdev) { struct v4l2_subdev *subdev = notifier->sd; struct sun6i_mipi_csi2_device *csi2_dev = @@ -462,7 +461,7 @@ sun6i_mipi_csi2_bridge_source_setup(struct sun6i_mipi_csi2_device *csi2_dev) { struct v4l2_async_notifier *notifier = &csi2_dev->bridge.notifier; struct v4l2_fwnode_endpoint *endpoint = &csi2_dev->bridge.endpoint; - struct v4l2_async_subdev *subdev_async; + struct v4l2_async_connection *subdev_async; struct fwnode_handle *handle; struct device *dev = csi2_dev->dev; int ret; @@ -480,7 +479,7 @@ sun6i_mipi_csi2_bridge_source_setup(struct sun6i_mipi_csi2_device *csi2_dev) subdev_async = v4l2_async_nf_add_fwnode_remote(notifier, handle, - struct v4l2_async_subdev); + struct v4l2_async_connection); if (IS_ERR(subdev_async)) ret = PTR_ERR(subdev_async); @@ -531,7 +530,7 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev) /* V4L2 Async */ - v4l2_async_nf_init(notifier); + v4l2_async_subdev_nf_init(notifier, subdev); notifier->ops = &sun6i_mipi_csi2_notifier_ops; ret = sun6i_mipi_csi2_bridge_source_setup(csi2_dev); @@ -540,7 +539,7 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev) /* Only register the notifier when a sensor is connected. */ if (ret != -ENODEV) { - ret = v4l2_async_subdev_nf_register(subdev, notifier); + ret = v4l2_async_nf_register(notifier); if (ret < 0) goto error_v4l2_notifier_cleanup; @@ -757,7 +756,7 @@ static struct platform_driver sun6i_mipi_csi2_platform_driver = { .remove_new = sun6i_mipi_csi2_remove, .driver = { .name = SUN6I_MIPI_CSI2_NAME, - .of_match_table = of_match_ptr(sun6i_mipi_csi2_of_match), + .of_match_table = sun6i_mipi_csi2_of_match, .pm = &sun6i_mipi_csi2_pm_ops, }, }; diff --git a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c index 23d32e198aaa..14a1844812c0 100644 --- a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c +++ b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c @@ -8,7 +8,6 @@ #include <linux/clk.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/phy/phy.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -445,7 +444,7 @@ static const struct media_entity_operations sun8i_a83t_mipi_csi2_entity_ops = { static int sun8i_a83t_mipi_csi2_notifier_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *remote_subdev, - struct v4l2_async_subdev *async_subdev) + struct v4l2_async_connection *async_subdev) { struct v4l2_subdev *subdev = notifier->sd; struct sun8i_a83t_mipi_csi2_device *csi2_dev = @@ -499,7 +498,7 @@ sun8i_a83t_mipi_csi2_bridge_source_setup(struct sun8i_a83t_mipi_csi2_device *csi { struct v4l2_async_notifier *notifier = &csi2_dev->bridge.notifier; struct v4l2_fwnode_endpoint *endpoint = &csi2_dev->bridge.endpoint; - struct v4l2_async_subdev *subdev_async; + struct v4l2_async_connection *subdev_async; struct fwnode_handle *handle; struct device *dev = csi2_dev->dev; int ret; @@ -517,7 +516,7 @@ sun8i_a83t_mipi_csi2_bridge_source_setup(struct sun8i_a83t_mipi_csi2_device *csi subdev_async = v4l2_async_nf_add_fwnode_remote(notifier, handle, - struct v4l2_async_subdev); + struct v4l2_async_connection); if (IS_ERR(subdev_async)) ret = PTR_ERR(subdev_async); @@ -569,7 +568,7 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev) /* V4L2 Async */ - v4l2_async_nf_init(notifier); + v4l2_async_subdev_nf_init(notifier, subdev); notifier->ops = &sun8i_a83t_mipi_csi2_notifier_ops; ret = sun8i_a83t_mipi_csi2_bridge_source_setup(csi2_dev); @@ -578,7 +577,7 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev) /* Only register the notifier when a sensor is connected. */ if (ret != -ENODEV) { - ret = v4l2_async_subdev_nf_register(subdev, notifier); + ret = v4l2_async_nf_register(notifier); if (ret < 0) goto error_v4l2_notifier_cleanup; @@ -824,7 +823,7 @@ static struct platform_driver sun8i_a83t_mipi_csi2_platform_driver = { .remove_new = sun8i_a83t_mipi_csi2_remove, .driver = { .name = SUN8I_A83T_MIPI_CSI2_NAME, - .of_match_table = of_match_ptr(sun8i_a83t_mipi_csi2_of_match), + .of_match_table = sun8i_a83t_mipi_csi2_of_match, .pm = &sun8i_a83t_mipi_csi2_pm_ops, }, }; diff --git a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c index e4b0fd793f55..90ab1d77b6a5 100644 --- a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c +++ b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c @@ -11,9 +11,9 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/iopoll.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> diff --git a/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c b/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c index bd0c4257bbff..0b025ec91826 100644 --- a/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c +++ b/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c @@ -9,9 +9,9 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/iopoll.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> diff --git a/drivers/media/platform/ti/am437x/am437x-vpfe.c b/drivers/media/platform/ti/am437x/am437x-vpfe.c index ffe1887cc429..63092013d476 100644 --- a/drivers/media/platform/ti/am437x/am437x-vpfe.c +++ b/drivers/media/platform/ti/am437x/am437x-vpfe.c @@ -2144,7 +2144,7 @@ static const struct v4l2_ioctl_ops vpfe_ioctl_ops = { static int vpfe_async_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct vpfe_device *vpfe = container_of(notifier->v4l2_dev, struct vpfe_device, v4l2_dev); @@ -2300,7 +2300,7 @@ vpfe_get_pdata(struct vpfe_device *vpfe) dev_dbg(dev, "vpfe_get_pdata\n"); - v4l2_async_nf_init(&vpfe->notifier); + v4l2_async_nf_init(&vpfe->notifier, &vpfe->v4l2_dev); if (!IS_ENABLED(CONFIG_OF) || !dev->of_node) return dev->platform_data; @@ -2370,8 +2370,7 @@ vpfe_get_pdata(struct vpfe_device *vpfe) pdata->asd[i] = v4l2_async_nf_add_fwnode(&vpfe->notifier, of_fwnode_handle(rem), - struct - v4l2_async_subdev); + struct v4l2_async_connection); of_node_put(rem); if (IS_ERR(pdata->asd[i])) goto cleanup; @@ -2404,10 +2403,17 @@ static int vpfe_probe(struct platform_device *pdev) vpfe->pdev = &pdev->dev; + ret = v4l2_device_register(&pdev->dev, &vpfe->v4l2_dev); + if (ret) { + vpfe_err(vpfe, "Unable to register v4l2 device.\n"); + return ret; + } + vpfe_cfg = vpfe_get_pdata(vpfe); if (!vpfe_cfg) { dev_err(&pdev->dev, "No platform data\n"); - return -EINVAL; + ret = -EINVAL; + goto probe_out_cleanup; } vpfe->cfg = vpfe_cfg; @@ -2420,10 +2426,8 @@ static int vpfe_probe(struct platform_device *pdev) } ret = platform_get_irq(pdev, 0); - if (ret <= 0) { - ret = -ENODEV; + if (ret < 0) goto probe_out_cleanup; - } vpfe->irq = ret; ret = devm_request_irq(vpfe->pdev, vpfe->irq, vpfe_isr, 0, @@ -2434,13 +2438,6 @@ static int vpfe_probe(struct platform_device *pdev) goto probe_out_cleanup; } - ret = v4l2_device_register(&pdev->dev, &vpfe->v4l2_dev); - if (ret) { - vpfe_err(vpfe, - "Unable to register v4l2 device.\n"); - goto probe_out_cleanup; - } - /* set the driver data in platform device */ platform_set_drvdata(pdev, vpfe); /* Enabling module functional clock */ @@ -2450,7 +2447,7 @@ static int vpfe_probe(struct platform_device *pdev) ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) { vpfe_err(vpfe, "Unable to resume device.\n"); - goto probe_out_v4l2_unregister; + goto probe_out_cleanup; } vpfe_ccdc_config_defaults(ccdc); @@ -2463,23 +2460,22 @@ static int vpfe_probe(struct platform_device *pdev) GFP_KERNEL); if (!vpfe->sd) { ret = -ENOMEM; - goto probe_out_v4l2_unregister; + goto probe_out_cleanup; } vpfe->notifier.ops = &vpfe_async_ops; - ret = v4l2_async_nf_register(&vpfe->v4l2_dev, &vpfe->notifier); + ret = v4l2_async_nf_register(&vpfe->notifier); if (ret) { vpfe_err(vpfe, "Error registering async notifier\n"); ret = -EINVAL; - goto probe_out_v4l2_unregister; + goto probe_out_cleanup; } return 0; -probe_out_v4l2_unregister: - v4l2_device_unregister(&vpfe->v4l2_dev); probe_out_cleanup: v4l2_async_nf_cleanup(&vpfe->notifier); + v4l2_device_unregister(&vpfe->v4l2_dev); return ret; } @@ -2494,8 +2490,8 @@ static void vpfe_remove(struct platform_device *pdev) v4l2_async_nf_unregister(&vpfe->notifier); v4l2_async_nf_cleanup(&vpfe->notifier); - v4l2_device_unregister(&vpfe->v4l2_dev); video_unregister_device(&vpfe->video_dev); + v4l2_device_unregister(&vpfe->v4l2_dev); } #ifdef CONFIG_PM_SLEEP @@ -2630,7 +2626,7 @@ static struct platform_driver vpfe_driver = { .driver = { .name = VPFE_MODULE_NAME, .pm = &vpfe_pm_ops, - .of_match_table = of_match_ptr(vpfe_of_match), + .of_match_table = vpfe_of_match, }, }; diff --git a/drivers/media/platform/ti/am437x/am437x-vpfe.h b/drivers/media/platform/ti/am437x/am437x-vpfe.h index f8b4e917b91a..50c3c793b370 100644 --- a/drivers/media/platform/ti/am437x/am437x-vpfe.h +++ b/drivers/media/platform/ti/am437x/am437x-vpfe.h @@ -84,7 +84,7 @@ struct vpfe_config { /* information about each subdev */ struct vpfe_subdev_info sub_devs[VPFE_MAX_SUBDEV]; /* Flat array, arranged in groups */ - struct v4l2_async_subdev *asd[VPFE_MAX_SUBDEV]; + struct v4l2_async_connection *asd[VPFE_MAX_SUBDEV]; }; struct vpfe_cap_buffer { diff --git a/drivers/media/platform/ti/cal/cal-camerarx.c b/drivers/media/platform/ti/cal/cal-camerarx.c index 16ae52879a79..1a4273bbe752 100644 --- a/drivers/media/platform/ti/cal/cal-camerarx.c +++ b/drivers/media/platform/ti/cal/cal-camerarx.c @@ -50,10 +50,16 @@ static s64 cal_camerarx_get_ext_link_freq(struct cal_camerarx *phy) struct v4l2_mbus_config_mipi_csi2 *mipi_csi2 = &phy->endpoint.bus.mipi_csi2; u32 num_lanes = mipi_csi2->num_data_lanes; const struct cal_format_info *fmtinfo; + struct v4l2_subdev_state *state; + struct v4l2_mbus_framefmt *fmt; u32 bpp; s64 freq; - fmtinfo = cal_format_by_code(phy->formats[CAL_CAMERARX_PAD_SINK].code); + state = v4l2_subdev_get_locked_active_state(&phy->subdev); + + fmt = v4l2_subdev_get_pad_format(&phy->subdev, state, CAL_CAMERARX_PAD_SINK); + + fmtinfo = cal_format_by_code(fmt->code); if (!fmtinfo) return -EINVAL; @@ -583,33 +589,6 @@ done: return ret; } -int cal_camerarx_get_remote_frame_desc(struct cal_camerarx *phy, - struct v4l2_mbus_frame_desc *desc) -{ - struct media_pad *pad; - int ret; - - if (!phy->source) - return -EPIPE; - - pad = media_pad_remote_pad_first(&phy->pads[CAL_CAMERARX_PAD_SINK]); - if (!pad) - return -EPIPE; - - ret = v4l2_subdev_call(phy->source, pad, get_frame_desc, pad->index, - desc); - if (ret) - return ret; - - if (desc->type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) { - dev_err(phy->cal->dev, - "Frame descriptor does not describe CSI-2 link"); - return -EINVAL; - } - - return 0; -} - /* ------------------------------------------------------------------ * V4L2 Subdev Operations * ------------------------------------------------------------------ @@ -620,34 +599,20 @@ static inline struct cal_camerarx *to_cal_camerarx(struct v4l2_subdev *sd) return container_of(sd, struct cal_camerarx, subdev); } -static struct v4l2_mbus_framefmt * -cal_camerarx_get_pad_format(struct cal_camerarx *phy, - struct v4l2_subdev_state *state, - unsigned int pad, u32 which) -{ - switch (which) { - case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(&phy->subdev, state, pad); - case V4L2_SUBDEV_FORMAT_ACTIVE: - return &phy->formats[pad]; - default: - return NULL; - } -} - static int cal_camerarx_sd_s_stream(struct v4l2_subdev *sd, int enable) { struct cal_camerarx *phy = to_cal_camerarx(sd); + struct v4l2_subdev_state *state; int ret = 0; - mutex_lock(&phy->mutex); + state = v4l2_subdev_lock_and_get_active_state(sd); if (enable) ret = cal_camerarx_start(phy); else cal_camerarx_stop(phy); - mutex_unlock(&phy->mutex); + v4l2_subdev_unlock_state(state); return ret; } @@ -657,62 +622,44 @@ static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_mbus_code_enum *code) { struct cal_camerarx *phy = to_cal_camerarx(sd); - int ret = 0; - - mutex_lock(&phy->mutex); /* No transcoding, source and sink codes must match. */ if (cal_rx_pad_is_source(code->pad)) { struct v4l2_mbus_framefmt *fmt; - if (code->index > 0) { - ret = -EINVAL; - goto out; - } + if (code->index > 0) + return -EINVAL; - fmt = cal_camerarx_get_pad_format(phy, state, - CAL_CAMERARX_PAD_SINK, - code->which); + fmt = v4l2_subdev_get_pad_format(&phy->subdev, state, + CAL_CAMERARX_PAD_SINK); code->code = fmt->code; } else { - if (code->index >= cal_num_formats) { - ret = -EINVAL; - goto out; - } + if (code->index >= cal_num_formats) + return -EINVAL; code->code = cal_formats[code->index].code; } -out: - mutex_unlock(&phy->mutex); - - return ret; + return 0; } static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_frame_size_enum *fse) { - struct cal_camerarx *phy = to_cal_camerarx(sd); const struct cal_format_info *fmtinfo; - int ret = 0; if (fse->index > 0) return -EINVAL; - mutex_lock(&phy->mutex); - /* No transcoding, source and sink formats must match. */ if (cal_rx_pad_is_source(fse->pad)) { struct v4l2_mbus_framefmt *fmt; - fmt = cal_camerarx_get_pad_format(phy, state, - CAL_CAMERARX_PAD_SINK, - fse->which); - if (fse->code != fmt->code) { - ret = -EINVAL; - goto out; - } + fmt = v4l2_subdev_get_pad_format(sd, state, + CAL_CAMERARX_PAD_SINK); + if (fse->code != fmt->code) + return -EINVAL; fse->min_width = fmt->width; fse->max_width = fmt->width; @@ -720,10 +667,8 @@ static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd, fse->max_height = fmt->height; } else { fmtinfo = cal_format_by_code(fse->code); - if (!fmtinfo) { - ret = -EINVAL; - goto out; - } + if (!fmtinfo) + return -EINVAL; fse->min_width = CAL_MIN_WIDTH_BYTES * 8 / ALIGN(fmtinfo->bpp, 8); fse->max_width = CAL_MAX_WIDTH_BYTES * 8 / ALIGN(fmtinfo->bpp, 8); @@ -731,27 +676,6 @@ static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd, fse->max_height = CAL_MAX_HEIGHT_LINES; } -out: - mutex_unlock(&phy->mutex); - - return ret; -} - -static int cal_camerarx_sd_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *state, - struct v4l2_subdev_format *format) -{ - struct cal_camerarx *phy = to_cal_camerarx(sd); - struct v4l2_mbus_framefmt *fmt; - - mutex_lock(&phy->mutex); - - fmt = cal_camerarx_get_pad_format(phy, state, format->pad, - format->which); - format->format = *fmt; - - mutex_unlock(&phy->mutex); - return 0; } @@ -759,14 +683,13 @@ static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_format *format) { - struct cal_camerarx *phy = to_cal_camerarx(sd); const struct cal_format_info *fmtinfo; struct v4l2_mbus_framefmt *fmt; unsigned int bpp; /* No transcoding, source and sink formats must match. */ if (cal_rx_pad_is_source(format->pad)) - return cal_camerarx_sd_get_fmt(sd, state, format); + return v4l2_subdev_get_fmt(sd, state, format); /* * Default to the first format if the requested media bus code isn't @@ -790,20 +713,13 @@ static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd, /* Store the format and propagate it to the source pad. */ - mutex_lock(&phy->mutex); - - fmt = cal_camerarx_get_pad_format(phy, state, - CAL_CAMERARX_PAD_SINK, - format->which); + fmt = v4l2_subdev_get_pad_format(sd, state, CAL_CAMERARX_PAD_SINK); *fmt = format->format; - fmt = cal_camerarx_get_pad_format(phy, state, - CAL_CAMERARX_PAD_FIRST_SOURCE, - format->which); + fmt = v4l2_subdev_get_pad_format(sd, state, + CAL_CAMERARX_PAD_FIRST_SOURCE); *fmt = format->format; - mutex_unlock(&phy->mutex); - return 0; } @@ -817,7 +733,7 @@ static int cal_camerarx_sd_init_cfg(struct v4l2_subdev *sd, .format = { .width = 640, .height = 480, - .code = MEDIA_BUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_1X16, .field = V4L2_FIELD_NONE, .colorspace = V4L2_COLORSPACE_SRGB, .ycbcr_enc = V4L2_YCBCR_ENC_601, @@ -829,6 +745,40 @@ static int cal_camerarx_sd_init_cfg(struct v4l2_subdev *sd, return cal_camerarx_sd_set_fmt(sd, state, &format); } +static int cal_camerarx_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad, + struct v4l2_mbus_frame_desc *fd) +{ + struct cal_camerarx *phy = to_cal_camerarx(sd); + struct v4l2_mbus_frame_desc remote_desc; + const struct media_pad *remote_pad; + int ret; + + remote_pad = media_pad_remote_pad_first(&phy->pads[CAL_CAMERARX_PAD_SINK]); + if (!remote_pad) + return -EPIPE; + + ret = v4l2_subdev_call(phy->source, pad, get_frame_desc, + remote_pad->index, &remote_desc); + if (ret) + return ret; + + if (remote_desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) { + cal_err(phy->cal, + "Frame descriptor does not describe CSI-2 link"); + return -EINVAL; + } + + if (remote_desc.num_entries > 1) + cal_err(phy->cal, + "Multiple streams not supported in remote frame descriptor, using the first one\n"); + + fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2; + fd->num_entries = 1; + fd->entry[0] = remote_desc.entry[0]; + + return 0; +} + static const struct v4l2_subdev_video_ops cal_camerarx_video_ops = { .s_stream = cal_camerarx_sd_s_stream, }; @@ -837,8 +787,9 @@ static const struct v4l2_subdev_pad_ops cal_camerarx_pad_ops = { .init_cfg = cal_camerarx_sd_init_cfg, .enum_mbus_code = cal_camerarx_sd_enum_mbus_code, .enum_frame_size = cal_camerarx_sd_enum_frame_size, - .get_fmt = cal_camerarx_sd_get_fmt, + .get_fmt = v4l2_subdev_get_fmt, .set_fmt = cal_camerarx_sd_set_fmt, + .get_frame_desc = cal_camerarx_get_frame_desc, }; static const struct v4l2_subdev_ops cal_camerarx_subdev_ops = { @@ -864,7 +815,7 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal, unsigned int i; int ret; - phy = kzalloc(sizeof(*phy), GFP_KERNEL); + phy = devm_kzalloc(cal->dev, sizeof(*phy), GFP_KERNEL); if (!phy) return ERR_PTR(-ENOMEM); @@ -872,7 +823,6 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal, phy->instance = instance; spin_lock_init(&phy->vc_lock); - mutex_init(&phy->mutex); phy->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, (instance == 0) ? @@ -881,8 +831,7 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal, phy->base = devm_ioremap_resource(cal->dev, phy->res); if (IS_ERR(phy->base)) { cal_err(cal, "failed to ioremap\n"); - ret = PTR_ERR(phy->base); - goto error; + return ERR_CAST(phy->base); } cal_dbg(1, cal, "ioresource %s at %pa - %pa\n", @@ -890,11 +839,11 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal, ret = cal_camerarx_regmap_init(cal, phy); if (ret) - goto error; + return ERR_PTR(ret); ret = cal_camerarx_parse_dt(phy); if (ret) - goto error; + return ERR_PTR(ret); /* Initialize the V4L2 subdev and media entity. */ sd = &phy->subdev; @@ -911,21 +860,25 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal, ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(phy->pads), phy->pads); if (ret) - goto error; + goto err_node_put; - ret = cal_camerarx_sd_init_cfg(sd, NULL); + ret = v4l2_subdev_init_finalize(sd); if (ret) - goto error; + goto err_entity_cleanup; ret = v4l2_device_register_subdev(&cal->v4l2_dev, sd); if (ret) - goto error; + goto err_free_state; return phy; -error: +err_free_state: + v4l2_subdev_cleanup(sd); +err_entity_cleanup: media_entity_cleanup(&phy->subdev.entity); - kfree(phy); +err_node_put: + of_node_put(phy->source_ep_node); + of_node_put(phy->source_node); return ERR_PTR(ret); } @@ -935,9 +888,8 @@ void cal_camerarx_destroy(struct cal_camerarx *phy) return; v4l2_device_unregister_subdev(&phy->subdev); + v4l2_subdev_cleanup(&phy->subdev); media_entity_cleanup(&phy->subdev.entity); of_node_put(phy->source_ep_node); of_node_put(phy->source_node); - mutex_destroy(&phy->mutex); - kfree(phy); } diff --git a/drivers/media/platform/ti/cal/cal-video.c b/drivers/media/platform/ti/cal/cal-video.c index ca906a9e4222..a8abcd0fee17 100644 --- a/drivers/media/platform/ti/cal/cal-video.c +++ b/drivers/media/platform/ti/cal/cal-video.c @@ -687,21 +687,34 @@ static void cal_release_buffers(struct cal_ctx *ctx, static int cal_video_check_format(struct cal_ctx *ctx) { const struct v4l2_mbus_framefmt *format; + struct v4l2_subdev_state *state; struct media_pad *remote_pad; + int ret = 0; remote_pad = media_pad_remote_pad_first(&ctx->pad); if (!remote_pad) return -ENODEV; - format = &ctx->phy->formats[remote_pad->index]; + state = v4l2_subdev_lock_and_get_active_state(&ctx->phy->subdev); + + format = v4l2_subdev_get_pad_format(&ctx->phy->subdev, state, remote_pad->index); + if (!format) { + ret = -EINVAL; + goto out; + } if (ctx->fmtinfo->code != format->code || ctx->v_fmt.fmt.pix.height != format->height || ctx->v_fmt.fmt.pix.width != format->width || - ctx->v_fmt.fmt.pix.field != format->field) - return -EPIPE; + ctx->v_fmt.fmt.pix.field != format->field) { + ret = -EPIPE; + goto out; + } - return 0; +out: + v4l2_subdev_unlock_state(state); + + return ret; } static int cal_start_streaming(struct vb2_queue *vq, unsigned int count) @@ -894,7 +907,7 @@ static int cal_ctx_v4l2_init_mc_format(struct cal_ctx *ctx) const struct cal_format_info *fmtinfo; struct v4l2_pix_format *pix_fmt = &ctx->v_fmt.fmt.pix; - fmtinfo = cal_format_by_code(MEDIA_BUS_FMT_UYVY8_2X8); + fmtinfo = cal_format_by_code(MEDIA_BUS_FMT_UYVY8_1X16); if (!fmtinfo) return -EINVAL; diff --git a/drivers/media/platform/ti/cal/cal.c b/drivers/media/platform/ti/cal/cal.c index 9c5105223d6b..528909ae4bd6 100644 --- a/drivers/media/platform/ti/cal/cal.c +++ b/drivers/media/platform/ti/cal/cal.c @@ -13,7 +13,7 @@ #include <linux/interrupt.h> #include <linux/mfd/syscon.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> @@ -61,49 +61,25 @@ MODULE_PARM_DESC(mc_api, "activates the MC API"); const struct cal_format_info cal_formats[] = { { .fourcc = V4L2_PIX_FMT_YUYV, - .code = MEDIA_BUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_1X16, .bpp = 16, }, { .fourcc = V4L2_PIX_FMT_UYVY, - .code = MEDIA_BUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_1X16, .bpp = 16, }, { .fourcc = V4L2_PIX_FMT_YVYU, - .code = MEDIA_BUS_FMT_YVYU8_2X8, + .code = MEDIA_BUS_FMT_YVYU8_1X16, .bpp = 16, }, { .fourcc = V4L2_PIX_FMT_VYUY, - .code = MEDIA_BUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_1X16, .bpp = 16, }, { - .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ - .code = MEDIA_BUS_FMT_RGB565_2X8_LE, + .fourcc = V4L2_PIX_FMT_RGB565, + .code = MEDIA_BUS_FMT_RGB565_1X16, .bpp = 16, }, { - .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ - .code = MEDIA_BUS_FMT_RGB565_2X8_BE, - .bpp = 16, - }, { - .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */ - .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, - .bpp = 16, - }, { - .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ - .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, - .bpp = 16, - }, { - .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */ - .code = MEDIA_BUS_FMT_RGB888_2X12_LE, - .bpp = 24, - }, { - .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */ - .code = MEDIA_BUS_FMT_RGB888_2X12_BE, - .bpp = 24, - }, { - .fourcc = V4L2_PIX_FMT_RGB32, /* argb */ - .code = MEDIA_BUS_FMT_ARGB8888_1X32, - .bpp = 32, - }, { .fourcc = V4L2_PIX_FMT_SBGGR8, .code = MEDIA_BUS_FMT_SBGGR8_1X8, .bpp = 8, @@ -470,30 +446,24 @@ static bool cal_ctx_wr_dma_stopped(struct cal_ctx *ctx) } static int -cal_get_remote_frame_desc_entry(struct cal_camerarx *phy, +cal_get_remote_frame_desc_entry(struct cal_ctx *ctx, struct v4l2_mbus_frame_desc_entry *entry) { struct v4l2_mbus_frame_desc fd; + struct media_pad *phy_source_pad; int ret; - ret = cal_camerarx_get_remote_frame_desc(phy, &fd); - if (ret) { - if (ret != -ENOIOCTLCMD) - dev_err(phy->cal->dev, - "Failed to get remote frame desc: %d\n", ret); - return ret; - } - - if (fd.num_entries == 0) { - dev_err(phy->cal->dev, - "No streams found in the remote frame descriptor\n"); - + phy_source_pad = media_pad_remote_pad_first(&ctx->pad); + if (!phy_source_pad) return -ENODEV; - } - if (fd.num_entries > 1) - dev_dbg(phy->cal->dev, - "Multiple streams not supported in remote frame descriptor, using the first one\n"); + ret = v4l2_subdev_call(&ctx->phy->subdev, pad, get_frame_desc, + phy_source_pad->index, &fd); + if (ret) + return ret; + + if (fd.num_entries != 1) + return -EINVAL; *entry = fd.entry[0]; @@ -505,7 +475,7 @@ int cal_ctx_prepare(struct cal_ctx *ctx) struct v4l2_mbus_frame_desc_entry entry; int ret; - ret = cal_get_remote_frame_desc_entry(ctx->phy, &entry); + ret = cal_get_remote_frame_desc_entry(ctx, &entry); if (ret == -ENOIOCTLCMD) { ctx->vc = 0; @@ -804,19 +774,19 @@ static irqreturn_t cal_irq(int irq_cal, void *data) */ struct cal_v4l2_async_subdev { - struct v4l2_async_subdev asd; /* Must be first */ + struct v4l2_async_connection asd; /* Must be first */ struct cal_camerarx *phy; }; static inline struct cal_v4l2_async_subdev * -to_cal_asd(struct v4l2_async_subdev *asd) +to_cal_asd(struct v4l2_async_connection *asd) { return container_of(asd, struct cal_v4l2_async_subdev, asd); } static int cal_async_notifier_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct cal_camerarx *phy = to_cal_asd(asd)->phy; int pad; @@ -895,7 +865,7 @@ static int cal_async_notifier_register(struct cal_dev *cal) unsigned int i; int ret; - v4l2_async_nf_init(&cal->notifier); + v4l2_async_nf_init(&cal->notifier, &cal->v4l2_dev); cal->notifier.ops = &cal_async_notifier_ops; for (i = 0; i < cal->data->num_csi2_phy; ++i) { @@ -919,7 +889,7 @@ static int cal_async_notifier_register(struct cal_dev *cal) casd->phy = phy; } - ret = v4l2_async_nf_register(&cal->v4l2_dev, &cal->notifier); + ret = v4l2_async_nf_register(&cal->notifier); if (ret) { cal_err(cal, "Error registering async notifier\n"); goto error; diff --git a/drivers/media/platform/ti/cal/cal.h b/drivers/media/platform/ti/cal/cal.h index de73d6d21b6f..0856297adc0b 100644 --- a/drivers/media/platform/ti/cal/cal.h +++ b/drivers/media/platform/ti/cal/cal.h @@ -177,7 +177,6 @@ struct cal_camerarx { struct v4l2_subdev subdev; struct media_pad pads[CAL_CAMERARX_NUM_PADS]; - struct v4l2_mbus_framefmt formats[CAL_CAMERARX_NUM_PADS]; /* protects the vc_* fields below */ spinlock_t vc_lock; @@ -185,13 +184,6 @@ struct cal_camerarx { u16 vc_frame_number[4]; u32 vc_sequence[4]; - /* - * Lock for camerarx ops. Protects: - * - formats - * - enable_count - */ - struct mutex mutex; - unsigned int enable_count; }; @@ -327,8 +319,6 @@ const struct cal_format_info *cal_format_by_code(u32 code); void cal_quickdump_regs(struct cal_dev *cal); -int cal_camerarx_get_remote_frame_desc(struct cal_camerarx *phy, - struct v4l2_mbus_frame_desc *desc); void cal_camerarx_disable(struct cal_camerarx *phy); void cal_camerarx_i913_errata(struct cal_camerarx *phy); struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal, diff --git a/drivers/media/platform/ti/davinci/vpif_capture.c b/drivers/media/platform/ti/davinci/vpif_capture.c index 44d269d6038c..99fae8830c41 100644 --- a/drivers/media/platform/ti/davinci/vpif_capture.c +++ b/drivers/media/platform/ti/davinci/vpif_capture.c @@ -1363,12 +1363,12 @@ static inline void free_vpif_objs(void) static int vpif_async_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { int i; for (i = 0; i < vpif_obj.config->asd_sizes[0]; i++) { - struct v4l2_async_subdev *_asd = vpif_obj.config->asd[i]; + struct v4l2_async_connection *_asd = vpif_obj.config->asd[i]; const struct fwnode_handle *fwnode = _asd->match.fwnode; if (fwnode == subdev->fwnode) { @@ -1483,7 +1483,8 @@ static const struct v4l2_async_notifier_operations vpif_async_ops = { }; static struct vpif_capture_config * -vpif_capture_get_pdata(struct platform_device *pdev) +vpif_capture_get_pdata(struct platform_device *pdev, + struct v4l2_device *v4l2_dev) { struct device_node *endpoint = NULL; struct device_node *rem = NULL; @@ -1492,7 +1493,7 @@ vpif_capture_get_pdata(struct platform_device *pdev) struct vpif_capture_chan_config *chan; unsigned int i; - v4l2_async_nf_init(&vpif_obj.notifier); + v4l2_async_nf_init(&vpif_obj.notifier, v4l2_dev); /* * DT boot: OF node from parent device contains @@ -1570,8 +1571,7 @@ vpif_capture_get_pdata(struct platform_device *pdev) pdata->asd[i] = v4l2_async_nf_add_fwnode(&vpif_obj.notifier, of_fwnode_handle(rem), - struct - v4l2_async_subdev); + struct v4l2_async_connection); if (IS_ERR(pdata->asd[i])) goto err_cleanup; @@ -1609,18 +1609,12 @@ static __init int vpif_probe(struct platform_device *pdev) int res_idx = 0; int i, err; - pdev->dev.platform_data = vpif_capture_get_pdata(pdev); - if (!pdev->dev.platform_data) { - dev_warn(&pdev->dev, "Missing platform data. Giving up.\n"); - return -EINVAL; - } - vpif_dev = &pdev->dev; err = initialize_vpif(); if (err) { v4l2_err(vpif_dev->driver, "Error initializing vpif\n"); - goto cleanup; + return err; } err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev); @@ -1647,13 +1641,21 @@ static __init int vpif_probe(struct platform_device *pdev) goto vpif_unregister; } while (++res_idx); + pdev->dev.platform_data = + vpif_capture_get_pdata(pdev, &vpif_obj.v4l2_dev); + if (!pdev->dev.platform_data) { + err = -EINVAL; + dev_warn(&pdev->dev, "Missing platform data. Giving up.\n"); + goto vpif_unregister; + } + vpif_obj.config = pdev->dev.platform_data; subdev_count = vpif_obj.config->subdev_count; vpif_obj.sd = kcalloc(subdev_count, sizeof(*vpif_obj.sd), GFP_KERNEL); if (!vpif_obj.sd) { err = -ENOMEM; - goto vpif_unregister; + goto probe_subdev_out; } if (!vpif_obj.config->asd_sizes[0]) { @@ -1684,8 +1686,7 @@ static __init int vpif_probe(struct platform_device *pdev) goto probe_subdev_out; } else { vpif_obj.notifier.ops = &vpif_async_ops; - err = v4l2_async_nf_register(&vpif_obj.v4l2_dev, - &vpif_obj.notifier); + err = v4l2_async_nf_register(&vpif_obj.notifier); if (err) { vpif_err("Error registering async notifier\n"); err = -EINVAL; @@ -1696,14 +1697,13 @@ static __init int vpif_probe(struct platform_device *pdev) return 0; probe_subdev_out: + v4l2_async_nf_cleanup(&vpif_obj.notifier); /* free sub devices memory */ kfree(vpif_obj.sd); vpif_unregister: v4l2_device_unregister(&vpif_obj.v4l2_dev); vpif_free: free_vpif_objs(); -cleanup: - v4l2_async_nf_cleanup(&vpif_obj.notifier); return err; } diff --git a/drivers/media/platform/ti/omap3isp/isp.c b/drivers/media/platform/ti/omap3isp/isp.c index f3aaa9e76492..1cda23244c7b 100644 --- a/drivers/media/platform/ti/omap3isp/isp.c +++ b/drivers/media/platform/ti/omap3isp/isp.c @@ -2002,6 +2002,7 @@ static void isp_remove(struct platform_device *pdev) struct isp_device *isp = platform_get_drvdata(pdev); v4l2_async_nf_unregister(&isp->notifier); + v4l2_async_nf_cleanup(&isp->notifier); isp_unregister_entities(isp); isp_cleanup_modules(isp); isp_xclk_cleanup(isp); @@ -2011,7 +2012,6 @@ static void isp_remove(struct platform_device *pdev) __omap3isp_put(isp, false); media_entity_enum_cleanup(&isp->crashed); - v4l2_async_nf_cleanup(&isp->notifier); kfree(isp); } @@ -2022,35 +2022,34 @@ enum isp_of_phy { ISP_OF_PHY_CSIPHY2, }; -static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) +static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async, + struct v4l2_subdev *sd, + struct v4l2_async_connection *asc) { struct isp_device *isp = container_of(async, struct isp_device, notifier); - struct v4l2_device *v4l2_dev = &isp->v4l2_dev; - struct v4l2_subdev *sd; + struct isp_bus_cfg *bus_cfg = + &container_of(asc, struct isp_async_subdev, asd)->bus; int ret; mutex_lock(&isp->media_dev.graph_mutex); + ret = isp_link_entity(isp, &sd->entity, bus_cfg->interface); + mutex_unlock(&isp->media_dev.graph_mutex); - ret = media_entity_enum_init(&isp->crashed, &isp->media_dev); - if (ret) { - mutex_unlock(&isp->media_dev.graph_mutex); - return ret; - } - - list_for_each_entry(sd, &v4l2_dev->subdevs, list) { - if (sd->notifier != &isp->notifier) - continue; + return ret; +} - ret = isp_link_entity(isp, &sd->entity, - v4l2_subdev_to_bus_cfg(sd)->interface); - if (ret < 0) { - mutex_unlock(&isp->media_dev.graph_mutex); - return ret; - } - } +static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) +{ + struct isp_device *isp = container_of(async, struct isp_device, + notifier); + int ret; + mutex_lock(&isp->media_dev.graph_mutex); + ret = media_entity_enum_init(&isp->crashed, &isp->media_dev); mutex_unlock(&isp->media_dev.graph_mutex); + if (ret) + return ret; ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev); if (ret < 0) @@ -2240,6 +2239,7 @@ static int isp_parse_of_endpoints(struct isp_device *isp) } static const struct v4l2_async_notifier_operations isp_subdev_notifier_ops = { + .bound = isp_subdev_notifier_bound, .complete = isp_subdev_notifier_complete, }; @@ -2288,13 +2288,8 @@ static int isp_probe(struct platform_device *pdev) mutex_init(&isp->isp_mutex); spin_lock_init(&isp->stat_lock); - v4l2_async_nf_init(&isp->notifier); isp->dev = &pdev->dev; - ret = isp_parse_of_endpoints(isp); - if (ret < 0) - goto error; - isp->ref_count = 0; ret = dma_coerce_mask_and_coherent(isp->dev, DMA_BIT_MASK(32)); @@ -2329,9 +2324,8 @@ static int isp_probe(struct platform_device *pdev) for (i = 0; i < 2; i++) { unsigned int map_idx = i ? OMAP3_ISP_IOMEM_CSI2A_REGS1 : 0; - mem = platform_get_resource(pdev, IORESOURCE_MEM, i); isp->mmio_base[map_idx] = - devm_ioremap_resource(isp->dev, mem); + devm_platform_get_and_ioremap_resource(pdev, i, &mem); if (IS_ERR(isp->mmio_base[map_idx])) { ret = PTR_ERR(isp->mmio_base[map_idx]); goto error; @@ -2398,10 +2392,8 @@ static int isp_probe(struct platform_device *pdev) /* Interrupt */ ret = platform_get_irq(pdev, 0); - if (ret <= 0) { - ret = -ENODEV; + if (ret < 0) goto error_iommu; - } isp->irq_num = ret; if (devm_request_irq(isp->dev, isp->irq_num, isp_isr, IRQF_SHARED, @@ -2426,7 +2418,13 @@ static int isp_probe(struct platform_device *pdev) isp->notifier.ops = &isp_subdev_notifier_ops; - ret = v4l2_async_nf_register(&isp->v4l2_dev, &isp->notifier); + v4l2_async_nf_init(&isp->notifier, &isp->v4l2_dev); + + ret = isp_parse_of_endpoints(isp); + if (ret < 0) + goto error_register_entities; + + ret = v4l2_async_nf_register(&isp->notifier); if (ret) goto error_register_entities; @@ -2436,6 +2434,7 @@ static int isp_probe(struct platform_device *pdev) return 0; error_register_entities: + v4l2_async_nf_cleanup(&isp->notifier); isp_unregister_entities(isp); error_modules: isp_cleanup_modules(isp); @@ -2445,7 +2444,6 @@ error_isp: isp_xclk_cleanup(isp); __omap3isp_put(isp, false); error: - v4l2_async_nf_cleanup(&isp->notifier); mutex_destroy(&isp->isp_mutex); error_release_isp: kfree(isp); diff --git a/drivers/media/platform/ti/omap3isp/isp.h b/drivers/media/platform/ti/omap3isp/isp.h index a9d760fbf349..b4793631ad97 100644 --- a/drivers/media/platform/ti/omap3isp/isp.h +++ b/drivers/media/platform/ti/omap3isp/isp.h @@ -220,12 +220,21 @@ struct isp_device { }; struct isp_async_subdev { - struct v4l2_async_subdev asd; + struct v4l2_async_connection asd; struct isp_bus_cfg bus; }; -#define v4l2_subdev_to_bus_cfg(sd) \ - (&container_of((sd)->asd, struct isp_async_subdev, asd)->bus) +static inline struct isp_bus_cfg * +v4l2_subdev_to_bus_cfg(struct v4l2_subdev *sd) +{ + struct v4l2_async_connection *asc; + + asc = v4l2_async_connection_unique(sd); + if (!asc) + return NULL; + + return &container_of(asc, struct isp_async_subdev, asd)->bus; +} #define v4l2_dev_to_isp_device(dev) \ container_of(dev, struct isp_device, v4l2_dev) diff --git a/drivers/media/platform/ti/omap3isp/ispccdc.c b/drivers/media/platform/ti/omap3isp/ispccdc.c index fdcdffe5fecb..2fe42aa91800 100644 --- a/drivers/media/platform/ti/omap3isp/ispccdc.c +++ b/drivers/media/platform/ti/omap3isp/ispccdc.c @@ -1140,8 +1140,13 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc) if (ccdc->input == CCDC_INPUT_PARALLEL) { struct v4l2_subdev *sd = to_isp_pipeline(&ccdc->subdev.entity)->external; + struct isp_bus_cfg *bus_cfg; - parcfg = &v4l2_subdev_to_bus_cfg(sd)->bus.parallel; + bus_cfg = v4l2_subdev_to_bus_cfg(sd); + if (WARN_ON(!bus_cfg)) + return; + + parcfg = &bus_cfg->bus.parallel; ccdc->bt656 = parcfg->bt656; } @@ -2436,7 +2441,11 @@ static int ccdc_link_validate(struct v4l2_subdev *sd, if (ccdc->input == CCDC_INPUT_PARALLEL) { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(link->source->entity); - struct isp_bus_cfg *bus_cfg = v4l2_subdev_to_bus_cfg(sd); + struct isp_bus_cfg *bus_cfg; + + bus_cfg = v4l2_subdev_to_bus_cfg(sd); + if (WARN_ON(!bus_cfg)) + return -EPIPE; parallel_shift = bus_cfg->bus.parallel.data_lane_shift; } else { diff --git a/drivers/media/platform/ti/omap3isp/ispccp2.c b/drivers/media/platform/ti/omap3isp/ispccp2.c index fc90ff88464f..da5f0176ec78 100644 --- a/drivers/media/platform/ti/omap3isp/ispccp2.c +++ b/drivers/media/platform/ti/omap3isp/ispccp2.c @@ -360,6 +360,8 @@ static int ccp2_if_configure(struct isp_ccp2_device *ccp2) pad = media_pad_remote_pad_first(&ccp2->pads[CCP2_PAD_SINK]); sensor = media_entity_to_v4l2_subdev(pad->entity); buscfg = v4l2_subdev_to_bus_cfg(pipe->external); + if (WARN_ON(!buscfg)) + return -EPIPE; ret = ccp2_phyif_config(ccp2, &buscfg->bus.ccp2); if (ret < 0) diff --git a/drivers/media/platform/ti/omap3isp/ispcsi2.c b/drivers/media/platform/ti/omap3isp/ispcsi2.c index 6870980a2fa9..0f9a54b11f98 100644 --- a/drivers/media/platform/ti/omap3isp/ispcsi2.c +++ b/drivers/media/platform/ti/omap3isp/ispcsi2.c @@ -564,6 +564,8 @@ static int csi2_configure(struct isp_csi2_device *csi2) pad = media_pad_remote_pad_first(&csi2->pads[CSI2_PAD_SINK]); sensor = media_entity_to_v4l2_subdev(pad->entity); buscfg = v4l2_subdev_to_bus_cfg(pipe->external); + if (WARN_ON(!buscfg)) + return -EPIPE; csi2->frame_skip = 0; v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip); diff --git a/drivers/media/platform/ti/omap3isp/ispcsiphy.c b/drivers/media/platform/ti/omap3isp/ispcsiphy.c index 1bde76c0adbe..29a84d8ca0df 100644 --- a/drivers/media/platform/ti/omap3isp/ispcsiphy.c +++ b/drivers/media/platform/ti/omap3isp/ispcsiphy.c @@ -163,13 +163,17 @@ static int csiphy_set_power(struct isp_csiphy *phy, u32 power) static int omap3isp_csiphy_config(struct isp_csiphy *phy) { struct isp_pipeline *pipe = to_isp_pipeline(phy->entity); - struct isp_bus_cfg *buscfg = v4l2_subdev_to_bus_cfg(pipe->external); + struct isp_bus_cfg *buscfg; struct isp_csiphy_lanes_cfg *lanes; int csi2_ddrclk_khz; unsigned int num_data_lanes, used_lanes = 0; unsigned int i; u32 reg; + buscfg = v4l2_subdev_to_bus_cfg(pipe->external); + if (WARN_ON(!buscfg)) + return -EPIPE; + if (buscfg->interface == ISP_INTERFACE_CCP2B_PHY1 || buscfg->interface == ISP_INTERFACE_CCP2B_PHY2) { lanes = &buscfg->bus.ccp2.lanecfg; @@ -306,8 +310,13 @@ void omap3isp_csiphy_release(struct isp_csiphy *phy) mutex_lock(&phy->mutex); if (phy->entity) { struct isp_pipeline *pipe = to_isp_pipeline(phy->entity); - struct isp_bus_cfg *buscfg = - v4l2_subdev_to_bus_cfg(pipe->external); + struct isp_bus_cfg *buscfg; + + buscfg = v4l2_subdev_to_bus_cfg(pipe->external); + if (WARN_ON(!buscfg)) { + mutex_unlock(&phy->mutex); + return; + } csiphy_routing_cfg(phy, buscfg->interface, false, buscfg->bus.ccp2.phy_layer); diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c index c0a368bacf88..423fc85d79ee 100644 --- a/drivers/media/platform/verisilicon/hantro_drv.c +++ b/drivers/media/platform/verisilicon/hantro_drv.c @@ -986,7 +986,6 @@ static int hantro_probe(struct platform_device *pdev) { const struct of_device_id *match; struct hantro_dev *vpu; - struct resource *res; int num_bases; int i, ret; @@ -1047,11 +1046,9 @@ static int hantro_probe(struct platform_device *pdev) return -ENOMEM; for (i = 0; i < num_bases; i++) { - res = vpu->variant->reg_names ? - platform_get_resource_byname(vpu->pdev, IORESOURCE_MEM, - vpu->variant->reg_names[i]) : - platform_get_resource(vpu->pdev, IORESOURCE_MEM, 0); - vpu->reg_bases[i] = devm_ioremap_resource(vpu->dev, res); + vpu->reg_bases[i] = vpu->variant->reg_names ? + devm_platform_ioremap_resource_byname(pdev, vpu->variant->reg_names[i]) : + devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(vpu->reg_bases[i])) return PTR_ERR(vpu->reg_bases[i]); } @@ -1088,8 +1085,8 @@ static int hantro_probe(struct platform_device *pdev) irq_name = "default"; irq = platform_get_irq(vpu->pdev, 0); } - if (irq <= 0) - return -ENXIO; + if (irq < 0) + return irq; ret = devm_request_irq(vpu->dev, irq, vpu->variant->irqs[i].handler, 0, @@ -1225,7 +1222,7 @@ static struct platform_driver hantro_driver = { .remove_new = hantro_remove, .driver = { .name = DRIVER_NAME, - .of_match_table = of_match_ptr(of_hantro_match), + .of_match_table = of_hantro_match, .pm = &hantro_pm_ops, }, }; diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c index e871c078dd59..b3ae037a50f6 100644 --- a/drivers/media/platform/verisilicon/hantro_v4l2.c +++ b/drivers/media/platform/verisilicon/hantro_v4l2.c @@ -297,6 +297,7 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx, enum v4l2_buf_type type) { const struct hantro_fmt *fmt; + const struct hantro_fmt *vpu_fmt; bool capture = V4L2_TYPE_IS_CAPTURE(type); bool coded; @@ -316,19 +317,23 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx, if (coded) { pix_mp->num_planes = 1; - } else if (!ctx->is_encoder) { + vpu_fmt = fmt; + } else if (ctx->is_encoder) { + vpu_fmt = hantro_find_format(ctx, ctx->dst_fmt.pixelformat); + } else { /* * Width/height on the CAPTURE end of a decoder are ignored and * replaced by the OUTPUT ones. */ pix_mp->width = ctx->src_fmt.width; pix_mp->height = ctx->src_fmt.height; + vpu_fmt = fmt; } pix_mp->field = V4L2_FIELD_NONE; v4l2_apply_frmsize_constraints(&pix_mp->width, &pix_mp->height, - &fmt->frmsize); + &vpu_fmt->frmsize); if (!coded) { /* Fill remaining fields */ diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c index 6d273abfe16c..5de6b6694f53 100644 --- a/drivers/media/platform/video-mux.c +++ b/drivers/media/platform/video-mux.c @@ -314,7 +314,7 @@ static const struct v4l2_subdev_ops video_mux_subdev_ops = { static int video_mux_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd, - struct v4l2_async_subdev *asd) + struct v4l2_async_connection *asd) { struct video_mux *vmux = notifier_to_video_mux(notifier); @@ -331,10 +331,10 @@ static int video_mux_async_register(struct video_mux *vmux, unsigned int i; int ret; - v4l2_async_nf_init(&vmux->notifier); + v4l2_async_subdev_nf_init(&vmux->notifier, &vmux->subdev); for (i = 0; i < num_input_pads; i++) { - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; struct fwnode_handle *ep, *remote_ep; ep = fwnode_graph_get_endpoint_by_id( @@ -352,7 +352,7 @@ static int video_mux_async_register(struct video_mux *vmux, fwnode_handle_put(remote_ep); asd = v4l2_async_nf_add_fwnode_remote(&vmux->notifier, ep, - struct v4l2_async_subdev); + struct v4l2_async_connection); fwnode_handle_put(ep); @@ -366,7 +366,7 @@ static int video_mux_async_register(struct video_mux *vmux, vmux->notifier.ops = &video_mux_notify_ops; - ret = v4l2_async_subdev_nf_register(&vmux->subdev, &vmux->notifier); + ret = v4l2_async_nf_register(&vmux->notifier); if (ret) goto err_nf_cleanup; diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c index 3123216b3f70..4285770fde18 100644 --- a/drivers/media/platform/xilinx/xilinx-vipp.c +++ b/drivers/media/platform/xilinx/xilinx-vipp.c @@ -34,13 +34,13 @@ * @subdev: V4L2 subdev */ struct xvip_graph_entity { - struct v4l2_async_subdev asd; /* must be first */ + struct v4l2_async_connection asd; /* must be first */ struct media_entity *entity; struct v4l2_subdev *subdev; }; static inline struct xvip_graph_entity * -to_xvip_entity(struct v4l2_async_subdev *asd) +to_xvip_entity(struct v4l2_async_connection *asd) { return container_of(asd, struct xvip_graph_entity, asd); } @@ -54,9 +54,9 @@ xvip_graph_find_entity(struct xvip_composite_device *xdev, const struct fwnode_handle *fwnode) { struct xvip_graph_entity *entity; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; - list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) { + list_for_each_entry(asd, &xdev->notifier.done_list, asc_entry) { entity = to_xvip_entity(asd); if (entity->asd.match.fwnode == fwnode) return entity; @@ -285,13 +285,13 @@ static int xvip_graph_notify_complete(struct v4l2_async_notifier *notifier) struct xvip_composite_device *xdev = container_of(notifier, struct xvip_composite_device, notifier); struct xvip_graph_entity *entity; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; int ret; dev_dbg(xdev->dev, "notify complete, all subdevs registered\n"); /* Create links for every entity. */ - list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) { + list_for_each_entry(asd, &xdev->notifier.done_list, asc_entry) { entity = to_xvip_entity(asd); ret = xvip_graph_build_one(xdev, entity); if (ret < 0) @@ -312,36 +312,14 @@ static int xvip_graph_notify_complete(struct v4l2_async_notifier *notifier) static int xvip_graph_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *unused) + struct v4l2_async_connection *asc) { - struct xvip_composite_device *xdev = - container_of(notifier, struct xvip_composite_device, notifier); - struct xvip_graph_entity *entity; - struct v4l2_async_subdev *asd; - - /* Locate the entity corresponding to the bound subdev and store the - * subdev pointer. - */ - list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) { - entity = to_xvip_entity(asd); - - if (entity->asd.match.fwnode != subdev->fwnode) - continue; + struct xvip_graph_entity *entity = to_xvip_entity(asc); - if (entity->subdev) { - dev_err(xdev->dev, "duplicate subdev for node %p\n", - entity->asd.match.fwnode); - return -EINVAL; - } + entity->entity = &subdev->entity; + entity->subdev = subdev; - dev_dbg(xdev->dev, "subdev %s bound\n", subdev->name); - entity->entity = &subdev->entity; - entity->subdev = subdev; - return 0; - } - - dev_err(xdev->dev, "no entity for subdev %s\n", subdev->name); - return -EINVAL; + return 0; } static const struct v4l2_async_notifier_operations xvip_graph_notify_ops = { @@ -402,7 +380,7 @@ err_notifier_cleanup: static int xvip_graph_parse(struct xvip_composite_device *xdev) { struct xvip_graph_entity *entity; - struct v4l2_async_subdev *asd; + struct v4l2_async_connection *asd; int ret; /* @@ -415,7 +393,7 @@ static int xvip_graph_parse(struct xvip_composite_device *xdev) if (ret < 0) return 0; - list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) { + list_for_each_entry(asd, &xdev->notifier.waiting_list, asc_entry) { entity = to_xvip_entity(asd); ret = xvip_graph_parse_one(xdev, entity->asd.match.fwnode); if (ret < 0) { @@ -516,6 +494,8 @@ static int xvip_graph_init(struct xvip_composite_device *xdev) goto done; } + v4l2_async_nf_init(&xdev->notifier, &xdev->v4l2_dev); + /* Parse the graph to extract a list of subdevice DT nodes. */ ret = xvip_graph_parse(xdev); if (ret < 0) { @@ -523,7 +503,7 @@ static int xvip_graph_init(struct xvip_composite_device *xdev) goto done; } - if (list_empty(&xdev->notifier.asd_list)) { + if (list_empty(&xdev->notifier.waiting_list)) { dev_err(xdev->dev, "no subdev found in graph\n"); ret = -ENOENT; goto done; @@ -532,7 +512,7 @@ static int xvip_graph_init(struct xvip_composite_device *xdev) /* Register the subdevices notifier. */ xdev->notifier.ops = &xvip_graph_notify_ops; - ret = v4l2_async_nf_register(&xdev->v4l2_dev, &xdev->notifier); + ret = v4l2_async_nf_register(&xdev->notifier); if (ret < 0) { dev_err(xdev->dev, "notifier registration failed\n"); goto done; @@ -596,7 +576,6 @@ static int xvip_composite_probe(struct platform_device *pdev) xdev->dev = &pdev->dev; INIT_LIST_HEAD(&xdev->dmas); - v4l2_async_nf_init(&xdev->notifier); ret = xvip_composite_v4l2_init(xdev); if (ret < 0) |