blob: 8f77ebb90335434a83d6ebb9c2ba691e08882b60 [file] [log] [blame]
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/jiffies.h>
15#include <linux/sched.h>
16#include <linux/slab.h>
17#include <linux/kernel.h>
18#include <linux/bitops.h>
19#include <soc/qcom/subsystem_restart.h>
20#include <asm/div64.h>
21#include "msm_vidc_common.h"
22#include "vidc_hfi_api.h"
23#include "msm_vidc_debug.h"
24#include "msm_vidc_clocks.h"
25
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -070026#define IS_ALREADY_IN_STATE(__p, __d) (\
27 (__p >= __d)\
28)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -080029
30#define V4L2_EVENT_SEQ_CHANGED_SUFFICIENT \
31 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT
32#define V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT \
33 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT
34#define V4L2_EVENT_RELEASE_BUFFER_REFERENCE \
35 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE
Chinmay Sawarkarb3c6ccb2017-02-23 18:01:32 -080036#define L_MODE V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -080037
38#define MAX_SUPPORTED_INSTANCES 16
39
40const char *const mpeg_video_vidc_extradata[] = {
41 "Extradata none",
42 "Extradata MB Quantization",
43 "Extradata Interlace Video",
Chinmay Sawarkar2bacf632017-04-13 14:46:43 -070044 "Reserved",
45 "Reserved",
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -080046 "Extradata timestamp",
47 "Extradata S3D Frame Packing",
48 "Extradata Frame Rate",
49 "Extradata Panscan Window",
50 "Extradata Recovery point SEI",
51 "Extradata Multislice info",
52 "Extradata number of concealed MB",
53 "Extradata metadata filler",
54 "Extradata input crop",
55 "Extradata digital zoom",
56 "Extradata aspect ratio",
57 "Extradata mpeg2 seqdisp",
58 "Extradata stream userdata",
59 "Extradata frame QP",
60 "Extradata frame bits info",
61 "Extradata LTR",
62 "Extradata macroblock metadata",
63 "Extradata VQZip SEI",
64 "Extradata YUV Stats",
65 "Extradata ROI QP",
66 "Extradata output crop",
67 "Extradata display colour SEI",
68 "Extradata light level SEI",
69 "Extradata PQ Info",
70 "Extradata display VUI",
71 "Extradata vpx color space",
72};
73
74struct getprop_buf {
75 struct list_head list;
76 void *data;
77};
78
79static void msm_comm_generate_session_error(struct msm_vidc_inst *inst);
80static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst);
81static void handle_session_error(enum hal_command_response cmd, void *data);
82static void msm_vidc_print_running_insts(struct msm_vidc_core *core);
83static void msm_comm_print_debug_info(struct msm_vidc_inst *inst);
84
85bool msm_comm_turbo_session(struct msm_vidc_inst *inst)
86{
87 return !!(inst->flags & VIDC_TURBO);
88}
89
90static inline bool is_thumbnail_session(struct msm_vidc_inst *inst)
91{
92 return !!(inst->flags & VIDC_THUMBNAIL);
93}
94
95static inline bool is_low_power_session(struct msm_vidc_inst *inst)
96{
97 return !!(inst->flags & VIDC_LOW_POWER);
98}
99
100static inline bool is_realtime_session(struct msm_vidc_inst *inst)
101{
102 return !!(inst->flags & VIDC_REALTIME);
103}
104
105int msm_comm_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
106{
107 return v4l2_g_ctrl(&inst->ctrl_handler, ctrl);
108}
109
110int msm_comm_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
111{
112 return v4l2_s_ctrl(NULL, &inst->ctrl_handler, ctrl);
113}
114
115int msm_comm_g_ctrl_for_id(struct msm_vidc_inst *inst, int id)
116{
117 int rc = 0;
118 struct v4l2_control ctrl = {
119 .id = id,
120 };
121
122 rc = msm_comm_g_ctrl(inst, &ctrl);
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -0700123 return rc ? rc : ctrl.value;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800124}
125
126static struct v4l2_ctrl **get_super_cluster(struct msm_vidc_inst *inst,
127 int num_ctrls)
128{
129 int c = 0;
130 struct v4l2_ctrl **cluster = kmalloc(sizeof(struct v4l2_ctrl *) *
131 num_ctrls, GFP_KERNEL);
132
133 if (!cluster || !inst)
134 return NULL;
135
136 for (c = 0; c < num_ctrls; c++)
137 cluster[c] = inst->ctrls[c];
138
139 return cluster;
140}
141
Chinmay Sawarkarb3c6ccb2017-02-23 18:01:32 -0800142int msm_comm_hal_to_v4l2(int id, int value)
143{
144 switch (id) {
145 /* H264 */
146 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
147 switch (value) {
148 case HAL_H264_PROFILE_BASELINE:
149 return V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
150 case HAL_H264_PROFILE_CONSTRAINED_BASE:
151 return
152 V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
153 case HAL_H264_PROFILE_MAIN:
154 return V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
155 case HAL_H264_PROFILE_EXTENDED:
156 return V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
157 case HAL_H264_PROFILE_HIGH:
158 return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
159 case HAL_H264_PROFILE_HIGH10:
160 return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
161 case HAL_H264_PROFILE_HIGH422:
162 return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
163 case HAL_H264_PROFILE_HIGH444:
164 return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
165 default:
166 goto unknown_value;
167 }
168 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
169 switch (value) {
170 case HAL_H264_LEVEL_1:
171 return V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
172 case HAL_H264_LEVEL_1b:
173 return V4L2_MPEG_VIDEO_H264_LEVEL_1B;
174 case HAL_H264_LEVEL_11:
175 return V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
176 case HAL_H264_LEVEL_12:
177 return V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
178 case HAL_H264_LEVEL_13:
179 return V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
180 case HAL_H264_LEVEL_2:
181 return V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
182 case HAL_H264_LEVEL_21:
183 return V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
184 case HAL_H264_LEVEL_22:
185 return V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
186 case HAL_H264_LEVEL_3:
187 return V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
188 case HAL_H264_LEVEL_31:
189 return V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
190 case HAL_H264_LEVEL_32:
191 return V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
192 case HAL_H264_LEVEL_4:
193 return V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
194 case HAL_H264_LEVEL_41:
195 return V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
196 case HAL_H264_LEVEL_42:
197 return V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
198 case HAL_H264_LEVEL_5:
199 return V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
200 case HAL_H264_LEVEL_51:
201 return V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
202 default:
203 goto unknown_value;
204 }
205
206 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
207 switch (value) {
208 case HAL_H264_ENTROPY_CAVLC:
209 return V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
210 case HAL_H264_ENTROPY_CABAC:
211 return V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
212 default:
213 goto unknown_value;
214 }
215 case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL:
216 case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE:
217 case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL:
218 /*
219 * Extremely dirty hack: we haven't implemented g_ctrl of
220 * any of these controls and have no intention of doing
221 * so in the near future. So just return 0 so that we
222 * don't see the annoying "Unknown control" errors at the
223 * bottom of this function.
224 */
225 return 0;
226 }
227
228unknown_value:
229 dprintk(VIDC_WARN, "Unknown control (%x, %d)\n", id, value);
230 return -EINVAL;
231}
232
233int msm_comm_v4l2_to_hal(int id, int value)
234{
235 switch (id) {
236 /* H264 */
237 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
238 switch (value) {
239 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
240 return HAL_H264_PROFILE_BASELINE;
241 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
242 return HAL_H264_PROFILE_CONSTRAINED_BASE;
243 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
244 return HAL_H264_PROFILE_MAIN;
245 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
246 return HAL_H264_PROFILE_EXTENDED;
247 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
248 return HAL_H264_PROFILE_HIGH;
249 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
250 return HAL_H264_PROFILE_HIGH10;
251 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
252 return HAL_H264_PROFILE_HIGH422;
253 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
254 return HAL_H264_PROFILE_HIGH444;
255 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
256 return HAL_H264_PROFILE_CONSTRAINED_HIGH;
257 default:
258 goto unknown_value;
259 }
260 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
261 switch (value) {
262 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
263 return HAL_H264_LEVEL_1;
264 case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
265 return HAL_H264_LEVEL_1b;
266 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
267 return HAL_H264_LEVEL_11;
268 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
269 return HAL_H264_LEVEL_12;
270 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
271 return HAL_H264_LEVEL_13;
272 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
273 return HAL_H264_LEVEL_2;
274 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
275 return HAL_H264_LEVEL_21;
276 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
277 return HAL_H264_LEVEL_22;
278 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
279 return HAL_H264_LEVEL_3;
280 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
281 return HAL_H264_LEVEL_31;
282 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
283 return HAL_H264_LEVEL_32;
284 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
285 return HAL_H264_LEVEL_4;
286 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
287 return HAL_H264_LEVEL_41;
288 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
289 return HAL_H264_LEVEL_42;
290 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
291 return HAL_H264_LEVEL_5;
292 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
293 return HAL_H264_LEVEL_51;
294 case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
295 return HAL_H264_LEVEL_52;
Vaibhav Deshu Venkatesh234b4dc2017-03-21 16:54:28 -0700296 case V4L2_MPEG_VIDEO_H264_LEVEL_UNKNOWN:
297 return HAL_H264_LEVEL_UNKNOWN;
Chinmay Sawarkarb3c6ccb2017-02-23 18:01:32 -0800298 default:
299 goto unknown_value;
300 }
301 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
302 switch (value) {
303 case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC:
304 return HAL_H264_ENTROPY_CAVLC;
305 case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC:
306 return HAL_H264_ENTROPY_CABAC;
307 default:
308 goto unknown_value;
309 }
310 case V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL:
311 switch (value) {
312 case V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0:
313 return HAL_H264_CABAC_MODEL_0;
314 case V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1:
315 return HAL_H264_CABAC_MODEL_1;
316 case V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2:
317 return HAL_H264_CABAC_MODEL_2;
318 default:
319 goto unknown_value;
320 }
321 case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL:
322 switch (value) {
323 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
324 return HAL_VPX_PROFILE_VERSION_0;
325 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
326 return HAL_VPX_PROFILE_VERSION_1;
327 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_2:
328 return HAL_VPX_PROFILE_VERSION_2;
329 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3:
330 return HAL_VPX_PROFILE_VERSION_3;
331 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
332 return HAL_VPX_PROFILE_UNUSED;
333 default:
334 goto unknown_value;
335 }
336 case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE:
337 switch (value) {
338 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
339 return HAL_HEVC_PROFILE_MAIN;
340 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
341 return HAL_HEVC_PROFILE_MAIN10;
342 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN_STILL_PIC:
343 return HAL_HEVC_PROFILE_MAIN_STILL_PIC;
344 default:
345 goto unknown_value;
346 }
347 case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL:
348 switch (value) {
349 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1:
350 return HAL_HEVC_MAIN_TIER_LEVEL_1;
351 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2:
352 return HAL_HEVC_MAIN_TIER_LEVEL_2;
353 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1:
354 return HAL_HEVC_MAIN_TIER_LEVEL_2_1;
355 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3:
356 return HAL_HEVC_MAIN_TIER_LEVEL_3;
357 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1:
358 return HAL_HEVC_MAIN_TIER_LEVEL_3_1;
359 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4:
360 return HAL_HEVC_MAIN_TIER_LEVEL_4;
361 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1:
362 return HAL_HEVC_MAIN_TIER_LEVEL_4_1;
363 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5:
364 return HAL_HEVC_MAIN_TIER_LEVEL_5;
365 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1:
366 return HAL_HEVC_MAIN_TIER_LEVEL_5_1;
367 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2:
368 return HAL_HEVC_MAIN_TIER_LEVEL_5_2;
369 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6:
370 return HAL_HEVC_MAIN_TIER_LEVEL_6;
371 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1:
372 return HAL_HEVC_MAIN_TIER_LEVEL_6_1;
373 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2:
374 return HAL_HEVC_MAIN_TIER_LEVEL_6_2;
375 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1:
376 return HAL_HEVC_HIGH_TIER_LEVEL_1;
377 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2:
378 return HAL_HEVC_HIGH_TIER_LEVEL_2;
379 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1:
380 return HAL_HEVC_HIGH_TIER_LEVEL_2_1;
381 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3:
382 return HAL_HEVC_HIGH_TIER_LEVEL_3;
383 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1:
384 return HAL_HEVC_HIGH_TIER_LEVEL_3_1;
385 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4:
386 return HAL_HEVC_HIGH_TIER_LEVEL_4;
387 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1:
388 return HAL_HEVC_HIGH_TIER_LEVEL_4_1;
389 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5:
390 return HAL_HEVC_HIGH_TIER_LEVEL_5;
391 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1:
392 return HAL_HEVC_HIGH_TIER_LEVEL_5_1;
393 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2:
394 return HAL_HEVC_HIGH_TIER_LEVEL_5_2;
395 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6:
396 return HAL_HEVC_HIGH_TIER_LEVEL_6;
397 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1:
398 return HAL_HEVC_HIGH_TIER_LEVEL_6_1;
Vaibhav Deshu Venkatesh234b4dc2017-03-21 16:54:28 -0700399 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_UNKNOWN:
400 return HAL_HEVC_TIER_LEVEL_UNKNOWN;
Chinmay Sawarkarb3c6ccb2017-02-23 18:01:32 -0800401 default:
402 goto unknown_value;
403 }
404 case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION:
405 switch (value) {
406 case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE:
407 return HAL_ROTATE_NONE;
408 case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90:
409 return HAL_ROTATE_90;
410 case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180:
411 return HAL_ROTATE_180;
412 case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270:
413 return HAL_ROTATE_270;
414 default:
415 goto unknown_value;
416 }
417 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
418 switch (value) {
419 case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED:
420 return HAL_H264_DB_MODE_DISABLE;
421 case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED:
422 return HAL_H264_DB_MODE_ALL_BOUNDARY;
423 case L_MODE:
424 return HAL_H264_DB_MODE_SKIP_SLICE_BOUNDARY;
425 default:
426 goto unknown_value;
427 }
428 case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE:
429 switch (value) {
430 case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT:
431 return HAL_IFRAMESIZE_TYPE_DEFAULT;
432 case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_MEDIUM:
433 return HAL_IFRAMESIZE_TYPE_MEDIUM;
434 case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_HUGE:
435 return HAL_IFRAMESIZE_TYPE_HUGE;
436 case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED:
437 return HAL_IFRAMESIZE_TYPE_UNLIMITED;
438 default:
439 goto unknown_value;
440 }
441 }
442
443unknown_value:
444 dprintk(VIDC_WARN, "Unknown control (%x, %d)\n", id, value);
445 return -EINVAL;
446}
447
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800448int msm_comm_ctrl_init(struct msm_vidc_inst *inst,
449 struct msm_vidc_ctrl *drv_ctrls, u32 num_ctrls,
450 const struct v4l2_ctrl_ops *ctrl_ops)
451{
452 int idx = 0;
453 struct v4l2_ctrl_config ctrl_cfg = {0};
454 int ret_val = 0;
455
456 if (!inst || !drv_ctrls || !ctrl_ops || !num_ctrls) {
457 dprintk(VIDC_ERR, "%s - invalid input\n", __func__);
458 return -EINVAL;
459 }
460
461 inst->ctrls = kcalloc(num_ctrls, sizeof(struct v4l2_ctrl *),
462 GFP_KERNEL);
463 if (!inst->ctrls) {
464 dprintk(VIDC_ERR, "%s - failed to allocate ctrl\n", __func__);
465 return -ENOMEM;
466 }
467
468 ret_val = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls);
469
470 if (ret_val) {
471 dprintk(VIDC_ERR, "CTRL ERR: Control handler init failed, %d\n",
472 inst->ctrl_handler.error);
473 return ret_val;
474 }
475
476 for (; idx < num_ctrls; idx++) {
477 struct v4l2_ctrl *ctrl = NULL;
478
479 if (1) {
480 /*add private control*/
481 ctrl_cfg.def = drv_ctrls[idx].default_value;
482 ctrl_cfg.flags = 0;
483 ctrl_cfg.id = drv_ctrls[idx].id;
484 ctrl_cfg.max = drv_ctrls[idx].maximum;
485 ctrl_cfg.min = drv_ctrls[idx].minimum;
486 ctrl_cfg.menu_skip_mask =
487 drv_ctrls[idx].menu_skip_mask;
488 ctrl_cfg.name = drv_ctrls[idx].name;
489 ctrl_cfg.ops = ctrl_ops;
490 ctrl_cfg.step = drv_ctrls[idx].step;
491 ctrl_cfg.type = drv_ctrls[idx].type;
492 ctrl_cfg.qmenu = drv_ctrls[idx].qmenu;
493
494 ctrl = v4l2_ctrl_new_custom(&inst->ctrl_handler,
495 &ctrl_cfg, NULL);
496 } else {
497 if (drv_ctrls[idx].type == V4L2_CTRL_TYPE_MENU) {
498 ctrl = v4l2_ctrl_new_std_menu(
499 &inst->ctrl_handler,
500 ctrl_ops,
501 drv_ctrls[idx].id,
502 drv_ctrls[idx].maximum,
503 drv_ctrls[idx].menu_skip_mask,
504 drv_ctrls[idx].default_value);
505 } else {
506 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
507 ctrl_ops,
508 drv_ctrls[idx].id,
509 drv_ctrls[idx].minimum,
510 drv_ctrls[idx].maximum,
511 drv_ctrls[idx].step,
512 drv_ctrls[idx].default_value);
513 }
514 }
515
516 if (!ctrl) {
517 dprintk(VIDC_ERR, "%s - invalid ctrl %s\n", __func__,
518 drv_ctrls[idx].name);
519 return -EINVAL;
520 }
521
522 ret_val = inst->ctrl_handler.error;
523 if (ret_val) {
524 dprintk(VIDC_ERR,
525 "Error adding ctrl (%s) to ctrl handle, %d\n",
526 drv_ctrls[idx].name, inst->ctrl_handler.error);
527 return ret_val;
528 }
529
530 ctrl->flags |= drv_ctrls[idx].flags;
531 inst->ctrls[idx] = ctrl;
532 }
533
534 /* Construct a super cluster of all controls */
535 inst->cluster = get_super_cluster(inst, num_ctrls);
536 if (!inst->cluster) {
537 dprintk(VIDC_WARN,
538 "Failed to setup super cluster\n");
539 return -EINVAL;
540 }
541
542 v4l2_ctrl_cluster(num_ctrls, inst->cluster);
543
544 return ret_val;
545}
546
547int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst)
548{
549 if (!inst) {
550 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
551 return -EINVAL;
552 }
553
554 kfree(inst->ctrls);
555 kfree(inst->cluster);
556 v4l2_ctrl_handler_free(&inst->ctrl_handler);
557
558 return 0;
559}
560
561enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst)
562{
563 switch (msm_comm_g_ctrl_for_id(inst,
564 V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE)) {
565 case V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY:
566 return HAL_VIDEO_DECODER_SECONDARY;
567 case V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY:
568 default:
569 return HAL_VIDEO_DECODER_PRIMARY;
570 }
571}
572
573static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst)
574{
575 int output_port_mbs, capture_port_mbs;
576 int fps;
577
578 output_port_mbs = inst->in_reconfig ?
579 NUM_MBS_PER_FRAME(inst->reconfig_width,
580 inst->reconfig_height) :
581 NUM_MBS_PER_FRAME(inst->prop.width[OUTPUT_PORT],
582 inst->prop.height[OUTPUT_PORT]);
583
584 capture_port_mbs = NUM_MBS_PER_FRAME(inst->prop.width[CAPTURE_PORT],
585 inst->prop.height[CAPTURE_PORT]);
586
587 if (inst->operating_rate) {
588 fps = (inst->operating_rate >> 16) ?
589 inst->operating_rate >> 16 : 1;
590 /*
591 * Check if operating rate is less than fps.
592 * If Yes, then use fps to scale clocks
593 */
594 fps = fps > inst->prop.fps ? fps : inst->prop.fps;
595 return max(output_port_mbs, capture_port_mbs) * fps;
596 } else {
597 return max(output_port_mbs, capture_port_mbs) * inst->prop.fps;
598 }
599}
600
601int msm_comm_get_inst_load(struct msm_vidc_inst *inst,
602 enum load_calc_quirks quirks)
603{
604 int load = 0;
605
606 mutex_lock(&inst->lock);
607
608 if (!(inst->state >= MSM_VIDC_OPEN_DONE &&
609 inst->state < MSM_VIDC_STOP_DONE))
610 goto exit;
611
612 load = msm_comm_get_mbs_per_sec(inst);
613
614 if (is_thumbnail_session(inst)) {
615 if (quirks & LOAD_CALC_IGNORE_THUMBNAIL_LOAD)
616 load = 0;
617 }
618
619 if (msm_comm_turbo_session(inst)) {
620 if (!(quirks & LOAD_CALC_IGNORE_TURBO_LOAD))
621 load = inst->core->resources.max_load;
622 }
623
624 /* Clock and Load calculations for REALTIME/NON-REALTIME
625 * OPERATING RATE SET/NO OPERATING RATE SET
626 *
627 * | OPERATING RATE SET | OPERATING RATE NOT SET |
628 * ----------------|--------------------- |------------------------|
629 * REALTIME | load = res * op_rate | load = res * fps |
630 * | clk = res * op_rate | clk = res * fps |
631 * ----------------|----------------------|------------------------|
632 * NON-REALTIME | load = res * 1 fps | load = res * 1 fps |
633 * | clk = res * op_rate | clk = res * fps |
634 * ----------------|----------------------|------------------------|
635 */
636
637 if (!is_realtime_session(inst) &&
638 (quirks & LOAD_CALC_IGNORE_NON_REALTIME_LOAD)) {
639 if (!inst->prop.fps) {
640 dprintk(VIDC_INFO, "instance:%pK fps = 0\n", inst);
641 load = 0;
642 } else {
643 load = msm_comm_get_mbs_per_sec(inst) / inst->prop.fps;
644 }
645 }
646
647exit:
648 mutex_unlock(&inst->lock);
649 return load;
650}
651
652int msm_comm_get_load(struct msm_vidc_core *core,
653 enum session_type type, enum load_calc_quirks quirks)
654{
655 struct msm_vidc_inst *inst = NULL;
656 int num_mbs_per_sec = 0;
657
658 if (!core) {
659 dprintk(VIDC_ERR, "Invalid args: %pK\n", core);
660 return -EINVAL;
661 }
662
663 mutex_lock(&core->lock);
664 list_for_each_entry(inst, &core->instances, list) {
665 if (inst->session_type != type)
666 continue;
667
668 num_mbs_per_sec += msm_comm_get_inst_load(inst, quirks);
669 }
670 mutex_unlock(&core->lock);
671
672 return num_mbs_per_sec;
673}
674
675enum hal_domain get_hal_domain(int session_type)
676{
677 enum hal_domain domain;
678
679 switch (session_type) {
680 case MSM_VIDC_ENCODER:
681 domain = HAL_VIDEO_DOMAIN_ENCODER;
682 break;
683 case MSM_VIDC_DECODER:
684 domain = HAL_VIDEO_DOMAIN_DECODER;
685 break;
686 default:
687 dprintk(VIDC_ERR, "Wrong domain\n");
688 domain = HAL_UNUSED_DOMAIN;
689 break;
690 }
691
692 return domain;
693}
694
695enum hal_video_codec get_hal_codec(int fourcc)
696{
697 enum hal_video_codec codec;
698
699 switch (fourcc) {
700 case V4L2_PIX_FMT_H264:
701 case V4L2_PIX_FMT_H264_NO_SC:
702 codec = HAL_VIDEO_CODEC_H264;
703 break;
704 case V4L2_PIX_FMT_H264_MVC:
705 codec = HAL_VIDEO_CODEC_MVC;
706 break;
Vaibhav Deshu Venkatesha2cf1b32017-03-30 17:40:48 -0700707
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800708 case V4L2_PIX_FMT_MPEG1:
709 codec = HAL_VIDEO_CODEC_MPEG1;
710 break;
711 case V4L2_PIX_FMT_MPEG2:
712 codec = HAL_VIDEO_CODEC_MPEG2;
713 break;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800714 case V4L2_PIX_FMT_VP8:
715 codec = HAL_VIDEO_CODEC_VP8;
716 break;
717 case V4L2_PIX_FMT_VP9:
718 codec = HAL_VIDEO_CODEC_VP9;
719 break;
720 case V4L2_PIX_FMT_HEVC:
721 codec = HAL_VIDEO_CODEC_HEVC;
722 break;
723 default:
724 dprintk(VIDC_ERR, "Wrong codec: %d\n", fourcc);
725 codec = HAL_UNUSED_CODEC;
726 break;
727 }
728
729 return codec;
730}
731
732static enum hal_uncompressed_format get_hal_uncompressed(int fourcc)
733{
734 enum hal_uncompressed_format format = HAL_UNUSED_COLOR;
735
736 switch (fourcc) {
737 case V4L2_PIX_FMT_NV12:
738 format = HAL_COLOR_FORMAT_NV12;
739 break;
740 case V4L2_PIX_FMT_NV21:
741 format = HAL_COLOR_FORMAT_NV21;
742 break;
743 case V4L2_PIX_FMT_NV12_UBWC:
744 format = HAL_COLOR_FORMAT_NV12_UBWC;
745 break;
746 case V4L2_PIX_FMT_NV12_TP10_UBWC:
747 format = HAL_COLOR_FORMAT_NV12_TP10_UBWC;
748 break;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800749 default:
750 format = HAL_UNUSED_COLOR;
751 break;
752 }
753
754 return format;
755}
756
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800757struct msm_vidc_core *get_vidc_core(int core_id)
758{
759 struct msm_vidc_core *core;
760 int found = 0;
761
762 if (core_id > MSM_VIDC_CORES_MAX) {
763 dprintk(VIDC_ERR, "Core id = %d is greater than max = %d\n",
764 core_id, MSM_VIDC_CORES_MAX);
765 return NULL;
766 }
767 mutex_lock(&vidc_driver->lock);
768 list_for_each_entry(core, &vidc_driver->cores, list) {
769 if (core->id == core_id) {
770 found = 1;
771 break;
772 }
773 }
774 mutex_unlock(&vidc_driver->lock);
775 if (found)
776 return core;
777 return NULL;
778}
779
780const struct msm_vidc_format *msm_comm_get_pixel_fmt_index(
781 const struct msm_vidc_format fmt[], int size, int index, int fmt_type)
782{
783 int i, k = 0;
784
785 if (!fmt || index < 0) {
786 dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK, index = %d\n",
787 fmt, index);
788 return NULL;
789 }
790 for (i = 0; i < size; i++) {
791 if (fmt[i].type != fmt_type)
792 continue;
793 if (k == index)
794 break;
795 k++;
796 }
797 if (i == size) {
798 dprintk(VIDC_INFO, "Format not found\n");
799 return NULL;
800 }
801 return &fmt[i];
802}
803struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc(
804 struct msm_vidc_format fmt[], int size, int fourcc, int fmt_type)
805{
806 int i;
807
808 if (!fmt) {
809 dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK\n", fmt);
810 return NULL;
811 }
812 for (i = 0; i < size; i++) {
813 if (fmt[i].fourcc == fourcc)
814 break;
815 }
816 if (i == size) {
817 dprintk(VIDC_INFO, "Format not found\n");
818 return NULL;
819 }
820 return &fmt[i];
821}
822
823struct buf_queue *msm_comm_get_vb2q(
824 struct msm_vidc_inst *inst, enum v4l2_buf_type type)
825{
826 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
827 return &inst->bufq[CAPTURE_PORT];
828 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
829 return &inst->bufq[OUTPUT_PORT];
830 return NULL;
831}
832
833static void handle_sys_init_done(enum hal_command_response cmd, void *data)
834{
835 struct msm_vidc_cb_cmd_done *response = data;
836 struct msm_vidc_core *core;
837 struct vidc_hal_sys_init_done *sys_init_msg;
838 u32 index;
839
840 if (!IS_HAL_SYS_CMD(cmd)) {
841 dprintk(VIDC_ERR, "%s - invalid cmd\n", __func__);
842 return;
843 }
844
845 index = SYS_MSG_INDEX(cmd);
846
847 if (!response) {
848 dprintk(VIDC_ERR,
849 "Failed to get valid response for sys init\n");
850 return;
851 }
852 core = get_vidc_core(response->device_id);
853 if (!core) {
854 dprintk(VIDC_ERR, "Wrong device_id received\n");
855 return;
856 }
857 sys_init_msg = &response->data.sys_init_done;
858 if (!sys_init_msg) {
859 dprintk(VIDC_ERR, "sys_init_done message not proper\n");
860 return;
861 }
862
863 core->enc_codec_supported = sys_init_msg->enc_codec_supported;
864 core->dec_codec_supported = sys_init_msg->dec_codec_supported;
865
866 /* This should come from sys_init_done */
867 core->resources.max_inst_count =
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -0700868 sys_init_msg->max_sessions_supported ?
869 sys_init_msg->max_sessions_supported :
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800870 MAX_SUPPORTED_INSTANCES;
871
872 core->resources.max_secure_inst_count =
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -0700873 core->resources.max_secure_inst_count ?
874 core->resources.max_secure_inst_count :
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800875 core->resources.max_inst_count;
876
877 if (core->id == MSM_VIDC_CORE_VENUS &&
878 (core->dec_codec_supported & HAL_VIDEO_CODEC_H264))
879 core->dec_codec_supported |=
880 HAL_VIDEO_CODEC_MVC;
881
882 core->codec_count = sys_init_msg->codec_count;
883 memcpy(core->capabilities, sys_init_msg->capabilities,
884 sys_init_msg->codec_count * sizeof(struct msm_vidc_capability));
885
886 dprintk(VIDC_DBG,
887 "%s: supported_codecs[%d]: enc = %#x, dec = %#x\n",
888 __func__, core->codec_count, core->enc_codec_supported,
889 core->dec_codec_supported);
890
891 complete(&(core->completions[index]));
892}
893
894static void put_inst(struct msm_vidc_inst *inst)
895{
896 void put_inst_helper(struct kref *kref)
897 {
898 struct msm_vidc_inst *inst = container_of(kref,
899 struct msm_vidc_inst, kref);
900
901 msm_vidc_destroy(inst);
902 }
903
904 if (!inst)
905 return;
906
907 kref_put(&inst->kref, put_inst_helper);
908}
909
910static struct msm_vidc_inst *get_inst(struct msm_vidc_core *core,
911 void *session_id)
912{
913 struct msm_vidc_inst *inst = NULL;
914 bool matches = false;
915
916 if (!core || !session_id)
917 return NULL;
918
919 mutex_lock(&core->lock);
920 /*
921 * This is as good as !list_empty(!inst->list), but at this point
922 * we don't really know if inst was kfree'd via close syscall before
923 * hardware could respond. So manually walk thru the list of active
924 * sessions
925 */
926 list_for_each_entry(inst, &core->instances, list) {
927 if (inst == session_id) {
928 /*
929 * Even if the instance is valid, we really shouldn't
930 * be receiving or handling callbacks when we've deleted
931 * our session with HFI
932 */
933 matches = !!inst->session;
934 break;
935 }
936 }
937
938 /*
939 * kref_* is atomic_int backed, so no need for inst->lock. But we can
940 * always acquire inst->lock and release it in put_inst for a stronger
941 * locking system.
942 */
943 inst = (matches && kref_get_unless_zero(&inst->kref)) ? inst : NULL;
944 mutex_unlock(&core->lock);
945
946 return inst;
947}
948
949static void handle_session_release_buf_done(enum hal_command_response cmd,
950 void *data)
951{
952 struct msm_vidc_cb_cmd_done *response = data;
953 struct msm_vidc_inst *inst;
954 struct internal_buf *buf;
955 struct list_head *ptr, *next;
956 struct hal_buffer_info *buffer;
957 u32 buf_found = false;
958 u32 address;
959
960 if (!response) {
961 dprintk(VIDC_ERR, "Invalid release_buf_done response\n");
962 return;
963 }
964
965 inst = get_inst(get_vidc_core(response->device_id),
966 response->session_id);
967 if (!inst) {
968 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
969 return;
970 }
971
972 buffer = &response->data.buffer_info;
973 address = buffer->buffer_addr;
974
975 mutex_lock(&inst->scratchbufs.lock);
976 list_for_each_safe(ptr, next, &inst->scratchbufs.list) {
977 buf = list_entry(ptr, struct internal_buf, list);
978 if (address == (u32)buf->handle->device_addr) {
979 dprintk(VIDC_DBG, "releasing scratch: %pa\n",
980 &buf->handle->device_addr);
981 buf_found = true;
982 }
983 }
984 mutex_unlock(&inst->scratchbufs.lock);
985
986 mutex_lock(&inst->persistbufs.lock);
987 list_for_each_safe(ptr, next, &inst->persistbufs.list) {
988 buf = list_entry(ptr, struct internal_buf, list);
989 if (address == (u32)buf->handle->device_addr) {
990 dprintk(VIDC_DBG, "releasing persist: %pa\n",
991 &buf->handle->device_addr);
992 buf_found = true;
993 }
994 }
995 mutex_unlock(&inst->persistbufs.lock);
996
997 if (!buf_found)
998 dprintk(VIDC_ERR, "invalid buffer received from firmware");
999 if (IS_HAL_SESSION_CMD(cmd))
1000 complete(&inst->completions[SESSION_MSG_INDEX(cmd)]);
1001 else
1002 dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd);
1003
1004 put_inst(inst);
1005}
1006
1007static void handle_sys_release_res_done(
1008 enum hal_command_response cmd, void *data)
1009{
1010 struct msm_vidc_cb_cmd_done *response = data;
1011 struct msm_vidc_core *core;
1012
1013 if (!response) {
1014 dprintk(VIDC_ERR,
1015 "Failed to get valid response for sys init\n");
1016 return;
1017 }
1018 core = get_vidc_core(response->device_id);
1019 if (!core) {
1020 dprintk(VIDC_ERR, "Wrong device_id received\n");
1021 return;
1022 }
1023 complete(&core->completions[
1024 SYS_MSG_INDEX(HAL_SYS_RELEASE_RESOURCE_DONE)]);
1025}
1026
1027static void change_inst_state(struct msm_vidc_inst *inst,
1028 enum instance_state state)
1029{
1030 if (!inst) {
1031 dprintk(VIDC_ERR, "Invalid parameter %s\n", __func__);
1032 return;
1033 }
1034 mutex_lock(&inst->lock);
1035 if (inst->state == MSM_VIDC_CORE_INVALID) {
1036 dprintk(VIDC_DBG,
1037 "Inst: %pK is in bad state can't change state to %d\n",
1038 inst, state);
1039 goto exit;
1040 }
1041 dprintk(VIDC_DBG, "Moved inst: %pK from state: %d to state: %d\n",
1042 inst, inst->state, state);
1043 inst->state = state;
1044exit:
1045 mutex_unlock(&inst->lock);
1046}
1047
1048static int signal_session_msg_receipt(enum hal_command_response cmd,
1049 struct msm_vidc_inst *inst)
1050{
1051 if (!inst) {
1052 dprintk(VIDC_ERR, "Invalid(%pK) instance id\n", inst);
1053 return -EINVAL;
1054 }
1055 if (IS_HAL_SESSION_CMD(cmd)) {
1056 complete(&inst->completions[SESSION_MSG_INDEX(cmd)]);
1057 } else {
1058 dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd);
1059 return -EINVAL;
1060 }
1061 return 0;
1062}
1063
1064static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst,
1065 enum hal_command_response cmd)
1066{
1067 int rc = 0;
1068 struct hfi_device *hdev;
1069
1070 if (!IS_HAL_SESSION_CMD(cmd)) {
1071 dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd);
1072 return -EINVAL;
1073 }
1074 hdev = (struct hfi_device *)(inst->core->device);
1075 rc = wait_for_completion_timeout(
1076 &inst->completions[SESSION_MSG_INDEX(cmd)],
1077 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
1078 if (!rc) {
1079 dprintk(VIDC_ERR, "Wait interrupted or timed out: %d\n",
1080 SESSION_MSG_INDEX(cmd));
1081 msm_comm_kill_session(inst);
1082 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
1083 dprintk(VIDC_ERR,
1084 "sess resp timeout can potentially crash the system\n");
1085 msm_comm_print_debug_info(inst);
1086 msm_vidc_handle_hw_error(inst->core);
1087 rc = -EIO;
1088 } else {
1089 rc = 0;
1090 }
1091 return rc;
1092}
1093
1094static int wait_for_state(struct msm_vidc_inst *inst,
1095 enum instance_state flipped_state,
1096 enum instance_state desired_state,
1097 enum hal_command_response hal_cmd)
1098{
1099 int rc = 0;
1100
1101 if (IS_ALREADY_IN_STATE(flipped_state, desired_state)) {
1102 dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n",
1103 inst, inst->state);
1104 goto err_same_state;
1105 }
1106 dprintk(VIDC_DBG, "Waiting for hal_cmd: %d\n", hal_cmd);
1107 rc = wait_for_sess_signal_receipt(inst, hal_cmd);
1108 if (!rc)
1109 change_inst_state(inst, desired_state);
1110err_same_state:
1111 return rc;
1112}
1113
1114void msm_vidc_queue_v4l2_event(struct msm_vidc_inst *inst, int event_type)
1115{
1116 struct v4l2_event event = {.id = 0, .type = event_type};
1117
1118 v4l2_event_queue_fh(&inst->event_handler, &event);
1119}
1120
1121static void msm_comm_generate_max_clients_error(struct msm_vidc_inst *inst)
1122{
1123 enum hal_command_response cmd = HAL_SESSION_ERROR;
1124 struct msm_vidc_cb_cmd_done response = {0};
1125
1126 if (!inst) {
1127 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
1128 return;
1129 }
1130 dprintk(VIDC_ERR, "%s: Too many clients\n", __func__);
1131 response.session_id = inst;
1132 response.status = VIDC_ERR_MAX_CLIENTS;
1133 handle_session_error(cmd, (void *)&response);
1134}
1135
1136static void print_cap(const char *type,
1137 struct hal_capability_supported *cap)
1138{
1139 dprintk(VIDC_DBG,
1140 "%-24s: %-8d %-8d %-8d\n",
1141 type, cap->min, cap->max, cap->step_size);
1142}
1143
Praneeth Paladugue1679112017-01-27 10:07:15 -08001144static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst,
1145 u32 id, struct hal_capability_supported *capability)
1146{
1147 struct v4l2_ctrl *ctrl = NULL;
1148 int rc = 0;
1149
1150 ctrl = v4l2_ctrl_find(&inst->ctrl_handler, id);
1151 if (ctrl) {
1152 v4l2_ctrl_modify_range(ctrl, capability->min,
1153 capability->max, ctrl->step,
1154 capability->min);
1155 dprintk(VIDC_DBG,
1156 "%s: Updated Range = %lld --> %lld Def value = %lld\n",
1157 ctrl->name, ctrl->minimum, ctrl->maximum,
1158 ctrl->default_value);
1159 } else {
1160 dprintk(VIDC_ERR,
1161 "Failed to find Conrol %d\n", id);
1162 rc = -EINVAL;
1163 }
1164
1165 return rc;
1166 }
1167
1168static void msm_vidc_comm_update_ctrl_limits(struct msm_vidc_inst *inst)
1169{
1170 msm_vidc_comm_update_ctrl(inst,
1171 V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE,
1172 &inst->capability.hier_p_hybrid);
1173 msm_vidc_comm_update_ctrl(inst,
1174 V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS,
1175 &inst->capability.hier_b);
1176 msm_vidc_comm_update_ctrl(inst,
1177 V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS,
1178 &inst->capability.hier_p);
1179 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE,
1180 &inst->capability.bitrate);
Vaibhav Deshu Venkatesh2c072532017-04-07 17:50:18 -07001181 msm_vidc_comm_update_ctrl(inst,
1182 V4L2_CID_MPEG_VIDC_VENC_PARAM_LAYER_BITRATE,
1183 &inst->capability.bitrate);
Praneeth Paladugue1679112017-01-27 10:07:15 -08001184 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
1185 &inst->capability.peakbitrate);
Praneeth Paladugu7fbd2792017-01-27 13:39:03 -08001186 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP,
1187 &inst->capability.i_qp);
1188 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP,
1189 &inst->capability.p_qp);
1190 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP,
1191 &inst->capability.b_qp);
1192 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP_MIN,
1193 &inst->capability.i_qp);
1194 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP_MIN,
1195 &inst->capability.p_qp);
1196 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP_MIN,
1197 &inst->capability.b_qp);
1198 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP_MAX,
1199 &inst->capability.i_qp);
1200 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP_MAX,
1201 &inst->capability.p_qp);
1202 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP_MAX,
1203 &inst->capability.b_qp);
Praneeth Paladugue1679112017-01-27 10:07:15 -08001204 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_BLUR_WIDTH,
1205 &inst->capability.blur_width);
1206 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_BLUR_HEIGHT,
1207 &inst->capability.blur_height);
1208 msm_vidc_comm_update_ctrl(inst,
1209 V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
1210 &inst->capability.slice_bytes);
1211 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
1212 &inst->capability.slice_mbs);
1213 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT,
1214 &inst->capability.ltr_count);
1215 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES,
1216 &inst->capability.bframe);
1217}
1218
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001219static void handle_session_init_done(enum hal_command_response cmd, void *data)
1220{
1221 struct msm_vidc_cb_cmd_done *response = data;
1222 struct msm_vidc_inst *inst = NULL;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001223 struct msm_vidc_capability *capability = NULL;
1224 struct hfi_device *hdev;
1225 struct msm_vidc_core *core;
1226 u32 i, codec;
1227
1228 if (!response) {
1229 dprintk(VIDC_ERR,
1230 "Failed to get valid response for session init\n");
1231 return;
1232 }
1233
1234 inst = get_inst(get_vidc_core(response->device_id),
1235 response->session_id);
1236
1237 if (!inst) {
1238 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1239 return;
1240 }
1241
1242 if (response->status) {
1243 dprintk(VIDC_ERR,
1244 "Session init response from FW : %#x\n",
1245 response->status);
1246 if (response->status == VIDC_ERR_MAX_CLIENTS)
1247 msm_comm_generate_max_clients_error(inst);
1248 else
1249 msm_comm_generate_session_error(inst);
1250
1251 signal_session_msg_receipt(cmd, inst);
1252 put_inst(inst);
1253 return;
1254 }
1255
1256 core = inst->core;
1257 hdev = inst->core->device;
1258 codec = inst->session_type == MSM_VIDC_DECODER ?
1259 inst->fmts[OUTPUT_PORT].fourcc :
1260 inst->fmts[CAPTURE_PORT].fourcc;
1261
1262 /* check if capabilities are available for this session */
1263 for (i = 0; i < VIDC_MAX_SESSIONS; i++) {
1264 if (core->capabilities[i].codec ==
1265 get_hal_codec(codec) &&
1266 core->capabilities[i].domain ==
1267 get_hal_domain(inst->session_type)) {
1268 capability = &core->capabilities[i];
1269 break;
1270 }
1271 }
1272
1273 if (capability) {
1274 dprintk(VIDC_DBG,
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001275 "%s: capabilities for codec 0x%x, domain %#x\n",
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001276 __func__, capability->codec, capability->domain);
1277 memcpy(&inst->capability, capability,
1278 sizeof(struct msm_vidc_capability));
1279 } else {
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001280 dprintk(VIDC_ERR,
1281 "Watch out : Some property may fail inst %pK\n", inst);
1282 dprintk(VIDC_ERR,
1283 "Caps N/A for codec 0x%x, domain %#x\n",
1284 inst->capability.codec, inst->capability.domain);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001285 }
1286 inst->capability.pixelprocess_capabilities =
1287 call_hfi_op(hdev, get_core_capabilities, hdev->hfi_device_data);
1288
1289 dprintk(VIDC_DBG,
1290 "Capability type : min max step size\n");
1291 print_cap("width", &inst->capability.width);
1292 print_cap("height", &inst->capability.height);
1293 print_cap("mbs_per_frame", &inst->capability.mbs_per_frame);
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001294 print_cap("mbs_per_sec", &inst->capability.mbs_per_sec);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001295 print_cap("frame_rate", &inst->capability.frame_rate);
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001296 print_cap("bitrate", &inst->capability.bitrate);
1297 print_cap("peak_bitrate", &inst->capability.peakbitrate);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001298 print_cap("scale_x", &inst->capability.scale_x);
1299 print_cap("scale_y", &inst->capability.scale_y);
1300 print_cap("hier_p", &inst->capability.hier_p);
1301 print_cap("ltr_count", &inst->capability.ltr_count);
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001302 print_cap("bframe", &inst->capability.bframe);
1303 print_cap("secure_output2_threshold",
1304 &inst->capability.secure_output2_threshold);
1305 print_cap("hier_b", &inst->capability.hier_b);
1306 print_cap("lcu_size", &inst->capability.lcu_size);
1307 print_cap("hier_p_hybrid", &inst->capability.hier_p_hybrid);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001308 print_cap("mbs_per_sec_low_power",
1309 &inst->capability.mbs_per_sec_power_save);
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001310 print_cap("extradata", &inst->capability.extradata);
1311 print_cap("profile", &inst->capability.profile);
1312 print_cap("level", &inst->capability.level);
1313 print_cap("i_qp", &inst->capability.i_qp);
1314 print_cap("p_qp", &inst->capability.p_qp);
1315 print_cap("b_qp", &inst->capability.b_qp);
1316 print_cap("rc_modes", &inst->capability.rc_modes);
1317 print_cap("blur_width", &inst->capability.blur_width);
1318 print_cap("blur_height", &inst->capability.blur_height);
1319 print_cap("slice_delivery_mode", &inst->capability.slice_delivery_mode);
1320 print_cap("slice_bytes", &inst->capability.slice_bytes);
1321 print_cap("slice_mbs", &inst->capability.slice_mbs);
1322 print_cap("secure", &inst->capability.secure);
1323 print_cap("max_num_b_frames", &inst->capability.max_num_b_frames);
1324 print_cap("max_video_cores", &inst->capability.max_video_cores);
1325 print_cap("max_work_modes", &inst->capability.max_work_modes);
1326 print_cap("ubwc_cr_stats", &inst->capability.ubwc_cr_stats);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001327
1328 signal_session_msg_receipt(cmd, inst);
Praneeth Paladugue1679112017-01-27 10:07:15 -08001329
1330 /*
1331 * Update controls after informing session_init_done to avoid
1332 * timeouts.
1333 */
1334
1335 msm_vidc_comm_update_ctrl_limits(inst);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001336 put_inst(inst);
1337}
1338
1339static void handle_event_change(enum hal_command_response cmd, void *data)
1340{
1341 struct msm_vidc_inst *inst = NULL;
1342 struct msm_vidc_cb_event *event_notify = data;
1343 int event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1344 struct v4l2_event seq_changed_event = {0};
1345 int rc = 0;
1346 struct hfi_device *hdev;
1347 u32 *ptr = NULL;
1348
1349 if (!event_notify) {
1350 dprintk(VIDC_WARN, "Got an empty event from hfi\n");
1351 return;
1352 }
1353
1354 inst = get_inst(get_vidc_core(event_notify->device_id),
1355 event_notify->session_id);
1356 if (!inst || !inst->core || !inst->core->device) {
1357 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1358 goto err_bad_event;
1359 }
1360 hdev = inst->core->device;
1361
1362 switch (event_notify->hal_event_type) {
1363 case HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES:
Umesh Pandeya4c63632017-03-20 14:44:08 -07001364 event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001365 break;
1366 case HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES:
1367 event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1368 break;
1369 case HAL_EVENT_RELEASE_BUFFER_REFERENCE:
1370 {
1371 struct v4l2_event buf_event = {0};
1372 struct buffer_info *binfo = NULL, *temp = NULL;
1373 u32 *ptr = NULL;
1374
1375 dprintk(VIDC_DBG, "%s - inst: %pK buffer: %pa extra: %pa\n",
1376 __func__, inst, &event_notify->packet_buffer,
1377 &event_notify->extra_data_buffer);
1378
1379 if (inst->state == MSM_VIDC_CORE_INVALID ||
1380 inst->core->state == VIDC_CORE_INVALID) {
1381 dprintk(VIDC_DBG,
1382 "Event release buf ref received in invalid state - discard\n");
1383 goto err_bad_event;
1384 }
1385
1386 /*
1387 * Get the buffer_info entry for the
1388 * device address.
1389 */
1390 binfo = device_to_uvaddr(&inst->registeredbufs,
1391 event_notify->packet_buffer);
1392 if (!binfo) {
1393 dprintk(VIDC_ERR,
1394 "%s buffer not found in registered list\n",
1395 __func__);
1396 goto err_bad_event;
1397 }
1398
1399 /* Fill event data to be sent to client*/
1400 buf_event.type = V4L2_EVENT_RELEASE_BUFFER_REFERENCE;
1401 ptr = (u32 *)buf_event.u.data;
1402 ptr[0] = binfo->fd[0];
1403 ptr[1] = binfo->buff_off[0];
1404
1405 dprintk(VIDC_DBG,
1406 "RELEASE REFERENCE EVENT FROM F/W - fd = %d offset = %d\n",
1407 ptr[0], ptr[1]);
1408
1409 /* Decrement buffer reference count*/
1410 mutex_lock(&inst->registeredbufs.lock);
1411 list_for_each_entry(temp, &inst->registeredbufs.list,
1412 list) {
1413 if (temp == binfo) {
1414 buf_ref_put(inst, binfo);
1415 break;
1416 }
1417 }
1418
1419 /*
1420 * Release buffer and remove from list
1421 * if reference goes to zero.
1422 */
1423 if (unmap_and_deregister_buf(inst, binfo))
1424 dprintk(VIDC_ERR,
1425 "%s: buffer unmap failed\n", __func__);
1426 mutex_unlock(&inst->registeredbufs.lock);
1427
1428 /*send event to client*/
1429 v4l2_event_queue_fh(&inst->event_handler, &buf_event);
1430 goto err_bad_event;
1431 }
1432 default:
1433 break;
1434 }
1435
1436 /* Bit depth and pic struct changed event are combined into a single
1437 * event (insufficient event) for the userspace. Currently bitdepth
1438 * changes is only for HEVC and interlaced support is for all
1439 * codecs except HEVC
1440 * event data is now as follows:
1441 * u32 *ptr = seq_changed_event.u.data;
1442 * ptr[0] = height
1443 * ptr[1] = width
1444 * ptr[2] = flag to indicate bit depth or/and pic struct changed
1445 * ptr[3] = bit depth
1446 * ptr[4] = pic struct (progressive or interlaced)
1447 * ptr[5] = colour space
1448 */
1449
Chinmay Sawarkarb3c6ccb2017-02-23 18:01:32 -08001450 inst->entropy_mode = msm_comm_hal_to_v4l2(
1451 V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
1452 event_notify->entropy_mode);
1453 inst->profile = msm_comm_hal_to_v4l2(
1454 V4L2_CID_MPEG_VIDEO_H264_PROFILE,
1455 event_notify->profile);
1456 inst->level = msm_comm_hal_to_v4l2(
1457 V4L2_CID_MPEG_VIDEO_H264_LEVEL,
1458 event_notify->level);
1459
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001460 ptr = (u32 *)seq_changed_event.u.data;
1461
1462 if (ptr != NULL) {
1463 ptr[2] = 0x0;
1464 ptr[3] = inst->bit_depth;
1465 ptr[4] = inst->pic_struct;
1466 ptr[5] = inst->colour_space;
1467
1468 if (inst->bit_depth != event_notify->bit_depth) {
1469 inst->bit_depth = event_notify->bit_depth;
1470 ptr[2] |= V4L2_EVENT_BITDEPTH_FLAG;
1471 ptr[3] = inst->bit_depth;
1472 event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1473 dprintk(VIDC_DBG,
1474 "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT due to bit-depth change\n");
1475 }
1476
1477 if (inst->pic_struct != event_notify->pic_struct) {
1478 inst->pic_struct = event_notify->pic_struct;
1479 event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1480 ptr[2] |= V4L2_EVENT_PICSTRUCT_FLAG;
1481 ptr[4] = inst->pic_struct;
1482 dprintk(VIDC_DBG,
1483 "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT due to pic-struct change\n");
1484 }
1485
1486 if (inst->bit_depth == MSM_VIDC_BIT_DEPTH_10
1487 && inst->colour_space !=
1488 event_notify->colour_space) {
1489 inst->colour_space = event_notify->colour_space;
1490 event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1491 ptr[2] |= V4L2_EVENT_COLOUR_SPACE_FLAG;
1492 ptr[5] = inst->colour_space;
1493 dprintk(VIDC_DBG,
1494 "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT due to colour space change\n");
1495 }
1496
1497 }
1498
1499 if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) {
1500 dprintk(VIDC_DBG, "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n");
1501 inst->reconfig_height = event_notify->height;
1502 inst->reconfig_width = event_notify->width;
1503 inst->in_reconfig = true;
1504 } else {
1505 dprintk(VIDC_DBG, "V4L2_EVENT_SEQ_CHANGED_SUFFICIENT\n");
1506 dprintk(VIDC_DBG,
1507 "event_notify->height = %d event_notify->width = %d\n",
1508 event_notify->height,
1509 event_notify->width);
1510 inst->prop.height[OUTPUT_PORT] = event_notify->height;
1511 inst->prop.width[OUTPUT_PORT] = event_notify->width;
1512 }
1513
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001514 rc = msm_vidc_check_session_supported(inst);
1515 if (!rc) {
1516 seq_changed_event.type = event;
1517 if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) {
1518 u32 *ptr = NULL;
1519
1520 ptr = (u32 *)seq_changed_event.u.data;
1521 ptr[0] = event_notify->height;
1522 ptr[1] = event_notify->width;
1523 }
1524 v4l2_event_queue_fh(&inst->event_handler, &seq_changed_event);
1525 } else if (rc == -ENOTSUPP) {
1526 msm_vidc_queue_v4l2_event(inst,
1527 V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED);
1528 } else if (rc == -EBUSY) {
1529 msm_vidc_queue_v4l2_event(inst,
1530 V4L2_EVENT_MSM_VIDC_HW_OVERLOAD);
1531 }
1532
1533err_bad_event:
1534 put_inst(inst);
1535}
1536
1537static void handle_session_prop_info(enum hal_command_response cmd, void *data)
1538{
1539 struct msm_vidc_cb_cmd_done *response = data;
1540 struct getprop_buf *getprop;
1541 struct msm_vidc_inst *inst;
1542
1543 if (!response) {
1544 dprintk(VIDC_ERR,
1545 "Failed to get valid response for prop info\n");
1546 return;
1547 }
1548
1549 inst = get_inst(get_vidc_core(response->device_id),
1550 response->session_id);
1551 if (!inst) {
1552 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1553 return;
1554 }
1555
1556 getprop = kzalloc(sizeof(*getprop), GFP_KERNEL);
1557 if (!getprop) {
1558 dprintk(VIDC_ERR, "%s: getprop kzalloc failed\n", __func__);
1559 goto err_prop_info;
1560 }
1561
1562 getprop->data = kmemdup(&response->data.property,
1563 sizeof(union hal_get_property), GFP_KERNEL);
1564 if (!getprop->data) {
1565 dprintk(VIDC_ERR, "%s: kmemdup failed\n", __func__);
1566 kfree(getprop);
1567 goto err_prop_info;
1568 }
1569
1570 mutex_lock(&inst->pending_getpropq.lock);
1571 list_add_tail(&getprop->list, &inst->pending_getpropq.list);
1572 mutex_unlock(&inst->pending_getpropq.lock);
1573
1574 signal_session_msg_receipt(cmd, inst);
1575err_prop_info:
1576 put_inst(inst);
1577}
1578
1579static void handle_load_resource_done(enum hal_command_response cmd, void *data)
1580{
1581 struct msm_vidc_cb_cmd_done *response = data;
1582 struct msm_vidc_inst *inst;
1583
1584 if (!response) {
1585 dprintk(VIDC_ERR,
1586 "Failed to get valid response for load resource\n");
1587 return;
1588 }
1589
1590 inst = get_inst(get_vidc_core(response->device_id),
1591 response->session_id);
1592 if (!inst) {
1593 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1594 return;
1595 }
1596
1597 if (response->status) {
1598 dprintk(VIDC_ERR,
1599 "Load resource response from FW : %#x\n",
1600 response->status);
1601 msm_comm_generate_session_error(inst);
1602 }
1603
1604 put_inst(inst);
1605}
1606
1607static void handle_start_done(enum hal_command_response cmd, void *data)
1608{
1609 struct msm_vidc_cb_cmd_done *response = data;
1610 struct msm_vidc_inst *inst;
1611
1612 if (!response) {
1613 dprintk(VIDC_ERR, "Failed to get valid response for start\n");
1614 return;
1615 }
1616
1617 inst = get_inst(get_vidc_core(response->device_id),
1618 response->session_id);
1619 if (!inst) {
1620 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1621 return;
1622 }
1623
1624 signal_session_msg_receipt(cmd, inst);
1625 put_inst(inst);
1626}
1627
1628static void handle_stop_done(enum hal_command_response cmd, void *data)
1629{
1630 struct msm_vidc_cb_cmd_done *response = data;
1631 struct msm_vidc_inst *inst;
1632
1633 if (!response) {
1634 dprintk(VIDC_ERR, "Failed to get valid response for stop\n");
1635 return;
1636 }
1637
1638 inst = get_inst(get_vidc_core(response->device_id),
1639 response->session_id);
1640 if (!inst) {
1641 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1642 return;
1643 }
1644
1645 signal_session_msg_receipt(cmd, inst);
1646 put_inst(inst);
1647}
1648
1649static void handle_release_res_done(enum hal_command_response cmd, void *data)
1650{
1651 struct msm_vidc_cb_cmd_done *response = data;
1652 struct msm_vidc_inst *inst;
1653
1654 if (!response) {
1655 dprintk(VIDC_ERR,
1656 "Failed to get valid response for release resource\n");
1657 return;
1658 }
1659
1660 inst = get_inst(get_vidc_core(response->device_id),
1661 response->session_id);
1662 if (!inst) {
1663 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1664 return;
1665 }
1666
1667 signal_session_msg_receipt(cmd, inst);
1668 put_inst(inst);
1669}
1670
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001671void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001672{
1673 struct internal_buf *binfo;
1674 u32 buffers_owned_by_driver = 0;
1675 struct hal_buffer_requirements *output_buf;
1676
1677 output_buf = get_buff_req_buffer(inst, HAL_BUFFER_OUTPUT);
1678
1679 if (!output_buf) {
1680 dprintk(VIDC_DBG,
1681 "This output buffer not required, buffer_type: %x\n",
1682 HAL_BUFFER_OUTPUT);
1683 return;
1684 }
1685 mutex_lock(&inst->outputbufs.lock);
1686 list_for_each_entry(binfo, &inst->outputbufs.list, list) {
1687 if (binfo->buffer_ownership != DRIVER) {
1688 dprintk(VIDC_DBG,
1689 "This buffer is with FW %pa\n",
1690 &binfo->handle->device_addr);
1691 continue;
1692 }
1693 buffers_owned_by_driver++;
1694 }
1695 mutex_unlock(&inst->outputbufs.lock);
1696
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001697 if (buffers_owned_by_driver != output_buf->buffer_count_actual) {
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001698 dprintk(VIDC_WARN,
1699 "OUTPUT Buffer count mismatch %d of %d\n",
1700 buffers_owned_by_driver,
1701 output_buf->buffer_count_actual);
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001702 msm_vidc_handle_hw_error(inst->core);
1703 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001704}
1705
1706int msm_comm_queue_output_buffers(struct msm_vidc_inst *inst)
1707{
1708 struct internal_buf *binfo;
1709 struct hfi_device *hdev;
1710 struct msm_smem *handle;
1711 struct vidc_frame_data frame_data = {0};
1712 struct hal_buffer_requirements *output_buf, *extra_buf;
1713 int rc = 0;
1714
1715 if (!inst || !inst->core || !inst->core->device) {
1716 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
1717 return -EINVAL;
1718 }
1719
1720 hdev = inst->core->device;
1721
1722 output_buf = get_buff_req_buffer(inst, HAL_BUFFER_OUTPUT);
1723 if (!output_buf) {
1724 dprintk(VIDC_DBG,
1725 "This output buffer not required, buffer_type: %x\n",
1726 HAL_BUFFER_OUTPUT);
1727 return 0;
1728 }
1729 dprintk(VIDC_DBG,
1730 "output: num = %d, size = %d\n",
1731 output_buf->buffer_count_actual,
1732 output_buf->buffer_size);
1733
1734 extra_buf = get_buff_req_buffer(inst, HAL_BUFFER_EXTRADATA_OUTPUT);
1735
1736 mutex_lock(&inst->outputbufs.lock);
1737 list_for_each_entry(binfo, &inst->outputbufs.list, list) {
1738 if (binfo->buffer_ownership != DRIVER)
1739 continue;
1740 handle = binfo->handle;
1741 frame_data.alloc_len = output_buf->buffer_size;
1742 frame_data.filled_len = 0;
1743 frame_data.offset = 0;
1744 frame_data.device_addr = handle->device_addr;
1745 frame_data.flags = 0;
1746 frame_data.extradata_addr = handle->device_addr +
1747 output_buf->buffer_size;
1748 frame_data.buffer_type = HAL_BUFFER_OUTPUT;
1749 frame_data.extradata_size = extra_buf ?
1750 extra_buf->buffer_size : 0;
1751 rc = call_hfi_op(hdev, session_ftb,
1752 (void *) inst->session, &frame_data);
1753 binfo->buffer_ownership = FIRMWARE;
1754 }
1755 mutex_unlock(&inst->outputbufs.lock);
1756
1757 return 0;
1758}
1759
1760static void handle_session_flush(enum hal_command_response cmd, void *data)
1761{
1762 struct msm_vidc_cb_cmd_done *response = data;
1763 struct msm_vidc_inst *inst;
1764 struct v4l2_event flush_event = {0};
1765 u32 *ptr = NULL;
1766 enum hal_flush flush_type;
1767 int rc;
1768
1769 if (!response) {
1770 dprintk(VIDC_ERR, "Failed to get valid response for flush\n");
1771 return;
1772 }
1773
1774 inst = get_inst(get_vidc_core(response->device_id),
1775 response->session_id);
1776 if (!inst) {
1777 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1778 return;
1779 }
1780
1781 if (msm_comm_get_stream_output_mode(inst) ==
1782 HAL_VIDEO_DECODER_SECONDARY) {
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001783
1784 if (!(inst->fmts[OUTPUT_PORT].defer_outputs &&
1785 inst->in_reconfig))
1786 msm_comm_validate_output_buffers(inst);
1787
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001788 if (!inst->in_reconfig) {
1789 rc = msm_comm_queue_output_buffers(inst);
1790 if (rc) {
1791 dprintk(VIDC_ERR,
1792 "Failed to queue output buffers: %d\n",
1793 rc);
1794 }
1795 }
1796 }
1797 atomic_dec(&inst->in_flush);
1798 flush_event.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
1799 ptr = (u32 *)flush_event.u.data;
1800
1801 flush_type = response->data.flush_type;
1802 switch (flush_type) {
1803 case HAL_FLUSH_INPUT:
1804 ptr[0] = V4L2_QCOM_CMD_FLUSH_OUTPUT;
1805 break;
1806 case HAL_FLUSH_OUTPUT:
1807 ptr[0] = V4L2_QCOM_CMD_FLUSH_CAPTURE;
1808 break;
1809 case HAL_FLUSH_ALL:
1810 ptr[0] |= V4L2_QCOM_CMD_FLUSH_CAPTURE;
1811 ptr[0] |= V4L2_QCOM_CMD_FLUSH_OUTPUT;
1812 break;
1813 default:
1814 dprintk(VIDC_ERR, "Invalid flush type received!");
1815 goto exit;
1816 }
1817
1818 dprintk(VIDC_DBG,
1819 "Notify flush complete, flush_type: %x\n", flush_type);
1820 v4l2_event_queue_fh(&inst->event_handler, &flush_event);
1821
1822exit:
1823 put_inst(inst);
1824}
1825
1826static void handle_session_error(enum hal_command_response cmd, void *data)
1827{
1828 struct msm_vidc_cb_cmd_done *response = data;
1829 struct hfi_device *hdev = NULL;
1830 struct msm_vidc_inst *inst = NULL;
1831 int event = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
1832
1833 if (!response) {
1834 dprintk(VIDC_ERR,
1835 "Failed to get valid response for session error\n");
1836 return;
1837 }
1838
1839 inst = get_inst(get_vidc_core(response->device_id),
1840 response->session_id);
1841 if (!inst) {
1842 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1843 return;
1844 }
1845
1846 hdev = inst->core->device;
1847 dprintk(VIDC_WARN, "Session error received for session %pK\n", inst);
1848 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
1849
1850 if (response->status == VIDC_ERR_MAX_CLIENTS) {
1851 dprintk(VIDC_WARN, "Too many clients, rejecting %pK", inst);
1852 event = V4L2_EVENT_MSM_VIDC_MAX_CLIENTS;
1853
1854 /*
1855 * Clean the HFI session now. Since inst->state is moved to
1856 * INVALID, forward thread doesn't know FW has valid session
1857 * or not. This is the last place driver knows that there is
1858 * no session in FW. Hence clean HFI session now.
1859 */
1860
1861 msm_comm_session_clean(inst);
1862 } else if (response->status == VIDC_ERR_NOT_SUPPORTED) {
1863 dprintk(VIDC_WARN, "Unsupported bitstream in %pK", inst);
1864 event = V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED;
1865 } else {
1866 dprintk(VIDC_WARN, "Unknown session error (%d) for %pK\n",
1867 response->status, inst);
1868 event = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
1869 }
1870
1871 msm_vidc_queue_v4l2_event(inst, event);
1872 put_inst(inst);
1873}
1874
1875static void msm_comm_clean_notify_client(struct msm_vidc_core *core)
1876{
1877 struct msm_vidc_inst *inst = NULL;
1878
1879 if (!core) {
1880 dprintk(VIDC_ERR, "%s: Invalid params\n", __func__);
1881 return;
1882 }
1883
1884 dprintk(VIDC_WARN, "%s: Core %pK\n", __func__, core);
1885 mutex_lock(&core->lock);
1886 core->state = VIDC_CORE_INVALID;
1887
1888 list_for_each_entry(inst, &core->instances, list) {
1889 mutex_lock(&inst->lock);
1890 inst->state = MSM_VIDC_CORE_INVALID;
1891 mutex_unlock(&inst->lock);
1892 dprintk(VIDC_WARN,
1893 "%s Send sys error for inst %pK\n", __func__, inst);
1894 msm_vidc_queue_v4l2_event(inst,
1895 V4L2_EVENT_MSM_VIDC_SYS_ERROR);
1896 }
1897 mutex_unlock(&core->lock);
1898}
1899
1900static void handle_sys_error(enum hal_command_response cmd, void *data)
1901{
1902 struct msm_vidc_cb_cmd_done *response = data;
1903 struct msm_vidc_core *core = NULL;
1904 struct hfi_device *hdev = NULL;
1905 struct msm_vidc_inst *inst = NULL;
1906 int rc = 0;
1907
1908 subsystem_crashed("venus");
1909 if (!response) {
1910 dprintk(VIDC_ERR,
1911 "Failed to get valid response for sys error\n");
1912 return;
1913 }
1914
1915 core = get_vidc_core(response->device_id);
1916 if (!core) {
1917 dprintk(VIDC_ERR,
1918 "Got SYS_ERR but unable to identify core\n");
1919 return;
1920 }
1921
1922 mutex_lock(&core->lock);
1923 if (core->state == VIDC_CORE_INVALID ||
1924 core->state == VIDC_CORE_UNINIT) {
1925 dprintk(VIDC_ERR,
1926 "%s: Core already moved to state %d\n",
1927 __func__, core->state);
1928 mutex_unlock(&core->lock);
1929 return;
1930 }
1931 mutex_unlock(&core->lock);
1932
1933 dprintk(VIDC_WARN, "SYS_ERROR %d received for core %pK\n", cmd, core);
1934 msm_comm_clean_notify_client(core);
1935
1936 hdev = core->device;
1937 mutex_lock(&core->lock);
1938 if (core->state == VIDC_CORE_INVALID) {
1939 dprintk(VIDC_DBG, "Calling core_release\n");
1940 rc = call_hfi_op(hdev, core_release,
1941 hdev->hfi_device_data);
1942 if (rc) {
1943 dprintk(VIDC_ERR, "core_release failed\n");
1944 mutex_unlock(&core->lock);
1945 return;
1946 }
1947 core->state = VIDC_CORE_UNINIT;
1948 }
1949 mutex_unlock(&core->lock);
1950
1951 msm_vidc_print_running_insts(core);
1952 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
1953 dprintk(VIDC_ERR,
1954 "SYS_ERROR can potentially crash the system\n");
1955
1956 /*
1957 * For SYS_ERROR, there will not be any inst pointer.
1958 * Just grab one of the inst from instances list and
1959 * use it.
1960 */
1961
1962 mutex_lock(&core->lock);
1963 inst = list_first_entry_or_null(&core->instances,
1964 struct msm_vidc_inst, list);
1965 mutex_unlock(&core->lock);
1966
1967 msm_comm_print_debug_info(inst);
1968
1969 msm_vidc_handle_hw_error(core);
1970}
1971
1972void msm_comm_session_clean(struct msm_vidc_inst *inst)
1973{
1974 int rc = 0;
1975 struct hfi_device *hdev = NULL;
1976
1977 if (!inst || !inst->core || !inst->core->device) {
1978 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
1979 return;
1980 }
1981
1982 hdev = inst->core->device;
1983 mutex_lock(&inst->lock);
1984 if (hdev && inst->session) {
1985 dprintk(VIDC_DBG, "cleaning up instance: %pK\n", inst);
1986 rc = call_hfi_op(hdev, session_clean,
1987 (void *)inst->session);
1988 if (rc) {
1989 dprintk(VIDC_ERR,
1990 "Session clean failed :%pK\n", inst);
1991 }
1992 inst->session = NULL;
1993 }
1994 mutex_unlock(&inst->lock);
1995}
1996
1997static void handle_session_close(enum hal_command_response cmd, void *data)
1998{
1999 struct msm_vidc_cb_cmd_done *response = data;
2000 struct msm_vidc_inst *inst;
2001
2002 if (!response) {
2003 dprintk(VIDC_ERR,
2004 "Failed to get valid response for session close\n");
2005 return;
2006 }
2007
2008 inst = get_inst(get_vidc_core(response->device_id),
2009 response->session_id);
2010 if (!inst) {
2011 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
2012 return;
2013 }
2014
2015 signal_session_msg_receipt(cmd, inst);
2016 show_stats(inst);
2017 put_inst(inst);
2018}
2019
2020static struct vb2_buffer *get_vb_from_device_addr(struct buf_queue *bufq,
2021 unsigned long dev_addr)
2022{
2023 struct vb2_buffer *vb = NULL;
2024 struct vb2_queue *q = NULL;
2025 int found = 0;
2026
2027 if (!bufq) {
2028 dprintk(VIDC_ERR, "Invalid parameter\n");
2029 return NULL;
2030 }
2031 q = &bufq->vb2_bufq;
2032 mutex_lock(&bufq->lock);
2033 list_for_each_entry(vb, &q->queued_list, queued_entry) {
2034 if (vb->planes[0].m.userptr == dev_addr &&
2035 vb->state == VB2_BUF_STATE_ACTIVE) {
2036 found = 1;
2037 dprintk(VIDC_DBG, "Found v4l2_buf index : %d\n",
2038 vb->index);
2039 break;
2040 }
2041 }
2042 mutex_unlock(&bufq->lock);
2043 if (!found) {
2044 dprintk(VIDC_DBG,
2045 "Failed to find buffer in queued list: %#lx, qtype = %d\n",
2046 dev_addr, q->type);
2047 vb = NULL;
2048 }
2049 return vb;
2050}
2051
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08002052static void handle_dynamic_buffer(struct msm_vidc_inst *inst,
2053 ion_phys_addr_t device_addr, u32 flags)
2054{
2055 struct buffer_info *binfo = NULL, *temp = NULL;
2056
2057 /*
2058 * Update reference count and release OR queue back the buffer,
2059 * only when firmware is not holding a reference.
2060 */
2061 binfo = device_to_uvaddr(&inst->registeredbufs, device_addr);
2062 if (!binfo) {
2063 dprintk(VIDC_ERR,
2064 "%s buffer not found in registered list\n",
2065 __func__);
2066 return;
2067 }
2068 if (flags & HAL_BUFFERFLAG_READONLY) {
2069 dprintk(VIDC_DBG,
2070 "FBD fd[0] = %d -> Reference with f/w, addr: %pa\n",
2071 binfo->fd[0], &device_addr);
2072 } else {
2073 dprintk(VIDC_DBG,
2074 "FBD fd[0] = %d -> FBD_ref_released, addr: %pa\n",
2075 binfo->fd[0], &device_addr);
2076
2077 mutex_lock(&inst->registeredbufs.lock);
2078 list_for_each_entry(temp, &inst->registeredbufs.list,
2079 list) {
2080 if (temp == binfo) {
2081 buf_ref_put(inst, binfo);
2082 break;
2083 }
2084 }
2085 mutex_unlock(&inst->registeredbufs.lock);
2086 }
2087}
2088
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002089static void handle_ebd(enum hal_command_response cmd, void *data)
2090{
2091 struct msm_vidc_cb_data_done *response = data;
2092 struct vb2_buffer *vb;
2093 struct msm_vidc_inst *inst;
2094 struct vidc_hal_ebd *empty_buf_done;
2095 struct vb2_v4l2_buffer *vbuf = NULL;
2096
2097 if (!response) {
2098 dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
2099 return;
2100 }
2101
2102 inst = get_inst(get_vidc_core(response->device_id),
2103 response->session_id);
2104 if (!inst) {
2105 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
2106 return;
2107 }
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08002108 if (inst->buffer_mode_set[OUTPUT_PORT] == HAL_BUFFER_MODE_DYNAMIC)
2109 handle_dynamic_buffer(inst,
2110 response->input_done.packet_buffer, 0);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002111
2112 vb = get_vb_from_device_addr(&inst->bufq[OUTPUT_PORT],
2113 response->input_done.packet_buffer);
2114 if (vb) {
2115 vbuf = to_vb2_v4l2_buffer(vb);
2116 vb->planes[0].bytesused = response->input_done.filled_len;
2117 vb->planes[0].data_offset = response->input_done.offset;
2118 if (vb->planes[0].data_offset > vb->planes[0].length)
2119 dprintk(VIDC_INFO, "data_offset overflow length\n");
2120 if (vb->planes[0].bytesused > vb->planes[0].length)
2121 dprintk(VIDC_INFO, "bytesused overflow length\n");
2122 if (vb->planes[0].m.userptr !=
2123 response->clnt_data)
2124 dprintk(VIDC_INFO, "Client data != bufaddr\n");
2125 empty_buf_done = (struct vidc_hal_ebd *)&response->input_done;
2126 if (empty_buf_done) {
2127 if (empty_buf_done->status == VIDC_ERR_NOT_SUPPORTED) {
2128 dprintk(VIDC_INFO,
2129 "Failed : Unsupported input stream\n");
2130 vbuf->flags |=
2131 V4L2_QCOM_BUF_INPUT_UNSUPPORTED;
2132 }
2133 if (empty_buf_done->status == VIDC_ERR_BITSTREAM_ERR) {
2134 dprintk(VIDC_INFO,
2135 "Failed : Corrupted input stream\n");
2136 vbuf->flags |=
2137 V4L2_QCOM_BUF_DATA_CORRUPT;
2138 }
2139 if (empty_buf_done->flags & HAL_BUFFERFLAG_SYNCFRAME)
2140 vbuf->flags |=
2141 V4L2_QCOM_BUF_FLAG_IDRFRAME |
2142 V4L2_BUF_FLAG_KEYFRAME;
2143 }
2144 dprintk(VIDC_DBG,
2145 "Got ebd from hal: device_addr: %pa, alloc: %d, status: %#x, pic_type: %#x, flags: %#x\n",
2146 &empty_buf_done->packet_buffer,
2147 empty_buf_done->alloc_len, empty_buf_done->status,
2148 empty_buf_done->picture_type, empty_buf_done->flags);
2149
Praneeth Paladugub71968b2015-08-19 20:47:57 -07002150 msm_vidc_clear_freq_entry(inst, empty_buf_done->packet_buffer);
2151
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002152 mutex_lock(&inst->bufq[OUTPUT_PORT].lock);
2153 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
2154 mutex_unlock(&inst->bufq[OUTPUT_PORT].lock);
2155 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_EBD);
2156 }
2157
2158 put_inst(inst);
2159}
2160
2161int buf_ref_get(struct msm_vidc_inst *inst, struct buffer_info *binfo)
2162{
2163 int cnt = 0;
2164
2165 if (!inst || !binfo)
2166 return -EINVAL;
2167
2168 atomic_inc(&binfo->ref_count);
2169 cnt = atomic_read(&binfo->ref_count);
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08002170 if (cnt >= 2)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002171 inst->buffers_held_in_driver++;
2172
2173 dprintk(VIDC_DBG, "REF_GET[%d] fd[0] = %d\n", cnt, binfo->fd[0]);
2174
2175 return cnt;
2176}
2177
2178int buf_ref_put(struct msm_vidc_inst *inst, struct buffer_info *binfo)
2179{
2180 int rc = 0;
2181 int cnt;
2182 bool release_buf = false;
2183 bool qbuf_again = false;
2184
2185 if (!inst || !binfo)
2186 return -EINVAL;
2187
2188 atomic_dec(&binfo->ref_count);
2189 cnt = atomic_read(&binfo->ref_count);
2190 dprintk(VIDC_DBG, "REF_PUT[%d] fd[0] = %d\n", cnt, binfo->fd[0]);
2191 if (!cnt)
2192 release_buf = true;
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08002193 else if (cnt >= 1)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002194 qbuf_again = true;
2195 else {
2196 dprintk(VIDC_DBG, "%s: invalid ref_cnt: %d\n", __func__, cnt);
2197 cnt = -EINVAL;
2198 }
2199
2200 if (cnt < 0)
2201 return cnt;
2202
2203 if (release_buf) {
2204 /*
2205 * We can not delete binfo here as we need to set the user
2206 * virtual address saved in binfo->uvaddr to the dequeued v4l2
2207 * buffer.
2208 *
2209 * We will set the pending_deletion flag to true here and delete
2210 * binfo from registered list in dqbuf after setting the uvaddr.
2211 */
2212 dprintk(VIDC_DBG, "fd[0] = %d -> pending_deletion = true\n",
2213 binfo->fd[0]);
2214 binfo->pending_deletion = true;
2215 } else if (qbuf_again) {
2216 inst->buffers_held_in_driver--;
2217 rc = qbuf_dynamic_buf(inst, binfo);
2218 if (!rc)
2219 return rc;
2220 }
2221 return cnt;
2222}
2223
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002224static int handle_multi_stream_buffers(struct msm_vidc_inst *inst,
2225 ion_phys_addr_t dev_addr)
2226{
2227 struct internal_buf *binfo;
2228 struct msm_smem *handle;
2229 bool found = false;
2230
2231 mutex_lock(&inst->outputbufs.lock);
2232 list_for_each_entry(binfo, &inst->outputbufs.list, list) {
2233 handle = binfo->handle;
2234 if (handle && dev_addr == handle->device_addr) {
2235 if (binfo->buffer_ownership == DRIVER) {
2236 dprintk(VIDC_ERR,
2237 "FW returned same buffer: %pa\n",
2238 &dev_addr);
2239 break;
2240 }
2241 binfo->buffer_ownership = DRIVER;
2242 found = true;
2243 break;
2244 }
2245 }
2246 mutex_unlock(&inst->outputbufs.lock);
2247
2248 if (!found) {
2249 dprintk(VIDC_ERR,
2250 "Failed to find output buffer in queued list: %pa\n",
2251 &dev_addr);
2252 }
2253
2254 return 0;
2255}
2256
2257enum hal_buffer msm_comm_get_hal_output_buffer(struct msm_vidc_inst *inst)
2258{
2259 if (msm_comm_get_stream_output_mode(inst) ==
2260 HAL_VIDEO_DECODER_SECONDARY)
2261 return HAL_BUFFER_OUTPUT2;
2262 else
2263 return HAL_BUFFER_OUTPUT;
2264}
2265
2266static void handle_fbd(enum hal_command_response cmd, void *data)
2267{
2268 struct msm_vidc_cb_data_done *response = data;
2269 struct msm_vidc_inst *inst;
2270 struct vb2_buffer *vb = NULL;
2271 struct vidc_hal_fbd *fill_buf_done;
2272 enum hal_buffer buffer_type;
2273 int extra_idx = 0;
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07002274 u64 time_usec = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002275 struct vb2_v4l2_buffer *vbuf = NULL;
2276
2277 if (!response) {
2278 dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
2279 return;
2280 }
2281
2282 inst = get_inst(get_vidc_core(response->device_id),
2283 response->session_id);
2284 if (!inst) {
2285 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
2286 return;
2287 }
2288
2289 fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
2290 buffer_type = msm_comm_get_hal_output_buffer(inst);
2291 if (fill_buf_done->buffer_type == buffer_type) {
2292 vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
2293 fill_buf_done->packet_buffer1);
2294 } else {
2295 if (handle_multi_stream_buffers(inst,
2296 fill_buf_done->packet_buffer1))
2297 dprintk(VIDC_ERR,
2298 "Failed : Output buffer not found %pa\n",
2299 &fill_buf_done->packet_buffer1);
2300 goto err_handle_fbd;
2301 }
2302
2303 if (vb) {
2304 vbuf = to_vb2_v4l2_buffer(vb);
Umesh Pandeyd24533d2017-03-14 18:18:18 -07002305 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DROP_FRAME ||
2306 fill_buf_done->flags1 & HAL_BUFFERFLAG_DECODEONLY)
2307 fill_buf_done->filled_len1 = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002308 vb->planes[0].bytesused = fill_buf_done->filled_len1;
2309 vb->planes[0].data_offset = fill_buf_done->offset1;
2310 if (vb->planes[0].data_offset > vb->planes[0].length)
2311 dprintk(VIDC_INFO,
2312 "fbd:Overflow data_offset = %d; length = %d\n",
2313 vb->planes[0].data_offset,
2314 vb->planes[0].length);
2315 if (vb->planes[0].bytesused > vb->planes[0].length)
2316 dprintk(VIDC_INFO,
2317 "fbd:Overflow bytesused = %d; length = %d\n",
2318 vb->planes[0].bytesused,
2319 vb->planes[0].length);
2320 if (!(fill_buf_done->flags1 &
2321 HAL_BUFFERFLAG_TIMESTAMPINVALID)) {
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07002322 time_usec = fill_buf_done->timestamp_hi;
2323 time_usec = (time_usec << 32) |
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002324 fill_buf_done->timestamp_lo;
2325 } else {
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07002326 time_usec = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002327 dprintk(VIDC_DBG,
2328 "Set zero timestamp for buffer %pa, filled: %d, (hi:%u, lo:%u)\n",
2329 &fill_buf_done->packet_buffer1,
2330 fill_buf_done->filled_len1,
2331 fill_buf_done->timestamp_hi,
2332 fill_buf_done->timestamp_lo);
2333 }
2334 vbuf->flags = 0;
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07002335 vb->timestamp = (time_usec * NSEC_PER_USEC);
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002336
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002337 extra_idx =
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08002338 EXTRADATA_IDX(inst->bufq[CAPTURE_PORT].num_planes);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002339 if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
2340 vb->planes[extra_idx].m.userptr =
2341 (unsigned long)fill_buf_done->extra_data_buffer;
2342 vb->planes[extra_idx].bytesused =
2343 vb->planes[extra_idx].length;
2344 vb->planes[extra_idx].data_offset = 0;
2345 }
2346
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08002347 if (inst->buffer_mode_set[CAPTURE_PORT] ==
2348 HAL_BUFFER_MODE_DYNAMIC)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002349 handle_dynamic_buffer(inst, fill_buf_done->packet_buffer1,
2350 fill_buf_done->flags1);
2351 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_READONLY)
2352 vbuf->flags |= V4L2_QCOM_BUF_FLAG_READONLY;
2353 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOS)
2354 vbuf->flags |= V4L2_QCOM_BUF_FLAG_EOS;
2355 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_CODECCONFIG)
2356 vbuf->flags &= ~V4L2_QCOM_BUF_FLAG_CODECCONFIG;
2357 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_SYNCFRAME)
2358 vbuf->flags |= V4L2_QCOM_BUF_FLAG_IDRFRAME;
2359 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOSEQ)
2360 vbuf->flags |= V4L2_QCOM_BUF_FLAG_EOSEQ;
Umesh Pandeyd24533d2017-03-14 18:18:18 -07002361 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DECODEONLY ||
2362 fill_buf_done->flags1 & HAL_BUFFERFLAG_DROP_FRAME)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002363 vbuf->flags |= V4L2_QCOM_BUF_FLAG_DECODEONLY;
2364 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DATACORRUPT)
2365 vbuf->flags |= V4L2_QCOM_BUF_DATA_CORRUPT;
2366
2367 switch (fill_buf_done->picture_type) {
2368 case HAL_PICTURE_IDR:
2369 vbuf->flags |= V4L2_QCOM_BUF_FLAG_IDRFRAME;
2370 vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
2371 break;
2372 case HAL_PICTURE_I:
2373 vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
2374 break;
2375 case HAL_PICTURE_P:
2376 vbuf->flags |= V4L2_BUF_FLAG_PFRAME;
2377 break;
2378 case HAL_PICTURE_B:
2379 vbuf->flags |= V4L2_BUF_FLAG_BFRAME;
2380 break;
2381 case HAL_FRAME_NOTCODED:
2382 case HAL_UNUSED_PICT:
2383 /* Do we need to care about these? */
2384 case HAL_FRAME_YUV:
2385 break;
2386 default:
2387 break;
2388 }
2389
2390 inst->count.fbd++;
2391
2392 if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
2393 dprintk(VIDC_DBG,
2394 "extradata: userptr = %pK;"
2395 " bytesused = %d; length = %d\n",
2396 (u8 *)vb->planes[extra_idx].m.userptr,
2397 vb->planes[extra_idx].bytesused,
2398 vb->planes[extra_idx].length);
2399 }
2400 dprintk(VIDC_DBG,
2401 "Got fbd from hal: device_addr: %pa, alloc: %d, filled: %d, offset: %d, ts: %lld, flags: %#x, crop: %d %d %d %d, pic_type: %#x, mark_data: %#x\n",
2402 &fill_buf_done->packet_buffer1, fill_buf_done->alloc_len1,
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07002403 fill_buf_done->filled_len1, fill_buf_done->offset1, time_usec,
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002404 fill_buf_done->flags1, fill_buf_done->start_x_coord,
2405 fill_buf_done->start_y_coord, fill_buf_done->frame_width,
2406 fill_buf_done->frame_height, fill_buf_done->picture_type,
2407 fill_buf_done->mark_data);
2408
2409 mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
2410 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
2411 mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
2412 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FBD);
2413 }
2414
2415err_handle_fbd:
2416 put_inst(inst);
2417}
2418
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002419void handle_cmd_response(enum hal_command_response cmd, void *data)
2420{
2421 dprintk(VIDC_DBG, "Command response = %d\n", cmd);
2422 switch (cmd) {
2423 case HAL_SYS_INIT_DONE:
2424 handle_sys_init_done(cmd, data);
2425 break;
2426 case HAL_SYS_RELEASE_RESOURCE_DONE:
2427 handle_sys_release_res_done(cmd, data);
2428 break;
2429 case HAL_SESSION_INIT_DONE:
2430 handle_session_init_done(cmd, data);
2431 break;
2432 case HAL_SESSION_PROPERTY_INFO:
2433 handle_session_prop_info(cmd, data);
2434 break;
2435 case HAL_SESSION_LOAD_RESOURCE_DONE:
2436 handle_load_resource_done(cmd, data);
2437 break;
2438 case HAL_SESSION_START_DONE:
2439 handle_start_done(cmd, data);
2440 break;
2441 case HAL_SESSION_ETB_DONE:
2442 handle_ebd(cmd, data);
2443 break;
2444 case HAL_SESSION_FTB_DONE:
2445 handle_fbd(cmd, data);
2446 break;
2447 case HAL_SESSION_STOP_DONE:
2448 handle_stop_done(cmd, data);
2449 break;
2450 case HAL_SESSION_RELEASE_RESOURCE_DONE:
2451 handle_release_res_done(cmd, data);
2452 break;
2453 case HAL_SESSION_END_DONE:
2454 case HAL_SESSION_ABORT_DONE:
2455 handle_session_close(cmd, data);
2456 break;
2457 case HAL_SESSION_EVENT_CHANGE:
2458 handle_event_change(cmd, data);
2459 break;
2460 case HAL_SESSION_FLUSH_DONE:
2461 handle_session_flush(cmd, data);
2462 break;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002463 case HAL_SYS_WATCHDOG_TIMEOUT:
2464 case HAL_SYS_ERROR:
2465 handle_sys_error(cmd, data);
2466 break;
2467 case HAL_SESSION_ERROR:
2468 handle_session_error(cmd, data);
2469 break;
2470 case HAL_SESSION_RELEASE_BUFFER_DONE:
2471 handle_session_release_buf_done(cmd, data);
2472 break;
2473 default:
2474 dprintk(VIDC_DBG, "response unhandled: %d\n", cmd);
2475 break;
2476 }
2477}
2478
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002479static inline enum msm_vidc_thermal_level msm_comm_vidc_thermal_level(int level)
2480{
2481 switch (level) {
2482 case 0:
2483 return VIDC_THERMAL_NORMAL;
2484 case 1:
2485 return VIDC_THERMAL_LOW;
2486 case 2:
2487 return VIDC_THERMAL_HIGH;
2488 default:
2489 return VIDC_THERMAL_CRITICAL;
2490 }
2491}
2492
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002493static bool is_core_turbo(struct msm_vidc_core *core, unsigned long freq)
2494{
2495 int i = 0;
Praneeth Paladugub71968b2015-08-19 20:47:57 -07002496 struct allowed_clock_rates_table *allowed_clks_tbl = NULL;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002497 u32 max_freq = 0;
2498
Praneeth Paladugub71968b2015-08-19 20:47:57 -07002499 allowed_clks_tbl = core->resources.allowed_clks_tbl;
2500 for (i = 0; i < core->resources.allowed_clks_tbl_size; i++) {
2501 if (max_freq < allowed_clks_tbl[i].clock_rate)
2502 max_freq = allowed_clks_tbl[i].clock_rate;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002503 }
2504 return freq >= max_freq;
2505}
2506
2507static bool is_thermal_permissible(struct msm_vidc_core *core)
2508{
2509 enum msm_vidc_thermal_level tl;
2510 unsigned long freq = 0;
2511 bool is_turbo = false;
2512
2513 if (!core->resources.thermal_mitigable)
2514 return true;
2515
2516 if (msm_vidc_thermal_mitigation_disabled) {
2517 dprintk(VIDC_DBG,
2518 "Thermal mitigation not enabled. debugfs %d\n",
2519 msm_vidc_thermal_mitigation_disabled);
2520 return true;
2521 }
2522
2523 tl = msm_comm_vidc_thermal_level(vidc_driver->thermal_level);
Praneeth Paladugub71968b2015-08-19 20:47:57 -07002524 freq = core->freq;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002525
2526 is_turbo = is_core_turbo(core, freq);
2527 dprintk(VIDC_DBG,
2528 "Core freq %ld Thermal level %d Turbo mode %d\n",
2529 freq, tl, is_turbo);
2530
2531 if (is_turbo && tl >= VIDC_THERMAL_LOW) {
2532 dprintk(VIDC_ERR,
2533 "Video session not allowed. Turbo mode %d Thermal level %d\n",
2534 is_turbo, tl);
2535 return false;
2536 }
2537 return true;
2538}
2539
2540static int msm_comm_session_abort(struct msm_vidc_inst *inst)
2541{
2542 int rc = 0, abort_completion = 0;
2543 struct hfi_device *hdev;
2544
2545 if (!inst || !inst->core || !inst->core->device) {
2546 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
2547 return -EINVAL;
2548 }
2549 hdev = inst->core->device;
2550 abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE);
2551
2552 rc = call_hfi_op(hdev, session_abort, (void *)inst->session);
2553 if (rc) {
2554 dprintk(VIDC_ERR,
2555 "%s session_abort failed rc: %d\n", __func__, rc);
2556 return rc;
2557 }
2558 rc = wait_for_completion_timeout(
2559 &inst->completions[abort_completion],
2560 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
2561 if (!rc) {
2562 dprintk(VIDC_ERR,
2563 "%s: Wait interrupted or timed out [%pK]: %d\n",
2564 __func__, inst, abort_completion);
2565 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
2566 dprintk(VIDC_ERR,
2567 "ABORT timeout can potentially crash the system\n");
2568 msm_comm_print_debug_info(inst);
2569
2570 msm_vidc_handle_hw_error(inst->core);
2571 rc = -EBUSY;
2572 } else {
2573 rc = 0;
2574 }
2575 msm_comm_session_clean(inst);
2576 return rc;
2577}
2578
2579static void handle_thermal_event(struct msm_vidc_core *core)
2580{
2581 int rc = 0;
2582 struct msm_vidc_inst *inst;
2583
2584 if (!core || !core->device) {
2585 dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
2586 return;
2587 }
2588 mutex_lock(&core->lock);
2589 list_for_each_entry(inst, &core->instances, list) {
2590 if (!inst->session)
2591 continue;
2592
2593 mutex_unlock(&core->lock);
2594 if (inst->state >= MSM_VIDC_OPEN_DONE &&
2595 inst->state < MSM_VIDC_CLOSE_DONE) {
2596 dprintk(VIDC_WARN, "%s: abort inst %pK\n",
2597 __func__, inst);
2598 rc = msm_comm_session_abort(inst);
2599 if (rc) {
2600 dprintk(VIDC_ERR,
2601 "%s session_abort failed rc: %d\n",
2602 __func__, rc);
2603 goto err_sess_abort;
2604 }
2605 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
2606 dprintk(VIDC_WARN,
2607 "%s Send sys error for inst %pK\n",
2608 __func__, inst);
2609 msm_vidc_queue_v4l2_event(inst,
2610 V4L2_EVENT_MSM_VIDC_SYS_ERROR);
2611 } else {
2612 msm_comm_generate_session_error(inst);
2613 }
2614 mutex_lock(&core->lock);
2615 }
2616 mutex_unlock(&core->lock);
2617 return;
2618
2619err_sess_abort:
2620 msm_comm_clean_notify_client(core);
2621}
2622
2623void msm_comm_handle_thermal_event(void)
2624{
2625 struct msm_vidc_core *core;
2626
2627 list_for_each_entry(core, &vidc_driver->cores, list) {
2628 if (!is_thermal_permissible(core)) {
2629 dprintk(VIDC_WARN,
2630 "Thermal level critical, stop all active sessions!\n");
2631 handle_thermal_event(core);
2632 }
2633 }
2634}
2635
2636int msm_comm_check_core_init(struct msm_vidc_core *core)
2637{
2638 int rc = 0;
2639 struct hfi_device *hdev;
2640 struct msm_vidc_inst *inst = NULL;
2641
2642 mutex_lock(&core->lock);
2643 if (core->state >= VIDC_CORE_INIT_DONE) {
2644 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
2645 core->id, core->state);
2646 goto exit;
2647 }
2648 dprintk(VIDC_DBG, "Waiting for SYS_INIT_DONE\n");
2649 hdev = (struct hfi_device *)core->device;
2650 rc = wait_for_completion_timeout(
2651 &core->completions[SYS_MSG_INDEX(HAL_SYS_INIT_DONE)],
2652 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
2653 if (!rc) {
2654 dprintk(VIDC_ERR, "%s: Wait interrupted or timed out: %d\n",
2655 __func__, SYS_MSG_INDEX(HAL_SYS_INIT_DONE));
2656 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
2657 dprintk(VIDC_ERR,
2658 "SYS_INIT timeout can potentially crash the system\n");
2659 /*
2660 * For SYS_INIT, there will not be any inst pointer.
2661 * Just grab one of the inst from instances list and
2662 * use it.
2663 */
2664 inst = list_first_entry(&core->instances,
2665 struct msm_vidc_inst, list);
2666
2667 mutex_unlock(&core->lock);
2668 msm_comm_print_debug_info(inst);
2669 mutex_lock(&core->lock);
2670
2671 msm_vidc_handle_hw_error(core);
2672 rc = -EIO;
2673 goto exit;
2674 } else {
2675 core->state = VIDC_CORE_INIT_DONE;
2676 rc = 0;
2677 }
2678 dprintk(VIDC_DBG, "SYS_INIT_DONE!!!\n");
2679exit:
2680 mutex_unlock(&core->lock);
2681 return rc;
2682}
2683
2684static int msm_comm_init_core_done(struct msm_vidc_inst *inst)
2685{
2686 int rc = 0;
2687
2688 rc = msm_comm_check_core_init(inst->core);
2689 if (rc) {
2690 dprintk(VIDC_ERR, "%s - failed to initialize core\n", __func__);
2691 msm_comm_generate_sys_error(inst);
2692 return rc;
2693 }
2694 change_inst_state(inst, MSM_VIDC_CORE_INIT_DONE);
2695 return rc;
2696}
2697
2698static int msm_comm_init_core(struct msm_vidc_inst *inst)
2699{
2700 int rc = 0;
2701 struct hfi_device *hdev;
2702 struct msm_vidc_core *core;
2703
2704 if (!inst || !inst->core || !inst->core->device)
2705 return -EINVAL;
2706
2707 core = inst->core;
2708 hdev = core->device;
2709 mutex_lock(&core->lock);
2710 if (core->state >= VIDC_CORE_INIT) {
2711 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
2712 core->id, core->state);
2713 goto core_already_inited;
2714 }
2715 if (!core->capabilities) {
2716 core->capabilities = kzalloc(VIDC_MAX_SESSIONS *
2717 sizeof(struct msm_vidc_capability), GFP_KERNEL);
2718 if (!core->capabilities) {
2719 dprintk(VIDC_ERR,
2720 "%s: failed to allocate capabilities\n",
2721 __func__);
2722 rc = -ENOMEM;
2723 goto fail_cap_alloc;
2724 }
2725 } else {
2726 dprintk(VIDC_WARN,
2727 "%s: capabilities memory is expected to be freed\n",
2728 __func__);
2729 }
2730
2731 rc = call_hfi_op(hdev, core_init, hdev->hfi_device_data);
2732 if (rc) {
2733 dprintk(VIDC_ERR, "Failed to init core, id = %d\n",
2734 core->id);
2735 goto fail_core_init;
2736 }
2737 core->state = VIDC_CORE_INIT;
2738 core->smmu_fault_handled = false;
2739core_already_inited:
2740 change_inst_state(inst, MSM_VIDC_CORE_INIT);
2741 mutex_unlock(&core->lock);
Praneeth Paladugub71968b2015-08-19 20:47:57 -07002742
2743 rc = msm_comm_scale_clocks_and_bus(inst);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002744 return rc;
2745
2746fail_core_init:
2747 kfree(core->capabilities);
2748fail_cap_alloc:
2749 core->capabilities = NULL;
2750 core->state = VIDC_CORE_UNINIT;
2751 mutex_unlock(&core->lock);
2752 return rc;
2753}
2754
2755static int msm_vidc_deinit_core(struct msm_vidc_inst *inst)
2756{
2757 struct msm_vidc_core *core;
2758 struct hfi_device *hdev;
2759
2760 if (!inst || !inst->core || !inst->core->device) {
2761 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
2762 return -EINVAL;
2763 }
2764
2765 core = inst->core;
2766 hdev = core->device;
2767
2768 mutex_lock(&core->lock);
2769 if (core->state == VIDC_CORE_UNINIT) {
2770 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
2771 core->id, core->state);
2772 goto core_already_uninited;
2773 }
2774 mutex_unlock(&core->lock);
2775
2776 msm_comm_scale_clocks_and_bus(inst);
2777
2778 mutex_lock(&core->lock);
2779
2780 if (!core->resources.never_unload_fw) {
2781 cancel_delayed_work(&core->fw_unload_work);
2782
2783 /*
2784 * Delay unloading of firmware. This is useful
2785 * in avoiding firmware download delays in cases where we
2786 * will have a burst of back to back video playback sessions
2787 * e.g. thumbnail generation.
2788 */
2789 schedule_delayed_work(&core->fw_unload_work,
2790 msecs_to_jiffies(core->state == VIDC_CORE_INVALID ?
2791 0 : msm_vidc_firmware_unload_delay));
2792
2793 dprintk(VIDC_DBG, "firmware unload delayed by %u ms\n",
2794 core->state == VIDC_CORE_INVALID ?
2795 0 : msm_vidc_firmware_unload_delay);
2796 }
2797
2798core_already_uninited:
2799 change_inst_state(inst, MSM_VIDC_CORE_UNINIT);
2800 mutex_unlock(&core->lock);
2801 return 0;
2802}
2803
2804int msm_comm_force_cleanup(struct msm_vidc_inst *inst)
2805{
2806 msm_comm_kill_session(inst);
2807 return msm_vidc_deinit_core(inst);
2808}
2809
2810static int msm_comm_session_init(int flipped_state,
2811 struct msm_vidc_inst *inst)
2812{
2813 int rc = 0;
2814 int fourcc = 0;
2815 struct hfi_device *hdev;
2816
2817 if (!inst || !inst->core || !inst->core->device) {
2818 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
2819 return -EINVAL;
2820 }
2821 hdev = inst->core->device;
2822
2823 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) {
2824 dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n",
2825 inst, inst->state);
2826 goto exit;
2827 }
2828 if (inst->session_type == MSM_VIDC_DECODER) {
2829 fourcc = inst->fmts[OUTPUT_PORT].fourcc;
2830 } else if (inst->session_type == MSM_VIDC_ENCODER) {
2831 fourcc = inst->fmts[CAPTURE_PORT].fourcc;
2832 } else {
2833 dprintk(VIDC_ERR, "Invalid session\n");
2834 return -EINVAL;
2835 }
2836
Praneeth Paladugub71968b2015-08-19 20:47:57 -07002837 msm_comm_init_clocks_and_bus_data(inst);
2838
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002839 rc = call_hfi_op(hdev, session_init, hdev->hfi_device_data,
2840 inst, get_hal_domain(inst->session_type),
2841 get_hal_codec(fourcc),
2842 &inst->session);
2843
2844 if (rc || !inst->session) {
2845 dprintk(VIDC_ERR,
2846 "Failed to call session init for: %pK, %pK, %d, %d\n",
2847 inst->core->device, inst,
2848 inst->session_type, fourcc);
2849 rc = -EINVAL;
2850 goto exit;
2851 }
2852 change_inst_state(inst, MSM_VIDC_OPEN);
2853exit:
2854 return rc;
2855}
2856
2857static void msm_vidc_print_running_insts(struct msm_vidc_core *core)
2858{
2859 struct msm_vidc_inst *temp;
2860
2861 dprintk(VIDC_ERR, "Running instances:\n");
2862 dprintk(VIDC_ERR, "%4s|%4s|%4s|%4s|%4s\n",
2863 "type", "w", "h", "fps", "prop");
2864
2865 mutex_lock(&core->lock);
2866 list_for_each_entry(temp, &core->instances, list) {
2867 if (temp->state >= MSM_VIDC_OPEN_DONE &&
2868 temp->state < MSM_VIDC_STOP_DONE) {
2869 char properties[4] = "";
2870
2871 if (is_thumbnail_session(temp))
2872 strlcat(properties, "N", sizeof(properties));
2873
2874 if (msm_comm_turbo_session(temp))
2875 strlcat(properties, "T", sizeof(properties));
2876
2877 dprintk(VIDC_ERR, "%4d|%4d|%4d|%4d|%4s\n",
2878 temp->session_type,
2879 max(temp->prop.width[CAPTURE_PORT],
2880 temp->prop.width[OUTPUT_PORT]),
2881 max(temp->prop.height[CAPTURE_PORT],
2882 temp->prop.height[OUTPUT_PORT]),
2883 temp->prop.fps, properties);
2884 }
2885 }
2886 mutex_unlock(&core->lock);
2887}
2888
2889static int msm_vidc_load_resources(int flipped_state,
2890 struct msm_vidc_inst *inst)
2891{
2892 int rc = 0;
2893 struct hfi_device *hdev;
2894 int num_mbs_per_sec = 0, max_load_adj = 0;
2895 struct msm_vidc_core *core;
2896 enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD |
2897 LOAD_CALC_IGNORE_THUMBNAIL_LOAD |
2898 LOAD_CALC_IGNORE_NON_REALTIME_LOAD;
2899
2900 if (!inst || !inst->core || !inst->core->device) {
2901 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
2902 return -EINVAL;
2903 }
2904
2905 core = inst->core;
2906 if (core->state == VIDC_CORE_INVALID) {
2907 dprintk(VIDC_ERR,
2908 "Core is in bad state can't do load res\n");
2909 return -EINVAL;
2910 }
2911
2912 if (inst->state == MSM_VIDC_CORE_INVALID) {
2913 dprintk(VIDC_ERR,
2914 "Instance is in invalid state can't do load res\n");
2915 return -EINVAL;
2916 }
2917
2918 num_mbs_per_sec =
2919 msm_comm_get_load(core, MSM_VIDC_DECODER, quirks) +
2920 msm_comm_get_load(core, MSM_VIDC_ENCODER, quirks);
2921
2922 max_load_adj = core->resources.max_load +
2923 inst->capability.mbs_per_frame.max;
2924
2925 if (num_mbs_per_sec > max_load_adj) {
2926 dprintk(VIDC_ERR, "HW is overloaded, needed: %d max: %d\n",
2927 num_mbs_per_sec, max_load_adj);
2928 msm_vidc_print_running_insts(core);
2929 inst->state = MSM_VIDC_CORE_INVALID;
2930 msm_comm_kill_session(inst);
2931 return -EBUSY;
2932 }
2933
2934 hdev = core->device;
2935 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) {
2936 dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n",
2937 inst, inst->state);
2938 goto exit;
2939 }
2940
2941 rc = call_hfi_op(hdev, session_load_res, (void *) inst->session);
2942 if (rc) {
2943 dprintk(VIDC_ERR,
2944 "Failed to send load resources\n");
2945 goto exit;
2946 }
2947 change_inst_state(inst, MSM_VIDC_LOAD_RESOURCES);
2948exit:
2949 return rc;
2950}
2951
2952static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst)
2953{
2954 int rc = 0;
2955 struct hfi_device *hdev;
2956
2957 if (!inst || !inst->core || !inst->core->device) {
2958 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
2959 return -EINVAL;
2960 }
2961 if (inst->state == MSM_VIDC_CORE_INVALID ||
2962 inst->core->state == VIDC_CORE_INVALID) {
2963 dprintk(VIDC_ERR,
2964 "Core is in bad state can't do start\n");
2965 return -EINVAL;
2966 }
2967
2968 hdev = inst->core->device;
2969
2970 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) {
2971 dprintk(VIDC_INFO,
2972 "inst: %pK is already in state: %d\n",
2973 inst, inst->state);
2974 goto exit;
2975 }
2976 rc = call_hfi_op(hdev, session_start, (void *) inst->session);
2977 if (rc) {
2978 dprintk(VIDC_ERR,
2979 "Failed to send start\n");
2980 goto exit;
2981 }
2982 change_inst_state(inst, MSM_VIDC_START);
2983exit:
2984 return rc;
2985}
2986
2987static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst)
2988{
2989 int rc = 0;
2990 struct hfi_device *hdev;
2991
2992 if (!inst || !inst->core || !inst->core->device) {
2993 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
2994 return -EINVAL;
2995 }
2996 hdev = inst->core->device;
2997
2998 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) {
2999 dprintk(VIDC_INFO,
3000 "inst: %pK is already in state: %d\n",
3001 inst, inst->state);
3002 goto exit;
3003 }
3004 dprintk(VIDC_DBG, "Send Stop to hal\n");
3005 rc = call_hfi_op(hdev, session_stop, (void *) inst->session);
3006 if (rc) {
3007 dprintk(VIDC_ERR, "Failed to send stop\n");
3008 goto exit;
3009 }
3010 change_inst_state(inst, MSM_VIDC_STOP);
3011exit:
3012 return rc;
3013}
3014
3015static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst)
3016{
3017 int rc = 0;
3018 struct hfi_device *hdev;
3019
3020 if (!inst || !inst->core || !inst->core->device) {
3021 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3022 return -EINVAL;
3023 }
3024 hdev = inst->core->device;
3025
3026 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) {
3027 dprintk(VIDC_INFO,
3028 "inst: %pK is already in state: %d\n",
3029 inst, inst->state);
3030 goto exit;
3031 }
3032 dprintk(VIDC_DBG,
3033 "Send release res to hal\n");
3034 rc = call_hfi_op(hdev, session_release_res, (void *) inst->session);
3035 if (rc) {
3036 dprintk(VIDC_ERR,
3037 "Failed to send release resources\n");
3038 goto exit;
3039 }
3040 change_inst_state(inst, MSM_VIDC_RELEASE_RESOURCES);
3041exit:
3042 return rc;
3043}
3044
3045static int msm_comm_session_close(int flipped_state,
3046 struct msm_vidc_inst *inst)
3047{
3048 int rc = 0;
3049 struct hfi_device *hdev;
3050
3051 if (!inst || !inst->core || !inst->core->device) {
3052 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
3053 return -EINVAL;
3054 }
3055 hdev = inst->core->device;
3056 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) {
3057 dprintk(VIDC_INFO,
3058 "inst: %pK is already in state: %d\n",
3059 inst, inst->state);
3060 goto exit;
3061 }
3062 dprintk(VIDC_DBG,
3063 "Send session close to hal\n");
3064 rc = call_hfi_op(hdev, session_end, (void *) inst->session);
3065 if (rc) {
3066 dprintk(VIDC_ERR,
3067 "Failed to send close\n");
3068 goto exit;
3069 }
3070 change_inst_state(inst, MSM_VIDC_CLOSE);
3071exit:
3072 return rc;
3073}
3074
3075int msm_comm_suspend(int core_id)
3076{
3077 struct hfi_device *hdev;
3078 struct msm_vidc_core *core;
3079 int rc = 0;
3080
3081 core = get_vidc_core(core_id);
3082 if (!core) {
3083 dprintk(VIDC_ERR,
3084 "%s: Failed to find core for core_id = %d\n",
3085 __func__, core_id);
3086 return -EINVAL;
3087 }
3088
3089 hdev = (struct hfi_device *)core->device;
3090 if (!hdev) {
3091 dprintk(VIDC_ERR, "%s Invalid device handle\n", __func__);
3092 return -EINVAL;
3093 }
3094
3095 mutex_lock(&core->lock);
3096 if (core->state == VIDC_CORE_INVALID) {
3097 dprintk(VIDC_ERR,
3098 "%s - fw is not in proper state, skip suspend\n",
3099 __func__);
3100 rc = -EINVAL;
3101 goto exit;
3102 }
3103
3104 rc = call_hfi_op(hdev, suspend, hdev->hfi_device_data);
3105 if (rc)
3106 dprintk(VIDC_WARN, "Failed to suspend\n");
3107
3108exit:
3109 mutex_unlock(&core->lock);
3110 return rc;
3111}
3112
3113static int get_flipped_state(int present_state,
3114 int desired_state)
3115{
3116 int flipped_state = present_state;
3117
3118 if (flipped_state < MSM_VIDC_STOP
3119 && desired_state > MSM_VIDC_STOP) {
3120 flipped_state = MSM_VIDC_STOP + (MSM_VIDC_STOP - flipped_state);
3121 flipped_state &= 0xFFFE;
3122 flipped_state = flipped_state - 1;
3123 } else if (flipped_state > MSM_VIDC_STOP
3124 && desired_state < MSM_VIDC_STOP) {
3125 flipped_state = MSM_VIDC_STOP -
3126 (flipped_state - MSM_VIDC_STOP + 1);
3127 flipped_state &= 0xFFFE;
3128 flipped_state = flipped_state - 1;
3129 }
3130 return flipped_state;
3131}
3132
3133struct hal_buffer_requirements *get_buff_req_buffer(
3134 struct msm_vidc_inst *inst, enum hal_buffer buffer_type)
3135{
3136 int i;
3137
3138 for (i = 0; i < HAL_BUFFER_MAX; i++) {
3139 if (inst->buff_req.buffer[i].buffer_type == buffer_type)
3140 return &inst->buff_req.buffer[i];
3141 }
3142 return NULL;
3143}
3144
3145static int set_output_buffers(struct msm_vidc_inst *inst,
3146 enum hal_buffer buffer_type)
3147{
3148 int rc = 0;
3149 struct msm_smem *handle;
3150 struct internal_buf *binfo;
3151 u32 smem_flags = 0, buffer_size;
3152 struct hal_buffer_requirements *output_buf, *extradata_buf;
3153 int i;
3154 struct hfi_device *hdev;
3155 struct hal_buffer_size_minimum b;
3156
3157 hdev = inst->core->device;
3158
3159 output_buf = get_buff_req_buffer(inst, buffer_type);
3160 if (!output_buf) {
3161 dprintk(VIDC_DBG,
3162 "This output buffer not required, buffer_type: %x\n",
3163 buffer_type);
3164 return 0;
3165 }
3166 dprintk(VIDC_DBG,
3167 "output: num = %d, size = %d\n",
3168 output_buf->buffer_count_actual,
3169 output_buf->buffer_size);
3170
3171 buffer_size = output_buf->buffer_size;
3172 b.buffer_type = buffer_type;
3173 b.buffer_size = buffer_size;
3174 rc = call_hfi_op(hdev, session_set_property,
3175 inst->session, HAL_PARAM_BUFFER_SIZE_MINIMUM,
3176 &b);
3177
3178 extradata_buf = get_buff_req_buffer(inst, HAL_BUFFER_EXTRADATA_OUTPUT);
3179 if (extradata_buf) {
3180 dprintk(VIDC_DBG,
3181 "extradata: num = %d, size = %d\n",
3182 extradata_buf->buffer_count_actual,
3183 extradata_buf->buffer_size);
3184 buffer_size += extradata_buf->buffer_size;
3185 } else {
3186 dprintk(VIDC_DBG,
3187 "This extradata buffer not required, buffer_type: %x\n",
3188 buffer_type);
3189 }
3190
3191 if (inst->flags & VIDC_SECURE)
3192 smem_flags |= SMEM_SECURE;
3193
3194 if (output_buf->buffer_size) {
3195 for (i = 0; i < output_buf->buffer_count_actual;
3196 i++) {
3197 handle = msm_comm_smem_alloc(inst,
3198 buffer_size, 1, smem_flags,
3199 buffer_type, 0);
3200 if (!handle) {
3201 dprintk(VIDC_ERR,
3202 "Failed to allocate output memory\n");
3203 rc = -ENOMEM;
3204 goto err_no_mem;
3205 }
3206 rc = msm_comm_smem_cache_operations(inst,
3207 handle, SMEM_CACHE_CLEAN);
3208 if (rc) {
3209 dprintk(VIDC_WARN,
3210 "Failed to clean cache may cause undefined behavior\n");
3211 }
3212 binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
3213 if (!binfo) {
3214 dprintk(VIDC_ERR, "Out of memory\n");
3215 rc = -ENOMEM;
3216 goto fail_kzalloc;
3217 }
3218
3219 binfo->handle = handle;
3220 binfo->buffer_type = buffer_type;
3221 binfo->buffer_ownership = DRIVER;
3222 dprintk(VIDC_DBG, "Output buffer address: %pa\n",
3223 &handle->device_addr);
3224
3225 if (inst->buffer_mode_set[CAPTURE_PORT] ==
3226 HAL_BUFFER_MODE_STATIC) {
3227 struct vidc_buffer_addr_info buffer_info = {0};
3228
3229 buffer_info.buffer_size =
3230 output_buf->buffer_size;
3231 buffer_info.buffer_type = buffer_type;
3232 buffer_info.num_buffers = 1;
3233 buffer_info.align_device_addr =
3234 handle->device_addr;
3235 buffer_info.extradata_addr =
3236 handle->device_addr +
3237 output_buf->buffer_size;
3238 if (extradata_buf)
3239 buffer_info.extradata_size =
3240 extradata_buf->buffer_size;
3241 rc = call_hfi_op(hdev, session_set_buffers,
3242 (void *) inst->session, &buffer_info);
3243 if (rc) {
3244 dprintk(VIDC_ERR,
3245 "%s : session_set_buffers failed\n",
3246 __func__);
3247 goto fail_set_buffers;
3248 }
3249 }
3250 mutex_lock(&inst->outputbufs.lock);
3251 list_add_tail(&binfo->list, &inst->outputbufs.list);
3252 mutex_unlock(&inst->outputbufs.lock);
3253 }
3254 }
3255 return rc;
3256fail_set_buffers:
3257 kfree(binfo);
3258fail_kzalloc:
3259 msm_comm_smem_free(inst, handle);
3260err_no_mem:
3261 return rc;
3262}
3263
3264static inline char *get_buffer_name(enum hal_buffer buffer_type)
3265{
3266 switch (buffer_type) {
3267 case HAL_BUFFER_INPUT: return "input";
3268 case HAL_BUFFER_OUTPUT: return "output";
3269 case HAL_BUFFER_OUTPUT2: return "output_2";
3270 case HAL_BUFFER_EXTRADATA_INPUT: return "input_extra";
3271 case HAL_BUFFER_EXTRADATA_OUTPUT: return "output_extra";
3272 case HAL_BUFFER_EXTRADATA_OUTPUT2: return "output2_extra";
3273 case HAL_BUFFER_INTERNAL_SCRATCH: return "scratch";
3274 case HAL_BUFFER_INTERNAL_SCRATCH_1: return "scratch_1";
3275 case HAL_BUFFER_INTERNAL_SCRATCH_2: return "scratch_2";
3276 case HAL_BUFFER_INTERNAL_PERSIST: return "persist";
3277 case HAL_BUFFER_INTERNAL_PERSIST_1: return "persist_1";
3278 case HAL_BUFFER_INTERNAL_CMD_QUEUE: return "queue";
3279 default: return "????";
3280 }
3281}
3282
3283static int set_internal_buf_on_fw(struct msm_vidc_inst *inst,
3284 enum hal_buffer buffer_type,
3285 struct msm_smem *handle, bool reuse)
3286{
3287 struct vidc_buffer_addr_info buffer_info;
3288 struct hfi_device *hdev;
3289 int rc = 0;
3290
3291 if (!inst || !inst->core || !inst->core->device || !handle) {
3292 dprintk(VIDC_ERR, "%s - invalid params\n", __func__);
3293 return -EINVAL;
3294 }
3295
3296 hdev = inst->core->device;
3297
3298 rc = msm_comm_smem_cache_operations(inst,
3299 handle, SMEM_CACHE_CLEAN);
3300 if (rc) {
3301 dprintk(VIDC_WARN,
3302 "Failed to clean cache. Undefined behavior\n");
3303 }
3304
3305 buffer_info.buffer_size = handle->size;
3306 buffer_info.buffer_type = buffer_type;
3307 buffer_info.num_buffers = 1;
3308 buffer_info.align_device_addr = handle->device_addr;
3309 dprintk(VIDC_DBG, "%s %s buffer : %pa\n",
3310 reuse ? "Reusing" : "Allocated",
3311 get_buffer_name(buffer_type),
3312 &buffer_info.align_device_addr);
3313
3314 rc = call_hfi_op(hdev, session_set_buffers,
3315 (void *) inst->session, &buffer_info);
3316 if (rc) {
3317 dprintk(VIDC_ERR,
3318 "vidc_hal_session_set_buffers failed\n");
3319 return rc;
3320 }
3321 return 0;
3322}
3323
3324static bool reuse_internal_buffers(struct msm_vidc_inst *inst,
3325 enum hal_buffer buffer_type, struct msm_vidc_list *buf_list)
3326{
3327 struct internal_buf *buf;
3328 int rc = 0;
3329 bool reused = false;
3330
3331 if (!inst || !buf_list) {
3332 dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
3333 return false;
3334 }
3335
3336 mutex_lock(&buf_list->lock);
3337 list_for_each_entry(buf, &buf_list->list, list) {
3338 if (!buf->handle) {
3339 reused = false;
3340 break;
3341 }
3342
3343 if (buf->buffer_type != buffer_type)
3344 continue;
3345
3346 /*
3347 * Persist buffer size won't change with resolution. If they
3348 * are in queue means that they are already allocated and
3349 * given to HW. HW can use them without reallocation. These
3350 * buffers are not released as part of port reconfig. So
3351 * driver no need to set them again.
3352 */
3353
3354 if (buffer_type != HAL_BUFFER_INTERNAL_PERSIST
3355 && buffer_type != HAL_BUFFER_INTERNAL_PERSIST_1) {
3356
3357 rc = set_internal_buf_on_fw(inst, buffer_type,
3358 buf->handle, true);
3359 if (rc) {
3360 dprintk(VIDC_ERR,
3361 "%s: session_set_buffers failed\n",
3362 __func__);
3363 reused = false;
3364 break;
3365 }
3366 }
3367 reused = true;
3368 dprintk(VIDC_DBG,
3369 "Re-using internal buffer type : %d\n", buffer_type);
3370 }
3371 mutex_unlock(&buf_list->lock);
3372 return reused;
3373}
3374
3375static int allocate_and_set_internal_bufs(struct msm_vidc_inst *inst,
3376 struct hal_buffer_requirements *internal_bufreq,
3377 struct msm_vidc_list *buf_list)
3378{
3379 struct msm_smem *handle;
3380 struct internal_buf *binfo;
3381 u32 smem_flags = 0;
3382 int rc = 0;
3383 int i = 0;
3384
3385 if (!inst || !internal_bufreq || !buf_list)
3386 return -EINVAL;
3387
3388 if (!internal_bufreq->buffer_size)
3389 return 0;
3390
3391 if (inst->flags & VIDC_SECURE)
3392 smem_flags |= SMEM_SECURE;
3393
3394 for (i = 0; i < internal_bufreq->buffer_count_actual; i++) {
3395 handle = msm_comm_smem_alloc(inst, internal_bufreq->buffer_size,
3396 1, smem_flags, internal_bufreq->buffer_type, 0);
3397 if (!handle) {
3398 dprintk(VIDC_ERR,
3399 "Failed to allocate scratch memory\n");
3400 rc = -ENOMEM;
3401 goto err_no_mem;
3402 }
3403
3404 binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
3405 if (!binfo) {
3406 dprintk(VIDC_ERR, "Out of memory\n");
3407 rc = -ENOMEM;
3408 goto fail_kzalloc;
3409 }
3410
3411 binfo->handle = handle;
3412 binfo->buffer_type = internal_bufreq->buffer_type;
3413
3414 rc = set_internal_buf_on_fw(inst, internal_bufreq->buffer_type,
3415 handle, false);
3416 if (rc)
3417 goto fail_set_buffers;
3418
3419 mutex_lock(&buf_list->lock);
3420 list_add_tail(&binfo->list, &buf_list->list);
3421 mutex_unlock(&buf_list->lock);
3422 }
3423 return rc;
3424
3425fail_set_buffers:
3426 kfree(binfo);
3427fail_kzalloc:
3428 msm_comm_smem_free(inst, handle);
3429err_no_mem:
3430 return rc;
3431
3432}
3433
3434static int set_internal_buffers(struct msm_vidc_inst *inst,
3435 enum hal_buffer buffer_type, struct msm_vidc_list *buf_list)
3436{
3437 struct hal_buffer_requirements *internal_buf;
3438
3439 internal_buf = get_buff_req_buffer(inst, buffer_type);
3440 if (!internal_buf) {
3441 dprintk(VIDC_DBG,
3442 "This internal buffer not required, buffer_type: %x\n",
3443 buffer_type);
3444 return 0;
3445 }
3446
3447 dprintk(VIDC_DBG, "Buffer type %s: num = %d, size = %d\n",
3448 get_buffer_name(buffer_type),
3449 internal_buf->buffer_count_actual, internal_buf->buffer_size);
3450
3451 /*
3452 * Try reusing existing internal buffers first.
3453 * If it's not possible to reuse, allocate new buffers.
3454 */
3455 if (reuse_internal_buffers(inst, buffer_type, buf_list))
3456 return 0;
3457
3458 return allocate_and_set_internal_bufs(inst, internal_buf,
3459 buf_list);
3460}
3461
3462int msm_comm_try_state(struct msm_vidc_inst *inst, int state)
3463{
3464 int rc = 0;
3465 int flipped_state;
3466 struct msm_vidc_core *core;
3467
3468 if (!inst) {
3469 dprintk(VIDC_ERR,
3470 "Invalid instance pointer = %pK\n", inst);
3471 return -EINVAL;
3472 }
3473 dprintk(VIDC_DBG,
3474 "Trying to move inst: %pK from: %#x to %#x\n",
3475 inst, inst->state, state);
3476 core = inst->core;
3477 if (!core) {
3478 dprintk(VIDC_ERR,
3479 "Invalid core pointer = %pK\n", inst);
3480 return -EINVAL;
3481 }
3482 mutex_lock(&inst->sync_lock);
3483 if (inst->state == MSM_VIDC_CORE_INVALID ||
3484 core->state == VIDC_CORE_INVALID) {
3485 dprintk(VIDC_ERR,
3486 "Core is in bad state can't change the state\n");
3487 rc = -EINVAL;
3488 goto exit;
3489 }
3490 flipped_state = get_flipped_state(inst->state, state);
3491 dprintk(VIDC_DBG,
3492 "flipped_state = %#x\n", flipped_state);
3493 switch (flipped_state) {
3494 case MSM_VIDC_CORE_UNINIT_DONE:
3495 case MSM_VIDC_CORE_INIT:
3496 rc = msm_comm_init_core(inst);
3497 if (rc || state <= get_flipped_state(inst->state, state))
3498 break;
3499 case MSM_VIDC_CORE_INIT_DONE:
3500 rc = msm_comm_init_core_done(inst);
3501 if (rc || state <= get_flipped_state(inst->state, state))
3502 break;
3503 case MSM_VIDC_OPEN:
3504 rc = msm_comm_session_init(flipped_state, inst);
3505 if (rc || state <= get_flipped_state(inst->state, state))
3506 break;
3507 case MSM_VIDC_OPEN_DONE:
3508 rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE,
3509 HAL_SESSION_INIT_DONE);
3510 if (rc || state <= get_flipped_state(inst->state, state))
3511 break;
3512 case MSM_VIDC_LOAD_RESOURCES:
3513 rc = msm_vidc_load_resources(flipped_state, inst);
3514 if (rc || state <= get_flipped_state(inst->state, state))
3515 break;
3516 case MSM_VIDC_LOAD_RESOURCES_DONE:
3517 case MSM_VIDC_START:
3518 rc = msm_vidc_start(flipped_state, inst);
3519 if (rc || state <= get_flipped_state(inst->state, state))
3520 break;
3521 case MSM_VIDC_START_DONE:
3522 rc = wait_for_state(inst, flipped_state, MSM_VIDC_START_DONE,
3523 HAL_SESSION_START_DONE);
3524 if (rc || state <= get_flipped_state(inst->state, state))
3525 break;
3526 case MSM_VIDC_STOP:
3527 rc = msm_vidc_stop(flipped_state, inst);
3528 if (rc || state <= get_flipped_state(inst->state, state))
3529 break;
3530 case MSM_VIDC_STOP_DONE:
3531 rc = wait_for_state(inst, flipped_state, MSM_VIDC_STOP_DONE,
3532 HAL_SESSION_STOP_DONE);
3533 if (rc || state <= get_flipped_state(inst->state, state))
3534 break;
3535 dprintk(VIDC_DBG, "Moving to Stop Done state\n");
3536 case MSM_VIDC_RELEASE_RESOURCES:
3537 rc = msm_vidc_release_res(flipped_state, inst);
3538 if (rc || state <= get_flipped_state(inst->state, state))
3539 break;
3540 case MSM_VIDC_RELEASE_RESOURCES_DONE:
3541 rc = wait_for_state(inst, flipped_state,
3542 MSM_VIDC_RELEASE_RESOURCES_DONE,
3543 HAL_SESSION_RELEASE_RESOURCE_DONE);
3544 if (rc || state <= get_flipped_state(inst->state, state))
3545 break;
3546 dprintk(VIDC_DBG,
3547 "Moving to release resources done state\n");
3548 case MSM_VIDC_CLOSE:
3549 rc = msm_comm_session_close(flipped_state, inst);
3550 if (rc || state <= get_flipped_state(inst->state, state))
3551 break;
3552 case MSM_VIDC_CLOSE_DONE:
3553 rc = wait_for_state(inst, flipped_state, MSM_VIDC_CLOSE_DONE,
3554 HAL_SESSION_END_DONE);
3555 if (rc || state <= get_flipped_state(inst->state, state))
3556 break;
3557 msm_comm_session_clean(inst);
3558 case MSM_VIDC_CORE_UNINIT:
3559 case MSM_VIDC_CORE_INVALID:
3560 dprintk(VIDC_DBG, "Sending core uninit\n");
3561 rc = msm_vidc_deinit_core(inst);
3562 if (rc || state == get_flipped_state(inst->state, state))
3563 break;
3564 default:
3565 dprintk(VIDC_ERR, "State not recognized\n");
3566 rc = -EINVAL;
3567 break;
3568 }
3569exit:
3570 mutex_unlock(&inst->sync_lock);
3571 if (rc)
3572 dprintk(VIDC_ERR,
3573 "Failed to move from state: %d to %d\n",
3574 inst->state, state);
3575 else
3576 trace_msm_vidc_common_state_change((void *)inst,
3577 inst->state, state);
3578 return rc;
3579}
3580
3581int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd)
3582{
3583 struct msm_vidc_inst *inst = instance;
3584 struct v4l2_decoder_cmd *dec = NULL;
3585 struct v4l2_encoder_cmd *enc = NULL;
3586 struct msm_vidc_core *core;
3587 int which_cmd = 0, flags = 0, rc = 0;
3588
3589 if (!inst || !inst->core || !cmd) {
3590 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
3591 return -EINVAL;
3592 }
3593 core = inst->core;
3594 if (inst->session_type == MSM_VIDC_ENCODER) {
3595 enc = (struct v4l2_encoder_cmd *)cmd;
3596 which_cmd = enc->cmd;
3597 flags = enc->flags;
3598 } else if (inst->session_type == MSM_VIDC_DECODER) {
3599 dec = (struct v4l2_decoder_cmd *)cmd;
3600 which_cmd = dec->cmd;
3601 flags = dec->flags;
3602 }
3603
3604
3605 switch (which_cmd) {
3606 case V4L2_QCOM_CMD_FLUSH:
3607 if (core->state != VIDC_CORE_INVALID &&
3608 inst->state == MSM_VIDC_CORE_INVALID) {
3609 rc = msm_comm_kill_session(inst);
3610 if (rc)
3611 dprintk(VIDC_ERR,
3612 "Fail to clean session: %d\n",
3613 rc);
3614 }
3615 rc = msm_comm_flush(inst, flags);
3616 if (rc) {
3617 dprintk(VIDC_ERR,
3618 "Failed to flush buffers: %d\n", rc);
3619 }
3620 break;
3621 case V4L2_DEC_QCOM_CMD_RECONFIG_HINT:
3622 {
3623 u32 *ptr = NULL;
3624 struct hal_buffer_requirements *output_buf;
3625
3626 rc = msm_comm_try_get_bufreqs(inst);
3627 if (rc) {
3628 dprintk(VIDC_ERR,
3629 "Getting buffer requirements failed: %d\n",
3630 rc);
3631 break;
3632 }
3633
3634 output_buf = get_buff_req_buffer(inst,
3635 msm_comm_get_hal_output_buffer(inst));
3636 if (output_buf) {
3637 if (dec) {
3638 ptr = (u32 *)dec->raw.data;
3639 ptr[0] = output_buf->buffer_size;
3640 ptr[1] = output_buf->buffer_count_actual;
3641 dprintk(VIDC_DBG,
3642 "Reconfig hint, size is %u, count is %u\n",
3643 ptr[0], ptr[1]);
3644 } else {
3645 dprintk(VIDC_ERR, "Null decoder\n");
3646 }
3647 } else {
3648 dprintk(VIDC_DBG,
3649 "This output buffer not required, buffer_type: %x\n",
3650 HAL_BUFFER_OUTPUT);
3651 }
3652 break;
3653 }
3654 default:
3655 dprintk(VIDC_ERR, "Unknown Command %d\n", which_cmd);
3656 rc = -ENOTSUPP;
3657 break;
3658 }
3659 return rc;
3660}
3661
3662static void populate_frame_data(struct vidc_frame_data *data,
3663 const struct vb2_buffer *vb, struct msm_vidc_inst *inst)
3664{
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07003665 u64 time_usec;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003666 int extra_idx;
3667 enum v4l2_buf_type type = vb->type;
3668 enum vidc_ports port = type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
3669 OUTPUT_PORT : CAPTURE_PORT;
3670 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
3671
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07003672 time_usec = vb->timestamp;
3673 do_div(time_usec, NSEC_PER_USEC);
3674
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003675 data->alloc_len = vb->planes[0].length;
3676 data->device_addr = vb->planes[0].m.userptr;
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07003677 data->timestamp = time_usec;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003678 data->flags = 0;
3679 data->clnt_data = data->device_addr;
3680
3681 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
3682 bool pic_decoding_mode = msm_comm_g_ctrl_for_id(inst,
3683 V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE);
3684
3685 data->buffer_type = HAL_BUFFER_INPUT;
3686 data->filled_len = vb->planes[0].bytesused;
3687 data->offset = vb->planes[0].data_offset;
3688
3689 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_EOS)
3690 data->flags |= HAL_BUFFERFLAG_EOS;
3691
3692 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
3693 data->flags |= HAL_BUFFERFLAG_CODECCONFIG;
3694
3695 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY)
3696 data->flags |= HAL_BUFFERFLAG_DECODEONLY;
3697
3698 if (vbuf->flags & V4L2_QCOM_BUF_TIMESTAMP_INVALID)
3699 data->timestamp = LLONG_MAX;
3700
3701 /* XXX: This is a dirty hack necessitated by the firmware,
3702 * which refuses to issue FBDs for non I-frames in Picture Type
3703 * Decoding mode, unless we pass in non-zero value in mark_data
3704 * and mark_target.
3705 */
3706 data->mark_data = data->mark_target =
3707 pic_decoding_mode ? 0xdeadbeef : 0;
3708
3709 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
3710 data->buffer_type = msm_comm_get_hal_output_buffer(inst);
3711 }
3712
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08003713 extra_idx = EXTRADATA_IDX(inst->bufq[port].num_planes);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003714 if (extra_idx && extra_idx < VIDEO_MAX_PLANES &&
3715 vb->planes[extra_idx].m.userptr) {
3716 data->extradata_addr = vb->planes[extra_idx].m.userptr;
3717 data->extradata_size = vb->planes[extra_idx].length;
3718 data->flags |= HAL_BUFFERFLAG_EXTRADATA;
3719 }
3720}
3721
3722static unsigned int count_single_batch(struct msm_vidc_list *list,
3723 enum v4l2_buf_type type)
3724{
3725 struct vb2_buf_entry *buf;
3726 int count = 0;
3727 struct vb2_v4l2_buffer *vbuf = NULL;
3728
3729 mutex_lock(&list->lock);
3730 list_for_each_entry(buf, &list->list, list) {
3731 if (buf->vb->type != type)
3732 continue;
3733
3734 ++count;
3735
3736 vbuf = to_vb2_v4l2_buffer(buf->vb);
3737 if (!(vbuf->flags & V4L2_MSM_BUF_FLAG_DEFER))
3738 goto found_batch;
3739 }
3740 /* don't have a full batch */
3741 count = 0;
3742
3743found_batch:
3744 mutex_unlock(&list->lock);
3745 return count;
3746}
3747
3748static unsigned int count_buffers(struct msm_vidc_list *list,
3749 enum v4l2_buf_type type)
3750{
3751 struct vb2_buf_entry *buf;
3752 int count = 0;
3753
3754 mutex_lock(&list->lock);
3755 list_for_each_entry(buf, &list->list, list) {
3756 if (buf->vb->type != type)
3757 continue;
3758
3759 ++count;
3760 }
3761 mutex_unlock(&list->lock);
3762
3763 return count;
3764}
3765
3766static void log_frame(struct msm_vidc_inst *inst, struct vidc_frame_data *data,
3767 enum v4l2_buf_type type)
3768{
Praneeth Paladugub71968b2015-08-19 20:47:57 -07003769
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003770 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
3771 dprintk(VIDC_DBG,
3772 "Sending etb (%pa) to hal: filled: %d, ts: %lld, flags = %#x\n",
3773 &data->device_addr, data->filled_len,
3774 data->timestamp, data->flags);
3775 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_ETB);
3776
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003777 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
3778 dprintk(VIDC_DBG,
3779 "Sending ftb (%pa) to hal: size: %d, ts: %lld, flags = %#x\n",
3780 &data->device_addr, data->alloc_len,
3781 data->timestamp, data->flags);
3782 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FTB);
3783 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003784}
3785
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003786/*
3787 * Attempts to queue `vb` to hardware. If, for various reasons, the buffer
3788 * cannot be queued to hardware, the buffer will be staged for commit in the
3789 * pending queue. Once the hardware reaches a good state (or if `vb` is NULL,
3790 * the subsequent *_qbuf will commit the previously staged buffers to hardware.
3791 */
3792int msm_comm_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb)
3793{
3794 int rc = 0, capture_count, output_count;
3795 struct msm_vidc_core *core;
3796 struct hfi_device *hdev;
3797 struct {
3798 struct vidc_frame_data *data;
3799 int count;
3800 } etbs, ftbs;
3801 bool defer = false, batch_mode;
3802 struct vb2_buf_entry *temp, *next;
3803 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
3804
3805 if (!inst) {
3806 dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__);
3807 return -EINVAL;
3808 }
3809
3810 core = inst->core;
3811 hdev = core->device;
3812
3813 if (inst->state == MSM_VIDC_CORE_INVALID ||
3814 core->state == VIDC_CORE_INVALID ||
3815 core->state == VIDC_CORE_UNINIT) {
3816 dprintk(VIDC_ERR, "Core is in bad state. Can't Queue\n");
3817 return -EINVAL;
3818 }
3819
3820 /*
3821 * Stick the buffer into the pendinq, we'll pop it out later on
3822 * if we want to commit it to hardware
3823 */
3824 if (vb) {
3825 temp = kzalloc(sizeof(*temp), GFP_KERNEL);
3826 if (!temp) {
3827 dprintk(VIDC_ERR, "Out of memory\n");
3828 goto err_no_mem;
3829 }
3830
3831 temp->vb = vb;
3832 mutex_lock(&inst->pendingq.lock);
3833 list_add_tail(&temp->list, &inst->pendingq.list);
3834 mutex_unlock(&inst->pendingq.lock);
3835 }
3836
3837 batch_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_VIDC_QBUF_MODE)
3838 == V4L2_VIDC_QBUF_BATCHED;
3839 capture_count = (batch_mode ? &count_single_batch : &count_buffers)
3840 (&inst->pendingq, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
3841 output_count = (batch_mode ? &count_single_batch : &count_buffers)
3842 (&inst->pendingq, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
3843
3844 /*
3845 * Somewhat complicated logic to prevent queuing the buffer to hardware.
3846 * Don't queue if:
3847 * 1) Hardware isn't ready (that's simple)
3848 */
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07003849 defer = defer ? defer : (inst->state != MSM_VIDC_START_DONE);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003850
3851 /*
3852 * 2) The client explicitly tells us not to because it wants this
3853 * buffer to be batched with future frames. The batch size (on both
3854 * capabilities) is completely determined by the client.
3855 */
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07003856 defer = defer ? defer : (vbuf && vbuf->flags & V4L2_MSM_BUF_FLAG_DEFER);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003857
3858 /* 3) If we're in batch mode, we must have full batches of both types */
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07003859 defer = defer ? defer:(batch_mode && (!output_count || !capture_count));
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003860
3861 if (defer) {
3862 dprintk(VIDC_DBG, "Deferring queue of %pK\n", vb);
3863 return 0;
3864 }
3865
Praneeth Paladugub71968b2015-08-19 20:47:57 -07003866 rc = msm_comm_scale_clocks_and_bus(inst);
3867
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003868 dprintk(VIDC_DBG, "%sing %d etbs and %d ftbs\n",
3869 batch_mode ? "Batch" : "Process",
3870 output_count, capture_count);
3871
3872 etbs.data = kcalloc(output_count, sizeof(*etbs.data), GFP_KERNEL);
3873 ftbs.data = kcalloc(capture_count, sizeof(*ftbs.data), GFP_KERNEL);
3874 /*
3875 * Note that it's perfectly normal for (e|f)tbs.data to be NULL if
3876 * we're not in batch mode (i.e. (output|capture)_count == 0)
3877 */
3878 if ((!etbs.data && output_count) ||
3879 (!ftbs.data && capture_count)) {
3880 dprintk(VIDC_ERR, "Failed to alloc memory for batching\n");
3881 kfree(etbs.data);
3882 etbs.data = NULL;
3883
3884 kfree(ftbs.data);
3885 ftbs.data = NULL;
3886 goto err_no_mem;
3887 }
3888
3889 etbs.count = ftbs.count = 0;
3890
3891 /*
3892 * Try to collect all pending buffers into 2 batches of ftb and etb
3893 * Note that these "batches" might be empty if we're no in batching mode
3894 * and the pendingq is empty
3895 */
3896 mutex_lock(&inst->pendingq.lock);
3897 list_for_each_entry_safe(temp, next, &inst->pendingq.list, list) {
3898 struct vidc_frame_data *frame_data = NULL;
3899
3900 switch (temp->vb->type) {
3901 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
3902 if (ftbs.count < capture_count && ftbs.data)
3903 frame_data = &ftbs.data[ftbs.count++];
3904 break;
3905 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
3906 if (etbs.count < output_count && etbs.data)
3907 frame_data = &etbs.data[etbs.count++];
3908 break;
3909 default:
3910 break;
3911 }
3912
3913 if (!frame_data)
3914 continue;
3915
3916 populate_frame_data(frame_data, temp->vb, inst);
3917
3918 list_del(&temp->list);
3919 kfree(temp);
3920 }
3921 mutex_unlock(&inst->pendingq.lock);
3922
3923 /* Finally commit all our frame(s) to H/W */
3924 if (batch_mode) {
3925 int ftb_index = 0, c = 0;
3926
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003927 ftb_index = c;
3928 rc = call_hfi_op(hdev, session_process_batch, inst->session,
3929 etbs.count, etbs.data,
3930 ftbs.count - ftb_index, &ftbs.data[ftb_index]);
3931 if (rc) {
3932 dprintk(VIDC_ERR,
3933 "Failed to queue batch of %d ETBs and %d FTBs\n",
3934 etbs.count, ftbs.count);
3935 goto err_bad_input;
3936 }
3937
3938 for (c = ftb_index; c < ftbs.count; ++c) {
3939 log_frame(inst, &ftbs.data[c],
3940 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
3941 }
3942
3943 for (c = 0; c < etbs.count; ++c) {
3944 log_frame(inst, &etbs.data[c],
3945 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
3946 }
3947 }
3948
3949 if (!batch_mode && etbs.count) {
3950 int c = 0;
3951
3952 for (c = 0; c < etbs.count; ++c) {
3953 struct vidc_frame_data *frame_data = &etbs.data[c];
3954
3955 rc = call_hfi_op(hdev, session_etb, inst->session,
3956 frame_data);
3957 if (rc) {
3958 dprintk(VIDC_ERR, "Failed to issue etb: %d\n",
3959 rc);
3960 goto err_bad_input;
3961 }
3962
3963 log_frame(inst, frame_data,
3964 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
3965 }
3966 }
3967
3968 if (!batch_mode && ftbs.count) {
3969 int c = 0;
3970
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003971 for (; c < ftbs.count; ++c) {
3972 struct vidc_frame_data *frame_data = &ftbs.data[c];
3973
3974 rc = call_hfi_op(hdev, session_ftb,
3975 inst->session, frame_data);
3976 if (rc) {
3977 dprintk(VIDC_ERR, "Failed to issue ftb: %d\n",
3978 rc);
3979 goto err_bad_input;
3980 }
3981
3982 log_frame(inst, frame_data,
3983 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
3984 }
3985 }
3986
3987err_bad_input:
3988 if (rc)
3989 dprintk(VIDC_ERR, "Failed to queue buffer\n");
3990
3991 kfree(etbs.data);
3992 kfree(ftbs.data);
3993err_no_mem:
3994 return rc;
3995}
3996
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07003997static int msm_vidc_update_host_buff_counts(struct msm_vidc_inst *inst)
3998{
3999 int extra_buffers, buffer_type;
4000 struct hal_buffer_requirements *bufreq;
4001
4002 bufreq = get_buff_req_buffer(inst,
4003 HAL_BUFFER_INPUT);
4004 if (!bufreq) {
4005 dprintk(VIDC_ERR,
4006 "Failed : No buffer requirements : %x\n",
4007 HAL_BUFFER_INPUT);
4008 return -EINVAL;
4009 }
4010 extra_buffers = msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_INPUT);
4011
4012 bufreq->buffer_count_min_host = bufreq->buffer_count_min +
4013 extra_buffers;
4014
4015 buffer_type = msm_comm_get_hal_output_buffer(inst);
4016 bufreq = get_buff_req_buffer(inst,
4017 buffer_type);
4018 if (!bufreq) {
4019 dprintk(VIDC_ERR,
4020 "Failed : No buffer requirements : %x\n",
4021 buffer_type);
4022 return -EINVAL;
4023 }
4024
4025 extra_buffers = msm_vidc_get_extra_buff_count(inst, buffer_type);
4026
4027 bufreq->buffer_count_min_host = bufreq->buffer_count_min +
4028 extra_buffers;
4029
4030 return 0;
4031}
4032
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004033int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst)
4034{
4035 int rc = 0, i = 0;
4036 union hal_get_property hprop;
4037
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07004038 memset(&hprop, 0x0, sizeof(hprop));
4039
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004040 rc = msm_comm_try_get_prop(inst, HAL_PARAM_GET_BUFFER_REQUIREMENTS,
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07004041 &hprop);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004042 if (rc) {
4043 dprintk(VIDC_ERR, "Failed getting buffer requirements: %d", rc);
4044 return rc;
4045 }
4046
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07004047 dprintk(VIDC_DBG, "Buffer requirements from HW:\n");
4048 dprintk(VIDC_DBG, "%15s %8s %8s %8s %8s\n",
4049 "buffer type", "count", "mincount_host", "mincount_fw", "size");
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004050 for (i = 0; i < HAL_BUFFER_MAX; i++) {
4051 struct hal_buffer_requirements req = hprop.buf_req.buffer[i];
4052
4053 inst->buff_req.buffer[i] = req;
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07004054 if (req.buffer_type != HAL_BUFFER_NONE) {
4055 dprintk(VIDC_DBG, "%15s %8d %8d %8d %8d\n",
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004056 get_buffer_name(req.buffer_type),
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07004057 req.buffer_count_actual,
4058 req.buffer_count_min_host,
4059 req.buffer_count_min, req.buffer_size);
4060 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004061 }
4062
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07004063 rc = msm_vidc_update_host_buff_counts(inst);
4064
4065 dprintk(VIDC_DBG, "Buffer requirements host adjusted:\n");
4066 dprintk(VIDC_DBG, "%15s %8s %8s %8s %8s\n",
4067 "buffer type", "count", "mincount_host", "mincount_fw", "size");
4068 for (i = 0; i < HAL_BUFFER_MAX; i++) {
4069 struct hal_buffer_requirements req = hprop.buf_req.buffer[i];
4070
4071 inst->buff_req.buffer[i] = req;
4072 if (req.buffer_type != HAL_BUFFER_NONE) {
4073 dprintk(VIDC_DBG, "%15s %8d %8d %8d %8d\n",
4074 get_buffer_name(req.buffer_type),
4075 req.buffer_count_actual,
4076 req.buffer_count_min_host,
4077 req.buffer_count_min, req.buffer_size);
4078 }
4079 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004080 return rc;
4081}
4082
4083int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
4084 union hal_get_property *hprop)
4085{
4086 int rc = 0;
4087 struct hfi_device *hdev;
4088 struct getprop_buf *buf;
4089
4090 if (!inst || !inst->core || !inst->core->device) {
4091 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4092 return -EINVAL;
4093 }
4094
4095 hdev = inst->core->device;
4096 mutex_lock(&inst->sync_lock);
4097 if (inst->state < MSM_VIDC_OPEN_DONE ||
4098 inst->state >= MSM_VIDC_CLOSE) {
4099
4100 /* No need to check inst->state == MSM_VIDC_INVALID since
4101 * INVALID is > CLOSE_DONE. When core went to INVALID state,
4102 * we put all the active instances in INVALID. So > CLOSE_DONE
4103 * is enough check to have.
4104 */
4105
4106 dprintk(VIDC_ERR,
4107 "In Wrong state to call Buf Req: Inst %pK or Core %pK\n",
4108 inst, inst->core);
4109 rc = -EAGAIN;
4110 mutex_unlock(&inst->sync_lock);
4111 goto exit;
4112 }
4113 mutex_unlock(&inst->sync_lock);
4114
4115 switch (ptype) {
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004116 case HAL_PARAM_GET_BUFFER_REQUIREMENTS:
4117 rc = call_hfi_op(hdev, session_get_buf_req, inst->session);
4118 break;
4119 default:
4120 rc = -EAGAIN;
4121 break;
4122 }
4123
4124 if (rc) {
4125 dprintk(VIDC_ERR, "Can't query hardware for property: %d\n",
4126 rc);
4127 goto exit;
4128 }
4129
4130 rc = wait_for_completion_timeout(&inst->completions[
4131 SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO)],
4132 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
4133 if (!rc) {
4134 dprintk(VIDC_ERR,
4135 "%s: Wait interrupted or timed out [%pK]: %d\n",
4136 __func__, inst,
4137 SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO));
4138 inst->state = MSM_VIDC_CORE_INVALID;
4139 msm_comm_kill_session(inst);
4140 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
4141 dprintk(VIDC_ERR,
4142 "SESS_PROP timeout can potentially crash the system\n");
4143 if (inst->core->resources.debug_timeout)
4144 msm_comm_print_debug_info(inst);
4145
4146 msm_vidc_handle_hw_error(inst->core);
4147 rc = -ETIMEDOUT;
4148 goto exit;
4149 } else {
4150 /* wait_for_completion_timeout returns jiffies before expiry */
4151 rc = 0;
4152 }
4153
4154 mutex_lock(&inst->pending_getpropq.lock);
4155 if (!list_empty(&inst->pending_getpropq.list)) {
4156 buf = list_first_entry(&inst->pending_getpropq.list,
4157 struct getprop_buf, list);
4158 *hprop = *(union hal_get_property *)buf->data;
4159 kfree(buf->data);
4160 list_del(&buf->list);
4161 kfree(buf);
4162 } else {
4163 dprintk(VIDC_ERR, "%s getprop list empty\n", __func__);
4164 rc = -EINVAL;
4165 }
4166 mutex_unlock(&inst->pending_getpropq.lock);
4167exit:
4168 return rc;
4169}
4170
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004171int msm_comm_release_output_buffers(struct msm_vidc_inst *inst,
4172 bool force_release)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004173{
4174 struct msm_smem *handle;
4175 struct internal_buf *buf, *dummy;
4176 struct vidc_buffer_addr_info buffer_info;
4177 int rc = 0;
4178 struct msm_vidc_core *core;
4179 struct hfi_device *hdev;
4180
4181 if (!inst) {
4182 dprintk(VIDC_ERR,
4183 "Invalid instance pointer = %pK\n", inst);
4184 return -EINVAL;
4185 }
4186 mutex_lock(&inst->outputbufs.lock);
4187 if (list_empty(&inst->outputbufs.list)) {
4188 dprintk(VIDC_DBG, "%s - No OUTPUT buffers allocated\n",
4189 __func__);
4190 mutex_unlock(&inst->outputbufs.lock);
4191 return 0;
4192 }
4193 mutex_unlock(&inst->outputbufs.lock);
4194
4195 core = inst->core;
4196 if (!core) {
4197 dprintk(VIDC_ERR,
4198 "Invalid core pointer = %pK\n", core);
4199 return -EINVAL;
4200 }
4201 hdev = core->device;
4202 if (!hdev) {
4203 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4204 return -EINVAL;
4205 }
4206 mutex_lock(&inst->outputbufs.lock);
4207 list_for_each_entry_safe(buf, dummy, &inst->outputbufs.list, list) {
4208 handle = buf->handle;
4209 if (!handle) {
4210 dprintk(VIDC_ERR, "%s - invalid handle\n", __func__);
4211 goto exit;
4212 }
4213
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004214 if ((buf->buffer_ownership == FIRMWARE) && !force_release) {
4215 dprintk(VIDC_INFO, "DPB is with f/w. Can't free it\n");
4216 continue;
4217 }
4218
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004219 buffer_info.buffer_size = handle->size;
4220 buffer_info.buffer_type = buf->buffer_type;
4221 buffer_info.num_buffers = 1;
4222 buffer_info.align_device_addr = handle->device_addr;
4223 if (inst->buffer_mode_set[CAPTURE_PORT] ==
4224 HAL_BUFFER_MODE_STATIC &&
4225 inst->state != MSM_VIDC_CORE_INVALID &&
4226 core->state != VIDC_CORE_INVALID) {
4227 buffer_info.response_required = false;
4228 rc = call_hfi_op(hdev, session_release_buffers,
4229 (void *)inst->session, &buffer_info);
4230 if (rc) {
4231 dprintk(VIDC_WARN,
4232 "Rel output buf fail:%pa, %d\n",
4233 &buffer_info.align_device_addr,
4234 buffer_info.buffer_size);
4235 }
4236 }
4237
4238 list_del(&buf->list);
4239 msm_comm_smem_free(inst, buf->handle);
4240 kfree(buf);
4241 }
4242
4243exit:
4244 mutex_unlock(&inst->outputbufs.lock);
4245 return rc;
4246}
4247
4248static enum hal_buffer scratch_buf_sufficient(struct msm_vidc_inst *inst,
4249 enum hal_buffer buffer_type)
4250{
4251 struct hal_buffer_requirements *bufreq = NULL;
4252 struct internal_buf *buf;
4253 int count = 0;
4254
4255 if (!inst) {
4256 dprintk(VIDC_ERR, "%s - invalid param\n", __func__);
4257 goto not_sufficient;
4258 }
4259
4260 bufreq = get_buff_req_buffer(inst, buffer_type);
4261 if (!bufreq)
4262 goto not_sufficient;
4263
4264 /* Check if current scratch buffers are sufficient */
4265 mutex_lock(&inst->scratchbufs.lock);
4266
4267 list_for_each_entry(buf, &inst->scratchbufs.list, list) {
4268 if (!buf->handle) {
4269 dprintk(VIDC_ERR, "%s: invalid buf handle\n", __func__);
4270 mutex_unlock(&inst->scratchbufs.lock);
4271 goto not_sufficient;
4272 }
4273 if (buf->buffer_type == buffer_type &&
4274 buf->handle->size >= bufreq->buffer_size)
4275 count++;
4276 }
4277 mutex_unlock(&inst->scratchbufs.lock);
4278
4279 if (count != bufreq->buffer_count_actual)
4280 goto not_sufficient;
4281
4282 dprintk(VIDC_DBG,
4283 "Existing scratch buffer is sufficient for buffer type %#x\n",
4284 buffer_type);
4285
4286 return buffer_type;
4287
4288not_sufficient:
4289 return HAL_BUFFER_NONE;
4290}
4291
4292int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst,
4293 bool check_for_reuse)
4294{
4295 struct msm_smem *handle;
4296 struct internal_buf *buf, *dummy;
4297 struct vidc_buffer_addr_info buffer_info;
4298 int rc = 0;
4299 struct msm_vidc_core *core;
4300 struct hfi_device *hdev;
4301 enum hal_buffer sufficiency = HAL_BUFFER_NONE;
4302
4303 if (!inst) {
4304 dprintk(VIDC_ERR,
4305 "Invalid instance pointer = %pK\n", inst);
4306 return -EINVAL;
4307 }
4308 core = inst->core;
4309 if (!core) {
4310 dprintk(VIDC_ERR,
4311 "Invalid core pointer = %pK\n", core);
4312 return -EINVAL;
4313 }
4314 hdev = core->device;
4315 if (!hdev) {
4316 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4317 return -EINVAL;
4318 }
4319
4320 if (check_for_reuse) {
4321 sufficiency |= scratch_buf_sufficient(inst,
4322 HAL_BUFFER_INTERNAL_SCRATCH);
4323
4324 sufficiency |= scratch_buf_sufficient(inst,
4325 HAL_BUFFER_INTERNAL_SCRATCH_1);
4326
4327 sufficiency |= scratch_buf_sufficient(inst,
4328 HAL_BUFFER_INTERNAL_SCRATCH_2);
4329 }
4330
4331 mutex_lock(&inst->scratchbufs.lock);
4332 list_for_each_entry_safe(buf, dummy, &inst->scratchbufs.list, list) {
4333 if (!buf->handle) {
4334 dprintk(VIDC_ERR, "%s - buf->handle NULL\n", __func__);
4335 rc = -EINVAL;
4336 goto exit;
4337 }
4338
4339 handle = buf->handle;
4340 buffer_info.buffer_size = handle->size;
4341 buffer_info.buffer_type = buf->buffer_type;
4342 buffer_info.num_buffers = 1;
4343 buffer_info.align_device_addr = handle->device_addr;
4344 if (inst->state != MSM_VIDC_CORE_INVALID &&
4345 core->state != VIDC_CORE_INVALID) {
4346 buffer_info.response_required = true;
4347 rc = call_hfi_op(hdev, session_release_buffers,
4348 (void *)inst->session, &buffer_info);
4349 if (rc) {
4350 dprintk(VIDC_WARN,
4351 "Rel scrtch buf fail:%pa, %d\n",
4352 &buffer_info.align_device_addr,
4353 buffer_info.buffer_size);
4354 }
4355 mutex_unlock(&inst->scratchbufs.lock);
4356 rc = wait_for_sess_signal_receipt(inst,
4357 HAL_SESSION_RELEASE_BUFFER_DONE);
4358 if (rc) {
4359 change_inst_state(inst,
4360 MSM_VIDC_CORE_INVALID);
4361 msm_comm_kill_session(inst);
4362 }
4363 mutex_lock(&inst->scratchbufs.lock);
4364 }
4365
4366 /*If scratch buffers can be reused, do not free the buffers*/
4367 if (sufficiency & buf->buffer_type)
4368 continue;
4369
4370 list_del(&buf->list);
4371 msm_comm_smem_free(inst, buf->handle);
4372 kfree(buf);
4373 }
4374
4375exit:
4376 mutex_unlock(&inst->scratchbufs.lock);
4377 return rc;
4378}
4379
4380int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst)
4381{
4382 struct msm_smem *handle;
4383 struct list_head *ptr, *next;
4384 struct internal_buf *buf;
4385 struct vidc_buffer_addr_info buffer_info;
4386 int rc = 0;
4387 struct msm_vidc_core *core;
4388 struct hfi_device *hdev;
4389
4390 if (!inst) {
4391 dprintk(VIDC_ERR,
4392 "Invalid instance pointer = %pK\n", inst);
4393 return -EINVAL;
4394 }
4395 core = inst->core;
4396 if (!core) {
4397 dprintk(VIDC_ERR,
4398 "Invalid core pointer = %pK\n", core);
4399 return -EINVAL;
4400 }
4401 hdev = core->device;
4402 if (!hdev) {
4403 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4404 return -EINVAL;
4405 }
4406
4407 mutex_lock(&inst->persistbufs.lock);
4408 list_for_each_safe(ptr, next, &inst->persistbufs.list) {
4409 buf = list_entry(ptr, struct internal_buf, list);
4410 handle = buf->handle;
4411 buffer_info.buffer_size = handle->size;
4412 buffer_info.buffer_type = buf->buffer_type;
4413 buffer_info.num_buffers = 1;
4414 buffer_info.align_device_addr = handle->device_addr;
4415 if (inst->state != MSM_VIDC_CORE_INVALID &&
4416 core->state != VIDC_CORE_INVALID) {
4417 buffer_info.response_required = true;
4418 rc = call_hfi_op(hdev, session_release_buffers,
4419 (void *)inst->session, &buffer_info);
4420 if (rc) {
4421 dprintk(VIDC_WARN,
4422 "Rel prst buf fail:%pa, %d\n",
4423 &buffer_info.align_device_addr,
4424 buffer_info.buffer_size);
4425 }
4426 mutex_unlock(&inst->persistbufs.lock);
4427 rc = wait_for_sess_signal_receipt(inst,
4428 HAL_SESSION_RELEASE_BUFFER_DONE);
4429 if (rc) {
4430 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
4431 msm_comm_kill_session(inst);
4432 }
4433 mutex_lock(&inst->persistbufs.lock);
4434 }
4435 list_del(&buf->list);
4436 msm_comm_smem_free(inst, buf->handle);
4437 kfree(buf);
4438 }
4439 mutex_unlock(&inst->persistbufs.lock);
4440 return rc;
4441}
4442
4443int msm_comm_try_set_prop(struct msm_vidc_inst *inst,
4444 enum hal_property ptype, void *pdata)
4445{
4446 int rc = 0;
4447 struct hfi_device *hdev;
4448
4449 if (!inst) {
4450 dprintk(VIDC_ERR, "Invalid input: %pK\n", inst);
4451 return -EINVAL;
4452 }
4453
4454 if (!inst->core || !inst->core->device) {
4455 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4456 return -EINVAL;
4457 }
4458 hdev = inst->core->device;
4459
4460 mutex_lock(&inst->sync_lock);
4461 if (inst->state < MSM_VIDC_OPEN_DONE || inst->state >= MSM_VIDC_CLOSE) {
4462 dprintk(VIDC_ERR, "Not in proper state to set property\n");
4463 rc = -EAGAIN;
4464 goto exit;
4465 }
4466 rc = call_hfi_op(hdev, session_set_property, (void *)inst->session,
4467 ptype, pdata);
4468 if (rc)
4469 dprintk(VIDC_ERR, "Failed to set hal property for framesize\n");
4470exit:
4471 mutex_unlock(&inst->sync_lock);
4472 return rc;
4473}
4474
4475int msm_comm_set_output_buffers(struct msm_vidc_inst *inst)
4476{
4477 int rc = 0;
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004478 bool force_release = true;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004479
4480 if (!inst || !inst->core || !inst->core->device) {
4481 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4482 return -EINVAL;
4483 }
4484
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004485 if (inst->fmts[OUTPUT_PORT].defer_outputs)
4486 force_release = false;
4487
4488 if (msm_comm_release_output_buffers(inst, force_release))
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004489 dprintk(VIDC_WARN, "Failed to release output buffers\n");
4490
4491 rc = set_output_buffers(inst, HAL_BUFFER_OUTPUT);
4492 if (rc)
4493 goto error;
4494 return rc;
4495error:
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004496 msm_comm_release_output_buffers(inst, true);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004497 return rc;
4498}
4499
4500int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst)
4501{
4502 int rc = 0;
4503
4504 if (!inst || !inst->core || !inst->core->device) {
4505 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4506 return -EINVAL;
4507 }
4508
4509 if (msm_comm_release_scratch_buffers(inst, true))
4510 dprintk(VIDC_WARN, "Failed to release scratch buffers\n");
4511
4512 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH,
4513 &inst->scratchbufs);
4514 if (rc)
4515 goto error;
4516
4517 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_1,
4518 &inst->scratchbufs);
4519 if (rc)
4520 goto error;
4521
4522 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_2,
4523 &inst->scratchbufs);
4524 if (rc)
4525 goto error;
4526
4527 return rc;
4528error:
4529 msm_comm_release_scratch_buffers(inst, false);
4530 return rc;
4531}
4532
4533int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst)
4534{
4535 int rc = 0;
4536
4537 if (!inst || !inst->core || !inst->core->device) {
4538 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4539 return -EINVAL;
4540 }
4541
4542 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST,
4543 &inst->persistbufs);
4544 if (rc)
4545 goto error;
4546
4547 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST_1,
4548 &inst->persistbufs);
4549 if (rc)
4550 goto error;
4551 return rc;
4552error:
4553 msm_comm_release_persist_buffers(inst);
4554 return rc;
4555}
4556
4557static void msm_comm_flush_in_invalid_state(struct msm_vidc_inst *inst)
4558{
4559 struct list_head *ptr, *next;
4560 enum vidc_ports ports[] = {OUTPUT_PORT, CAPTURE_PORT};
4561 int c = 0;
4562
4563 for (c = 0; c < ARRAY_SIZE(ports); ++c) {
4564 enum vidc_ports port = ports[c];
4565
4566 dprintk(VIDC_DBG, "Flushing buffers of type %d in bad state\n",
4567 port);
4568 mutex_lock(&inst->bufq[port].lock);
4569 list_for_each_safe(ptr, next, &inst->bufq[port].
4570 vb2_bufq.queued_list) {
4571 struct vb2_buffer *vb = container_of(ptr,
4572 struct vb2_buffer, queued_entry);
4573
4574 vb->planes[0].bytesused = 0;
4575 vb->planes[0].data_offset = 0;
4576
4577 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
4578 }
4579 mutex_unlock(&inst->bufq[port].lock);
4580 }
4581
4582 msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_FLUSH_DONE);
4583}
4584
4585void msm_comm_flush_dynamic_buffers(struct msm_vidc_inst *inst)
4586{
4587 struct buffer_info *binfo = NULL;
4588
4589 if (inst->buffer_mode_set[CAPTURE_PORT] != HAL_BUFFER_MODE_DYNAMIC)
4590 return;
4591
4592 /*
4593 * dynamic buffer mode:- if flush is called during seek
4594 * driver should not queue any new buffer it has been holding.
4595 *
4596 * Each dynamic o/p buffer can have one of following ref_count:
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08004597 * ref_count : 0 - f/w has released reference and sent dynamic
4598 * buffer back. The buffer has been returned
4599 * back to client.
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004600 *
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08004601 * ref_count : 1 - f/w is holding reference. f/w may have released
4602 * dynamic buffer as read_only OR dynamic buffer is
4603 * pending. f/w will release reference before sending
4604 * flush_done.
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004605 *
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08004606 * ref_count : >=2 - f/w is holding reference, f/w has released dynamic
4607 * buffer as read_only, which client has queued back
4608 * to driver. Driver holds this buffer and will queue
4609 * back only when f/w releases the reference. During
4610 * flush_done, f/w will release the reference but
4611 * driver should not queue back the buffer to f/w.
4612 * Flush all buffers with ref_count >= 2.
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004613 */
4614 mutex_lock(&inst->registeredbufs.lock);
4615 if (!list_empty(&inst->registeredbufs.list)) {
4616 struct v4l2_event buf_event = {0};
4617 u32 *ptr = NULL;
4618
4619 list_for_each_entry(binfo, &inst->registeredbufs.list, list) {
4620 if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08004621 atomic_read(&binfo->ref_count) >= 2) {
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004622
4623 atomic_dec(&binfo->ref_count);
4624 buf_event.type =
4625 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER;
4626 ptr = (u32 *)buf_event.u.data;
4627 ptr[0] = binfo->fd[0];
4628 ptr[1] = binfo->buff_off[0];
4629 ptr[2] = binfo->uvaddr[0];
4630 ptr[3] = (u32) binfo->timestamp.tv_sec;
4631 ptr[4] = (u32) binfo->timestamp.tv_usec;
4632 ptr[5] = binfo->v4l2_index;
4633 dprintk(VIDC_DBG,
4634 "released buffer held in driver before issuing flush: %pa fd[0]: %d\n",
4635 &binfo->device_addr[0], binfo->fd[0]);
4636 /*send event to client*/
4637 v4l2_event_queue_fh(&inst->event_handler,
4638 &buf_event);
4639 }
4640 }
4641 }
4642 mutex_unlock(&inst->registeredbufs.lock);
4643}
4644
4645void msm_comm_flush_pending_dynamic_buffers(struct msm_vidc_inst *inst)
4646{
4647 struct buffer_info *binfo = NULL;
4648
4649 if (!inst)
4650 return;
4651
4652 if (inst->buffer_mode_set[CAPTURE_PORT] != HAL_BUFFER_MODE_DYNAMIC)
4653 return;
4654
4655 if (list_empty(&inst->pendingq.list) ||
4656 list_empty(&inst->registeredbufs.list))
4657 return;
4658
4659 /*
4660 * Dynamic Buffer mode - Since pendingq is not empty
4661 * no output buffers have been sent to firmware yet.
4662 * Hence remove reference to all pendingq o/p buffers
4663 * before flushing them.
4664 */
4665
4666 mutex_lock(&inst->registeredbufs.lock);
4667 list_for_each_entry(binfo, &inst->registeredbufs.list, list) {
4668 if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
4669 dprintk(VIDC_DBG,
4670 "%s: binfo = %pK device_addr = %pa\n",
4671 __func__, binfo, &binfo->device_addr[0]);
4672 buf_ref_put(inst, binfo);
4673 }
4674 }
4675 mutex_unlock(&inst->registeredbufs.lock);
4676}
4677
4678int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags)
4679{
4680 int rc = 0;
4681 bool ip_flush = false;
4682 bool op_flush = false;
4683 struct vb2_buf_entry *temp, *next;
4684 struct mutex *lock;
4685 struct msm_vidc_core *core;
4686 struct hfi_device *hdev;
4687
4688 if (!inst) {
4689 dprintk(VIDC_ERR,
4690 "Invalid instance pointer = %pK\n", inst);
4691 return -EINVAL;
4692 }
4693 core = inst->core;
4694 if (!core) {
4695 dprintk(VIDC_ERR,
4696 "Invalid core pointer = %pK\n", core);
4697 return -EINVAL;
4698 }
4699 hdev = core->device;
4700 if (!hdev) {
4701 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4702 return -EINVAL;
4703 }
4704
4705 ip_flush = flags & V4L2_QCOM_CMD_FLUSH_OUTPUT;
4706 op_flush = flags & V4L2_QCOM_CMD_FLUSH_CAPTURE;
4707
4708 if (ip_flush && !op_flush) {
4709 dprintk(VIDC_INFO, "Input only flush not supported\n");
4710 return 0;
4711 }
4712
Praneeth Paladugu75cf18e2016-12-08 16:12:11 -08004713 // Finish FLUSH As Soon As Possible.
4714 inst->dcvs.buffer_counter = 0;
4715 msm_comm_scale_clocks_and_bus(inst);
4716
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004717 msm_comm_flush_dynamic_buffers(inst);
4718
4719 if (inst->state == MSM_VIDC_CORE_INVALID ||
4720 core->state == VIDC_CORE_INVALID ||
4721 core->state == VIDC_CORE_UNINIT) {
4722 dprintk(VIDC_ERR,
4723 "Core %pK and inst %pK are in bad state\n",
4724 core, inst);
4725 msm_comm_flush_in_invalid_state(inst);
4726 return 0;
4727 }
4728
4729 if (inst->in_reconfig && !ip_flush && op_flush) {
4730 mutex_lock(&inst->pendingq.lock);
4731 if (!list_empty(&inst->pendingq.list)) {
4732 /*
4733 * Execution can never reach here since port reconfig
4734 * wont happen unless pendingq is emptied out
4735 * (both pendingq and flush being secured with same
4736 * lock). Printing a message here incase this breaks.
4737 */
4738 dprintk(VIDC_WARN,
4739 "FLUSH BUG: Pending q not empty! It should be empty\n");
4740 }
4741 mutex_unlock(&inst->pendingq.lock);
4742 atomic_inc(&inst->in_flush);
4743 dprintk(VIDC_DBG, "Send flush Output to firmware\n");
4744 rc = call_hfi_op(hdev, session_flush, inst->session,
4745 HAL_FLUSH_OUTPUT);
4746 } else {
4747 msm_comm_flush_pending_dynamic_buffers(inst);
4748 /*
4749 * If flush is called after queueing buffers but before
4750 * streamon driver should flush the pending queue
4751 */
4752 mutex_lock(&inst->pendingq.lock);
4753 list_for_each_entry_safe(temp, next,
4754 &inst->pendingq.list, list) {
4755 enum v4l2_buf_type type = temp->vb->type;
4756
4757 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
4758 lock = &inst->bufq[CAPTURE_PORT].lock;
4759 else
4760 lock = &inst->bufq[OUTPUT_PORT].lock;
4761
4762 temp->vb->planes[0].bytesused = 0;
4763
4764 mutex_lock(lock);
4765 vb2_buffer_done(temp->vb, VB2_BUF_STATE_DONE);
4766 msm_vidc_debugfs_update(inst,
4767 type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ?
4768 MSM_VIDC_DEBUGFS_EVENT_FBD :
4769 MSM_VIDC_DEBUGFS_EVENT_EBD);
4770 list_del(&temp->list);
4771 mutex_unlock(lock);
4772
4773 kfree(temp);
4774 }
4775 mutex_unlock(&inst->pendingq.lock);
4776
4777 /*Do not send flush in case of session_error */
4778 if (!(inst->state == MSM_VIDC_CORE_INVALID &&
4779 core->state != VIDC_CORE_INVALID)) {
4780 atomic_inc(&inst->in_flush);
4781 dprintk(VIDC_DBG, "Send flush all to firmware\n");
4782 rc = call_hfi_op(hdev, session_flush, inst->session,
4783 HAL_FLUSH_ALL);
4784 }
4785 }
4786
4787 return rc;
4788}
4789
4790
4791enum hal_extradata_id msm_comm_get_hal_extradata_index(
4792 enum v4l2_mpeg_vidc_extradata index)
4793{
4794 int ret = 0;
4795
4796 switch (index) {
4797 case V4L2_MPEG_VIDC_EXTRADATA_NONE:
4798 ret = HAL_EXTRADATA_NONE;
4799 break;
4800 case V4L2_MPEG_VIDC_EXTRADATA_MB_QUANTIZATION:
4801 ret = HAL_EXTRADATA_MB_QUANTIZATION;
4802 break;
4803 case V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO:
4804 ret = HAL_EXTRADATA_INTERLACE_VIDEO;
4805 break;
4806 case V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP:
4807 ret = HAL_EXTRADATA_TIMESTAMP;
4808 break;
4809 case V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING:
4810 ret = HAL_EXTRADATA_S3D_FRAME_PACKING;
4811 break;
4812 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE:
4813 ret = HAL_EXTRADATA_FRAME_RATE;
4814 break;
4815 case V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW:
4816 ret = HAL_EXTRADATA_PANSCAN_WINDOW;
4817 break;
4818 case V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
4819 ret = HAL_EXTRADATA_RECOVERY_POINT_SEI;
4820 break;
4821 case V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO:
4822 ret = HAL_EXTRADATA_MULTISLICE_INFO;
4823 break;
4824 case V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB:
4825 ret = HAL_EXTRADATA_NUM_CONCEALED_MB;
4826 break;
4827 case V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER:
4828 ret = HAL_EXTRADATA_METADATA_FILLER;
4829 break;
4830 case V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO:
4831 ret = HAL_EXTRADATA_ASPECT_RATIO;
4832 break;
4833 case V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP:
4834 ret = HAL_EXTRADATA_INPUT_CROP;
4835 break;
4836 case V4L2_MPEG_VIDC_EXTRADATA_DIGITAL_ZOOM:
4837 ret = HAL_EXTRADATA_DIGITAL_ZOOM;
4838 break;
4839 case V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP:
4840 ret = HAL_EXTRADATA_MPEG2_SEQDISP;
4841 break;
4842 case V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA:
4843 ret = HAL_EXTRADATA_STREAM_USERDATA;
4844 break;
4845 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP:
4846 ret = HAL_EXTRADATA_FRAME_QP;
4847 break;
4848 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO:
4849 ret = HAL_EXTRADATA_FRAME_BITS_INFO;
4850 break;
4851 case V4L2_MPEG_VIDC_EXTRADATA_LTR:
4852 ret = HAL_EXTRADATA_LTR_INFO;
4853 break;
4854 case V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI:
4855 ret = HAL_EXTRADATA_METADATA_MBI;
4856 break;
4857 case V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI:
4858 ret = HAL_EXTRADATA_VQZIP_SEI;
4859 break;
4860 case V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS:
4861 ret = HAL_EXTRADATA_YUV_STATS;
4862 break;
4863 case V4L2_MPEG_VIDC_EXTRADATA_ROI_QP:
4864 ret = HAL_EXTRADATA_ROI_QP;
4865 break;
4866 case V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP:
4867 ret = HAL_EXTRADATA_OUTPUT_CROP;
4868 break;
4869 case V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI:
4870 ret = HAL_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI;
4871 break;
4872 case V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI:
4873 ret = HAL_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI;
4874 break;
4875 case V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO:
4876 ret = HAL_EXTRADATA_PQ_INFO;
4877 break;
4878
4879 case V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY:
4880 ret = HAL_EXTRADATA_VUI_DISPLAY_INFO;
4881 break;
4882 case V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE:
4883 ret = HAL_EXTRADATA_VPX_COLORSPACE;
4884 break;
4885 default:
4886 dprintk(VIDC_WARN, "Extradata not found: %d\n", index);
4887 break;
4888 }
4889 return ret;
4890};
4891
4892int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
4893 enum hal_ssr_trigger_type type)
4894{
4895 int rc = 0;
4896 struct hfi_device *hdev;
4897
4898 if (!core || !core->device) {
4899 dprintk(VIDC_WARN, "Invalid parameters: %pK\n", core);
4900 return -EINVAL;
4901 }
4902 hdev = core->device;
4903 if (core->state == VIDC_CORE_INIT_DONE) {
4904 /*
4905 * In current implementation user-initiated SSR triggers
4906 * a fatal error from hardware. However, there is no way
4907 * to know if fatal error is due to SSR or not. Handle
4908 * user SSR as non-fatal.
4909 */
4910 mutex_lock(&core->lock);
4911 core->resources.debug_timeout = false;
4912 mutex_unlock(&core->lock);
4913 rc = call_hfi_op(hdev, core_trigger_ssr,
4914 hdev->hfi_device_data, type);
4915 }
4916
4917 return rc;
4918}
4919
4920static int msm_vidc_load_supported(struct msm_vidc_inst *inst)
4921{
4922 int num_mbs_per_sec = 0, max_load_adj = 0;
4923 enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD |
4924 LOAD_CALC_IGNORE_THUMBNAIL_LOAD |
4925 LOAD_CALC_IGNORE_NON_REALTIME_LOAD;
4926
4927 if (inst->state == MSM_VIDC_OPEN_DONE) {
4928 max_load_adj = inst->core->resources.max_load +
4929 inst->capability.mbs_per_frame.max;
4930 num_mbs_per_sec = msm_comm_get_load(inst->core,
4931 MSM_VIDC_DECODER, quirks);
4932 num_mbs_per_sec += msm_comm_get_load(inst->core,
4933 MSM_VIDC_ENCODER, quirks);
4934 if (num_mbs_per_sec > max_load_adj) {
4935 dprintk(VIDC_ERR,
4936 "H/W is overloaded. needed: %d max: %d\n",
4937 num_mbs_per_sec,
4938 max_load_adj);
4939 msm_vidc_print_running_insts(inst->core);
4940 return -EBUSY;
4941 }
4942 }
4943 return 0;
4944}
4945
4946int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst)
4947{
4948 u32 x_min, x_max, y_min, y_max;
4949 u32 input_height, input_width, output_height, output_width;
4950
4951 input_height = inst->prop.height[OUTPUT_PORT];
4952 input_width = inst->prop.width[OUTPUT_PORT];
4953 output_height = inst->prop.height[CAPTURE_PORT];
4954 output_width = inst->prop.width[CAPTURE_PORT];
4955
4956 if (!input_height || !input_width || !output_height || !output_width) {
4957 dprintk(VIDC_ERR,
4958 "Invalid : Input height = %d width = %d",
4959 input_height, input_width);
4960 dprintk(VIDC_ERR,
4961 " output height = %d width = %d\n",
4962 output_height, output_width);
4963 return -ENOTSUPP;
4964 }
4965
4966 if (!inst->capability.scale_x.min ||
4967 !inst->capability.scale_x.max ||
4968 !inst->capability.scale_y.min ||
4969 !inst->capability.scale_y.max) {
4970
4971 if (input_width * input_height !=
4972 output_width * output_height) {
4973 dprintk(VIDC_ERR,
4974 "%s: scaling is not supported (%dx%d != %dx%d)\n",
4975 __func__, input_width, input_height,
4976 output_width, output_height);
4977 return -ENOTSUPP;
4978 }
4979
4980 dprintk(VIDC_DBG, "%s: supported WxH = %dx%d\n",
4981 __func__, input_width, input_height);
4982 return 0;
4983 }
4984
4985 x_min = (1<<16)/inst->capability.scale_x.min;
4986 y_min = (1<<16)/inst->capability.scale_y.min;
4987 x_max = inst->capability.scale_x.max >> 16;
4988 y_max = inst->capability.scale_y.max >> 16;
4989
4990 if (input_height > output_height) {
4991 if (input_height > x_min * output_height) {
4992 dprintk(VIDC_ERR,
4993 "Unsupported height downscale ratio %d vs %d\n",
4994 input_height/output_height, x_min);
4995 return -ENOTSUPP;
4996 }
4997 } else {
4998 if (output_height > x_max * input_height) {
4999 dprintk(VIDC_ERR,
5000 "Unsupported height upscale ratio %d vs %d\n",
5001 input_height/output_height, x_max);
5002 return -ENOTSUPP;
5003 }
5004 }
5005 if (input_width > output_width) {
5006 if (input_width > y_min * output_width) {
5007 dprintk(VIDC_ERR,
5008 "Unsupported width downscale ratio %d vs %d\n",
5009 input_width/output_width, y_min);
5010 return -ENOTSUPP;
5011 }
5012 } else {
5013 if (output_width > y_max * input_width) {
5014 dprintk(VIDC_ERR,
5015 "Unsupported width upscale ratio %d vs %d\n",
5016 input_width/output_width, y_max);
5017 return -ENOTSUPP;
5018 }
5019 }
5020 return 0;
5021}
5022
5023int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
5024{
5025 struct msm_vidc_capability *capability;
5026 int rc = 0;
5027 struct hfi_device *hdev;
5028 struct msm_vidc_core *core;
5029
5030 if (!inst || !inst->core || !inst->core->device) {
5031 dprintk(VIDC_WARN, "%s: Invalid parameter\n", __func__);
5032 return -EINVAL;
5033 }
5034 capability = &inst->capability;
5035 hdev = inst->core->device;
5036 core = inst->core;
5037 rc = msm_vidc_load_supported(inst);
5038 if (rc) {
5039 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
5040 msm_comm_kill_session(inst);
5041 dprintk(VIDC_WARN,
5042 "%s: Hardware is overloaded\n", __func__);
5043 return rc;
5044 }
5045
5046 if (!is_thermal_permissible(core)) {
5047 dprintk(VIDC_WARN,
5048 "Thermal level critical, stop all active sessions!\n");
5049 return -ENOTSUPP;
5050 }
5051
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08005052 if (!rc) {
5053 if (inst->prop.width[CAPTURE_PORT] < capability->width.min ||
5054 inst->prop.height[CAPTURE_PORT] <
5055 capability->height.min) {
5056 dprintk(VIDC_ERR,
5057 "Unsupported WxH = (%u)x(%u), min supported is - (%u)x(%u)\n",
5058 inst->prop.width[CAPTURE_PORT],
5059 inst->prop.height[CAPTURE_PORT],
5060 capability->width.min,
5061 capability->height.min);
5062 rc = -ENOTSUPP;
5063 }
5064 if (!rc && inst->prop.width[CAPTURE_PORT] >
5065 capability->width.max) {
5066 dprintk(VIDC_ERR,
5067 "Unsupported width = %u supported max width = %u",
5068 inst->prop.width[CAPTURE_PORT],
5069 capability->width.max);
5070 rc = -ENOTSUPP;
5071 }
5072
5073 if (!rc && inst->prop.height[CAPTURE_PORT]
5074 * inst->prop.width[CAPTURE_PORT] >
5075 capability->width.max * capability->height.max) {
5076 dprintk(VIDC_ERR,
5077 "Unsupported WxH = (%u)x(%u), max supported is - (%u)x(%u)\n",
5078 inst->prop.width[CAPTURE_PORT],
5079 inst->prop.height[CAPTURE_PORT],
5080 capability->width.max, capability->height.max);
5081 rc = -ENOTSUPP;
5082 }
5083 }
5084 if (rc) {
5085 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
5086 msm_comm_kill_session(inst);
5087 dprintk(VIDC_ERR,
5088 "%s: Resolution unsupported\n", __func__);
5089 }
5090 return rc;
5091}
5092
5093static void msm_comm_generate_session_error(struct msm_vidc_inst *inst)
5094{
5095 enum hal_command_response cmd = HAL_SESSION_ERROR;
5096 struct msm_vidc_cb_cmd_done response = {0};
5097
5098 dprintk(VIDC_WARN, "msm_comm_generate_session_error\n");
5099 if (!inst || !inst->core) {
5100 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5101 return;
5102 }
5103
5104 response.session_id = inst;
5105 response.status = VIDC_ERR_FAIL;
5106 handle_session_error(cmd, (void *)&response);
5107}
5108
5109static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst)
5110{
5111 struct msm_vidc_core *core;
5112 enum hal_command_response cmd = HAL_SYS_ERROR;
5113 struct msm_vidc_cb_cmd_done response = {0};
5114
5115 if (!inst || !inst->core) {
5116 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5117 return;
5118 }
5119 core = inst->core;
5120 response.device_id = (u32) core->id;
5121 handle_sys_error(cmd, (void *) &response);
5122
5123}
5124
5125int msm_comm_kill_session(struct msm_vidc_inst *inst)
5126{
5127 int rc = 0;
5128
5129 if (!inst || !inst->core || !inst->core->device) {
5130 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5131 return -EINVAL;
5132 } else if (!inst->session) {
5133 /* There's no hfi session to kill */
5134 return 0;
5135 }
5136
5137 /*
5138 * We're internally forcibly killing the session, if fw is aware of
5139 * the session send session_abort to firmware to clean up and release
5140 * the session, else just kill the session inside the driver.
5141 */
5142 if ((inst->state >= MSM_VIDC_OPEN_DONE &&
5143 inst->state < MSM_VIDC_CLOSE_DONE) ||
5144 inst->state == MSM_VIDC_CORE_INVALID) {
5145 if (msm_comm_session_abort(inst)) {
5146 msm_comm_generate_sys_error(inst);
5147 return 0;
5148 }
5149 change_inst_state(inst, MSM_VIDC_CLOSE_DONE);
5150 msm_comm_generate_session_error(inst);
5151 } else {
5152 dprintk(VIDC_WARN,
5153 "Inactive session %pK, triggering an internal session error\n",
5154 inst);
5155 msm_comm_generate_session_error(inst);
5156
5157 }
5158
5159 return rc;
5160}
5161
5162struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst,
5163 size_t size, u32 align, u32 flags,
5164 enum hal_buffer buffer_type, int map_kernel)
5165{
5166 struct msm_smem *m = NULL;
5167
5168 if (!inst || !inst->core) {
5169 dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst);
5170 return NULL;
5171 }
5172 m = msm_smem_alloc(inst->mem_client, size, align,
5173 flags, buffer_type, map_kernel);
5174 return m;
5175}
5176
5177void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem)
5178{
5179 if (!inst || !inst->core || !mem) {
5180 dprintk(VIDC_ERR,
5181 "%s: invalid params: %pK %pK\n", __func__, inst, mem);
5182 return;
5183 }
5184 msm_smem_free(inst->mem_client, mem);
5185}
5186
5187int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst,
5188 struct msm_smem *mem, enum smem_cache_ops cache_ops)
5189{
5190 if (!inst || !mem) {
5191 dprintk(VIDC_ERR,
5192 "%s: invalid params: %pK %pK\n", __func__, inst, mem);
5193 return -EINVAL;
5194 }
5195 return msm_smem_cache_operations(inst->mem_client, mem, cache_ops);
5196}
5197
5198struct msm_smem *msm_comm_smem_user_to_kernel(struct msm_vidc_inst *inst,
5199 int fd, u32 offset, enum hal_buffer buffer_type)
5200{
5201 struct msm_smem *m = NULL;
5202
5203 if (!inst || !inst->core) {
5204 dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst);
5205 return NULL;
5206 }
5207
5208 if (inst->state == MSM_VIDC_CORE_INVALID) {
5209 dprintk(VIDC_ERR, "Core in Invalid state, returning from %s\n",
5210 __func__);
5211 return NULL;
5212 }
5213
5214 m = msm_smem_user_to_kernel(inst->mem_client,
5215 fd, offset, buffer_type);
5216 return m;
5217}
5218
5219void msm_vidc_fw_unload_handler(struct work_struct *work)
5220{
5221 struct msm_vidc_core *core = NULL;
5222 struct hfi_device *hdev = NULL;
5223 int rc = 0;
5224
5225 core = container_of(work, struct msm_vidc_core, fw_unload_work.work);
5226 if (!core || !core->device) {
5227 dprintk(VIDC_ERR, "%s - invalid work or core handle\n",
5228 __func__);
5229 return;
5230 }
5231
5232 hdev = core->device;
5233
5234 mutex_lock(&core->lock);
5235 if (list_empty(&core->instances) &&
5236 core->state != VIDC_CORE_UNINIT) {
5237 if (core->state > VIDC_CORE_INIT) {
5238 dprintk(VIDC_DBG, "Calling vidc_hal_core_release\n");
5239 rc = call_hfi_op(hdev, core_release,
5240 hdev->hfi_device_data);
5241 if (rc) {
5242 dprintk(VIDC_ERR,
5243 "Failed to release core, id = %d\n",
5244 core->id);
5245 mutex_unlock(&core->lock);
5246 return;
5247 }
5248 }
5249 core->state = VIDC_CORE_UNINIT;
5250 kfree(core->capabilities);
5251 core->capabilities = NULL;
5252 }
5253 mutex_unlock(&core->lock);
5254}
5255
5256int msm_comm_set_color_format(struct msm_vidc_inst *inst,
5257 enum hal_buffer buffer_type, int fourcc)
5258{
5259 struct hal_uncompressed_format_select hal_fmt = {0};
5260 enum hal_uncompressed_format format = HAL_UNUSED_COLOR;
5261 int rc = 0;
5262 struct hfi_device *hdev;
5263
5264 if (!inst || !inst->core || !inst->core->device) {
5265 dprintk(VIDC_ERR, "%s - invalid param\n", __func__);
5266 return -EINVAL;
5267 }
5268
5269 hdev = inst->core->device;
5270
5271 format = get_hal_uncompressed(fourcc);
5272 if (format == HAL_UNUSED_COLOR) {
5273 dprintk(VIDC_ERR, "Using unsupported colorformat %#x\n",
5274 fourcc);
5275 rc = -ENOTSUPP;
5276 goto exit;
5277 }
5278
5279 hal_fmt.buffer_type = buffer_type;
5280 hal_fmt.format = format;
5281
5282 rc = call_hfi_op(hdev, session_set_property, inst->session,
5283 HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT, &hal_fmt);
5284 if (rc)
5285 dprintk(VIDC_ERR,
5286 "Failed to set input color format\n");
5287 else
5288 dprintk(VIDC_DBG, "Setting uncompressed colorformat to %#x\n",
5289 format);
5290
5291exit:
5292 return rc;
5293}
5294
5295int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
5296{
5297 u32 property_id = 0;
5298 u64 us_per_frame = 0;
5299 void *pdata;
5300 int rc = 0, fps = 0;
5301 struct hal_frame_rate frame_rate;
5302 struct hfi_device *hdev;
5303
5304 if (!inst || !inst->core || !inst->core->device || !a) {
5305 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
5306 return -EINVAL;
5307 }
5308
5309 hdev = inst->core->device;
5310 property_id = HAL_CONFIG_FRAME_RATE;
5311
5312 if (a->parm.output.timeperframe.denominator) {
5313 switch (a->type) {
5314 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
5315 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
5316 us_per_frame = a->parm.output.timeperframe.numerator *
5317 (u64)USEC_PER_SEC;
5318 do_div(us_per_frame, a->parm.output.
5319 timeperframe.denominator);
5320 break;
5321 default:
5322 dprintk(VIDC_ERR,
5323 "Scale clocks : Unknown buffer type %d\n",
5324 a->type);
5325 break;
5326 }
5327 }
5328
5329 if (!us_per_frame) {
5330 dprintk(VIDC_ERR,
5331 "Failed to scale clocks : time between frames is 0\n");
5332 rc = -EINVAL;
5333 goto exit;
5334 }
5335
5336 fps = USEC_PER_SEC;
5337 do_div(fps, us_per_frame);
5338
5339 if (fps % 15 == 14 || fps % 24 == 23)
5340 fps = fps + 1;
5341 else if ((fps > 1) && (fps % 24 == 1 || fps % 15 == 1))
5342 fps = fps - 1;
5343
Praneeth Paladugue1679112017-01-27 10:07:15 -08005344 if (fps < inst->capability.frame_rate.min ||
5345 fps > inst->capability.frame_rate.max) {
5346 dprintk(VIDC_ERR,
5347 "FPS is out of limits : fps = %d Min = %d, Max = %d\n",
5348 fps, inst->capability.frame_rate.min,
5349 inst->capability.frame_rate.max);
5350 rc = -EINVAL;
5351 goto exit;
5352 }
5353
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08005354 if (inst->prop.fps != fps) {
5355 dprintk(VIDC_PROF, "reported fps changed for %pK: %d->%d\n",
5356 inst, inst->prop.fps, fps);
5357 inst->prop.fps = fps;
5358 frame_rate.frame_rate = inst->prop.fps * BIT(16);
5359 frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
5360 pdata = &frame_rate;
5361 if (inst->session_type == MSM_VIDC_ENCODER) {
5362 rc = call_hfi_op(hdev, session_set_property,
5363 inst->session, property_id, pdata);
5364
5365 if (rc)
5366 dprintk(VIDC_WARN,
5367 "Failed to set frame rate %d\n", rc);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08005368 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08005369 }
5370exit:
5371 return rc;
5372}
5373
5374void msm_comm_print_inst_info(struct msm_vidc_inst *inst)
5375{
5376 struct buffer_info *temp;
5377 struct internal_buf *buf;
5378 int i = 0;
5379 bool is_decode = false;
5380 enum vidc_ports port;
5381 bool is_secure = false;
5382
5383 if (!inst) {
5384 dprintk(VIDC_ERR, "%s - invalid param %pK\n",
5385 __func__, inst);
5386 return;
5387 }
5388
5389 is_decode = inst->session_type == MSM_VIDC_DECODER;
5390 port = is_decode ? OUTPUT_PORT : CAPTURE_PORT;
5391 is_secure = inst->flags & VIDC_SECURE;
5392 dprintk(VIDC_ERR,
5393 "%s session, %s, Codec type: %s HxW: %d x %d fps: %d bitrate: %d bit-depth: %s\n",
5394 is_decode ? "Decode" : "Encode",
5395 is_secure ? "Secure" : "Non-Secure",
5396 inst->fmts[port].name,
5397 inst->prop.height[port], inst->prop.width[port],
5398 inst->prop.fps, inst->prop.bitrate,
5399 !inst->bit_depth ? "8" : "10");
5400
5401 dprintk(VIDC_ERR,
5402 "---Buffer details for inst: %pK of type: %d---\n",
5403 inst, inst->session_type);
5404 mutex_lock(&inst->registeredbufs.lock);
5405 dprintk(VIDC_ERR, "registered buffer list:\n");
5406 list_for_each_entry(temp, &inst->registeredbufs.list, list)
5407 for (i = 0; i < temp->num_planes; i++)
5408 dprintk(VIDC_ERR,
5409 "type: %d plane: %d addr: %pa size: %d\n",
5410 temp->type, i, &temp->device_addr[i],
5411 temp->size[i]);
5412
5413 mutex_unlock(&inst->registeredbufs.lock);
5414
5415 mutex_lock(&inst->scratchbufs.lock);
5416 dprintk(VIDC_ERR, "scratch buffer list:\n");
5417 list_for_each_entry(buf, &inst->scratchbufs.list, list)
5418 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5419 buf->buffer_type, &buf->handle->device_addr,
5420 buf->handle->size);
5421 mutex_unlock(&inst->scratchbufs.lock);
5422
5423 mutex_lock(&inst->persistbufs.lock);
5424 dprintk(VIDC_ERR, "persist buffer list:\n");
5425 list_for_each_entry(buf, &inst->persistbufs.list, list)
5426 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5427 buf->buffer_type, &buf->handle->device_addr,
5428 buf->handle->size);
5429 mutex_unlock(&inst->persistbufs.lock);
5430
5431 mutex_lock(&inst->outputbufs.lock);
5432 dprintk(VIDC_ERR, "dpb buffer list:\n");
5433 list_for_each_entry(buf, &inst->outputbufs.list, list)
5434 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5435 buf->buffer_type, &buf->handle->device_addr,
5436 buf->handle->size);
5437 mutex_unlock(&inst->outputbufs.lock);
5438}
5439
5440static void msm_comm_print_debug_info(struct msm_vidc_inst *inst)
5441{
5442 struct msm_vidc_core *core = NULL;
5443 struct msm_vidc_inst *temp = NULL;
5444
5445 if (!inst || !inst->core) {
5446 dprintk(VIDC_ERR, "%s - invalid param %pK %pK\n",
5447 __func__, inst, core);
5448 return;
5449 }
5450 core = inst->core;
5451
Praneeth Paladugub71968b2015-08-19 20:47:57 -07005452 dprintk(VIDC_ERR, "Venus core frequency = %lu", core->freq);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08005453 mutex_lock(&core->lock);
5454 dprintk(VIDC_ERR, "Printing instance info that caused Error\n");
5455 msm_comm_print_inst_info(inst);
5456 dprintk(VIDC_ERR, "Printing remaining instances info\n");
5457 list_for_each_entry(temp, &core->instances, list) {
5458 /* inst already printed above. Hence don't repeat.*/
5459 if (temp == inst)
5460 continue;
5461 msm_comm_print_inst_info(temp);
5462 }
5463 mutex_unlock(&core->lock);
5464}