| 1 | |
| 2 | |
| 3 | * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
| 4 |
|
| 5 |
|
| 6 | #include <linux/pm_runtime.h>
|
| 7 | #include <media/v4l2-mem2mem.h>
|
| 8 |
|
| 9 | #include "iris_instance.h"
|
| 10 | #include "iris_utils.h"
|
| 11 |
|
| 12 | bool iris_res_is_less_than(u32 width, u32 height,
|
| 13 | u32 ref_width, u32 ref_height)
|
| 14 | {
|
| 15 | u32 num_mbs = NUM_MBS_PER_FRAME(height, width);
|
| 16 | u32 max_side = max(ref_width, ref_height);
|
| 17 |
|
| 18 | if (num_mbs < NUM_MBS_PER_FRAME(ref_height, ref_width) &&
|
| 19 | width < max_side &&
|
| 20 | height < max_side)
|
| 21 | return true;
|
| 22 |
|
| 23 | return false;
|
| 24 | }
|
| 25 |
|
| 26 | int iris_get_mbpf(struct iris_inst *inst)
|
| 27 | {
|
| 28 | struct v4l2_format *inp_f = inst->fmt_src;
|
| 29 | u32 height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
|
| 30 | u32 width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
|
| 31 |
|
| 32 | return NUM_MBS_PER_FRAME(height, width);
|
| 33 | }
|
| 34 |
|
| 35 | bool iris_split_mode_enabled(struct iris_inst *inst)
|
| 36 | {
|
| 37 | return inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_NV12 ||
|
| 38 | inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C ||
|
| 39 | inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_P010 ||
|
| 40 | inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC10C;
|
| 41 | }
|
| 42 |
|
| 43 | bool iris_fmt_is_8bit(u32 pixelformat)
|
| 44 | {
|
| 45 | return pixelformat == V4L2_PIX_FMT_NV12 ||
|
| 46 | pixelformat == V4L2_PIX_FMT_QC08C;
|
| 47 | }
|
| 48 |
|
| 49 | bool iris_fmt_is_10bit(u32 pixelformat)
|
| 50 | {
|
| 51 | return pixelformat == V4L2_PIX_FMT_P010 ||
|
| 52 | pixelformat == V4L2_PIX_FMT_QC10C;
|
| 53 | }
|
| 54 |
|
| 55 | void iris_helper_buffers_done(struct iris_inst *inst, unsigned int type,
|
| 56 | enum vb2_buffer_state state)
|
| 57 | {
|
| 58 | struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
|
| 59 | struct vb2_v4l2_buffer *buf;
|
| 60 |
|
| 61 | if (V4L2_TYPE_IS_OUTPUT(type)) {
|
| 62 | while ((buf = v4l2_m2m_src_buf_remove(m2m_ctx)))
|
| 63 | v4l2_m2m_buf_done(buf, state);
|
| 64 | } else if (V4L2_TYPE_IS_CAPTURE(type)) {
|
| 65 | while ((buf = v4l2_m2m_dst_buf_remove(m2m_ctx)))
|
| 66 | v4l2_m2m_buf_done(buf, state);
|
| 67 | }
|
| 68 | }
|
| 69 |
|
| 70 | int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush)
|
| 71 | {
|
| 72 | struct completion *done;
|
| 73 | int ret;
|
| 74 |
|
| 75 | done = is_flush ? &inst->flush_completion : &inst->completion;
|
| 76 |
|
| 77 | mutex_unlock(&inst->lock);
|
| 78 | ret = wait_for_completion_timeout(done, msecs_to_jiffies(HW_RESPONSE_TIMEOUT_VALUE));
|
| 79 | mutex_lock(&inst->lock);
|
| 80 | if (!ret) {
|
| 81 | iris_inst_change_state(inst, IRIS_INST_ERROR);
|
| 82 | return -ETIMEDOUT;
|
| 83 | }
|
| 84 |
|
| 85 | return 0;
|
| 86 | }
|
| 87 |
|
| 88 | struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id)
|
| 89 | {
|
| 90 | struct iris_inst *inst;
|
| 91 |
|
| 92 | mutex_lock(&core->lock);
|
| 93 | list_for_each_entry(inst, &core->instances, list) {
|
| 94 | if (inst->session_id == session_id) {
|
| 95 | mutex_unlock(&core->lock);
|
| 96 | return inst;
|
| 97 | }
|
| 98 | }
|
| 99 |
|
| 100 | mutex_unlock(&core->lock);
|
| 101 | return NULL;
|
| 102 | }
|
| 103 |
|
| 104 | int iris_check_core_mbpf(struct iris_inst *inst)
|
| 105 | {
|
| 106 | struct iris_core *core = inst->core;
|
| 107 | struct iris_inst *instance;
|
| 108 | u32 total_mbpf = 0;
|
| 109 |
|
| 110 | mutex_lock(&core->lock);
|
| 111 | list_for_each_entry(instance, &core->instances, list)
|
| 112 | total_mbpf += iris_get_mbpf(instance);
|
| 113 | mutex_unlock(&core->lock);
|
| 114 |
|
| 115 | if (total_mbpf > core->iris_platform_data->max_core_mbpf)
|
| 116 | return -ENOMEM;
|
| 117 |
|
| 118 | return 0;
|
| 119 | }
|
| 120 |
|
| 121 | int iris_check_core_mbps(struct iris_inst *inst)
|
| 122 | {
|
| 123 | struct iris_core *core = inst->core;
|
| 124 | struct iris_inst *instance;
|
| 125 | u32 total_mbps = 0, fps = 0;
|
| 126 |
|
| 127 | mutex_lock(&core->lock);
|
| 128 | list_for_each_entry(instance, &core->instances, list) {
|
| 129 | fps = max(instance->frame_rate, instance->operating_rate);
|
| 130 | total_mbps += iris_get_mbpf(instance) * fps;
|
| 131 | }
|
| 132 | mutex_unlock(&core->lock);
|
| 133 |
|
| 134 | if (total_mbps > core->iris_platform_data->max_core_mbps)
|
| 135 | return -ENOMEM;
|
| 136 |
|
| 137 | return 0;
|
| 138 | }
|
| 139 |
|
| 140 | bool is_rotation_90_or_270(struct iris_inst *inst)
|
| 141 | {
|
| 142 | return inst->fw_caps[ROTATION].value == 90 ||
|
| 143 | inst->fw_caps[ROTATION].value == 270;
|
| 144 | }
|