blob: 4aaa525141c1a83febf3f3ea8865d75282157c74 [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
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001528 rc = msm_vidc_check_session_supported(inst);
1529 if (!rc) {
1530 seq_changed_event.type = event;
1531 if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) {
1532 u32 *ptr = NULL;
1533
1534 ptr = (u32 *)seq_changed_event.u.data;
1535 ptr[0] = event_notify->height;
1536 ptr[1] = event_notify->width;
1537 }
1538 v4l2_event_queue_fh(&inst->event_handler, &seq_changed_event);
1539 } else if (rc == -ENOTSUPP) {
1540 msm_vidc_queue_v4l2_event(inst,
1541 V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED);
1542 } else if (rc == -EBUSY) {
1543 msm_vidc_queue_v4l2_event(inst,
1544 V4L2_EVENT_MSM_VIDC_HW_OVERLOAD);
1545 }
1546
1547err_bad_event:
1548 put_inst(inst);
1549}
1550
1551static void handle_session_prop_info(enum hal_command_response cmd, void *data)
1552{
1553 struct msm_vidc_cb_cmd_done *response = data;
1554 struct getprop_buf *getprop;
1555 struct msm_vidc_inst *inst;
1556
1557 if (!response) {
1558 dprintk(VIDC_ERR,
1559 "Failed to get valid response for prop info\n");
1560 return;
1561 }
1562
1563 inst = get_inst(get_vidc_core(response->device_id),
1564 response->session_id);
1565 if (!inst) {
1566 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1567 return;
1568 }
1569
1570 getprop = kzalloc(sizeof(*getprop), GFP_KERNEL);
1571 if (!getprop) {
1572 dprintk(VIDC_ERR, "%s: getprop kzalloc failed\n", __func__);
1573 goto err_prop_info;
1574 }
1575
1576 getprop->data = kmemdup(&response->data.property,
1577 sizeof(union hal_get_property), GFP_KERNEL);
1578 if (!getprop->data) {
1579 dprintk(VIDC_ERR, "%s: kmemdup failed\n", __func__);
1580 kfree(getprop);
1581 goto err_prop_info;
1582 }
1583
1584 mutex_lock(&inst->pending_getpropq.lock);
1585 list_add_tail(&getprop->list, &inst->pending_getpropq.list);
1586 mutex_unlock(&inst->pending_getpropq.lock);
1587
1588 signal_session_msg_receipt(cmd, inst);
1589err_prop_info:
1590 put_inst(inst);
1591}
1592
1593static void handle_load_resource_done(enum hal_command_response cmd, void *data)
1594{
1595 struct msm_vidc_cb_cmd_done *response = data;
1596 struct msm_vidc_inst *inst;
1597
1598 if (!response) {
1599 dprintk(VIDC_ERR,
1600 "Failed to get valid response for load resource\n");
1601 return;
1602 }
1603
1604 inst = get_inst(get_vidc_core(response->device_id),
1605 response->session_id);
1606 if (!inst) {
1607 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1608 return;
1609 }
1610
1611 if (response->status) {
1612 dprintk(VIDC_ERR,
1613 "Load resource response from FW : %#x\n",
1614 response->status);
1615 msm_comm_generate_session_error(inst);
1616 }
1617
1618 put_inst(inst);
1619}
1620
1621static void handle_start_done(enum hal_command_response cmd, void *data)
1622{
1623 struct msm_vidc_cb_cmd_done *response = data;
1624 struct msm_vidc_inst *inst;
1625
1626 if (!response) {
1627 dprintk(VIDC_ERR, "Failed to get valid response for start\n");
1628 return;
1629 }
1630
1631 inst = get_inst(get_vidc_core(response->device_id),
1632 response->session_id);
1633 if (!inst) {
1634 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1635 return;
1636 }
1637
1638 signal_session_msg_receipt(cmd, inst);
1639 put_inst(inst);
1640}
1641
1642static void handle_stop_done(enum hal_command_response cmd, void *data)
1643{
1644 struct msm_vidc_cb_cmd_done *response = data;
1645 struct msm_vidc_inst *inst;
1646
1647 if (!response) {
1648 dprintk(VIDC_ERR, "Failed to get valid response for stop\n");
1649 return;
1650 }
1651
1652 inst = get_inst(get_vidc_core(response->device_id),
1653 response->session_id);
1654 if (!inst) {
1655 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1656 return;
1657 }
1658
1659 signal_session_msg_receipt(cmd, inst);
1660 put_inst(inst);
1661}
1662
1663static void handle_release_res_done(enum hal_command_response cmd, void *data)
1664{
1665 struct msm_vidc_cb_cmd_done *response = data;
1666 struct msm_vidc_inst *inst;
1667
1668 if (!response) {
1669 dprintk(VIDC_ERR,
1670 "Failed to get valid response for release resource\n");
1671 return;
1672 }
1673
1674 inst = get_inst(get_vidc_core(response->device_id),
1675 response->session_id);
1676 if (!inst) {
1677 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1678 return;
1679 }
1680
1681 signal_session_msg_receipt(cmd, inst);
1682 put_inst(inst);
1683}
1684
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001685void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001686{
1687 struct internal_buf *binfo;
1688 u32 buffers_owned_by_driver = 0;
1689 struct hal_buffer_requirements *output_buf;
1690
1691 output_buf = get_buff_req_buffer(inst, HAL_BUFFER_OUTPUT);
1692
1693 if (!output_buf) {
1694 dprintk(VIDC_DBG,
1695 "This output buffer not required, buffer_type: %x\n",
1696 HAL_BUFFER_OUTPUT);
1697 return;
1698 }
1699 mutex_lock(&inst->outputbufs.lock);
1700 list_for_each_entry(binfo, &inst->outputbufs.list, list) {
1701 if (binfo->buffer_ownership != DRIVER) {
1702 dprintk(VIDC_DBG,
1703 "This buffer is with FW %pa\n",
1704 &binfo->handle->device_addr);
1705 continue;
1706 }
1707 buffers_owned_by_driver++;
1708 }
1709 mutex_unlock(&inst->outputbufs.lock);
1710
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001711 if (buffers_owned_by_driver != output_buf->buffer_count_actual) {
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001712 dprintk(VIDC_WARN,
1713 "OUTPUT Buffer count mismatch %d of %d\n",
1714 buffers_owned_by_driver,
1715 output_buf->buffer_count_actual);
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001716 msm_vidc_handle_hw_error(inst->core);
1717 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001718}
1719
1720int msm_comm_queue_output_buffers(struct msm_vidc_inst *inst)
1721{
1722 struct internal_buf *binfo;
1723 struct hfi_device *hdev;
1724 struct msm_smem *handle;
1725 struct vidc_frame_data frame_data = {0};
1726 struct hal_buffer_requirements *output_buf, *extra_buf;
1727 int rc = 0;
1728
1729 if (!inst || !inst->core || !inst->core->device) {
1730 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
1731 return -EINVAL;
1732 }
1733
1734 hdev = inst->core->device;
1735
1736 output_buf = get_buff_req_buffer(inst, HAL_BUFFER_OUTPUT);
1737 if (!output_buf) {
1738 dprintk(VIDC_DBG,
1739 "This output buffer not required, buffer_type: %x\n",
1740 HAL_BUFFER_OUTPUT);
1741 return 0;
1742 }
1743 dprintk(VIDC_DBG,
1744 "output: num = %d, size = %d\n",
1745 output_buf->buffer_count_actual,
1746 output_buf->buffer_size);
1747
1748 extra_buf = get_buff_req_buffer(inst, HAL_BUFFER_EXTRADATA_OUTPUT);
1749
1750 mutex_lock(&inst->outputbufs.lock);
1751 list_for_each_entry(binfo, &inst->outputbufs.list, list) {
1752 if (binfo->buffer_ownership != DRIVER)
1753 continue;
1754 handle = binfo->handle;
1755 frame_data.alloc_len = output_buf->buffer_size;
1756 frame_data.filled_len = 0;
1757 frame_data.offset = 0;
1758 frame_data.device_addr = handle->device_addr;
1759 frame_data.flags = 0;
1760 frame_data.extradata_addr = handle->device_addr +
1761 output_buf->buffer_size;
1762 frame_data.buffer_type = HAL_BUFFER_OUTPUT;
1763 frame_data.extradata_size = extra_buf ?
1764 extra_buf->buffer_size : 0;
1765 rc = call_hfi_op(hdev, session_ftb,
1766 (void *) inst->session, &frame_data);
1767 binfo->buffer_ownership = FIRMWARE;
1768 }
1769 mutex_unlock(&inst->outputbufs.lock);
1770
1771 return 0;
1772}
1773
1774static void handle_session_flush(enum hal_command_response cmd, void *data)
1775{
1776 struct msm_vidc_cb_cmd_done *response = data;
1777 struct msm_vidc_inst *inst;
1778 struct v4l2_event flush_event = {0};
1779 u32 *ptr = NULL;
1780 enum hal_flush flush_type;
1781 int rc;
1782
1783 if (!response) {
1784 dprintk(VIDC_ERR, "Failed to get valid response for flush\n");
1785 return;
1786 }
1787
1788 inst = get_inst(get_vidc_core(response->device_id),
1789 response->session_id);
1790 if (!inst) {
1791 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1792 return;
1793 }
1794
1795 if (msm_comm_get_stream_output_mode(inst) ==
1796 HAL_VIDEO_DECODER_SECONDARY) {
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001797
1798 if (!(inst->fmts[OUTPUT_PORT].defer_outputs &&
1799 inst->in_reconfig))
1800 msm_comm_validate_output_buffers(inst);
1801
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001802 if (!inst->in_reconfig) {
1803 rc = msm_comm_queue_output_buffers(inst);
1804 if (rc) {
1805 dprintk(VIDC_ERR,
1806 "Failed to queue output buffers: %d\n",
1807 rc);
1808 }
1809 }
1810 }
1811 atomic_dec(&inst->in_flush);
1812 flush_event.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
1813 ptr = (u32 *)flush_event.u.data;
1814
1815 flush_type = response->data.flush_type;
1816 switch (flush_type) {
1817 case HAL_FLUSH_INPUT:
1818 ptr[0] = V4L2_QCOM_CMD_FLUSH_OUTPUT;
1819 break;
1820 case HAL_FLUSH_OUTPUT:
1821 ptr[0] = V4L2_QCOM_CMD_FLUSH_CAPTURE;
1822 break;
1823 case HAL_FLUSH_ALL:
1824 ptr[0] |= V4L2_QCOM_CMD_FLUSH_CAPTURE;
1825 ptr[0] |= V4L2_QCOM_CMD_FLUSH_OUTPUT;
1826 break;
1827 default:
1828 dprintk(VIDC_ERR, "Invalid flush type received!");
1829 goto exit;
1830 }
1831
1832 dprintk(VIDC_DBG,
1833 "Notify flush complete, flush_type: %x\n", flush_type);
1834 v4l2_event_queue_fh(&inst->event_handler, &flush_event);
1835
1836exit:
1837 put_inst(inst);
1838}
1839
1840static void handle_session_error(enum hal_command_response cmd, void *data)
1841{
1842 struct msm_vidc_cb_cmd_done *response = data;
1843 struct hfi_device *hdev = NULL;
1844 struct msm_vidc_inst *inst = NULL;
1845 int event = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
1846
1847 if (!response) {
1848 dprintk(VIDC_ERR,
1849 "Failed to get valid response for session error\n");
1850 return;
1851 }
1852
1853 inst = get_inst(get_vidc_core(response->device_id),
1854 response->session_id);
1855 if (!inst) {
1856 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1857 return;
1858 }
1859
1860 hdev = inst->core->device;
1861 dprintk(VIDC_WARN, "Session error received for session %pK\n", inst);
1862 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
1863
1864 if (response->status == VIDC_ERR_MAX_CLIENTS) {
1865 dprintk(VIDC_WARN, "Too many clients, rejecting %pK", inst);
1866 event = V4L2_EVENT_MSM_VIDC_MAX_CLIENTS;
1867
1868 /*
1869 * Clean the HFI session now. Since inst->state is moved to
1870 * INVALID, forward thread doesn't know FW has valid session
1871 * or not. This is the last place driver knows that there is
1872 * no session in FW. Hence clean HFI session now.
1873 */
1874
1875 msm_comm_session_clean(inst);
1876 } else if (response->status == VIDC_ERR_NOT_SUPPORTED) {
1877 dprintk(VIDC_WARN, "Unsupported bitstream in %pK", inst);
1878 event = V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED;
1879 } else {
1880 dprintk(VIDC_WARN, "Unknown session error (%d) for %pK\n",
1881 response->status, inst);
1882 event = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
1883 }
1884
1885 msm_vidc_queue_v4l2_event(inst, event);
1886 put_inst(inst);
1887}
1888
1889static void msm_comm_clean_notify_client(struct msm_vidc_core *core)
1890{
1891 struct msm_vidc_inst *inst = NULL;
1892
1893 if (!core) {
1894 dprintk(VIDC_ERR, "%s: Invalid params\n", __func__);
1895 return;
1896 }
1897
1898 dprintk(VIDC_WARN, "%s: Core %pK\n", __func__, core);
1899 mutex_lock(&core->lock);
1900 core->state = VIDC_CORE_INVALID;
1901
1902 list_for_each_entry(inst, &core->instances, list) {
1903 mutex_lock(&inst->lock);
1904 inst->state = MSM_VIDC_CORE_INVALID;
1905 mutex_unlock(&inst->lock);
1906 dprintk(VIDC_WARN,
1907 "%s Send sys error for inst %pK\n", __func__, inst);
1908 msm_vidc_queue_v4l2_event(inst,
1909 V4L2_EVENT_MSM_VIDC_SYS_ERROR);
1910 }
1911 mutex_unlock(&core->lock);
1912}
1913
1914static void handle_sys_error(enum hal_command_response cmd, void *data)
1915{
1916 struct msm_vidc_cb_cmd_done *response = data;
1917 struct msm_vidc_core *core = NULL;
1918 struct hfi_device *hdev = NULL;
1919 struct msm_vidc_inst *inst = NULL;
1920 int rc = 0;
1921
1922 subsystem_crashed("venus");
1923 if (!response) {
1924 dprintk(VIDC_ERR,
1925 "Failed to get valid response for sys error\n");
1926 return;
1927 }
1928
1929 core = get_vidc_core(response->device_id);
1930 if (!core) {
1931 dprintk(VIDC_ERR,
1932 "Got SYS_ERR but unable to identify core\n");
1933 return;
1934 }
1935
1936 mutex_lock(&core->lock);
1937 if (core->state == VIDC_CORE_INVALID ||
1938 core->state == VIDC_CORE_UNINIT) {
1939 dprintk(VIDC_ERR,
1940 "%s: Core already moved to state %d\n",
1941 __func__, core->state);
1942 mutex_unlock(&core->lock);
1943 return;
1944 }
1945 mutex_unlock(&core->lock);
1946
1947 dprintk(VIDC_WARN, "SYS_ERROR %d received for core %pK\n", cmd, core);
1948 msm_comm_clean_notify_client(core);
1949
1950 hdev = core->device;
1951 mutex_lock(&core->lock);
1952 if (core->state == VIDC_CORE_INVALID) {
1953 dprintk(VIDC_DBG, "Calling core_release\n");
1954 rc = call_hfi_op(hdev, core_release,
1955 hdev->hfi_device_data);
1956 if (rc) {
1957 dprintk(VIDC_ERR, "core_release failed\n");
1958 mutex_unlock(&core->lock);
1959 return;
1960 }
1961 core->state = VIDC_CORE_UNINIT;
1962 }
1963 mutex_unlock(&core->lock);
1964
1965 msm_vidc_print_running_insts(core);
1966 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
1967 dprintk(VIDC_ERR,
1968 "SYS_ERROR can potentially crash the system\n");
1969
1970 /*
1971 * For SYS_ERROR, there will not be any inst pointer.
1972 * Just grab one of the inst from instances list and
1973 * use it.
1974 */
1975
1976 mutex_lock(&core->lock);
1977 inst = list_first_entry_or_null(&core->instances,
1978 struct msm_vidc_inst, list);
1979 mutex_unlock(&core->lock);
1980
1981 msm_comm_print_debug_info(inst);
1982
1983 msm_vidc_handle_hw_error(core);
1984}
1985
1986void msm_comm_session_clean(struct msm_vidc_inst *inst)
1987{
1988 int rc = 0;
1989 struct hfi_device *hdev = NULL;
1990
1991 if (!inst || !inst->core || !inst->core->device) {
1992 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
1993 return;
1994 }
1995
1996 hdev = inst->core->device;
1997 mutex_lock(&inst->lock);
1998 if (hdev && inst->session) {
1999 dprintk(VIDC_DBG, "cleaning up instance: %pK\n", inst);
2000 rc = call_hfi_op(hdev, session_clean,
2001 (void *)inst->session);
2002 if (rc) {
2003 dprintk(VIDC_ERR,
2004 "Session clean failed :%pK\n", inst);
2005 }
2006 inst->session = NULL;
2007 }
2008 mutex_unlock(&inst->lock);
2009}
2010
2011static void handle_session_close(enum hal_command_response cmd, void *data)
2012{
2013 struct msm_vidc_cb_cmd_done *response = data;
2014 struct msm_vidc_inst *inst;
2015
2016 if (!response) {
2017 dprintk(VIDC_ERR,
2018 "Failed to get valid response for session close\n");
2019 return;
2020 }
2021
2022 inst = get_inst(get_vidc_core(response->device_id),
2023 response->session_id);
2024 if (!inst) {
2025 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
2026 return;
2027 }
2028
2029 signal_session_msg_receipt(cmd, inst);
2030 show_stats(inst);
2031 put_inst(inst);
2032}
2033
2034static struct vb2_buffer *get_vb_from_device_addr(struct buf_queue *bufq,
2035 unsigned long dev_addr)
2036{
2037 struct vb2_buffer *vb = NULL;
2038 struct vb2_queue *q = NULL;
2039 int found = 0;
2040
2041 if (!bufq) {
2042 dprintk(VIDC_ERR, "Invalid parameter\n");
2043 return NULL;
2044 }
2045 q = &bufq->vb2_bufq;
2046 mutex_lock(&bufq->lock);
2047 list_for_each_entry(vb, &q->queued_list, queued_entry) {
2048 if (vb->planes[0].m.userptr == dev_addr &&
2049 vb->state == VB2_BUF_STATE_ACTIVE) {
2050 found = 1;
2051 dprintk(VIDC_DBG, "Found v4l2_buf index : %d\n",
2052 vb->index);
2053 break;
2054 }
2055 }
2056 mutex_unlock(&bufq->lock);
2057 if (!found) {
2058 dprintk(VIDC_DBG,
2059 "Failed to find buffer in queued list: %#lx, qtype = %d\n",
2060 dev_addr, q->type);
2061 vb = NULL;
2062 }
2063 return vb;
2064}
2065
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08002066static void handle_dynamic_buffer(struct msm_vidc_inst *inst,
2067 ion_phys_addr_t device_addr, u32 flags)
2068{
2069 struct buffer_info *binfo = NULL, *temp = NULL;
2070
2071 /*
2072 * Update reference count and release OR queue back the buffer,
2073 * only when firmware is not holding a reference.
2074 */
2075 binfo = device_to_uvaddr(&inst->registeredbufs, device_addr);
2076 if (!binfo) {
2077 dprintk(VIDC_ERR,
2078 "%s buffer not found in registered list\n",
2079 __func__);
2080 return;
2081 }
2082 if (flags & HAL_BUFFERFLAG_READONLY) {
2083 dprintk(VIDC_DBG,
2084 "FBD fd[0] = %d -> Reference with f/w, addr: %pa\n",
2085 binfo->fd[0], &device_addr);
2086 } else {
2087 dprintk(VIDC_DBG,
2088 "FBD fd[0] = %d -> FBD_ref_released, addr: %pa\n",
2089 binfo->fd[0], &device_addr);
2090
2091 mutex_lock(&inst->registeredbufs.lock);
2092 list_for_each_entry(temp, &inst->registeredbufs.list,
2093 list) {
2094 if (temp == binfo) {
2095 buf_ref_put(inst, binfo);
2096 break;
2097 }
2098 }
2099 mutex_unlock(&inst->registeredbufs.lock);
2100 }
2101}
2102
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002103static void handle_ebd(enum hal_command_response cmd, void *data)
2104{
2105 struct msm_vidc_cb_data_done *response = data;
2106 struct vb2_buffer *vb;
2107 struct msm_vidc_inst *inst;
2108 struct vidc_hal_ebd *empty_buf_done;
2109 struct vb2_v4l2_buffer *vbuf = NULL;
2110
2111 if (!response) {
2112 dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
2113 return;
2114 }
2115
2116 inst = get_inst(get_vidc_core(response->device_id),
2117 response->session_id);
2118 if (!inst) {
2119 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
2120 return;
2121 }
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08002122 if (inst->buffer_mode_set[OUTPUT_PORT] == HAL_BUFFER_MODE_DYNAMIC)
2123 handle_dynamic_buffer(inst,
2124 response->input_done.packet_buffer, 0);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002125
2126 vb = get_vb_from_device_addr(&inst->bufq[OUTPUT_PORT],
2127 response->input_done.packet_buffer);
2128 if (vb) {
2129 vbuf = to_vb2_v4l2_buffer(vb);
2130 vb->planes[0].bytesused = response->input_done.filled_len;
2131 vb->planes[0].data_offset = response->input_done.offset;
2132 if (vb->planes[0].data_offset > vb->planes[0].length)
2133 dprintk(VIDC_INFO, "data_offset overflow length\n");
2134 if (vb->planes[0].bytesused > vb->planes[0].length)
2135 dprintk(VIDC_INFO, "bytesused overflow length\n");
2136 if (vb->planes[0].m.userptr !=
2137 response->clnt_data)
2138 dprintk(VIDC_INFO, "Client data != bufaddr\n");
2139 empty_buf_done = (struct vidc_hal_ebd *)&response->input_done;
2140 if (empty_buf_done) {
2141 if (empty_buf_done->status == VIDC_ERR_NOT_SUPPORTED) {
2142 dprintk(VIDC_INFO,
2143 "Failed : Unsupported input stream\n");
2144 vbuf->flags |=
2145 V4L2_QCOM_BUF_INPUT_UNSUPPORTED;
2146 }
2147 if (empty_buf_done->status == VIDC_ERR_BITSTREAM_ERR) {
2148 dprintk(VIDC_INFO,
2149 "Failed : Corrupted input stream\n");
2150 vbuf->flags |=
2151 V4L2_QCOM_BUF_DATA_CORRUPT;
2152 }
2153 if (empty_buf_done->flags & HAL_BUFFERFLAG_SYNCFRAME)
2154 vbuf->flags |=
2155 V4L2_QCOM_BUF_FLAG_IDRFRAME |
2156 V4L2_BUF_FLAG_KEYFRAME;
2157 }
2158 dprintk(VIDC_DBG,
2159 "Got ebd from hal: device_addr: %pa, alloc: %d, status: %#x, pic_type: %#x, flags: %#x\n",
2160 &empty_buf_done->packet_buffer,
2161 empty_buf_done->alloc_len, empty_buf_done->status,
2162 empty_buf_done->picture_type, empty_buf_done->flags);
2163
Praneeth Paladugub71968b2015-08-19 20:47:57 -07002164 msm_vidc_clear_freq_entry(inst, empty_buf_done->packet_buffer);
2165
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002166 mutex_lock(&inst->bufq[OUTPUT_PORT].lock);
2167 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
2168 mutex_unlock(&inst->bufq[OUTPUT_PORT].lock);
2169 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_EBD);
2170 }
2171
2172 put_inst(inst);
2173}
2174
2175int buf_ref_get(struct msm_vidc_inst *inst, struct buffer_info *binfo)
2176{
2177 int cnt = 0;
2178
2179 if (!inst || !binfo)
2180 return -EINVAL;
2181
2182 atomic_inc(&binfo->ref_count);
2183 cnt = atomic_read(&binfo->ref_count);
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08002184 if (cnt >= 2)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002185 inst->buffers_held_in_driver++;
2186
2187 dprintk(VIDC_DBG, "REF_GET[%d] fd[0] = %d\n", cnt, binfo->fd[0]);
2188
2189 return cnt;
2190}
2191
2192int buf_ref_put(struct msm_vidc_inst *inst, struct buffer_info *binfo)
2193{
2194 int rc = 0;
2195 int cnt;
2196 bool release_buf = false;
2197 bool qbuf_again = false;
2198
2199 if (!inst || !binfo)
2200 return -EINVAL;
2201
2202 atomic_dec(&binfo->ref_count);
2203 cnt = atomic_read(&binfo->ref_count);
2204 dprintk(VIDC_DBG, "REF_PUT[%d] fd[0] = %d\n", cnt, binfo->fd[0]);
2205 if (!cnt)
2206 release_buf = true;
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08002207 else if (cnt >= 1)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002208 qbuf_again = true;
2209 else {
2210 dprintk(VIDC_DBG, "%s: invalid ref_cnt: %d\n", __func__, cnt);
2211 cnt = -EINVAL;
2212 }
2213
2214 if (cnt < 0)
2215 return cnt;
2216
2217 if (release_buf) {
2218 /*
2219 * We can not delete binfo here as we need to set the user
2220 * virtual address saved in binfo->uvaddr to the dequeued v4l2
2221 * buffer.
2222 *
2223 * We will set the pending_deletion flag to true here and delete
2224 * binfo from registered list in dqbuf after setting the uvaddr.
2225 */
2226 dprintk(VIDC_DBG, "fd[0] = %d -> pending_deletion = true\n",
2227 binfo->fd[0]);
2228 binfo->pending_deletion = true;
2229 } else if (qbuf_again) {
2230 inst->buffers_held_in_driver--;
2231 rc = qbuf_dynamic_buf(inst, binfo);
2232 if (!rc)
2233 return rc;
2234 }
2235 return cnt;
2236}
2237
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002238static int handle_multi_stream_buffers(struct msm_vidc_inst *inst,
2239 ion_phys_addr_t dev_addr)
2240{
2241 struct internal_buf *binfo;
2242 struct msm_smem *handle;
2243 bool found = false;
2244
2245 mutex_lock(&inst->outputbufs.lock);
2246 list_for_each_entry(binfo, &inst->outputbufs.list, list) {
2247 handle = binfo->handle;
2248 if (handle && dev_addr == handle->device_addr) {
2249 if (binfo->buffer_ownership == DRIVER) {
2250 dprintk(VIDC_ERR,
2251 "FW returned same buffer: %pa\n",
2252 &dev_addr);
2253 break;
2254 }
2255 binfo->buffer_ownership = DRIVER;
2256 found = true;
2257 break;
2258 }
2259 }
2260 mutex_unlock(&inst->outputbufs.lock);
2261
2262 if (!found) {
2263 dprintk(VIDC_ERR,
2264 "Failed to find output buffer in queued list: %pa\n",
2265 &dev_addr);
2266 }
2267
2268 return 0;
2269}
2270
2271enum hal_buffer msm_comm_get_hal_output_buffer(struct msm_vidc_inst *inst)
2272{
2273 if (msm_comm_get_stream_output_mode(inst) ==
2274 HAL_VIDEO_DECODER_SECONDARY)
2275 return HAL_BUFFER_OUTPUT2;
2276 else
2277 return HAL_BUFFER_OUTPUT;
2278}
2279
2280static void handle_fbd(enum hal_command_response cmd, void *data)
2281{
2282 struct msm_vidc_cb_data_done *response = data;
2283 struct msm_vidc_inst *inst;
2284 struct vb2_buffer *vb = NULL;
2285 struct vidc_hal_fbd *fill_buf_done;
2286 enum hal_buffer buffer_type;
2287 int extra_idx = 0;
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07002288 u64 time_usec = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002289 struct vb2_v4l2_buffer *vbuf = NULL;
2290
2291 if (!response) {
2292 dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
2293 return;
2294 }
2295
2296 inst = get_inst(get_vidc_core(response->device_id),
2297 response->session_id);
2298 if (!inst) {
2299 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
2300 return;
2301 }
2302
2303 fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
2304 buffer_type = msm_comm_get_hal_output_buffer(inst);
2305 if (fill_buf_done->buffer_type == buffer_type) {
2306 vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
2307 fill_buf_done->packet_buffer1);
2308 } else {
2309 if (handle_multi_stream_buffers(inst,
2310 fill_buf_done->packet_buffer1))
2311 dprintk(VIDC_ERR,
2312 "Failed : Output buffer not found %pa\n",
2313 &fill_buf_done->packet_buffer1);
2314 goto err_handle_fbd;
2315 }
2316
2317 if (vb) {
2318 vbuf = to_vb2_v4l2_buffer(vb);
Umesh Pandeyd24533d2017-03-14 18:18:18 -07002319 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DROP_FRAME ||
2320 fill_buf_done->flags1 & HAL_BUFFERFLAG_DECODEONLY)
2321 fill_buf_done->filled_len1 = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002322 vb->planes[0].bytesused = fill_buf_done->filled_len1;
2323 vb->planes[0].data_offset = fill_buf_done->offset1;
2324 if (vb->planes[0].data_offset > vb->planes[0].length)
2325 dprintk(VIDC_INFO,
2326 "fbd:Overflow data_offset = %d; length = %d\n",
2327 vb->planes[0].data_offset,
2328 vb->planes[0].length);
2329 if (vb->planes[0].bytesused > vb->planes[0].length)
2330 dprintk(VIDC_INFO,
2331 "fbd:Overflow bytesused = %d; length = %d\n",
2332 vb->planes[0].bytesused,
2333 vb->planes[0].length);
2334 if (!(fill_buf_done->flags1 &
2335 HAL_BUFFERFLAG_TIMESTAMPINVALID)) {
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07002336 time_usec = fill_buf_done->timestamp_hi;
2337 time_usec = (time_usec << 32) |
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002338 fill_buf_done->timestamp_lo;
2339 } else {
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07002340 time_usec = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002341 dprintk(VIDC_DBG,
2342 "Set zero timestamp for buffer %pa, filled: %d, (hi:%u, lo:%u)\n",
2343 &fill_buf_done->packet_buffer1,
2344 fill_buf_done->filled_len1,
2345 fill_buf_done->timestamp_hi,
2346 fill_buf_done->timestamp_lo);
2347 }
2348 vbuf->flags = 0;
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07002349 vb->timestamp = (time_usec * NSEC_PER_USEC);
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002350
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002351 extra_idx =
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08002352 EXTRADATA_IDX(inst->bufq[CAPTURE_PORT].num_planes);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002353 if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
2354 vb->planes[extra_idx].m.userptr =
2355 (unsigned long)fill_buf_done->extra_data_buffer;
2356 vb->planes[extra_idx].bytesused =
2357 vb->planes[extra_idx].length;
2358 vb->planes[extra_idx].data_offset = 0;
2359 }
2360
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08002361 if (inst->buffer_mode_set[CAPTURE_PORT] ==
2362 HAL_BUFFER_MODE_DYNAMIC)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002363 handle_dynamic_buffer(inst, fill_buf_done->packet_buffer1,
2364 fill_buf_done->flags1);
2365 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_READONLY)
2366 vbuf->flags |= V4L2_QCOM_BUF_FLAG_READONLY;
2367 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOS)
2368 vbuf->flags |= V4L2_QCOM_BUF_FLAG_EOS;
2369 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_CODECCONFIG)
2370 vbuf->flags &= ~V4L2_QCOM_BUF_FLAG_CODECCONFIG;
2371 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_SYNCFRAME)
2372 vbuf->flags |= V4L2_QCOM_BUF_FLAG_IDRFRAME;
2373 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOSEQ)
2374 vbuf->flags |= V4L2_QCOM_BUF_FLAG_EOSEQ;
Umesh Pandeyd24533d2017-03-14 18:18:18 -07002375 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DECODEONLY ||
2376 fill_buf_done->flags1 & HAL_BUFFERFLAG_DROP_FRAME)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002377 vbuf->flags |= V4L2_QCOM_BUF_FLAG_DECODEONLY;
2378 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DATACORRUPT)
2379 vbuf->flags |= V4L2_QCOM_BUF_DATA_CORRUPT;
2380
2381 switch (fill_buf_done->picture_type) {
2382 case HAL_PICTURE_IDR:
2383 vbuf->flags |= V4L2_QCOM_BUF_FLAG_IDRFRAME;
2384 vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
2385 break;
2386 case HAL_PICTURE_I:
2387 vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
2388 break;
2389 case HAL_PICTURE_P:
2390 vbuf->flags |= V4L2_BUF_FLAG_PFRAME;
2391 break;
2392 case HAL_PICTURE_B:
2393 vbuf->flags |= V4L2_BUF_FLAG_BFRAME;
2394 break;
2395 case HAL_FRAME_NOTCODED:
2396 case HAL_UNUSED_PICT:
2397 /* Do we need to care about these? */
2398 case HAL_FRAME_YUV:
2399 break;
2400 default:
2401 break;
2402 }
2403
2404 inst->count.fbd++;
2405
2406 if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
2407 dprintk(VIDC_DBG,
2408 "extradata: userptr = %pK;"
2409 " bytesused = %d; length = %d\n",
2410 (u8 *)vb->planes[extra_idx].m.userptr,
2411 vb->planes[extra_idx].bytesused,
2412 vb->planes[extra_idx].length);
2413 }
2414 dprintk(VIDC_DBG,
2415 "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",
2416 &fill_buf_done->packet_buffer1, fill_buf_done->alloc_len1,
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07002417 fill_buf_done->filled_len1, fill_buf_done->offset1, time_usec,
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002418 fill_buf_done->flags1, fill_buf_done->start_x_coord,
2419 fill_buf_done->start_y_coord, fill_buf_done->frame_width,
2420 fill_buf_done->frame_height, fill_buf_done->picture_type,
2421 fill_buf_done->mark_data);
2422
2423 mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
2424 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
2425 mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
2426 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FBD);
2427 }
2428
2429err_handle_fbd:
2430 put_inst(inst);
2431}
2432
2433static void handle_seq_hdr_done(enum hal_command_response cmd, void *data)
2434{
2435 struct msm_vidc_cb_data_done *response = data;
2436 struct msm_vidc_inst *inst;
2437 struct vb2_buffer *vb;
2438 struct vidc_hal_fbd *fill_buf_done;
2439 struct vb2_v4l2_buffer *vbuf;
2440
2441 if (!response) {
2442 dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
2443 return;
2444 }
2445
2446 inst = get_inst(get_vidc_core(response->device_id),
2447 response->session_id);
2448 if (!inst) {
2449 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
2450 return;
2451 }
2452
2453 fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
2454 vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
2455 fill_buf_done->packet_buffer1);
2456 if (!vb) {
2457 dprintk(VIDC_ERR,
2458 "Failed to find video buffer for seq_hdr_done: %pa\n",
2459 &fill_buf_done->packet_buffer1);
2460 goto err_seq_hdr_done;
2461 }
2462 vbuf = to_vb2_v4l2_buffer(vb);
Umesh Pandeyd24533d2017-03-14 18:18:18 -07002463 vb->timestamp = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002464
2465 vb->planes[0].bytesused = fill_buf_done->filled_len1;
2466 vb->planes[0].data_offset = fill_buf_done->offset1;
2467
2468 vbuf->flags = V4L2_QCOM_BUF_FLAG_CODECCONFIG;
2469
2470 dprintk(VIDC_DBG, "Filled length = %d; offset = %d; flags %x\n",
2471 vb->planes[0].bytesused,
2472 vb->planes[0].data_offset,
2473 vbuf->flags);
2474 mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
2475 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
2476 mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
2477
2478err_seq_hdr_done:
2479 put_inst(inst);
2480}
2481
2482void handle_cmd_response(enum hal_command_response cmd, void *data)
2483{
2484 dprintk(VIDC_DBG, "Command response = %d\n", cmd);
2485 switch (cmd) {
2486 case HAL_SYS_INIT_DONE:
2487 handle_sys_init_done(cmd, data);
2488 break;
2489 case HAL_SYS_RELEASE_RESOURCE_DONE:
2490 handle_sys_release_res_done(cmd, data);
2491 break;
2492 case HAL_SESSION_INIT_DONE:
2493 handle_session_init_done(cmd, data);
2494 break;
2495 case HAL_SESSION_PROPERTY_INFO:
2496 handle_session_prop_info(cmd, data);
2497 break;
2498 case HAL_SESSION_LOAD_RESOURCE_DONE:
2499 handle_load_resource_done(cmd, data);
2500 break;
2501 case HAL_SESSION_START_DONE:
2502 handle_start_done(cmd, data);
2503 break;
2504 case HAL_SESSION_ETB_DONE:
2505 handle_ebd(cmd, data);
2506 break;
2507 case HAL_SESSION_FTB_DONE:
2508 handle_fbd(cmd, data);
2509 break;
2510 case HAL_SESSION_STOP_DONE:
2511 handle_stop_done(cmd, data);
2512 break;
2513 case HAL_SESSION_RELEASE_RESOURCE_DONE:
2514 handle_release_res_done(cmd, data);
2515 break;
2516 case HAL_SESSION_END_DONE:
2517 case HAL_SESSION_ABORT_DONE:
2518 handle_session_close(cmd, data);
2519 break;
2520 case HAL_SESSION_EVENT_CHANGE:
2521 handle_event_change(cmd, data);
2522 break;
2523 case HAL_SESSION_FLUSH_DONE:
2524 handle_session_flush(cmd, data);
2525 break;
2526 case HAL_SESSION_GET_SEQ_HDR_DONE:
2527 handle_seq_hdr_done(cmd, data);
2528 break;
2529 case HAL_SYS_WATCHDOG_TIMEOUT:
2530 case HAL_SYS_ERROR:
2531 handle_sys_error(cmd, data);
2532 break;
2533 case HAL_SESSION_ERROR:
2534 handle_session_error(cmd, data);
2535 break;
2536 case HAL_SESSION_RELEASE_BUFFER_DONE:
2537 handle_session_release_buf_done(cmd, data);
2538 break;
2539 default:
2540 dprintk(VIDC_DBG, "response unhandled: %d\n", cmd);
2541 break;
2542 }
2543}
2544
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002545static inline enum msm_vidc_thermal_level msm_comm_vidc_thermal_level(int level)
2546{
2547 switch (level) {
2548 case 0:
2549 return VIDC_THERMAL_NORMAL;
2550 case 1:
2551 return VIDC_THERMAL_LOW;
2552 case 2:
2553 return VIDC_THERMAL_HIGH;
2554 default:
2555 return VIDC_THERMAL_CRITICAL;
2556 }
2557}
2558
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002559static bool is_core_turbo(struct msm_vidc_core *core, unsigned long freq)
2560{
2561 int i = 0;
Praneeth Paladugub71968b2015-08-19 20:47:57 -07002562 struct allowed_clock_rates_table *allowed_clks_tbl = NULL;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002563 u32 max_freq = 0;
2564
Praneeth Paladugub71968b2015-08-19 20:47:57 -07002565 allowed_clks_tbl = core->resources.allowed_clks_tbl;
2566 for (i = 0; i < core->resources.allowed_clks_tbl_size; i++) {
2567 if (max_freq < allowed_clks_tbl[i].clock_rate)
2568 max_freq = allowed_clks_tbl[i].clock_rate;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002569 }
2570 return freq >= max_freq;
2571}
2572
2573static bool is_thermal_permissible(struct msm_vidc_core *core)
2574{
2575 enum msm_vidc_thermal_level tl;
2576 unsigned long freq = 0;
2577 bool is_turbo = false;
2578
2579 if (!core->resources.thermal_mitigable)
2580 return true;
2581
2582 if (msm_vidc_thermal_mitigation_disabled) {
2583 dprintk(VIDC_DBG,
2584 "Thermal mitigation not enabled. debugfs %d\n",
2585 msm_vidc_thermal_mitigation_disabled);
2586 return true;
2587 }
2588
2589 tl = msm_comm_vidc_thermal_level(vidc_driver->thermal_level);
Praneeth Paladugub71968b2015-08-19 20:47:57 -07002590 freq = core->freq;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002591
2592 is_turbo = is_core_turbo(core, freq);
2593 dprintk(VIDC_DBG,
2594 "Core freq %ld Thermal level %d Turbo mode %d\n",
2595 freq, tl, is_turbo);
2596
2597 if (is_turbo && tl >= VIDC_THERMAL_LOW) {
2598 dprintk(VIDC_ERR,
2599 "Video session not allowed. Turbo mode %d Thermal level %d\n",
2600 is_turbo, tl);
2601 return false;
2602 }
2603 return true;
2604}
2605
2606static int msm_comm_session_abort(struct msm_vidc_inst *inst)
2607{
2608 int rc = 0, abort_completion = 0;
2609 struct hfi_device *hdev;
2610
2611 if (!inst || !inst->core || !inst->core->device) {
2612 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
2613 return -EINVAL;
2614 }
2615 hdev = inst->core->device;
2616 abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE);
2617
2618 rc = call_hfi_op(hdev, session_abort, (void *)inst->session);
2619 if (rc) {
2620 dprintk(VIDC_ERR,
2621 "%s session_abort failed rc: %d\n", __func__, rc);
2622 return rc;
2623 }
2624 rc = wait_for_completion_timeout(
2625 &inst->completions[abort_completion],
2626 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
2627 if (!rc) {
2628 dprintk(VIDC_ERR,
2629 "%s: Wait interrupted or timed out [%pK]: %d\n",
2630 __func__, inst, abort_completion);
2631 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
2632 dprintk(VIDC_ERR,
2633 "ABORT timeout can potentially crash the system\n");
2634 msm_comm_print_debug_info(inst);
2635
2636 msm_vidc_handle_hw_error(inst->core);
2637 rc = -EBUSY;
2638 } else {
2639 rc = 0;
2640 }
2641 msm_comm_session_clean(inst);
2642 return rc;
2643}
2644
2645static void handle_thermal_event(struct msm_vidc_core *core)
2646{
2647 int rc = 0;
2648 struct msm_vidc_inst *inst;
2649
2650 if (!core || !core->device) {
2651 dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
2652 return;
2653 }
2654 mutex_lock(&core->lock);
2655 list_for_each_entry(inst, &core->instances, list) {
2656 if (!inst->session)
2657 continue;
2658
2659 mutex_unlock(&core->lock);
2660 if (inst->state >= MSM_VIDC_OPEN_DONE &&
2661 inst->state < MSM_VIDC_CLOSE_DONE) {
2662 dprintk(VIDC_WARN, "%s: abort inst %pK\n",
2663 __func__, inst);
2664 rc = msm_comm_session_abort(inst);
2665 if (rc) {
2666 dprintk(VIDC_ERR,
2667 "%s session_abort failed rc: %d\n",
2668 __func__, rc);
2669 goto err_sess_abort;
2670 }
2671 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
2672 dprintk(VIDC_WARN,
2673 "%s Send sys error for inst %pK\n",
2674 __func__, inst);
2675 msm_vidc_queue_v4l2_event(inst,
2676 V4L2_EVENT_MSM_VIDC_SYS_ERROR);
2677 } else {
2678 msm_comm_generate_session_error(inst);
2679 }
2680 mutex_lock(&core->lock);
2681 }
2682 mutex_unlock(&core->lock);
2683 return;
2684
2685err_sess_abort:
2686 msm_comm_clean_notify_client(core);
2687}
2688
2689void msm_comm_handle_thermal_event(void)
2690{
2691 struct msm_vidc_core *core;
2692
2693 list_for_each_entry(core, &vidc_driver->cores, list) {
2694 if (!is_thermal_permissible(core)) {
2695 dprintk(VIDC_WARN,
2696 "Thermal level critical, stop all active sessions!\n");
2697 handle_thermal_event(core);
2698 }
2699 }
2700}
2701
2702int msm_comm_check_core_init(struct msm_vidc_core *core)
2703{
2704 int rc = 0;
2705 struct hfi_device *hdev;
2706 struct msm_vidc_inst *inst = NULL;
2707
2708 mutex_lock(&core->lock);
2709 if (core->state >= VIDC_CORE_INIT_DONE) {
2710 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
2711 core->id, core->state);
2712 goto exit;
2713 }
2714 dprintk(VIDC_DBG, "Waiting for SYS_INIT_DONE\n");
2715 hdev = (struct hfi_device *)core->device;
2716 rc = wait_for_completion_timeout(
2717 &core->completions[SYS_MSG_INDEX(HAL_SYS_INIT_DONE)],
2718 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
2719 if (!rc) {
2720 dprintk(VIDC_ERR, "%s: Wait interrupted or timed out: %d\n",
2721 __func__, SYS_MSG_INDEX(HAL_SYS_INIT_DONE));
2722 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
2723 dprintk(VIDC_ERR,
2724 "SYS_INIT timeout can potentially crash the system\n");
2725 /*
2726 * For SYS_INIT, there will not be any inst pointer.
2727 * Just grab one of the inst from instances list and
2728 * use it.
2729 */
2730 inst = list_first_entry(&core->instances,
2731 struct msm_vidc_inst, list);
2732
2733 mutex_unlock(&core->lock);
2734 msm_comm_print_debug_info(inst);
2735 mutex_lock(&core->lock);
2736
2737 msm_vidc_handle_hw_error(core);
2738 rc = -EIO;
2739 goto exit;
2740 } else {
2741 core->state = VIDC_CORE_INIT_DONE;
2742 rc = 0;
2743 }
2744 dprintk(VIDC_DBG, "SYS_INIT_DONE!!!\n");
2745exit:
2746 mutex_unlock(&core->lock);
2747 return rc;
2748}
2749
2750static int msm_comm_init_core_done(struct msm_vidc_inst *inst)
2751{
2752 int rc = 0;
2753
2754 rc = msm_comm_check_core_init(inst->core);
2755 if (rc) {
2756 dprintk(VIDC_ERR, "%s - failed to initialize core\n", __func__);
2757 msm_comm_generate_sys_error(inst);
2758 return rc;
2759 }
2760 change_inst_state(inst, MSM_VIDC_CORE_INIT_DONE);
2761 return rc;
2762}
2763
2764static int msm_comm_init_core(struct msm_vidc_inst *inst)
2765{
2766 int rc = 0;
2767 struct hfi_device *hdev;
2768 struct msm_vidc_core *core;
2769
2770 if (!inst || !inst->core || !inst->core->device)
2771 return -EINVAL;
2772
2773 core = inst->core;
2774 hdev = core->device;
2775 mutex_lock(&core->lock);
2776 if (core->state >= VIDC_CORE_INIT) {
2777 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
2778 core->id, core->state);
2779 goto core_already_inited;
2780 }
2781 if (!core->capabilities) {
2782 core->capabilities = kzalloc(VIDC_MAX_SESSIONS *
2783 sizeof(struct msm_vidc_capability), GFP_KERNEL);
2784 if (!core->capabilities) {
2785 dprintk(VIDC_ERR,
2786 "%s: failed to allocate capabilities\n",
2787 __func__);
2788 rc = -ENOMEM;
2789 goto fail_cap_alloc;
2790 }
2791 } else {
2792 dprintk(VIDC_WARN,
2793 "%s: capabilities memory is expected to be freed\n",
2794 __func__);
2795 }
2796
2797 rc = call_hfi_op(hdev, core_init, hdev->hfi_device_data);
2798 if (rc) {
2799 dprintk(VIDC_ERR, "Failed to init core, id = %d\n",
2800 core->id);
2801 goto fail_core_init;
2802 }
2803 core->state = VIDC_CORE_INIT;
2804 core->smmu_fault_handled = false;
2805core_already_inited:
2806 change_inst_state(inst, MSM_VIDC_CORE_INIT);
2807 mutex_unlock(&core->lock);
Praneeth Paladugub71968b2015-08-19 20:47:57 -07002808
2809 rc = msm_comm_scale_clocks_and_bus(inst);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002810 return rc;
2811
2812fail_core_init:
2813 kfree(core->capabilities);
2814fail_cap_alloc:
2815 core->capabilities = NULL;
2816 core->state = VIDC_CORE_UNINIT;
2817 mutex_unlock(&core->lock);
2818 return rc;
2819}
2820
2821static int msm_vidc_deinit_core(struct msm_vidc_inst *inst)
2822{
2823 struct msm_vidc_core *core;
2824 struct hfi_device *hdev;
2825
2826 if (!inst || !inst->core || !inst->core->device) {
2827 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
2828 return -EINVAL;
2829 }
2830
2831 core = inst->core;
2832 hdev = core->device;
2833
2834 mutex_lock(&core->lock);
2835 if (core->state == VIDC_CORE_UNINIT) {
2836 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
2837 core->id, core->state);
2838 goto core_already_uninited;
2839 }
2840 mutex_unlock(&core->lock);
2841
2842 msm_comm_scale_clocks_and_bus(inst);
2843
2844 mutex_lock(&core->lock);
2845
2846 if (!core->resources.never_unload_fw) {
2847 cancel_delayed_work(&core->fw_unload_work);
2848
2849 /*
2850 * Delay unloading of firmware. This is useful
2851 * in avoiding firmware download delays in cases where we
2852 * will have a burst of back to back video playback sessions
2853 * e.g. thumbnail generation.
2854 */
2855 schedule_delayed_work(&core->fw_unload_work,
2856 msecs_to_jiffies(core->state == VIDC_CORE_INVALID ?
2857 0 : msm_vidc_firmware_unload_delay));
2858
2859 dprintk(VIDC_DBG, "firmware unload delayed by %u ms\n",
2860 core->state == VIDC_CORE_INVALID ?
2861 0 : msm_vidc_firmware_unload_delay);
2862 }
2863
2864core_already_uninited:
2865 change_inst_state(inst, MSM_VIDC_CORE_UNINIT);
2866 mutex_unlock(&core->lock);
2867 return 0;
2868}
2869
2870int msm_comm_force_cleanup(struct msm_vidc_inst *inst)
2871{
2872 msm_comm_kill_session(inst);
2873 return msm_vidc_deinit_core(inst);
2874}
2875
2876static int msm_comm_session_init(int flipped_state,
2877 struct msm_vidc_inst *inst)
2878{
2879 int rc = 0;
2880 int fourcc = 0;
2881 struct hfi_device *hdev;
2882
2883 if (!inst || !inst->core || !inst->core->device) {
2884 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
2885 return -EINVAL;
2886 }
2887 hdev = inst->core->device;
2888
2889 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) {
2890 dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n",
2891 inst, inst->state);
2892 goto exit;
2893 }
2894 if (inst->session_type == MSM_VIDC_DECODER) {
2895 fourcc = inst->fmts[OUTPUT_PORT].fourcc;
2896 } else if (inst->session_type == MSM_VIDC_ENCODER) {
2897 fourcc = inst->fmts[CAPTURE_PORT].fourcc;
2898 } else {
2899 dprintk(VIDC_ERR, "Invalid session\n");
2900 return -EINVAL;
2901 }
2902
Praneeth Paladugub71968b2015-08-19 20:47:57 -07002903 msm_comm_init_clocks_and_bus_data(inst);
2904
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002905 rc = call_hfi_op(hdev, session_init, hdev->hfi_device_data,
2906 inst, get_hal_domain(inst->session_type),
2907 get_hal_codec(fourcc),
2908 &inst->session);
2909
2910 if (rc || !inst->session) {
2911 dprintk(VIDC_ERR,
2912 "Failed to call session init for: %pK, %pK, %d, %d\n",
2913 inst->core->device, inst,
2914 inst->session_type, fourcc);
2915 rc = -EINVAL;
2916 goto exit;
2917 }
2918 change_inst_state(inst, MSM_VIDC_OPEN);
2919exit:
2920 return rc;
2921}
2922
2923static void msm_vidc_print_running_insts(struct msm_vidc_core *core)
2924{
2925 struct msm_vidc_inst *temp;
2926
2927 dprintk(VIDC_ERR, "Running instances:\n");
2928 dprintk(VIDC_ERR, "%4s|%4s|%4s|%4s|%4s\n",
2929 "type", "w", "h", "fps", "prop");
2930
2931 mutex_lock(&core->lock);
2932 list_for_each_entry(temp, &core->instances, list) {
2933 if (temp->state >= MSM_VIDC_OPEN_DONE &&
2934 temp->state < MSM_VIDC_STOP_DONE) {
2935 char properties[4] = "";
2936
2937 if (is_thumbnail_session(temp))
2938 strlcat(properties, "N", sizeof(properties));
2939
2940 if (msm_comm_turbo_session(temp))
2941 strlcat(properties, "T", sizeof(properties));
2942
2943 dprintk(VIDC_ERR, "%4d|%4d|%4d|%4d|%4s\n",
2944 temp->session_type,
2945 max(temp->prop.width[CAPTURE_PORT],
2946 temp->prop.width[OUTPUT_PORT]),
2947 max(temp->prop.height[CAPTURE_PORT],
2948 temp->prop.height[OUTPUT_PORT]),
2949 temp->prop.fps, properties);
2950 }
2951 }
2952 mutex_unlock(&core->lock);
2953}
2954
2955static int msm_vidc_load_resources(int flipped_state,
2956 struct msm_vidc_inst *inst)
2957{
2958 int rc = 0;
2959 struct hfi_device *hdev;
2960 int num_mbs_per_sec = 0, max_load_adj = 0;
2961 struct msm_vidc_core *core;
2962 enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD |
2963 LOAD_CALC_IGNORE_THUMBNAIL_LOAD |
2964 LOAD_CALC_IGNORE_NON_REALTIME_LOAD;
2965
2966 if (!inst || !inst->core || !inst->core->device) {
2967 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
2968 return -EINVAL;
2969 }
2970
2971 core = inst->core;
2972 if (core->state == VIDC_CORE_INVALID) {
2973 dprintk(VIDC_ERR,
2974 "Core is in bad state can't do load res\n");
2975 return -EINVAL;
2976 }
2977
2978 if (inst->state == MSM_VIDC_CORE_INVALID) {
2979 dprintk(VIDC_ERR,
2980 "Instance is in invalid state can't do load res\n");
2981 return -EINVAL;
2982 }
2983
2984 num_mbs_per_sec =
2985 msm_comm_get_load(core, MSM_VIDC_DECODER, quirks) +
2986 msm_comm_get_load(core, MSM_VIDC_ENCODER, quirks);
2987
2988 max_load_adj = core->resources.max_load +
2989 inst->capability.mbs_per_frame.max;
2990
2991 if (num_mbs_per_sec > max_load_adj) {
2992 dprintk(VIDC_ERR, "HW is overloaded, needed: %d max: %d\n",
2993 num_mbs_per_sec, max_load_adj);
2994 msm_vidc_print_running_insts(core);
2995 inst->state = MSM_VIDC_CORE_INVALID;
2996 msm_comm_kill_session(inst);
2997 return -EBUSY;
2998 }
2999
3000 hdev = core->device;
3001 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) {
3002 dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n",
3003 inst, inst->state);
3004 goto exit;
3005 }
3006
3007 rc = call_hfi_op(hdev, session_load_res, (void *) inst->session);
3008 if (rc) {
3009 dprintk(VIDC_ERR,
3010 "Failed to send load resources\n");
3011 goto exit;
3012 }
3013 change_inst_state(inst, MSM_VIDC_LOAD_RESOURCES);
3014exit:
3015 return rc;
3016}
3017
3018static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst)
3019{
3020 int rc = 0;
3021 struct hfi_device *hdev;
3022
3023 if (!inst || !inst->core || !inst->core->device) {
3024 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3025 return -EINVAL;
3026 }
3027 if (inst->state == MSM_VIDC_CORE_INVALID ||
3028 inst->core->state == VIDC_CORE_INVALID) {
3029 dprintk(VIDC_ERR,
3030 "Core is in bad state can't do start\n");
3031 return -EINVAL;
3032 }
3033
3034 hdev = inst->core->device;
3035
3036 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) {
3037 dprintk(VIDC_INFO,
3038 "inst: %pK is already in state: %d\n",
3039 inst, inst->state);
3040 goto exit;
3041 }
3042 rc = call_hfi_op(hdev, session_start, (void *) inst->session);
3043 if (rc) {
3044 dprintk(VIDC_ERR,
3045 "Failed to send start\n");
3046 goto exit;
3047 }
3048 change_inst_state(inst, MSM_VIDC_START);
3049exit:
3050 return rc;
3051}
3052
3053static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst)
3054{
3055 int rc = 0;
3056 struct hfi_device *hdev;
3057
3058 if (!inst || !inst->core || !inst->core->device) {
3059 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3060 return -EINVAL;
3061 }
3062 hdev = inst->core->device;
3063
3064 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) {
3065 dprintk(VIDC_INFO,
3066 "inst: %pK is already in state: %d\n",
3067 inst, inst->state);
3068 goto exit;
3069 }
3070 dprintk(VIDC_DBG, "Send Stop to hal\n");
3071 rc = call_hfi_op(hdev, session_stop, (void *) inst->session);
3072 if (rc) {
3073 dprintk(VIDC_ERR, "Failed to send stop\n");
3074 goto exit;
3075 }
3076 change_inst_state(inst, MSM_VIDC_STOP);
3077exit:
3078 return rc;
3079}
3080
3081static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst)
3082{
3083 int rc = 0;
3084 struct hfi_device *hdev;
3085
3086 if (!inst || !inst->core || !inst->core->device) {
3087 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3088 return -EINVAL;
3089 }
3090 hdev = inst->core->device;
3091
3092 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) {
3093 dprintk(VIDC_INFO,
3094 "inst: %pK is already in state: %d\n",
3095 inst, inst->state);
3096 goto exit;
3097 }
3098 dprintk(VIDC_DBG,
3099 "Send release res to hal\n");
3100 rc = call_hfi_op(hdev, session_release_res, (void *) inst->session);
3101 if (rc) {
3102 dprintk(VIDC_ERR,
3103 "Failed to send release resources\n");
3104 goto exit;
3105 }
3106 change_inst_state(inst, MSM_VIDC_RELEASE_RESOURCES);
3107exit:
3108 return rc;
3109}
3110
3111static int msm_comm_session_close(int flipped_state,
3112 struct msm_vidc_inst *inst)
3113{
3114 int rc = 0;
3115 struct hfi_device *hdev;
3116
3117 if (!inst || !inst->core || !inst->core->device) {
3118 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
3119 return -EINVAL;
3120 }
3121 hdev = inst->core->device;
3122 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) {
3123 dprintk(VIDC_INFO,
3124 "inst: %pK is already in state: %d\n",
3125 inst, inst->state);
3126 goto exit;
3127 }
3128 dprintk(VIDC_DBG,
3129 "Send session close to hal\n");
3130 rc = call_hfi_op(hdev, session_end, (void *) inst->session);
3131 if (rc) {
3132 dprintk(VIDC_ERR,
3133 "Failed to send close\n");
3134 goto exit;
3135 }
3136 change_inst_state(inst, MSM_VIDC_CLOSE);
3137exit:
3138 return rc;
3139}
3140
3141int msm_comm_suspend(int core_id)
3142{
3143 struct hfi_device *hdev;
3144 struct msm_vidc_core *core;
3145 int rc = 0;
3146
3147 core = get_vidc_core(core_id);
3148 if (!core) {
3149 dprintk(VIDC_ERR,
3150 "%s: Failed to find core for core_id = %d\n",
3151 __func__, core_id);
3152 return -EINVAL;
3153 }
3154
3155 hdev = (struct hfi_device *)core->device;
3156 if (!hdev) {
3157 dprintk(VIDC_ERR, "%s Invalid device handle\n", __func__);
3158 return -EINVAL;
3159 }
3160
3161 mutex_lock(&core->lock);
3162 if (core->state == VIDC_CORE_INVALID) {
3163 dprintk(VIDC_ERR,
3164 "%s - fw is not in proper state, skip suspend\n",
3165 __func__);
3166 rc = -EINVAL;
3167 goto exit;
3168 }
3169
3170 rc = call_hfi_op(hdev, suspend, hdev->hfi_device_data);
3171 if (rc)
3172 dprintk(VIDC_WARN, "Failed to suspend\n");
3173
3174exit:
3175 mutex_unlock(&core->lock);
3176 return rc;
3177}
3178
3179static int get_flipped_state(int present_state,
3180 int desired_state)
3181{
3182 int flipped_state = present_state;
3183
3184 if (flipped_state < MSM_VIDC_STOP
3185 && desired_state > MSM_VIDC_STOP) {
3186 flipped_state = MSM_VIDC_STOP + (MSM_VIDC_STOP - flipped_state);
3187 flipped_state &= 0xFFFE;
3188 flipped_state = flipped_state - 1;
3189 } else if (flipped_state > MSM_VIDC_STOP
3190 && desired_state < MSM_VIDC_STOP) {
3191 flipped_state = MSM_VIDC_STOP -
3192 (flipped_state - MSM_VIDC_STOP + 1);
3193 flipped_state &= 0xFFFE;
3194 flipped_state = flipped_state - 1;
3195 }
3196 return flipped_state;
3197}
3198
3199struct hal_buffer_requirements *get_buff_req_buffer(
3200 struct msm_vidc_inst *inst, enum hal_buffer buffer_type)
3201{
3202 int i;
3203
3204 for (i = 0; i < HAL_BUFFER_MAX; i++) {
3205 if (inst->buff_req.buffer[i].buffer_type == buffer_type)
3206 return &inst->buff_req.buffer[i];
3207 }
3208 return NULL;
3209}
3210
3211static int set_output_buffers(struct msm_vidc_inst *inst,
3212 enum hal_buffer buffer_type)
3213{
3214 int rc = 0;
3215 struct msm_smem *handle;
3216 struct internal_buf *binfo;
3217 u32 smem_flags = 0, buffer_size;
3218 struct hal_buffer_requirements *output_buf, *extradata_buf;
3219 int i;
3220 struct hfi_device *hdev;
3221 struct hal_buffer_size_minimum b;
3222
3223 hdev = inst->core->device;
3224
3225 output_buf = get_buff_req_buffer(inst, buffer_type);
3226 if (!output_buf) {
3227 dprintk(VIDC_DBG,
3228 "This output buffer not required, buffer_type: %x\n",
3229 buffer_type);
3230 return 0;
3231 }
3232 dprintk(VIDC_DBG,
3233 "output: num = %d, size = %d\n",
3234 output_buf->buffer_count_actual,
3235 output_buf->buffer_size);
3236
3237 buffer_size = output_buf->buffer_size;
3238 b.buffer_type = buffer_type;
3239 b.buffer_size = buffer_size;
3240 rc = call_hfi_op(hdev, session_set_property,
3241 inst->session, HAL_PARAM_BUFFER_SIZE_MINIMUM,
3242 &b);
3243
3244 extradata_buf = get_buff_req_buffer(inst, HAL_BUFFER_EXTRADATA_OUTPUT);
3245 if (extradata_buf) {
3246 dprintk(VIDC_DBG,
3247 "extradata: num = %d, size = %d\n",
3248 extradata_buf->buffer_count_actual,
3249 extradata_buf->buffer_size);
3250 buffer_size += extradata_buf->buffer_size;
3251 } else {
3252 dprintk(VIDC_DBG,
3253 "This extradata buffer not required, buffer_type: %x\n",
3254 buffer_type);
3255 }
3256
3257 if (inst->flags & VIDC_SECURE)
3258 smem_flags |= SMEM_SECURE;
3259
3260 if (output_buf->buffer_size) {
3261 for (i = 0; i < output_buf->buffer_count_actual;
3262 i++) {
3263 handle = msm_comm_smem_alloc(inst,
3264 buffer_size, 1, smem_flags,
3265 buffer_type, 0);
3266 if (!handle) {
3267 dprintk(VIDC_ERR,
3268 "Failed to allocate output memory\n");
3269 rc = -ENOMEM;
3270 goto err_no_mem;
3271 }
3272 rc = msm_comm_smem_cache_operations(inst,
3273 handle, SMEM_CACHE_CLEAN);
3274 if (rc) {
3275 dprintk(VIDC_WARN,
3276 "Failed to clean cache may cause undefined behavior\n");
3277 }
3278 binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
3279 if (!binfo) {
3280 dprintk(VIDC_ERR, "Out of memory\n");
3281 rc = -ENOMEM;
3282 goto fail_kzalloc;
3283 }
3284
3285 binfo->handle = handle;
3286 binfo->buffer_type = buffer_type;
3287 binfo->buffer_ownership = DRIVER;
3288 dprintk(VIDC_DBG, "Output buffer address: %pa\n",
3289 &handle->device_addr);
3290
3291 if (inst->buffer_mode_set[CAPTURE_PORT] ==
3292 HAL_BUFFER_MODE_STATIC) {
3293 struct vidc_buffer_addr_info buffer_info = {0};
3294
3295 buffer_info.buffer_size =
3296 output_buf->buffer_size;
3297 buffer_info.buffer_type = buffer_type;
3298 buffer_info.num_buffers = 1;
3299 buffer_info.align_device_addr =
3300 handle->device_addr;
3301 buffer_info.extradata_addr =
3302 handle->device_addr +
3303 output_buf->buffer_size;
3304 if (extradata_buf)
3305 buffer_info.extradata_size =
3306 extradata_buf->buffer_size;
3307 rc = call_hfi_op(hdev, session_set_buffers,
3308 (void *) inst->session, &buffer_info);
3309 if (rc) {
3310 dprintk(VIDC_ERR,
3311 "%s : session_set_buffers failed\n",
3312 __func__);
3313 goto fail_set_buffers;
3314 }
3315 }
3316 mutex_lock(&inst->outputbufs.lock);
3317 list_add_tail(&binfo->list, &inst->outputbufs.list);
3318 mutex_unlock(&inst->outputbufs.lock);
3319 }
3320 }
3321 return rc;
3322fail_set_buffers:
3323 kfree(binfo);
3324fail_kzalloc:
3325 msm_comm_smem_free(inst, handle);
3326err_no_mem:
3327 return rc;
3328}
3329
3330static inline char *get_buffer_name(enum hal_buffer buffer_type)
3331{
3332 switch (buffer_type) {
3333 case HAL_BUFFER_INPUT: return "input";
3334 case HAL_BUFFER_OUTPUT: return "output";
3335 case HAL_BUFFER_OUTPUT2: return "output_2";
3336 case HAL_BUFFER_EXTRADATA_INPUT: return "input_extra";
3337 case HAL_BUFFER_EXTRADATA_OUTPUT: return "output_extra";
3338 case HAL_BUFFER_EXTRADATA_OUTPUT2: return "output2_extra";
3339 case HAL_BUFFER_INTERNAL_SCRATCH: return "scratch";
3340 case HAL_BUFFER_INTERNAL_SCRATCH_1: return "scratch_1";
3341 case HAL_BUFFER_INTERNAL_SCRATCH_2: return "scratch_2";
3342 case HAL_BUFFER_INTERNAL_PERSIST: return "persist";
3343 case HAL_BUFFER_INTERNAL_PERSIST_1: return "persist_1";
3344 case HAL_BUFFER_INTERNAL_CMD_QUEUE: return "queue";
3345 default: return "????";
3346 }
3347}
3348
3349static int set_internal_buf_on_fw(struct msm_vidc_inst *inst,
3350 enum hal_buffer buffer_type,
3351 struct msm_smem *handle, bool reuse)
3352{
3353 struct vidc_buffer_addr_info buffer_info;
3354 struct hfi_device *hdev;
3355 int rc = 0;
3356
3357 if (!inst || !inst->core || !inst->core->device || !handle) {
3358 dprintk(VIDC_ERR, "%s - invalid params\n", __func__);
3359 return -EINVAL;
3360 }
3361
3362 hdev = inst->core->device;
3363
3364 rc = msm_comm_smem_cache_operations(inst,
3365 handle, SMEM_CACHE_CLEAN);
3366 if (rc) {
3367 dprintk(VIDC_WARN,
3368 "Failed to clean cache. Undefined behavior\n");
3369 }
3370
3371 buffer_info.buffer_size = handle->size;
3372 buffer_info.buffer_type = buffer_type;
3373 buffer_info.num_buffers = 1;
3374 buffer_info.align_device_addr = handle->device_addr;
3375 dprintk(VIDC_DBG, "%s %s buffer : %pa\n",
3376 reuse ? "Reusing" : "Allocated",
3377 get_buffer_name(buffer_type),
3378 &buffer_info.align_device_addr);
3379
3380 rc = call_hfi_op(hdev, session_set_buffers,
3381 (void *) inst->session, &buffer_info);
3382 if (rc) {
3383 dprintk(VIDC_ERR,
3384 "vidc_hal_session_set_buffers failed\n");
3385 return rc;
3386 }
3387 return 0;
3388}
3389
3390static bool reuse_internal_buffers(struct msm_vidc_inst *inst,
3391 enum hal_buffer buffer_type, struct msm_vidc_list *buf_list)
3392{
3393 struct internal_buf *buf;
3394 int rc = 0;
3395 bool reused = false;
3396
3397 if (!inst || !buf_list) {
3398 dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
3399 return false;
3400 }
3401
3402 mutex_lock(&buf_list->lock);
3403 list_for_each_entry(buf, &buf_list->list, list) {
3404 if (!buf->handle) {
3405 reused = false;
3406 break;
3407 }
3408
3409 if (buf->buffer_type != buffer_type)
3410 continue;
3411
3412 /*
3413 * Persist buffer size won't change with resolution. If they
3414 * are in queue means that they are already allocated and
3415 * given to HW. HW can use them without reallocation. These
3416 * buffers are not released as part of port reconfig. So
3417 * driver no need to set them again.
3418 */
3419
3420 if (buffer_type != HAL_BUFFER_INTERNAL_PERSIST
3421 && buffer_type != HAL_BUFFER_INTERNAL_PERSIST_1) {
3422
3423 rc = set_internal_buf_on_fw(inst, buffer_type,
3424 buf->handle, true);
3425 if (rc) {
3426 dprintk(VIDC_ERR,
3427 "%s: session_set_buffers failed\n",
3428 __func__);
3429 reused = false;
3430 break;
3431 }
3432 }
3433 reused = true;
3434 dprintk(VIDC_DBG,
3435 "Re-using internal buffer type : %d\n", buffer_type);
3436 }
3437 mutex_unlock(&buf_list->lock);
3438 return reused;
3439}
3440
3441static int allocate_and_set_internal_bufs(struct msm_vidc_inst *inst,
3442 struct hal_buffer_requirements *internal_bufreq,
3443 struct msm_vidc_list *buf_list)
3444{
3445 struct msm_smem *handle;
3446 struct internal_buf *binfo;
3447 u32 smem_flags = 0;
3448 int rc = 0;
3449 int i = 0;
3450
3451 if (!inst || !internal_bufreq || !buf_list)
3452 return -EINVAL;
3453
3454 if (!internal_bufreq->buffer_size)
3455 return 0;
3456
3457 if (inst->flags & VIDC_SECURE)
3458 smem_flags |= SMEM_SECURE;
3459
3460 for (i = 0; i < internal_bufreq->buffer_count_actual; i++) {
3461 handle = msm_comm_smem_alloc(inst, internal_bufreq->buffer_size,
3462 1, smem_flags, internal_bufreq->buffer_type, 0);
3463 if (!handle) {
3464 dprintk(VIDC_ERR,
3465 "Failed to allocate scratch memory\n");
3466 rc = -ENOMEM;
3467 goto err_no_mem;
3468 }
3469
3470 binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
3471 if (!binfo) {
3472 dprintk(VIDC_ERR, "Out of memory\n");
3473 rc = -ENOMEM;
3474 goto fail_kzalloc;
3475 }
3476
3477 binfo->handle = handle;
3478 binfo->buffer_type = internal_bufreq->buffer_type;
3479
3480 rc = set_internal_buf_on_fw(inst, internal_bufreq->buffer_type,
3481 handle, false);
3482 if (rc)
3483 goto fail_set_buffers;
3484
3485 mutex_lock(&buf_list->lock);
3486 list_add_tail(&binfo->list, &buf_list->list);
3487 mutex_unlock(&buf_list->lock);
3488 }
3489 return rc;
3490
3491fail_set_buffers:
3492 kfree(binfo);
3493fail_kzalloc:
3494 msm_comm_smem_free(inst, handle);
3495err_no_mem:
3496 return rc;
3497
3498}
3499
3500static int set_internal_buffers(struct msm_vidc_inst *inst,
3501 enum hal_buffer buffer_type, struct msm_vidc_list *buf_list)
3502{
3503 struct hal_buffer_requirements *internal_buf;
3504
3505 internal_buf = get_buff_req_buffer(inst, buffer_type);
3506 if (!internal_buf) {
3507 dprintk(VIDC_DBG,
3508 "This internal buffer not required, buffer_type: %x\n",
3509 buffer_type);
3510 return 0;
3511 }
3512
3513 dprintk(VIDC_DBG, "Buffer type %s: num = %d, size = %d\n",
3514 get_buffer_name(buffer_type),
3515 internal_buf->buffer_count_actual, internal_buf->buffer_size);
3516
3517 /*
3518 * Try reusing existing internal buffers first.
3519 * If it's not possible to reuse, allocate new buffers.
3520 */
3521 if (reuse_internal_buffers(inst, buffer_type, buf_list))
3522 return 0;
3523
3524 return allocate_and_set_internal_bufs(inst, internal_buf,
3525 buf_list);
3526}
3527
3528int msm_comm_try_state(struct msm_vidc_inst *inst, int state)
3529{
3530 int rc = 0;
3531 int flipped_state;
3532 struct msm_vidc_core *core;
3533
3534 if (!inst) {
3535 dprintk(VIDC_ERR,
3536 "Invalid instance pointer = %pK\n", inst);
3537 return -EINVAL;
3538 }
3539 dprintk(VIDC_DBG,
3540 "Trying to move inst: %pK from: %#x to %#x\n",
3541 inst, inst->state, state);
3542 core = inst->core;
3543 if (!core) {
3544 dprintk(VIDC_ERR,
3545 "Invalid core pointer = %pK\n", inst);
3546 return -EINVAL;
3547 }
3548 mutex_lock(&inst->sync_lock);
3549 if (inst->state == MSM_VIDC_CORE_INVALID ||
3550 core->state == VIDC_CORE_INVALID) {
3551 dprintk(VIDC_ERR,
3552 "Core is in bad state can't change the state\n");
3553 rc = -EINVAL;
3554 goto exit;
3555 }
3556 flipped_state = get_flipped_state(inst->state, state);
3557 dprintk(VIDC_DBG,
3558 "flipped_state = %#x\n", flipped_state);
3559 switch (flipped_state) {
3560 case MSM_VIDC_CORE_UNINIT_DONE:
3561 case MSM_VIDC_CORE_INIT:
3562 rc = msm_comm_init_core(inst);
3563 if (rc || state <= get_flipped_state(inst->state, state))
3564 break;
3565 case MSM_VIDC_CORE_INIT_DONE:
3566 rc = msm_comm_init_core_done(inst);
3567 if (rc || state <= get_flipped_state(inst->state, state))
3568 break;
3569 case MSM_VIDC_OPEN:
3570 rc = msm_comm_session_init(flipped_state, inst);
3571 if (rc || state <= get_flipped_state(inst->state, state))
3572 break;
3573 case MSM_VIDC_OPEN_DONE:
3574 rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE,
3575 HAL_SESSION_INIT_DONE);
3576 if (rc || state <= get_flipped_state(inst->state, state))
3577 break;
3578 case MSM_VIDC_LOAD_RESOURCES:
3579 rc = msm_vidc_load_resources(flipped_state, inst);
3580 if (rc || state <= get_flipped_state(inst->state, state))
3581 break;
3582 case MSM_VIDC_LOAD_RESOURCES_DONE:
3583 case MSM_VIDC_START:
3584 rc = msm_vidc_start(flipped_state, inst);
3585 if (rc || state <= get_flipped_state(inst->state, state))
3586 break;
3587 case MSM_VIDC_START_DONE:
3588 rc = wait_for_state(inst, flipped_state, MSM_VIDC_START_DONE,
3589 HAL_SESSION_START_DONE);
3590 if (rc || state <= get_flipped_state(inst->state, state))
3591 break;
3592 case MSM_VIDC_STOP:
3593 rc = msm_vidc_stop(flipped_state, inst);
3594 if (rc || state <= get_flipped_state(inst->state, state))
3595 break;
3596 case MSM_VIDC_STOP_DONE:
3597 rc = wait_for_state(inst, flipped_state, MSM_VIDC_STOP_DONE,
3598 HAL_SESSION_STOP_DONE);
3599 if (rc || state <= get_flipped_state(inst->state, state))
3600 break;
3601 dprintk(VIDC_DBG, "Moving to Stop Done state\n");
3602 case MSM_VIDC_RELEASE_RESOURCES:
3603 rc = msm_vidc_release_res(flipped_state, inst);
3604 if (rc || state <= get_flipped_state(inst->state, state))
3605 break;
3606 case MSM_VIDC_RELEASE_RESOURCES_DONE:
3607 rc = wait_for_state(inst, flipped_state,
3608 MSM_VIDC_RELEASE_RESOURCES_DONE,
3609 HAL_SESSION_RELEASE_RESOURCE_DONE);
3610 if (rc || state <= get_flipped_state(inst->state, state))
3611 break;
3612 dprintk(VIDC_DBG,
3613 "Moving to release resources done state\n");
3614 case MSM_VIDC_CLOSE:
3615 rc = msm_comm_session_close(flipped_state, inst);
3616 if (rc || state <= get_flipped_state(inst->state, state))
3617 break;
3618 case MSM_VIDC_CLOSE_DONE:
3619 rc = wait_for_state(inst, flipped_state, MSM_VIDC_CLOSE_DONE,
3620 HAL_SESSION_END_DONE);
3621 if (rc || state <= get_flipped_state(inst->state, state))
3622 break;
3623 msm_comm_session_clean(inst);
3624 case MSM_VIDC_CORE_UNINIT:
3625 case MSM_VIDC_CORE_INVALID:
3626 dprintk(VIDC_DBG, "Sending core uninit\n");
3627 rc = msm_vidc_deinit_core(inst);
3628 if (rc || state == get_flipped_state(inst->state, state))
3629 break;
3630 default:
3631 dprintk(VIDC_ERR, "State not recognized\n");
3632 rc = -EINVAL;
3633 break;
3634 }
3635exit:
3636 mutex_unlock(&inst->sync_lock);
3637 if (rc)
3638 dprintk(VIDC_ERR,
3639 "Failed to move from state: %d to %d\n",
3640 inst->state, state);
3641 else
3642 trace_msm_vidc_common_state_change((void *)inst,
3643 inst->state, state);
3644 return rc;
3645}
3646
3647int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd)
3648{
3649 struct msm_vidc_inst *inst = instance;
3650 struct v4l2_decoder_cmd *dec = NULL;
3651 struct v4l2_encoder_cmd *enc = NULL;
3652 struct msm_vidc_core *core;
3653 int which_cmd = 0, flags = 0, rc = 0;
3654
3655 if (!inst || !inst->core || !cmd) {
3656 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
3657 return -EINVAL;
3658 }
3659 core = inst->core;
3660 if (inst->session_type == MSM_VIDC_ENCODER) {
3661 enc = (struct v4l2_encoder_cmd *)cmd;
3662 which_cmd = enc->cmd;
3663 flags = enc->flags;
3664 } else if (inst->session_type == MSM_VIDC_DECODER) {
3665 dec = (struct v4l2_decoder_cmd *)cmd;
3666 which_cmd = dec->cmd;
3667 flags = dec->flags;
3668 }
3669
3670
3671 switch (which_cmd) {
3672 case V4L2_QCOM_CMD_FLUSH:
3673 if (core->state != VIDC_CORE_INVALID &&
3674 inst->state == MSM_VIDC_CORE_INVALID) {
3675 rc = msm_comm_kill_session(inst);
3676 if (rc)
3677 dprintk(VIDC_ERR,
3678 "Fail to clean session: %d\n",
3679 rc);
3680 }
3681 rc = msm_comm_flush(inst, flags);
3682 if (rc) {
3683 dprintk(VIDC_ERR,
3684 "Failed to flush buffers: %d\n", rc);
3685 }
3686 break;
3687 case V4L2_DEC_QCOM_CMD_RECONFIG_HINT:
3688 {
3689 u32 *ptr = NULL;
3690 struct hal_buffer_requirements *output_buf;
3691
3692 rc = msm_comm_try_get_bufreqs(inst);
3693 if (rc) {
3694 dprintk(VIDC_ERR,
3695 "Getting buffer requirements failed: %d\n",
3696 rc);
3697 break;
3698 }
3699
3700 output_buf = get_buff_req_buffer(inst,
3701 msm_comm_get_hal_output_buffer(inst));
3702 if (output_buf) {
3703 if (dec) {
3704 ptr = (u32 *)dec->raw.data;
3705 ptr[0] = output_buf->buffer_size;
3706 ptr[1] = output_buf->buffer_count_actual;
3707 dprintk(VIDC_DBG,
3708 "Reconfig hint, size is %u, count is %u\n",
3709 ptr[0], ptr[1]);
3710 } else {
3711 dprintk(VIDC_ERR, "Null decoder\n");
3712 }
3713 } else {
3714 dprintk(VIDC_DBG,
3715 "This output buffer not required, buffer_type: %x\n",
3716 HAL_BUFFER_OUTPUT);
3717 }
3718 break;
3719 }
3720 default:
3721 dprintk(VIDC_ERR, "Unknown Command %d\n", which_cmd);
3722 rc = -ENOTSUPP;
3723 break;
3724 }
3725 return rc;
3726}
3727
3728static void populate_frame_data(struct vidc_frame_data *data,
3729 const struct vb2_buffer *vb, struct msm_vidc_inst *inst)
3730{
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07003731 u64 time_usec;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003732 int extra_idx;
3733 enum v4l2_buf_type type = vb->type;
3734 enum vidc_ports port = type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
3735 OUTPUT_PORT : CAPTURE_PORT;
3736 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
3737
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07003738 time_usec = vb->timestamp;
3739 do_div(time_usec, NSEC_PER_USEC);
3740
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003741 data->alloc_len = vb->planes[0].length;
3742 data->device_addr = vb->planes[0].m.userptr;
Vaibhav Deshu Venkateshe5800332017-03-21 14:27:11 -07003743 data->timestamp = time_usec;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003744 data->flags = 0;
3745 data->clnt_data = data->device_addr;
3746
3747 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
3748 bool pic_decoding_mode = msm_comm_g_ctrl_for_id(inst,
3749 V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE);
3750
3751 data->buffer_type = HAL_BUFFER_INPUT;
3752 data->filled_len = vb->planes[0].bytesused;
3753 data->offset = vb->planes[0].data_offset;
3754
3755 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_EOS)
3756 data->flags |= HAL_BUFFERFLAG_EOS;
3757
3758 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
3759 data->flags |= HAL_BUFFERFLAG_CODECCONFIG;
3760
3761 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY)
3762 data->flags |= HAL_BUFFERFLAG_DECODEONLY;
3763
3764 if (vbuf->flags & V4L2_QCOM_BUF_TIMESTAMP_INVALID)
3765 data->timestamp = LLONG_MAX;
3766
3767 /* XXX: This is a dirty hack necessitated by the firmware,
3768 * which refuses to issue FBDs for non I-frames in Picture Type
3769 * Decoding mode, unless we pass in non-zero value in mark_data
3770 * and mark_target.
3771 */
3772 data->mark_data = data->mark_target =
3773 pic_decoding_mode ? 0xdeadbeef : 0;
3774
3775 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
3776 data->buffer_type = msm_comm_get_hal_output_buffer(inst);
3777 }
3778
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08003779 extra_idx = EXTRADATA_IDX(inst->bufq[port].num_planes);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003780 if (extra_idx && extra_idx < VIDEO_MAX_PLANES &&
3781 vb->planes[extra_idx].m.userptr) {
3782 data->extradata_addr = vb->planes[extra_idx].m.userptr;
3783 data->extradata_size = vb->planes[extra_idx].length;
3784 data->flags |= HAL_BUFFERFLAG_EXTRADATA;
3785 }
3786}
3787
3788static unsigned int count_single_batch(struct msm_vidc_list *list,
3789 enum v4l2_buf_type type)
3790{
3791 struct vb2_buf_entry *buf;
3792 int count = 0;
3793 struct vb2_v4l2_buffer *vbuf = NULL;
3794
3795 mutex_lock(&list->lock);
3796 list_for_each_entry(buf, &list->list, list) {
3797 if (buf->vb->type != type)
3798 continue;
3799
3800 ++count;
3801
3802 vbuf = to_vb2_v4l2_buffer(buf->vb);
3803 if (!(vbuf->flags & V4L2_MSM_BUF_FLAG_DEFER))
3804 goto found_batch;
3805 }
3806 /* don't have a full batch */
3807 count = 0;
3808
3809found_batch:
3810 mutex_unlock(&list->lock);
3811 return count;
3812}
3813
3814static unsigned int count_buffers(struct msm_vidc_list *list,
3815 enum v4l2_buf_type type)
3816{
3817 struct vb2_buf_entry *buf;
3818 int count = 0;
3819
3820 mutex_lock(&list->lock);
3821 list_for_each_entry(buf, &list->list, list) {
3822 if (buf->vb->type != type)
3823 continue;
3824
3825 ++count;
3826 }
3827 mutex_unlock(&list->lock);
3828
3829 return count;
3830}
3831
3832static void log_frame(struct msm_vidc_inst *inst, struct vidc_frame_data *data,
3833 enum v4l2_buf_type type)
3834{
Praneeth Paladugub71968b2015-08-19 20:47:57 -07003835
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003836 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
3837 dprintk(VIDC_DBG,
3838 "Sending etb (%pa) to hal: filled: %d, ts: %lld, flags = %#x\n",
3839 &data->device_addr, data->filled_len,
3840 data->timestamp, data->flags);
3841 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_ETB);
3842
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003843 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
3844 dprintk(VIDC_DBG,
3845 "Sending ftb (%pa) to hal: size: %d, ts: %lld, flags = %#x\n",
3846 &data->device_addr, data->alloc_len,
3847 data->timestamp, data->flags);
3848 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FTB);
3849 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003850}
3851
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003852/*
3853 * Attempts to queue `vb` to hardware. If, for various reasons, the buffer
3854 * cannot be queued to hardware, the buffer will be staged for commit in the
3855 * pending queue. Once the hardware reaches a good state (or if `vb` is NULL,
3856 * the subsequent *_qbuf will commit the previously staged buffers to hardware.
3857 */
3858int msm_comm_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb)
3859{
3860 int rc = 0, capture_count, output_count;
3861 struct msm_vidc_core *core;
3862 struct hfi_device *hdev;
3863 struct {
3864 struct vidc_frame_data *data;
3865 int count;
3866 } etbs, ftbs;
3867 bool defer = false, batch_mode;
3868 struct vb2_buf_entry *temp, *next;
3869 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
3870
3871 if (!inst) {
3872 dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__);
3873 return -EINVAL;
3874 }
3875
3876 core = inst->core;
3877 hdev = core->device;
3878
3879 if (inst->state == MSM_VIDC_CORE_INVALID ||
3880 core->state == VIDC_CORE_INVALID ||
3881 core->state == VIDC_CORE_UNINIT) {
3882 dprintk(VIDC_ERR, "Core is in bad state. Can't Queue\n");
3883 return -EINVAL;
3884 }
3885
3886 /*
3887 * Stick the buffer into the pendinq, we'll pop it out later on
3888 * if we want to commit it to hardware
3889 */
3890 if (vb) {
3891 temp = kzalloc(sizeof(*temp), GFP_KERNEL);
3892 if (!temp) {
3893 dprintk(VIDC_ERR, "Out of memory\n");
3894 goto err_no_mem;
3895 }
3896
3897 temp->vb = vb;
3898 mutex_lock(&inst->pendingq.lock);
3899 list_add_tail(&temp->list, &inst->pendingq.list);
3900 mutex_unlock(&inst->pendingq.lock);
3901 }
3902
3903 batch_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_VIDC_QBUF_MODE)
3904 == V4L2_VIDC_QBUF_BATCHED;
3905 capture_count = (batch_mode ? &count_single_batch : &count_buffers)
3906 (&inst->pendingq, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
3907 output_count = (batch_mode ? &count_single_batch : &count_buffers)
3908 (&inst->pendingq, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
3909
3910 /*
3911 * Somewhat complicated logic to prevent queuing the buffer to hardware.
3912 * Don't queue if:
3913 * 1) Hardware isn't ready (that's simple)
3914 */
3915 defer = defer ?: inst->state != MSM_VIDC_START_DONE;
3916
3917 /*
3918 * 2) The client explicitly tells us not to because it wants this
3919 * buffer to be batched with future frames. The batch size (on both
3920 * capabilities) is completely determined by the client.
3921 */
3922 defer = defer ?: vbuf && vbuf->flags & V4L2_MSM_BUF_FLAG_DEFER;
3923
3924 /* 3) If we're in batch mode, we must have full batches of both types */
3925 defer = defer ?: batch_mode && (!output_count || !capture_count);
3926
3927 if (defer) {
3928 dprintk(VIDC_DBG, "Deferring queue of %pK\n", vb);
3929 return 0;
3930 }
3931
Praneeth Paladugub71968b2015-08-19 20:47:57 -07003932 rc = msm_comm_scale_clocks_and_bus(inst);
3933
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003934 dprintk(VIDC_DBG, "%sing %d etbs and %d ftbs\n",
3935 batch_mode ? "Batch" : "Process",
3936 output_count, capture_count);
3937
3938 etbs.data = kcalloc(output_count, sizeof(*etbs.data), GFP_KERNEL);
3939 ftbs.data = kcalloc(capture_count, sizeof(*ftbs.data), GFP_KERNEL);
3940 /*
3941 * Note that it's perfectly normal for (e|f)tbs.data to be NULL if
3942 * we're not in batch mode (i.e. (output|capture)_count == 0)
3943 */
3944 if ((!etbs.data && output_count) ||
3945 (!ftbs.data && capture_count)) {
3946 dprintk(VIDC_ERR, "Failed to alloc memory for batching\n");
3947 kfree(etbs.data);
3948 etbs.data = NULL;
3949
3950 kfree(ftbs.data);
3951 ftbs.data = NULL;
3952 goto err_no_mem;
3953 }
3954
3955 etbs.count = ftbs.count = 0;
3956
3957 /*
3958 * Try to collect all pending buffers into 2 batches of ftb and etb
3959 * Note that these "batches" might be empty if we're no in batching mode
3960 * and the pendingq is empty
3961 */
3962 mutex_lock(&inst->pendingq.lock);
3963 list_for_each_entry_safe(temp, next, &inst->pendingq.list, list) {
3964 struct vidc_frame_data *frame_data = NULL;
3965
3966 switch (temp->vb->type) {
3967 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
3968 if (ftbs.count < capture_count && ftbs.data)
3969 frame_data = &ftbs.data[ftbs.count++];
3970 break;
3971 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
3972 if (etbs.count < output_count && etbs.data)
3973 frame_data = &etbs.data[etbs.count++];
3974 break;
3975 default:
3976 break;
3977 }
3978
3979 if (!frame_data)
3980 continue;
3981
3982 populate_frame_data(frame_data, temp->vb, inst);
3983
3984 list_del(&temp->list);
3985 kfree(temp);
3986 }
3987 mutex_unlock(&inst->pendingq.lock);
3988
3989 /* Finally commit all our frame(s) to H/W */
3990 if (batch_mode) {
3991 int ftb_index = 0, c = 0;
3992
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003993 ftb_index = c;
3994 rc = call_hfi_op(hdev, session_process_batch, inst->session,
3995 etbs.count, etbs.data,
3996 ftbs.count - ftb_index, &ftbs.data[ftb_index]);
3997 if (rc) {
3998 dprintk(VIDC_ERR,
3999 "Failed to queue batch of %d ETBs and %d FTBs\n",
4000 etbs.count, ftbs.count);
4001 goto err_bad_input;
4002 }
4003
4004 for (c = ftb_index; c < ftbs.count; ++c) {
4005 log_frame(inst, &ftbs.data[c],
4006 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
4007 }
4008
4009 for (c = 0; c < etbs.count; ++c) {
4010 log_frame(inst, &etbs.data[c],
4011 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
4012 }
4013 }
4014
4015 if (!batch_mode && etbs.count) {
4016 int c = 0;
4017
4018 for (c = 0; c < etbs.count; ++c) {
4019 struct vidc_frame_data *frame_data = &etbs.data[c];
4020
4021 rc = call_hfi_op(hdev, session_etb, inst->session,
4022 frame_data);
4023 if (rc) {
4024 dprintk(VIDC_ERR, "Failed to issue etb: %d\n",
4025 rc);
4026 goto err_bad_input;
4027 }
4028
4029 log_frame(inst, frame_data,
4030 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
4031 }
4032 }
4033
4034 if (!batch_mode && ftbs.count) {
4035 int c = 0;
4036
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004037 for (; c < ftbs.count; ++c) {
4038 struct vidc_frame_data *frame_data = &ftbs.data[c];
4039
4040 rc = call_hfi_op(hdev, session_ftb,
4041 inst->session, frame_data);
4042 if (rc) {
4043 dprintk(VIDC_ERR, "Failed to issue ftb: %d\n",
4044 rc);
4045 goto err_bad_input;
4046 }
4047
4048 log_frame(inst, frame_data,
4049 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
4050 }
4051 }
4052
4053err_bad_input:
4054 if (rc)
4055 dprintk(VIDC_ERR, "Failed to queue buffer\n");
4056
4057 kfree(etbs.data);
4058 kfree(ftbs.data);
4059err_no_mem:
4060 return rc;
4061}
4062
4063int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst)
4064{
4065 int rc = 0, i = 0;
4066 union hal_get_property hprop;
4067
4068 rc = msm_comm_try_get_prop(inst, HAL_PARAM_GET_BUFFER_REQUIREMENTS,
4069 &hprop);
4070 if (rc) {
4071 dprintk(VIDC_ERR, "Failed getting buffer requirements: %d", rc);
4072 return rc;
4073 }
4074
4075 dprintk(VIDC_DBG, "Buffer requirements:\n");
4076 dprintk(VIDC_DBG, "%15s %8s %8s\n", "buffer type", "count", "size");
4077 for (i = 0; i < HAL_BUFFER_MAX; i++) {
4078 struct hal_buffer_requirements req = hprop.buf_req.buffer[i];
4079
4080 inst->buff_req.buffer[i] = req;
4081 dprintk(VIDC_DBG, "%15s %8d %8d\n",
4082 get_buffer_name(req.buffer_type),
4083 req.buffer_count_actual, req.buffer_size);
4084 }
4085
4086 dprintk(VIDC_PROF, "Input buffers: %d, Output buffers: %d\n",
4087 inst->buff_req.buffer[0].buffer_count_actual,
4088 inst->buff_req.buffer[1].buffer_count_actual);
4089 return rc;
4090}
4091
4092int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
4093 union hal_get_property *hprop)
4094{
4095 int rc = 0;
4096 struct hfi_device *hdev;
4097 struct getprop_buf *buf;
4098
4099 if (!inst || !inst->core || !inst->core->device) {
4100 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4101 return -EINVAL;
4102 }
4103
4104 hdev = inst->core->device;
4105 mutex_lock(&inst->sync_lock);
4106 if (inst->state < MSM_VIDC_OPEN_DONE ||
4107 inst->state >= MSM_VIDC_CLOSE) {
4108
4109 /* No need to check inst->state == MSM_VIDC_INVALID since
4110 * INVALID is > CLOSE_DONE. When core went to INVALID state,
4111 * we put all the active instances in INVALID. So > CLOSE_DONE
4112 * is enough check to have.
4113 */
4114
4115 dprintk(VIDC_ERR,
4116 "In Wrong state to call Buf Req: Inst %pK or Core %pK\n",
4117 inst, inst->core);
4118 rc = -EAGAIN;
4119 mutex_unlock(&inst->sync_lock);
4120 goto exit;
4121 }
4122 mutex_unlock(&inst->sync_lock);
4123
4124 switch (ptype) {
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004125 case HAL_PARAM_GET_BUFFER_REQUIREMENTS:
4126 rc = call_hfi_op(hdev, session_get_buf_req, inst->session);
4127 break;
4128 default:
4129 rc = -EAGAIN;
4130 break;
4131 }
4132
4133 if (rc) {
4134 dprintk(VIDC_ERR, "Can't query hardware for property: %d\n",
4135 rc);
4136 goto exit;
4137 }
4138
4139 rc = wait_for_completion_timeout(&inst->completions[
4140 SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO)],
4141 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
4142 if (!rc) {
4143 dprintk(VIDC_ERR,
4144 "%s: Wait interrupted or timed out [%pK]: %d\n",
4145 __func__, inst,
4146 SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO));
4147 inst->state = MSM_VIDC_CORE_INVALID;
4148 msm_comm_kill_session(inst);
4149 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
4150 dprintk(VIDC_ERR,
4151 "SESS_PROP timeout can potentially crash the system\n");
4152 if (inst->core->resources.debug_timeout)
4153 msm_comm_print_debug_info(inst);
4154
4155 msm_vidc_handle_hw_error(inst->core);
4156 rc = -ETIMEDOUT;
4157 goto exit;
4158 } else {
4159 /* wait_for_completion_timeout returns jiffies before expiry */
4160 rc = 0;
4161 }
4162
4163 mutex_lock(&inst->pending_getpropq.lock);
4164 if (!list_empty(&inst->pending_getpropq.list)) {
4165 buf = list_first_entry(&inst->pending_getpropq.list,
4166 struct getprop_buf, list);
4167 *hprop = *(union hal_get_property *)buf->data;
4168 kfree(buf->data);
4169 list_del(&buf->list);
4170 kfree(buf);
4171 } else {
4172 dprintk(VIDC_ERR, "%s getprop list empty\n", __func__);
4173 rc = -EINVAL;
4174 }
4175 mutex_unlock(&inst->pending_getpropq.lock);
4176exit:
4177 return rc;
4178}
4179
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004180int msm_comm_release_output_buffers(struct msm_vidc_inst *inst,
4181 bool force_release)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004182{
4183 struct msm_smem *handle;
4184 struct internal_buf *buf, *dummy;
4185 struct vidc_buffer_addr_info buffer_info;
4186 int rc = 0;
4187 struct msm_vidc_core *core;
4188 struct hfi_device *hdev;
4189
4190 if (!inst) {
4191 dprintk(VIDC_ERR,
4192 "Invalid instance pointer = %pK\n", inst);
4193 return -EINVAL;
4194 }
4195 mutex_lock(&inst->outputbufs.lock);
4196 if (list_empty(&inst->outputbufs.list)) {
4197 dprintk(VIDC_DBG, "%s - No OUTPUT buffers allocated\n",
4198 __func__);
4199 mutex_unlock(&inst->outputbufs.lock);
4200 return 0;
4201 }
4202 mutex_unlock(&inst->outputbufs.lock);
4203
4204 core = inst->core;
4205 if (!core) {
4206 dprintk(VIDC_ERR,
4207 "Invalid core pointer = %pK\n", core);
4208 return -EINVAL;
4209 }
4210 hdev = core->device;
4211 if (!hdev) {
4212 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4213 return -EINVAL;
4214 }
4215 mutex_lock(&inst->outputbufs.lock);
4216 list_for_each_entry_safe(buf, dummy, &inst->outputbufs.list, list) {
4217 handle = buf->handle;
4218 if (!handle) {
4219 dprintk(VIDC_ERR, "%s - invalid handle\n", __func__);
4220 goto exit;
4221 }
4222
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004223 if ((buf->buffer_ownership == FIRMWARE) && !force_release) {
4224 dprintk(VIDC_INFO, "DPB is with f/w. Can't free it\n");
4225 continue;
4226 }
4227
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004228 buffer_info.buffer_size = handle->size;
4229 buffer_info.buffer_type = buf->buffer_type;
4230 buffer_info.num_buffers = 1;
4231 buffer_info.align_device_addr = handle->device_addr;
4232 if (inst->buffer_mode_set[CAPTURE_PORT] ==
4233 HAL_BUFFER_MODE_STATIC &&
4234 inst->state != MSM_VIDC_CORE_INVALID &&
4235 core->state != VIDC_CORE_INVALID) {
4236 buffer_info.response_required = false;
4237 rc = call_hfi_op(hdev, session_release_buffers,
4238 (void *)inst->session, &buffer_info);
4239 if (rc) {
4240 dprintk(VIDC_WARN,
4241 "Rel output buf fail:%pa, %d\n",
4242 &buffer_info.align_device_addr,
4243 buffer_info.buffer_size);
4244 }
4245 }
4246
4247 list_del(&buf->list);
4248 msm_comm_smem_free(inst, buf->handle);
4249 kfree(buf);
4250 }
4251
4252exit:
4253 mutex_unlock(&inst->outputbufs.lock);
4254 return rc;
4255}
4256
4257static enum hal_buffer scratch_buf_sufficient(struct msm_vidc_inst *inst,
4258 enum hal_buffer buffer_type)
4259{
4260 struct hal_buffer_requirements *bufreq = NULL;
4261 struct internal_buf *buf;
4262 int count = 0;
4263
4264 if (!inst) {
4265 dprintk(VIDC_ERR, "%s - invalid param\n", __func__);
4266 goto not_sufficient;
4267 }
4268
4269 bufreq = get_buff_req_buffer(inst, buffer_type);
4270 if (!bufreq)
4271 goto not_sufficient;
4272
4273 /* Check if current scratch buffers are sufficient */
4274 mutex_lock(&inst->scratchbufs.lock);
4275
4276 list_for_each_entry(buf, &inst->scratchbufs.list, list) {
4277 if (!buf->handle) {
4278 dprintk(VIDC_ERR, "%s: invalid buf handle\n", __func__);
4279 mutex_unlock(&inst->scratchbufs.lock);
4280 goto not_sufficient;
4281 }
4282 if (buf->buffer_type == buffer_type &&
4283 buf->handle->size >= bufreq->buffer_size)
4284 count++;
4285 }
4286 mutex_unlock(&inst->scratchbufs.lock);
4287
4288 if (count != bufreq->buffer_count_actual)
4289 goto not_sufficient;
4290
4291 dprintk(VIDC_DBG,
4292 "Existing scratch buffer is sufficient for buffer type %#x\n",
4293 buffer_type);
4294
4295 return buffer_type;
4296
4297not_sufficient:
4298 return HAL_BUFFER_NONE;
4299}
4300
4301int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst,
4302 bool check_for_reuse)
4303{
4304 struct msm_smem *handle;
4305 struct internal_buf *buf, *dummy;
4306 struct vidc_buffer_addr_info buffer_info;
4307 int rc = 0;
4308 struct msm_vidc_core *core;
4309 struct hfi_device *hdev;
4310 enum hal_buffer sufficiency = HAL_BUFFER_NONE;
4311
4312 if (!inst) {
4313 dprintk(VIDC_ERR,
4314 "Invalid instance pointer = %pK\n", inst);
4315 return -EINVAL;
4316 }
4317 core = inst->core;
4318 if (!core) {
4319 dprintk(VIDC_ERR,
4320 "Invalid core pointer = %pK\n", core);
4321 return -EINVAL;
4322 }
4323 hdev = core->device;
4324 if (!hdev) {
4325 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4326 return -EINVAL;
4327 }
4328
4329 if (check_for_reuse) {
4330 sufficiency |= scratch_buf_sufficient(inst,
4331 HAL_BUFFER_INTERNAL_SCRATCH);
4332
4333 sufficiency |= scratch_buf_sufficient(inst,
4334 HAL_BUFFER_INTERNAL_SCRATCH_1);
4335
4336 sufficiency |= scratch_buf_sufficient(inst,
4337 HAL_BUFFER_INTERNAL_SCRATCH_2);
4338 }
4339
4340 mutex_lock(&inst->scratchbufs.lock);
4341 list_for_each_entry_safe(buf, dummy, &inst->scratchbufs.list, list) {
4342 if (!buf->handle) {
4343 dprintk(VIDC_ERR, "%s - buf->handle NULL\n", __func__);
4344 rc = -EINVAL;
4345 goto exit;
4346 }
4347
4348 handle = buf->handle;
4349 buffer_info.buffer_size = handle->size;
4350 buffer_info.buffer_type = buf->buffer_type;
4351 buffer_info.num_buffers = 1;
4352 buffer_info.align_device_addr = handle->device_addr;
4353 if (inst->state != MSM_VIDC_CORE_INVALID &&
4354 core->state != VIDC_CORE_INVALID) {
4355 buffer_info.response_required = true;
4356 rc = call_hfi_op(hdev, session_release_buffers,
4357 (void *)inst->session, &buffer_info);
4358 if (rc) {
4359 dprintk(VIDC_WARN,
4360 "Rel scrtch buf fail:%pa, %d\n",
4361 &buffer_info.align_device_addr,
4362 buffer_info.buffer_size);
4363 }
4364 mutex_unlock(&inst->scratchbufs.lock);
4365 rc = wait_for_sess_signal_receipt(inst,
4366 HAL_SESSION_RELEASE_BUFFER_DONE);
4367 if (rc) {
4368 change_inst_state(inst,
4369 MSM_VIDC_CORE_INVALID);
4370 msm_comm_kill_session(inst);
4371 }
4372 mutex_lock(&inst->scratchbufs.lock);
4373 }
4374
4375 /*If scratch buffers can be reused, do not free the buffers*/
4376 if (sufficiency & buf->buffer_type)
4377 continue;
4378
4379 list_del(&buf->list);
4380 msm_comm_smem_free(inst, buf->handle);
4381 kfree(buf);
4382 }
4383
4384exit:
4385 mutex_unlock(&inst->scratchbufs.lock);
4386 return rc;
4387}
4388
4389int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst)
4390{
4391 struct msm_smem *handle;
4392 struct list_head *ptr, *next;
4393 struct internal_buf *buf;
4394 struct vidc_buffer_addr_info buffer_info;
4395 int rc = 0;
4396 struct msm_vidc_core *core;
4397 struct hfi_device *hdev;
4398
4399 if (!inst) {
4400 dprintk(VIDC_ERR,
4401 "Invalid instance pointer = %pK\n", inst);
4402 return -EINVAL;
4403 }
4404 core = inst->core;
4405 if (!core) {
4406 dprintk(VIDC_ERR,
4407 "Invalid core pointer = %pK\n", core);
4408 return -EINVAL;
4409 }
4410 hdev = core->device;
4411 if (!hdev) {
4412 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4413 return -EINVAL;
4414 }
4415
4416 mutex_lock(&inst->persistbufs.lock);
4417 list_for_each_safe(ptr, next, &inst->persistbufs.list) {
4418 buf = list_entry(ptr, struct internal_buf, list);
4419 handle = buf->handle;
4420 buffer_info.buffer_size = handle->size;
4421 buffer_info.buffer_type = buf->buffer_type;
4422 buffer_info.num_buffers = 1;
4423 buffer_info.align_device_addr = handle->device_addr;
4424 if (inst->state != MSM_VIDC_CORE_INVALID &&
4425 core->state != VIDC_CORE_INVALID) {
4426 buffer_info.response_required = true;
4427 rc = call_hfi_op(hdev, session_release_buffers,
4428 (void *)inst->session, &buffer_info);
4429 if (rc) {
4430 dprintk(VIDC_WARN,
4431 "Rel prst buf fail:%pa, %d\n",
4432 &buffer_info.align_device_addr,
4433 buffer_info.buffer_size);
4434 }
4435 mutex_unlock(&inst->persistbufs.lock);
4436 rc = wait_for_sess_signal_receipt(inst,
4437 HAL_SESSION_RELEASE_BUFFER_DONE);
4438 if (rc) {
4439 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
4440 msm_comm_kill_session(inst);
4441 }
4442 mutex_lock(&inst->persistbufs.lock);
4443 }
4444 list_del(&buf->list);
4445 msm_comm_smem_free(inst, buf->handle);
4446 kfree(buf);
4447 }
4448 mutex_unlock(&inst->persistbufs.lock);
4449 return rc;
4450}
4451
4452int msm_comm_try_set_prop(struct msm_vidc_inst *inst,
4453 enum hal_property ptype, void *pdata)
4454{
4455 int rc = 0;
4456 struct hfi_device *hdev;
4457
4458 if (!inst) {
4459 dprintk(VIDC_ERR, "Invalid input: %pK\n", inst);
4460 return -EINVAL;
4461 }
4462
4463 if (!inst->core || !inst->core->device) {
4464 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4465 return -EINVAL;
4466 }
4467 hdev = inst->core->device;
4468
4469 mutex_lock(&inst->sync_lock);
4470 if (inst->state < MSM_VIDC_OPEN_DONE || inst->state >= MSM_VIDC_CLOSE) {
4471 dprintk(VIDC_ERR, "Not in proper state to set property\n");
4472 rc = -EAGAIN;
4473 goto exit;
4474 }
4475 rc = call_hfi_op(hdev, session_set_property, (void *)inst->session,
4476 ptype, pdata);
4477 if (rc)
4478 dprintk(VIDC_ERR, "Failed to set hal property for framesize\n");
4479exit:
4480 mutex_unlock(&inst->sync_lock);
4481 return rc;
4482}
4483
4484int msm_comm_set_output_buffers(struct msm_vidc_inst *inst)
4485{
4486 int rc = 0;
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004487 bool force_release = true;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004488
4489 if (!inst || !inst->core || !inst->core->device) {
4490 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4491 return -EINVAL;
4492 }
4493
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004494 if (inst->fmts[OUTPUT_PORT].defer_outputs)
4495 force_release = false;
4496
4497 if (msm_comm_release_output_buffers(inst, force_release))
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004498 dprintk(VIDC_WARN, "Failed to release output buffers\n");
4499
4500 rc = set_output_buffers(inst, HAL_BUFFER_OUTPUT);
4501 if (rc)
4502 goto error;
4503 return rc;
4504error:
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004505 msm_comm_release_output_buffers(inst, true);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004506 return rc;
4507}
4508
4509int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst)
4510{
4511 int rc = 0;
4512
4513 if (!inst || !inst->core || !inst->core->device) {
4514 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4515 return -EINVAL;
4516 }
4517
4518 if (msm_comm_release_scratch_buffers(inst, true))
4519 dprintk(VIDC_WARN, "Failed to release scratch buffers\n");
4520
4521 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH,
4522 &inst->scratchbufs);
4523 if (rc)
4524 goto error;
4525
4526 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_1,
4527 &inst->scratchbufs);
4528 if (rc)
4529 goto error;
4530
4531 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_2,
4532 &inst->scratchbufs);
4533 if (rc)
4534 goto error;
4535
4536 return rc;
4537error:
4538 msm_comm_release_scratch_buffers(inst, false);
4539 return rc;
4540}
4541
4542int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst)
4543{
4544 int rc = 0;
4545
4546 if (!inst || !inst->core || !inst->core->device) {
4547 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4548 return -EINVAL;
4549 }
4550
4551 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST,
4552 &inst->persistbufs);
4553 if (rc)
4554 goto error;
4555
4556 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST_1,
4557 &inst->persistbufs);
4558 if (rc)
4559 goto error;
4560 return rc;
4561error:
4562 msm_comm_release_persist_buffers(inst);
4563 return rc;
4564}
4565
4566static void msm_comm_flush_in_invalid_state(struct msm_vidc_inst *inst)
4567{
4568 struct list_head *ptr, *next;
4569 enum vidc_ports ports[] = {OUTPUT_PORT, CAPTURE_PORT};
4570 int c = 0;
4571
4572 for (c = 0; c < ARRAY_SIZE(ports); ++c) {
4573 enum vidc_ports port = ports[c];
4574
4575 dprintk(VIDC_DBG, "Flushing buffers of type %d in bad state\n",
4576 port);
4577 mutex_lock(&inst->bufq[port].lock);
4578 list_for_each_safe(ptr, next, &inst->bufq[port].
4579 vb2_bufq.queued_list) {
4580 struct vb2_buffer *vb = container_of(ptr,
4581 struct vb2_buffer, queued_entry);
4582
4583 vb->planes[0].bytesused = 0;
4584 vb->planes[0].data_offset = 0;
4585
4586 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
4587 }
4588 mutex_unlock(&inst->bufq[port].lock);
4589 }
4590
4591 msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_FLUSH_DONE);
4592}
4593
4594void msm_comm_flush_dynamic_buffers(struct msm_vidc_inst *inst)
4595{
4596 struct buffer_info *binfo = NULL;
4597
4598 if (inst->buffer_mode_set[CAPTURE_PORT] != HAL_BUFFER_MODE_DYNAMIC)
4599 return;
4600
4601 /*
4602 * dynamic buffer mode:- if flush is called during seek
4603 * driver should not queue any new buffer it has been holding.
4604 *
4605 * Each dynamic o/p buffer can have one of following ref_count:
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08004606 * ref_count : 0 - f/w has released reference and sent dynamic
4607 * buffer back. The buffer has been returned
4608 * back to client.
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004609 *
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08004610 * ref_count : 1 - f/w is holding reference. f/w may have released
4611 * dynamic buffer as read_only OR dynamic buffer is
4612 * pending. f/w will release reference before sending
4613 * flush_done.
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004614 *
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08004615 * ref_count : >=2 - f/w is holding reference, f/w has released dynamic
4616 * buffer as read_only, which client has queued back
4617 * to driver. Driver holds this buffer and will queue
4618 * back only when f/w releases the reference. During
4619 * flush_done, f/w will release the reference but
4620 * driver should not queue back the buffer to f/w.
4621 * Flush all buffers with ref_count >= 2.
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004622 */
4623 mutex_lock(&inst->registeredbufs.lock);
4624 if (!list_empty(&inst->registeredbufs.list)) {
4625 struct v4l2_event buf_event = {0};
4626 u32 *ptr = NULL;
4627
4628 list_for_each_entry(binfo, &inst->registeredbufs.list, list) {
4629 if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
Praneeth Paladuguf4223b72016-12-22 11:36:50 -08004630 atomic_read(&binfo->ref_count) >= 2) {
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004631
4632 atomic_dec(&binfo->ref_count);
4633 buf_event.type =
4634 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER;
4635 ptr = (u32 *)buf_event.u.data;
4636 ptr[0] = binfo->fd[0];
4637 ptr[1] = binfo->buff_off[0];
4638 ptr[2] = binfo->uvaddr[0];
4639 ptr[3] = (u32) binfo->timestamp.tv_sec;
4640 ptr[4] = (u32) binfo->timestamp.tv_usec;
4641 ptr[5] = binfo->v4l2_index;
4642 dprintk(VIDC_DBG,
4643 "released buffer held in driver before issuing flush: %pa fd[0]: %d\n",
4644 &binfo->device_addr[0], binfo->fd[0]);
4645 /*send event to client*/
4646 v4l2_event_queue_fh(&inst->event_handler,
4647 &buf_event);
4648 }
4649 }
4650 }
4651 mutex_unlock(&inst->registeredbufs.lock);
4652}
4653
4654void msm_comm_flush_pending_dynamic_buffers(struct msm_vidc_inst *inst)
4655{
4656 struct buffer_info *binfo = NULL;
4657
4658 if (!inst)
4659 return;
4660
4661 if (inst->buffer_mode_set[CAPTURE_PORT] != HAL_BUFFER_MODE_DYNAMIC)
4662 return;
4663
4664 if (list_empty(&inst->pendingq.list) ||
4665 list_empty(&inst->registeredbufs.list))
4666 return;
4667
4668 /*
4669 * Dynamic Buffer mode - Since pendingq is not empty
4670 * no output buffers have been sent to firmware yet.
4671 * Hence remove reference to all pendingq o/p buffers
4672 * before flushing them.
4673 */
4674
4675 mutex_lock(&inst->registeredbufs.lock);
4676 list_for_each_entry(binfo, &inst->registeredbufs.list, list) {
4677 if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
4678 dprintk(VIDC_DBG,
4679 "%s: binfo = %pK device_addr = %pa\n",
4680 __func__, binfo, &binfo->device_addr[0]);
4681 buf_ref_put(inst, binfo);
4682 }
4683 }
4684 mutex_unlock(&inst->registeredbufs.lock);
4685}
4686
4687int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags)
4688{
4689 int rc = 0;
4690 bool ip_flush = false;
4691 bool op_flush = false;
4692 struct vb2_buf_entry *temp, *next;
4693 struct mutex *lock;
4694 struct msm_vidc_core *core;
4695 struct hfi_device *hdev;
4696
4697 if (!inst) {
4698 dprintk(VIDC_ERR,
4699 "Invalid instance pointer = %pK\n", inst);
4700 return -EINVAL;
4701 }
4702 core = inst->core;
4703 if (!core) {
4704 dprintk(VIDC_ERR,
4705 "Invalid core pointer = %pK\n", core);
4706 return -EINVAL;
4707 }
4708 hdev = core->device;
4709 if (!hdev) {
4710 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4711 return -EINVAL;
4712 }
4713
4714 ip_flush = flags & V4L2_QCOM_CMD_FLUSH_OUTPUT;
4715 op_flush = flags & V4L2_QCOM_CMD_FLUSH_CAPTURE;
4716
4717 if (ip_flush && !op_flush) {
4718 dprintk(VIDC_INFO, "Input only flush not supported\n");
4719 return 0;
4720 }
4721
Praneeth Paladugu75cf18e2016-12-08 16:12:11 -08004722 // Finish FLUSH As Soon As Possible.
4723 inst->dcvs.buffer_counter = 0;
4724 msm_comm_scale_clocks_and_bus(inst);
4725
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004726 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
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08005061 if (!rc) {
5062 if (inst->prop.width[CAPTURE_PORT] < capability->width.min ||
5063 inst->prop.height[CAPTURE_PORT] <
5064 capability->height.min) {
5065 dprintk(VIDC_ERR,
5066 "Unsupported WxH = (%u)x(%u), min supported is - (%u)x(%u)\n",
5067 inst->prop.width[CAPTURE_PORT],
5068 inst->prop.height[CAPTURE_PORT],
5069 capability->width.min,
5070 capability->height.min);
5071 rc = -ENOTSUPP;
5072 }
5073 if (!rc && inst->prop.width[CAPTURE_PORT] >
5074 capability->width.max) {
5075 dprintk(VIDC_ERR,
5076 "Unsupported width = %u supported max width = %u",
5077 inst->prop.width[CAPTURE_PORT],
5078 capability->width.max);
5079 rc = -ENOTSUPP;
5080 }
5081
5082 if (!rc && inst->prop.height[CAPTURE_PORT]
5083 * inst->prop.width[CAPTURE_PORT] >
5084 capability->width.max * capability->height.max) {
5085 dprintk(VIDC_ERR,
5086 "Unsupported WxH = (%u)x(%u), max supported is - (%u)x(%u)\n",
5087 inst->prop.width[CAPTURE_PORT],
5088 inst->prop.height[CAPTURE_PORT],
5089 capability->width.max, capability->height.max);
5090 rc = -ENOTSUPP;
5091 }
5092 }
5093 if (rc) {
5094 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
5095 msm_comm_kill_session(inst);
5096 dprintk(VIDC_ERR,
5097 "%s: Resolution unsupported\n", __func__);
5098 }
5099 return rc;
5100}
5101
5102static void msm_comm_generate_session_error(struct msm_vidc_inst *inst)
5103{
5104 enum hal_command_response cmd = HAL_SESSION_ERROR;
5105 struct msm_vidc_cb_cmd_done response = {0};
5106
5107 dprintk(VIDC_WARN, "msm_comm_generate_session_error\n");
5108 if (!inst || !inst->core) {
5109 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5110 return;
5111 }
5112
5113 response.session_id = inst;
5114 response.status = VIDC_ERR_FAIL;
5115 handle_session_error(cmd, (void *)&response);
5116}
5117
5118static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst)
5119{
5120 struct msm_vidc_core *core;
5121 enum hal_command_response cmd = HAL_SYS_ERROR;
5122 struct msm_vidc_cb_cmd_done response = {0};
5123
5124 if (!inst || !inst->core) {
5125 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5126 return;
5127 }
5128 core = inst->core;
5129 response.device_id = (u32) core->id;
5130 handle_sys_error(cmd, (void *) &response);
5131
5132}
5133
5134int msm_comm_kill_session(struct msm_vidc_inst *inst)
5135{
5136 int rc = 0;
5137
5138 if (!inst || !inst->core || !inst->core->device) {
5139 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5140 return -EINVAL;
5141 } else if (!inst->session) {
5142 /* There's no hfi session to kill */
5143 return 0;
5144 }
5145
5146 /*
5147 * We're internally forcibly killing the session, if fw is aware of
5148 * the session send session_abort to firmware to clean up and release
5149 * the session, else just kill the session inside the driver.
5150 */
5151 if ((inst->state >= MSM_VIDC_OPEN_DONE &&
5152 inst->state < MSM_VIDC_CLOSE_DONE) ||
5153 inst->state == MSM_VIDC_CORE_INVALID) {
5154 if (msm_comm_session_abort(inst)) {
5155 msm_comm_generate_sys_error(inst);
5156 return 0;
5157 }
5158 change_inst_state(inst, MSM_VIDC_CLOSE_DONE);
5159 msm_comm_generate_session_error(inst);
5160 } else {
5161 dprintk(VIDC_WARN,
5162 "Inactive session %pK, triggering an internal session error\n",
5163 inst);
5164 msm_comm_generate_session_error(inst);
5165
5166 }
5167
5168 return rc;
5169}
5170
5171struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst,
5172 size_t size, u32 align, u32 flags,
5173 enum hal_buffer buffer_type, int map_kernel)
5174{
5175 struct msm_smem *m = NULL;
5176
5177 if (!inst || !inst->core) {
5178 dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst);
5179 return NULL;
5180 }
5181 m = msm_smem_alloc(inst->mem_client, size, align,
5182 flags, buffer_type, map_kernel);
5183 return m;
5184}
5185
5186void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem)
5187{
5188 if (!inst || !inst->core || !mem) {
5189 dprintk(VIDC_ERR,
5190 "%s: invalid params: %pK %pK\n", __func__, inst, mem);
5191 return;
5192 }
5193 msm_smem_free(inst->mem_client, mem);
5194}
5195
5196int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst,
5197 struct msm_smem *mem, enum smem_cache_ops cache_ops)
5198{
5199 if (!inst || !mem) {
5200 dprintk(VIDC_ERR,
5201 "%s: invalid params: %pK %pK\n", __func__, inst, mem);
5202 return -EINVAL;
5203 }
5204 return msm_smem_cache_operations(inst->mem_client, mem, cache_ops);
5205}
5206
5207struct msm_smem *msm_comm_smem_user_to_kernel(struct msm_vidc_inst *inst,
5208 int fd, u32 offset, enum hal_buffer buffer_type)
5209{
5210 struct msm_smem *m = NULL;
5211
5212 if (!inst || !inst->core) {
5213 dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst);
5214 return NULL;
5215 }
5216
5217 if (inst->state == MSM_VIDC_CORE_INVALID) {
5218 dprintk(VIDC_ERR, "Core in Invalid state, returning from %s\n",
5219 __func__);
5220 return NULL;
5221 }
5222
5223 m = msm_smem_user_to_kernel(inst->mem_client,
5224 fd, offset, buffer_type);
5225 return m;
5226}
5227
5228void msm_vidc_fw_unload_handler(struct work_struct *work)
5229{
5230 struct msm_vidc_core *core = NULL;
5231 struct hfi_device *hdev = NULL;
5232 int rc = 0;
5233
5234 core = container_of(work, struct msm_vidc_core, fw_unload_work.work);
5235 if (!core || !core->device) {
5236 dprintk(VIDC_ERR, "%s - invalid work or core handle\n",
5237 __func__);
5238 return;
5239 }
5240
5241 hdev = core->device;
5242
5243 mutex_lock(&core->lock);
5244 if (list_empty(&core->instances) &&
5245 core->state != VIDC_CORE_UNINIT) {
5246 if (core->state > VIDC_CORE_INIT) {
5247 dprintk(VIDC_DBG, "Calling vidc_hal_core_release\n");
5248 rc = call_hfi_op(hdev, core_release,
5249 hdev->hfi_device_data);
5250 if (rc) {
5251 dprintk(VIDC_ERR,
5252 "Failed to release core, id = %d\n",
5253 core->id);
5254 mutex_unlock(&core->lock);
5255 return;
5256 }
5257 }
5258 core->state = VIDC_CORE_UNINIT;
5259 kfree(core->capabilities);
5260 core->capabilities = NULL;
5261 }
5262 mutex_unlock(&core->lock);
5263}
5264
5265int msm_comm_set_color_format(struct msm_vidc_inst *inst,
5266 enum hal_buffer buffer_type, int fourcc)
5267{
5268 struct hal_uncompressed_format_select hal_fmt = {0};
5269 enum hal_uncompressed_format format = HAL_UNUSED_COLOR;
5270 int rc = 0;
5271 struct hfi_device *hdev;
5272
5273 if (!inst || !inst->core || !inst->core->device) {
5274 dprintk(VIDC_ERR, "%s - invalid param\n", __func__);
5275 return -EINVAL;
5276 }
5277
5278 hdev = inst->core->device;
5279
5280 format = get_hal_uncompressed(fourcc);
5281 if (format == HAL_UNUSED_COLOR) {
5282 dprintk(VIDC_ERR, "Using unsupported colorformat %#x\n",
5283 fourcc);
5284 rc = -ENOTSUPP;
5285 goto exit;
5286 }
5287
5288 hal_fmt.buffer_type = buffer_type;
5289 hal_fmt.format = format;
5290
5291 rc = call_hfi_op(hdev, session_set_property, inst->session,
5292 HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT, &hal_fmt);
5293 if (rc)
5294 dprintk(VIDC_ERR,
5295 "Failed to set input color format\n");
5296 else
5297 dprintk(VIDC_DBG, "Setting uncompressed colorformat to %#x\n",
5298 format);
5299
5300exit:
5301 return rc;
5302}
5303
5304int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
5305{
5306 u32 property_id = 0;
5307 u64 us_per_frame = 0;
5308 void *pdata;
5309 int rc = 0, fps = 0;
5310 struct hal_frame_rate frame_rate;
5311 struct hfi_device *hdev;
5312
5313 if (!inst || !inst->core || !inst->core->device || !a) {
5314 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
5315 return -EINVAL;
5316 }
5317
5318 hdev = inst->core->device;
5319 property_id = HAL_CONFIG_FRAME_RATE;
5320
5321 if (a->parm.output.timeperframe.denominator) {
5322 switch (a->type) {
5323 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
5324 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
5325 us_per_frame = a->parm.output.timeperframe.numerator *
5326 (u64)USEC_PER_SEC;
5327 do_div(us_per_frame, a->parm.output.
5328 timeperframe.denominator);
5329 break;
5330 default:
5331 dprintk(VIDC_ERR,
5332 "Scale clocks : Unknown buffer type %d\n",
5333 a->type);
5334 break;
5335 }
5336 }
5337
5338 if (!us_per_frame) {
5339 dprintk(VIDC_ERR,
5340 "Failed to scale clocks : time between frames is 0\n");
5341 rc = -EINVAL;
5342 goto exit;
5343 }
5344
5345 fps = USEC_PER_SEC;
5346 do_div(fps, us_per_frame);
5347
5348 if (fps % 15 == 14 || fps % 24 == 23)
5349 fps = fps + 1;
5350 else if ((fps > 1) && (fps % 24 == 1 || fps % 15 == 1))
5351 fps = fps - 1;
5352
Praneeth Paladugue1679112017-01-27 10:07:15 -08005353 if (fps < inst->capability.frame_rate.min ||
5354 fps > inst->capability.frame_rate.max) {
5355 dprintk(VIDC_ERR,
5356 "FPS is out of limits : fps = %d Min = %d, Max = %d\n",
5357 fps, inst->capability.frame_rate.min,
5358 inst->capability.frame_rate.max);
5359 rc = -EINVAL;
5360 goto exit;
5361 }
5362
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08005363 if (inst->prop.fps != fps) {
5364 dprintk(VIDC_PROF, "reported fps changed for %pK: %d->%d\n",
5365 inst, inst->prop.fps, fps);
5366 inst->prop.fps = fps;
5367 frame_rate.frame_rate = inst->prop.fps * BIT(16);
5368 frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
5369 pdata = &frame_rate;
5370 if (inst->session_type == MSM_VIDC_ENCODER) {
5371 rc = call_hfi_op(hdev, session_set_property,
5372 inst->session, property_id, pdata);
5373
5374 if (rc)
5375 dprintk(VIDC_WARN,
5376 "Failed to set frame rate %d\n", rc);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08005377 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08005378 }
5379exit:
5380 return rc;
5381}
5382
5383void msm_comm_print_inst_info(struct msm_vidc_inst *inst)
5384{
5385 struct buffer_info *temp;
5386 struct internal_buf *buf;
5387 int i = 0;
5388 bool is_decode = false;
5389 enum vidc_ports port;
5390 bool is_secure = false;
5391
5392 if (!inst) {
5393 dprintk(VIDC_ERR, "%s - invalid param %pK\n",
5394 __func__, inst);
5395 return;
5396 }
5397
5398 is_decode = inst->session_type == MSM_VIDC_DECODER;
5399 port = is_decode ? OUTPUT_PORT : CAPTURE_PORT;
5400 is_secure = inst->flags & VIDC_SECURE;
5401 dprintk(VIDC_ERR,
5402 "%s session, %s, Codec type: %s HxW: %d x %d fps: %d bitrate: %d bit-depth: %s\n",
5403 is_decode ? "Decode" : "Encode",
5404 is_secure ? "Secure" : "Non-Secure",
5405 inst->fmts[port].name,
5406 inst->prop.height[port], inst->prop.width[port],
5407 inst->prop.fps, inst->prop.bitrate,
5408 !inst->bit_depth ? "8" : "10");
5409
5410 dprintk(VIDC_ERR,
5411 "---Buffer details for inst: %pK of type: %d---\n",
5412 inst, inst->session_type);
5413 mutex_lock(&inst->registeredbufs.lock);
5414 dprintk(VIDC_ERR, "registered buffer list:\n");
5415 list_for_each_entry(temp, &inst->registeredbufs.list, list)
5416 for (i = 0; i < temp->num_planes; i++)
5417 dprintk(VIDC_ERR,
5418 "type: %d plane: %d addr: %pa size: %d\n",
5419 temp->type, i, &temp->device_addr[i],
5420 temp->size[i]);
5421
5422 mutex_unlock(&inst->registeredbufs.lock);
5423
5424 mutex_lock(&inst->scratchbufs.lock);
5425 dprintk(VIDC_ERR, "scratch buffer list:\n");
5426 list_for_each_entry(buf, &inst->scratchbufs.list, list)
5427 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5428 buf->buffer_type, &buf->handle->device_addr,
5429 buf->handle->size);
5430 mutex_unlock(&inst->scratchbufs.lock);
5431
5432 mutex_lock(&inst->persistbufs.lock);
5433 dprintk(VIDC_ERR, "persist buffer list:\n");
5434 list_for_each_entry(buf, &inst->persistbufs.list, list)
5435 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5436 buf->buffer_type, &buf->handle->device_addr,
5437 buf->handle->size);
5438 mutex_unlock(&inst->persistbufs.lock);
5439
5440 mutex_lock(&inst->outputbufs.lock);
5441 dprintk(VIDC_ERR, "dpb buffer list:\n");
5442 list_for_each_entry(buf, &inst->outputbufs.list, list)
5443 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5444 buf->buffer_type, &buf->handle->device_addr,
5445 buf->handle->size);
5446 mutex_unlock(&inst->outputbufs.lock);
5447}
5448
5449static void msm_comm_print_debug_info(struct msm_vidc_inst *inst)
5450{
5451 struct msm_vidc_core *core = NULL;
5452 struct msm_vidc_inst *temp = NULL;
5453
5454 if (!inst || !inst->core) {
5455 dprintk(VIDC_ERR, "%s - invalid param %pK %pK\n",
5456 __func__, inst, core);
5457 return;
5458 }
5459 core = inst->core;
5460
Praneeth Paladugub71968b2015-08-19 20:47:57 -07005461 dprintk(VIDC_ERR, "Venus core frequency = %lu", core->freq);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08005462 mutex_lock(&core->lock);
5463 dprintk(VIDC_ERR, "Printing instance info that caused Error\n");
5464 msm_comm_print_inst_info(inst);
5465 dprintk(VIDC_ERR, "Printing remaining instances info\n");
5466 list_for_each_entry(temp, &core->instances, list) {
5467 /* inst already printed above. Hence don't repeat.*/
5468 if (temp == inst)
5469 continue;
5470 msm_comm_print_inst_info(temp);
5471 }
5472 mutex_unlock(&core->lock);
5473}