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