1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  */
5 
6 #include <linux/types.h>
7 #include <media/v4l2-mem2mem.h>
8 
9 #include "iris_ctrls.h"
10 #include "iris_instance.h"
11 
iris_valid_cap_id(enum platform_inst_fw_cap_type cap_id)12 static inline bool iris_valid_cap_id(enum platform_inst_fw_cap_type cap_id)
13 {
14 	return cap_id >= 1 && cap_id < INST_FW_CAP_MAX;
15 }
16 
iris_get_cap_id(u32 id)17 static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
18 {
19 	switch (id) {
20 	case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
21 		return DEBLOCK;
22 	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
23 		return PROFILE;
24 	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
25 		return LEVEL;
26 	default:
27 		return INST_FW_CAP_MAX;
28 	}
29 }
30 
iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)31 static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
32 {
33 	if (!iris_valid_cap_id(cap_id))
34 		return 0;
35 
36 	switch (cap_id) {
37 	case DEBLOCK:
38 		return V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER;
39 	case PROFILE:
40 		return V4L2_CID_MPEG_VIDEO_H264_PROFILE;
41 	case LEVEL:
42 		return V4L2_CID_MPEG_VIDEO_H264_LEVEL;
43 	default:
44 		return 0;
45 	}
46 }
47 
iris_vdec_op_s_ctrl(struct v4l2_ctrl * ctrl)48 static int iris_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
49 {
50 	struct iris_inst *inst = container_of(ctrl->handler, struct iris_inst, ctrl_handler);
51 	enum platform_inst_fw_cap_type cap_id;
52 	struct platform_inst_fw_cap *cap;
53 	struct vb2_queue *q;
54 
55 	cap = &inst->fw_caps[0];
56 	cap_id = iris_get_cap_id(ctrl->id);
57 	if (!iris_valid_cap_id(cap_id))
58 		return -EINVAL;
59 
60 	q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
61 	if (vb2_is_streaming(q) &&
62 	    (!(inst->fw_caps[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED)))
63 		return -EINVAL;
64 
65 	cap[cap_id].flags |= CAP_FLAG_CLIENT_SET;
66 
67 	inst->fw_caps[cap_id].value = ctrl->val;
68 
69 	return 0;
70 }
71 
72 static const struct v4l2_ctrl_ops iris_ctrl_ops = {
73 	.s_ctrl = iris_vdec_op_s_ctrl,
74 };
75 
iris_ctrls_init(struct iris_inst * inst)76 int iris_ctrls_init(struct iris_inst *inst)
77 {
78 	struct platform_inst_fw_cap *cap = &inst->fw_caps[0];
79 	u32 num_ctrls = 0, ctrl_idx = 0, idx = 0;
80 	u32 v4l2_id;
81 	int ret;
82 
83 	for (idx = 1; idx < INST_FW_CAP_MAX; idx++) {
84 		if (iris_get_v4l2_id(cap[idx].cap_id))
85 			num_ctrls++;
86 	}
87 	if (!num_ctrls)
88 		return -EINVAL;
89 
90 	/* Adding 1 to num_ctrls to include V4L2_CID_MIN_BUFFERS_FOR_CAPTURE */
91 
92 	ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls + 1);
93 	if (ret)
94 		return ret;
95 
96 	for (idx = 1; idx < INST_FW_CAP_MAX; idx++) {
97 		struct v4l2_ctrl *ctrl;
98 
99 		v4l2_id = iris_get_v4l2_id(cap[idx].cap_id);
100 		if (!v4l2_id)
101 			continue;
102 
103 		if (ctrl_idx >= num_ctrls) {
104 			ret = -EINVAL;
105 			goto error;
106 		}
107 
108 		if (cap[idx].flags & CAP_FLAG_MENU) {
109 			ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler,
110 						      &iris_ctrl_ops,
111 						      v4l2_id,
112 						      cap[idx].max,
113 						      ~(cap[idx].step_or_mask),
114 						      cap[idx].value);
115 		} else {
116 			ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
117 						 &iris_ctrl_ops,
118 						 v4l2_id,
119 						 cap[idx].min,
120 						 cap[idx].max,
121 						 cap[idx].step_or_mask,
122 						 cap[idx].value);
123 		}
124 		if (!ctrl) {
125 			ret = -EINVAL;
126 			goto error;
127 		}
128 
129 		ctrl_idx++;
130 	}
131 
132 	v4l2_ctrl_new_std(&inst->ctrl_handler, NULL,
133 			  V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 4);
134 
135 	ret = inst->ctrl_handler.error;
136 	if (ret)
137 		goto error;
138 
139 	return 0;
140 error:
141 	v4l2_ctrl_handler_free(&inst->ctrl_handler);
142 
143 	return ret;
144 }
145 
iris_session_init_caps(struct iris_core * core)146 void iris_session_init_caps(struct iris_core *core)
147 {
148 	struct platform_inst_fw_cap *caps;
149 	u32 i, num_cap, cap_id;
150 
151 	caps = core->iris_platform_data->inst_fw_caps;
152 	num_cap = core->iris_platform_data->inst_fw_caps_size;
153 
154 	for (i = 0; i < num_cap; i++) {
155 		cap_id = caps[i].cap_id;
156 		if (!iris_valid_cap_id(cap_id))
157 			continue;
158 
159 		core->inst_fw_caps[cap_id].cap_id = caps[i].cap_id;
160 		core->inst_fw_caps[cap_id].min = caps[i].min;
161 		core->inst_fw_caps[cap_id].max = caps[i].max;
162 		core->inst_fw_caps[cap_id].step_or_mask = caps[i].step_or_mask;
163 		core->inst_fw_caps[cap_id].value = caps[i].value;
164 		core->inst_fw_caps[cap_id].flags = caps[i].flags;
165 		core->inst_fw_caps[cap_id].hfi_id = caps[i].hfi_id;
166 	}
167 }
168 
iris_get_port_info(struct iris_inst * inst,enum platform_inst_fw_cap_type cap_id)169 static u32 iris_get_port_info(struct iris_inst *inst,
170 			      enum platform_inst_fw_cap_type cap_id)
171 {
172 	if (inst->fw_caps[cap_id].flags & CAP_FLAG_INPUT_PORT)
173 		return HFI_PORT_BITSTREAM;
174 	else if (inst->fw_caps[cap_id].flags & CAP_FLAG_OUTPUT_PORT)
175 		return HFI_PORT_RAW;
176 
177 	return HFI_PORT_NONE;
178 }
179 
iris_set_u32_enum(struct iris_inst * inst,enum platform_inst_fw_cap_type cap_id)180 int iris_set_u32_enum(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
181 {
182 	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
183 	u32 hfi_value = inst->fw_caps[cap_id].value;
184 	u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
185 
186 	return hfi_ops->session_set_property(inst, hfi_id,
187 					     HFI_HOST_FLAGS_NONE,
188 					     iris_get_port_info(inst, cap_id),
189 					     HFI_PAYLOAD_U32_ENUM,
190 					     &hfi_value, sizeof(u32));
191 }
192 
iris_set_u32(struct iris_inst * inst,enum platform_inst_fw_cap_type cap_id)193 int iris_set_u32(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
194 {
195 	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
196 	u32 hfi_value = inst->fw_caps[cap_id].value;
197 	u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
198 
199 	return hfi_ops->session_set_property(inst, hfi_id,
200 					     HFI_HOST_FLAGS_NONE,
201 					     iris_get_port_info(inst, cap_id),
202 					     HFI_PAYLOAD_U32,
203 					     &hfi_value, sizeof(u32));
204 }
205 
iris_set_stage(struct iris_inst * inst,enum platform_inst_fw_cap_type cap_id)206 int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
207 {
208 	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
209 	struct v4l2_format *inp_f = inst->fmt_src;
210 	u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
211 	u32 height = inp_f->fmt.pix_mp.height;
212 	u32 width = inp_f->fmt.pix_mp.width;
213 	u32 work_mode = STAGE_2;
214 
215 	if (iris_res_is_less_than(width, height, 1280, 720))
216 		work_mode = STAGE_1;
217 
218 	return hfi_ops->session_set_property(inst, hfi_id,
219 					     HFI_HOST_FLAGS_NONE,
220 					     iris_get_port_info(inst, cap_id),
221 					     HFI_PAYLOAD_U32,
222 					     &work_mode, sizeof(u32));
223 }
224 
iris_set_pipe(struct iris_inst * inst,enum platform_inst_fw_cap_type cap_id)225 int iris_set_pipe(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
226 {
227 	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
228 	u32 work_route = inst->fw_caps[PIPE].value;
229 	u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
230 
231 	return hfi_ops->session_set_property(inst, hfi_id,
232 					     HFI_HOST_FLAGS_NONE,
233 					     iris_get_port_info(inst, cap_id),
234 					     HFI_PAYLOAD_U32,
235 					     &work_route, sizeof(u32));
236 }
237 
iris_set_properties(struct iris_inst * inst,u32 plane)238 int iris_set_properties(struct iris_inst *inst, u32 plane)
239 {
240 	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
241 	struct platform_inst_fw_cap *cap;
242 	int ret;
243 	u32 i;
244 
245 	ret = hfi_ops->session_set_config_params(inst, plane);
246 	if (ret)
247 		return ret;
248 
249 	for (i = 1; i < INST_FW_CAP_MAX; i++) {
250 		cap = &inst->fw_caps[i];
251 		if (!iris_valid_cap_id(cap->cap_id))
252 			continue;
253 
254 		if (cap->cap_id && cap->set)
255 			cap->set(inst, i);
256 	}
257 
258 	return 0;
259 }
260