blob: 302c306521721c3572e04930b107f863451b9017 [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
776static int msm_comm_vote_bus(struct msm_vidc_core *core)
777{
778 int rc = 0, vote_data_count = 0, i = 0;
779 struct hfi_device *hdev;
780 struct msm_vidc_inst *inst = NULL;
781 struct vidc_bus_vote_data *vote_data = NULL;
782 unsigned long core_freq = 0;
783
784 if (!core) {
785 dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core);
786 return -EINVAL;
787 }
788
789 hdev = core->device;
790 if (!hdev) {
791 dprintk(VIDC_ERR, "%s Invalid device handle: %pK\n",
792 __func__, hdev);
793 return -EINVAL;
794 }
795
796 mutex_lock(&core->lock);
797 list_for_each_entry(inst, &core->instances, list)
798 ++vote_data_count;
799
800 vote_data = kcalloc(vote_data_count, sizeof(*vote_data),
801 GFP_TEMPORARY);
802 if (!vote_data) {
803 dprintk(VIDC_ERR, "%s: failed to allocate memory\n", __func__);
804 rc = -ENOMEM;
805 goto fail_alloc;
806 }
807
808 core_freq = call_hfi_op(hdev, get_core_clock_rate,
809 hdev->hfi_device_data, 0);
810
811 list_for_each_entry(inst, &core->instances, list) {
812 int codec = 0, yuv = 0;
813
814 codec = inst->session_type == MSM_VIDC_DECODER ?
815 inst->fmts[OUTPUT_PORT].fourcc :
816 inst->fmts[CAPTURE_PORT].fourcc;
817
818 yuv = inst->session_type == MSM_VIDC_DECODER ?
819 inst->fmts[CAPTURE_PORT].fourcc :
820 inst->fmts[OUTPUT_PORT].fourcc;
821
822 vote_data[i].domain = get_hal_domain(inst->session_type);
823 vote_data[i].codec = get_hal_codec(codec);
824 vote_data[i].width = max(inst->prop.width[CAPTURE_PORT],
825 inst->prop.width[OUTPUT_PORT]);
826 vote_data[i].height = max(inst->prop.height[CAPTURE_PORT],
827 inst->prop.height[OUTPUT_PORT]);
828
829 if (inst->operating_rate)
830 vote_data[i].fps = (inst->operating_rate >> 16) ?
831 inst->operating_rate >> 16 : 1;
832 else
833 vote_data[i].fps = inst->prop.fps;
834
835 if (msm_comm_turbo_session(inst))
836 vote_data[i].power_mode = VIDC_POWER_TURBO;
837 else if (is_low_power_session(inst))
838 vote_data[i].power_mode = VIDC_POWER_LOW;
839 else
840 vote_data[i].power_mode = VIDC_POWER_NORMAL;
841 if (i == 0) {
842 vote_data[i].imem_ab_tbl = core->resources.imem_ab_tbl;
843 vote_data[i].imem_ab_tbl_size =
844 core->resources.imem_ab_tbl_size;
845 vote_data[i].core_freq = core_freq;
846 }
847
848 /*
849 * TODO: support for OBP-DBP split mode hasn't been yet
850 * implemented, once it is, this part of code needs to be
851 * revisited since passing in accurate information to the bus
852 * governor will drastically reduce bandwidth
853 */
854 vote_data[i].color_formats[0] = get_hal_uncompressed(yuv);
855 vote_data[i].num_formats = 1;
856 i++;
857 }
858 mutex_unlock(&core->lock);
859
860 rc = call_hfi_op(hdev, vote_bus, hdev->hfi_device_data, vote_data,
861 vote_data_count);
862 if (rc)
863 dprintk(VIDC_ERR, "Failed to scale bus: %d\n", rc);
864
865 kfree(vote_data);
866 return rc;
867
868fail_alloc:
869 mutex_unlock(&core->lock);
870 return rc;
871}
872
873struct msm_vidc_core *get_vidc_core(int core_id)
874{
875 struct msm_vidc_core *core;
876 int found = 0;
877
878 if (core_id > MSM_VIDC_CORES_MAX) {
879 dprintk(VIDC_ERR, "Core id = %d is greater than max = %d\n",
880 core_id, MSM_VIDC_CORES_MAX);
881 return NULL;
882 }
883 mutex_lock(&vidc_driver->lock);
884 list_for_each_entry(core, &vidc_driver->cores, list) {
885 if (core->id == core_id) {
886 found = 1;
887 break;
888 }
889 }
890 mutex_unlock(&vidc_driver->lock);
891 if (found)
892 return core;
893 return NULL;
894}
895
896const struct msm_vidc_format *msm_comm_get_pixel_fmt_index(
897 const struct msm_vidc_format fmt[], int size, int index, int fmt_type)
898{
899 int i, k = 0;
900
901 if (!fmt || index < 0) {
902 dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK, index = %d\n",
903 fmt, index);
904 return NULL;
905 }
906 for (i = 0; i < size; i++) {
907 if (fmt[i].type != fmt_type)
908 continue;
909 if (k == index)
910 break;
911 k++;
912 }
913 if (i == size) {
914 dprintk(VIDC_INFO, "Format not found\n");
915 return NULL;
916 }
917 return &fmt[i];
918}
919struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc(
920 struct msm_vidc_format fmt[], int size, int fourcc, int fmt_type)
921{
922 int i;
923
924 if (!fmt) {
925 dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK\n", fmt);
926 return NULL;
927 }
928 for (i = 0; i < size; i++) {
929 if (fmt[i].fourcc == fourcc)
930 break;
931 }
932 if (i == size) {
933 dprintk(VIDC_INFO, "Format not found\n");
934 return NULL;
935 }
936 return &fmt[i];
937}
938
939struct buf_queue *msm_comm_get_vb2q(
940 struct msm_vidc_inst *inst, enum v4l2_buf_type type)
941{
942 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
943 return &inst->bufq[CAPTURE_PORT];
944 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
945 return &inst->bufq[OUTPUT_PORT];
946 return NULL;
947}
948
949static void handle_sys_init_done(enum hal_command_response cmd, void *data)
950{
951 struct msm_vidc_cb_cmd_done *response = data;
952 struct msm_vidc_core *core;
953 struct vidc_hal_sys_init_done *sys_init_msg;
954 u32 index;
955
956 if (!IS_HAL_SYS_CMD(cmd)) {
957 dprintk(VIDC_ERR, "%s - invalid cmd\n", __func__);
958 return;
959 }
960
961 index = SYS_MSG_INDEX(cmd);
962
963 if (!response) {
964 dprintk(VIDC_ERR,
965 "Failed to get valid response for sys init\n");
966 return;
967 }
968 core = get_vidc_core(response->device_id);
969 if (!core) {
970 dprintk(VIDC_ERR, "Wrong device_id received\n");
971 return;
972 }
973 sys_init_msg = &response->data.sys_init_done;
974 if (!sys_init_msg) {
975 dprintk(VIDC_ERR, "sys_init_done message not proper\n");
976 return;
977 }
978
979 core->enc_codec_supported = sys_init_msg->enc_codec_supported;
980 core->dec_codec_supported = sys_init_msg->dec_codec_supported;
981
982 /* This should come from sys_init_done */
983 core->resources.max_inst_count =
984 sys_init_msg->max_sessions_supported ? :
985 MAX_SUPPORTED_INSTANCES;
986
987 core->resources.max_secure_inst_count =
988 core->resources.max_secure_inst_count ? :
989 core->resources.max_inst_count;
990
991 if (core->id == MSM_VIDC_CORE_VENUS &&
992 (core->dec_codec_supported & HAL_VIDEO_CODEC_H264))
993 core->dec_codec_supported |=
994 HAL_VIDEO_CODEC_MVC;
995
996 core->codec_count = sys_init_msg->codec_count;
997 memcpy(core->capabilities, sys_init_msg->capabilities,
998 sys_init_msg->codec_count * sizeof(struct msm_vidc_capability));
999
1000 dprintk(VIDC_DBG,
1001 "%s: supported_codecs[%d]: enc = %#x, dec = %#x\n",
1002 __func__, core->codec_count, core->enc_codec_supported,
1003 core->dec_codec_supported);
1004
1005 complete(&(core->completions[index]));
1006}
1007
1008static void put_inst(struct msm_vidc_inst *inst)
1009{
1010 void put_inst_helper(struct kref *kref)
1011 {
1012 struct msm_vidc_inst *inst = container_of(kref,
1013 struct msm_vidc_inst, kref);
1014
1015 msm_vidc_destroy(inst);
1016 }
1017
1018 if (!inst)
1019 return;
1020
1021 kref_put(&inst->kref, put_inst_helper);
1022}
1023
1024static struct msm_vidc_inst *get_inst(struct msm_vidc_core *core,
1025 void *session_id)
1026{
1027 struct msm_vidc_inst *inst = NULL;
1028 bool matches = false;
1029
1030 if (!core || !session_id)
1031 return NULL;
1032
1033 mutex_lock(&core->lock);
1034 /*
1035 * This is as good as !list_empty(!inst->list), but at this point
1036 * we don't really know if inst was kfree'd via close syscall before
1037 * hardware could respond. So manually walk thru the list of active
1038 * sessions
1039 */
1040 list_for_each_entry(inst, &core->instances, list) {
1041 if (inst == session_id) {
1042 /*
1043 * Even if the instance is valid, we really shouldn't
1044 * be receiving or handling callbacks when we've deleted
1045 * our session with HFI
1046 */
1047 matches = !!inst->session;
1048 break;
1049 }
1050 }
1051
1052 /*
1053 * kref_* is atomic_int backed, so no need for inst->lock. But we can
1054 * always acquire inst->lock and release it in put_inst for a stronger
1055 * locking system.
1056 */
1057 inst = (matches && kref_get_unless_zero(&inst->kref)) ? inst : NULL;
1058 mutex_unlock(&core->lock);
1059
1060 return inst;
1061}
1062
1063static void handle_session_release_buf_done(enum hal_command_response cmd,
1064 void *data)
1065{
1066 struct msm_vidc_cb_cmd_done *response = data;
1067 struct msm_vidc_inst *inst;
1068 struct internal_buf *buf;
1069 struct list_head *ptr, *next;
1070 struct hal_buffer_info *buffer;
1071 u32 buf_found = false;
1072 u32 address;
1073
1074 if (!response) {
1075 dprintk(VIDC_ERR, "Invalid release_buf_done response\n");
1076 return;
1077 }
1078
1079 inst = get_inst(get_vidc_core(response->device_id),
1080 response->session_id);
1081 if (!inst) {
1082 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1083 return;
1084 }
1085
1086 buffer = &response->data.buffer_info;
1087 address = buffer->buffer_addr;
1088
1089 mutex_lock(&inst->scratchbufs.lock);
1090 list_for_each_safe(ptr, next, &inst->scratchbufs.list) {
1091 buf = list_entry(ptr, struct internal_buf, list);
1092 if (address == (u32)buf->handle->device_addr) {
1093 dprintk(VIDC_DBG, "releasing scratch: %pa\n",
1094 &buf->handle->device_addr);
1095 buf_found = true;
1096 }
1097 }
1098 mutex_unlock(&inst->scratchbufs.lock);
1099
1100 mutex_lock(&inst->persistbufs.lock);
1101 list_for_each_safe(ptr, next, &inst->persistbufs.list) {
1102 buf = list_entry(ptr, struct internal_buf, list);
1103 if (address == (u32)buf->handle->device_addr) {
1104 dprintk(VIDC_DBG, "releasing persist: %pa\n",
1105 &buf->handle->device_addr);
1106 buf_found = true;
1107 }
1108 }
1109 mutex_unlock(&inst->persistbufs.lock);
1110
1111 if (!buf_found)
1112 dprintk(VIDC_ERR, "invalid buffer received from firmware");
1113 if (IS_HAL_SESSION_CMD(cmd))
1114 complete(&inst->completions[SESSION_MSG_INDEX(cmd)]);
1115 else
1116 dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd);
1117
1118 put_inst(inst);
1119}
1120
1121static void handle_sys_release_res_done(
1122 enum hal_command_response cmd, void *data)
1123{
1124 struct msm_vidc_cb_cmd_done *response = data;
1125 struct msm_vidc_core *core;
1126
1127 if (!response) {
1128 dprintk(VIDC_ERR,
1129 "Failed to get valid response for sys init\n");
1130 return;
1131 }
1132 core = get_vidc_core(response->device_id);
1133 if (!core) {
1134 dprintk(VIDC_ERR, "Wrong device_id received\n");
1135 return;
1136 }
1137 complete(&core->completions[
1138 SYS_MSG_INDEX(HAL_SYS_RELEASE_RESOURCE_DONE)]);
1139}
1140
1141static void change_inst_state(struct msm_vidc_inst *inst,
1142 enum instance_state state)
1143{
1144 if (!inst) {
1145 dprintk(VIDC_ERR, "Invalid parameter %s\n", __func__);
1146 return;
1147 }
1148 mutex_lock(&inst->lock);
1149 if (inst->state == MSM_VIDC_CORE_INVALID) {
1150 dprintk(VIDC_DBG,
1151 "Inst: %pK is in bad state can't change state to %d\n",
1152 inst, state);
1153 goto exit;
1154 }
1155 dprintk(VIDC_DBG, "Moved inst: %pK from state: %d to state: %d\n",
1156 inst, inst->state, state);
1157 inst->state = state;
1158exit:
1159 mutex_unlock(&inst->lock);
1160}
1161
1162static int signal_session_msg_receipt(enum hal_command_response cmd,
1163 struct msm_vidc_inst *inst)
1164{
1165 if (!inst) {
1166 dprintk(VIDC_ERR, "Invalid(%pK) instance id\n", inst);
1167 return -EINVAL;
1168 }
1169 if (IS_HAL_SESSION_CMD(cmd)) {
1170 complete(&inst->completions[SESSION_MSG_INDEX(cmd)]);
1171 } else {
1172 dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd);
1173 return -EINVAL;
1174 }
1175 return 0;
1176}
1177
1178static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst,
1179 enum hal_command_response cmd)
1180{
1181 int rc = 0;
1182 struct hfi_device *hdev;
1183
1184 if (!IS_HAL_SESSION_CMD(cmd)) {
1185 dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd);
1186 return -EINVAL;
1187 }
1188 hdev = (struct hfi_device *)(inst->core->device);
1189 rc = wait_for_completion_timeout(
1190 &inst->completions[SESSION_MSG_INDEX(cmd)],
1191 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
1192 if (!rc) {
1193 dprintk(VIDC_ERR, "Wait interrupted or timed out: %d\n",
1194 SESSION_MSG_INDEX(cmd));
1195 msm_comm_kill_session(inst);
1196 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
1197 dprintk(VIDC_ERR,
1198 "sess resp timeout can potentially crash the system\n");
1199 msm_comm_print_debug_info(inst);
1200 msm_vidc_handle_hw_error(inst->core);
1201 rc = -EIO;
1202 } else {
1203 rc = 0;
1204 }
1205 return rc;
1206}
1207
1208static int wait_for_state(struct msm_vidc_inst *inst,
1209 enum instance_state flipped_state,
1210 enum instance_state desired_state,
1211 enum hal_command_response hal_cmd)
1212{
1213 int rc = 0;
1214
1215 if (IS_ALREADY_IN_STATE(flipped_state, desired_state)) {
1216 dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n",
1217 inst, inst->state);
1218 goto err_same_state;
1219 }
1220 dprintk(VIDC_DBG, "Waiting for hal_cmd: %d\n", hal_cmd);
1221 rc = wait_for_sess_signal_receipt(inst, hal_cmd);
1222 if (!rc)
1223 change_inst_state(inst, desired_state);
1224err_same_state:
1225 return rc;
1226}
1227
1228void msm_vidc_queue_v4l2_event(struct msm_vidc_inst *inst, int event_type)
1229{
1230 struct v4l2_event event = {.id = 0, .type = event_type};
1231
1232 v4l2_event_queue_fh(&inst->event_handler, &event);
1233}
1234
1235static void msm_comm_generate_max_clients_error(struct msm_vidc_inst *inst)
1236{
1237 enum hal_command_response cmd = HAL_SESSION_ERROR;
1238 struct msm_vidc_cb_cmd_done response = {0};
1239
1240 if (!inst) {
1241 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
1242 return;
1243 }
1244 dprintk(VIDC_ERR, "%s: Too many clients\n", __func__);
1245 response.session_id = inst;
1246 response.status = VIDC_ERR_MAX_CLIENTS;
1247 handle_session_error(cmd, (void *)&response);
1248}
1249
1250static void print_cap(const char *type,
1251 struct hal_capability_supported *cap)
1252{
1253 dprintk(VIDC_DBG,
1254 "%-24s: %-8d %-8d %-8d\n",
1255 type, cap->min, cap->max, cap->step_size);
1256}
1257
Praneeth Paladugue1679112017-01-27 10:07:15 -08001258static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst,
1259 u32 id, struct hal_capability_supported *capability)
1260{
1261 struct v4l2_ctrl *ctrl = NULL;
1262 int rc = 0;
1263
1264 ctrl = v4l2_ctrl_find(&inst->ctrl_handler, id);
1265 if (ctrl) {
1266 v4l2_ctrl_modify_range(ctrl, capability->min,
1267 capability->max, ctrl->step,
1268 capability->min);
1269 dprintk(VIDC_DBG,
1270 "%s: Updated Range = %lld --> %lld Def value = %lld\n",
1271 ctrl->name, ctrl->minimum, ctrl->maximum,
1272 ctrl->default_value);
1273 } else {
1274 dprintk(VIDC_ERR,
1275 "Failed to find Conrol %d\n", id);
1276 rc = -EINVAL;
1277 }
1278
1279 return rc;
1280 }
1281
1282static void msm_vidc_comm_update_ctrl_limits(struct msm_vidc_inst *inst)
1283{
1284 msm_vidc_comm_update_ctrl(inst,
1285 V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE,
1286 &inst->capability.hier_p_hybrid);
1287 msm_vidc_comm_update_ctrl(inst,
1288 V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS,
1289 &inst->capability.hier_b);
1290 msm_vidc_comm_update_ctrl(inst,
1291 V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS,
1292 &inst->capability.hier_p);
1293 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE,
1294 &inst->capability.bitrate);
1295 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
1296 &inst->capability.peakbitrate);
Praneeth Paladugu7fbd2792017-01-27 13:39:03 -08001297 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP,
1298 &inst->capability.i_qp);
1299 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP,
1300 &inst->capability.p_qp);
1301 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP,
1302 &inst->capability.b_qp);
1303 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP_MIN,
1304 &inst->capability.i_qp);
1305 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP_MIN,
1306 &inst->capability.p_qp);
1307 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP_MIN,
1308 &inst->capability.b_qp);
1309 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP_MAX,
1310 &inst->capability.i_qp);
1311 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP_MAX,
1312 &inst->capability.p_qp);
1313 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP_MAX,
1314 &inst->capability.b_qp);
Praneeth Paladugue1679112017-01-27 10:07:15 -08001315 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_BLUR_WIDTH,
1316 &inst->capability.blur_width);
1317 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_BLUR_HEIGHT,
1318 &inst->capability.blur_height);
1319 msm_vidc_comm_update_ctrl(inst,
1320 V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
1321 &inst->capability.slice_bytes);
1322 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
1323 &inst->capability.slice_mbs);
1324 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT,
1325 &inst->capability.ltr_count);
1326 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES,
1327 &inst->capability.bframe);
1328}
1329
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001330static void handle_session_init_done(enum hal_command_response cmd, void *data)
1331{
1332 struct msm_vidc_cb_cmd_done *response = data;
1333 struct msm_vidc_inst *inst = NULL;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001334 struct msm_vidc_capability *capability = NULL;
1335 struct hfi_device *hdev;
1336 struct msm_vidc_core *core;
1337 u32 i, codec;
1338
1339 if (!response) {
1340 dprintk(VIDC_ERR,
1341 "Failed to get valid response for session init\n");
1342 return;
1343 }
1344
1345 inst = get_inst(get_vidc_core(response->device_id),
1346 response->session_id);
1347
1348 if (!inst) {
1349 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1350 return;
1351 }
1352
1353 if (response->status) {
1354 dprintk(VIDC_ERR,
1355 "Session init response from FW : %#x\n",
1356 response->status);
1357 if (response->status == VIDC_ERR_MAX_CLIENTS)
1358 msm_comm_generate_max_clients_error(inst);
1359 else
1360 msm_comm_generate_session_error(inst);
1361
1362 signal_session_msg_receipt(cmd, inst);
1363 put_inst(inst);
1364 return;
1365 }
1366
1367 core = inst->core;
1368 hdev = inst->core->device;
1369 codec = inst->session_type == MSM_VIDC_DECODER ?
1370 inst->fmts[OUTPUT_PORT].fourcc :
1371 inst->fmts[CAPTURE_PORT].fourcc;
1372
1373 /* check if capabilities are available for this session */
1374 for (i = 0; i < VIDC_MAX_SESSIONS; i++) {
1375 if (core->capabilities[i].codec ==
1376 get_hal_codec(codec) &&
1377 core->capabilities[i].domain ==
1378 get_hal_domain(inst->session_type)) {
1379 capability = &core->capabilities[i];
1380 break;
1381 }
1382 }
1383
1384 if (capability) {
1385 dprintk(VIDC_DBG,
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001386 "%s: capabilities for codec 0x%x, domain %#x\n",
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001387 __func__, capability->codec, capability->domain);
1388 memcpy(&inst->capability, capability,
1389 sizeof(struct msm_vidc_capability));
1390 } else {
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001391 dprintk(VIDC_ERR,
1392 "Watch out : Some property may fail inst %pK\n", inst);
1393 dprintk(VIDC_ERR,
1394 "Caps N/A for codec 0x%x, domain %#x\n",
1395 inst->capability.codec, inst->capability.domain);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001396 }
1397 inst->capability.pixelprocess_capabilities =
1398 call_hfi_op(hdev, get_core_capabilities, hdev->hfi_device_data);
1399
1400 dprintk(VIDC_DBG,
1401 "Capability type : min max step size\n");
1402 print_cap("width", &inst->capability.width);
1403 print_cap("height", &inst->capability.height);
1404 print_cap("mbs_per_frame", &inst->capability.mbs_per_frame);
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001405 print_cap("mbs_per_sec", &inst->capability.mbs_per_sec);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001406 print_cap("frame_rate", &inst->capability.frame_rate);
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001407 print_cap("bitrate", &inst->capability.bitrate);
1408 print_cap("peak_bitrate", &inst->capability.peakbitrate);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001409 print_cap("scale_x", &inst->capability.scale_x);
1410 print_cap("scale_y", &inst->capability.scale_y);
1411 print_cap("hier_p", &inst->capability.hier_p);
1412 print_cap("ltr_count", &inst->capability.ltr_count);
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001413 print_cap("bframe", &inst->capability.bframe);
1414 print_cap("secure_output2_threshold",
1415 &inst->capability.secure_output2_threshold);
1416 print_cap("hier_b", &inst->capability.hier_b);
1417 print_cap("lcu_size", &inst->capability.lcu_size);
1418 print_cap("hier_p_hybrid", &inst->capability.hier_p_hybrid);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001419 print_cap("mbs_per_sec_low_power",
1420 &inst->capability.mbs_per_sec_power_save);
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001421 print_cap("extradata", &inst->capability.extradata);
1422 print_cap("profile", &inst->capability.profile);
1423 print_cap("level", &inst->capability.level);
1424 print_cap("i_qp", &inst->capability.i_qp);
1425 print_cap("p_qp", &inst->capability.p_qp);
1426 print_cap("b_qp", &inst->capability.b_qp);
1427 print_cap("rc_modes", &inst->capability.rc_modes);
1428 print_cap("blur_width", &inst->capability.blur_width);
1429 print_cap("blur_height", &inst->capability.blur_height);
1430 print_cap("slice_delivery_mode", &inst->capability.slice_delivery_mode);
1431 print_cap("slice_bytes", &inst->capability.slice_bytes);
1432 print_cap("slice_mbs", &inst->capability.slice_mbs);
1433 print_cap("secure", &inst->capability.secure);
1434 print_cap("max_num_b_frames", &inst->capability.max_num_b_frames);
1435 print_cap("max_video_cores", &inst->capability.max_video_cores);
1436 print_cap("max_work_modes", &inst->capability.max_work_modes);
1437 print_cap("ubwc_cr_stats", &inst->capability.ubwc_cr_stats);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001438
1439 signal_session_msg_receipt(cmd, inst);
Praneeth Paladugue1679112017-01-27 10:07:15 -08001440
1441 /*
1442 * Update controls after informing session_init_done to avoid
1443 * timeouts.
1444 */
1445
1446 msm_vidc_comm_update_ctrl_limits(inst);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001447 put_inst(inst);
1448}
1449
1450static void handle_event_change(enum hal_command_response cmd, void *data)
1451{
1452 struct msm_vidc_inst *inst = NULL;
1453 struct msm_vidc_cb_event *event_notify = data;
1454 int event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1455 struct v4l2_event seq_changed_event = {0};
1456 int rc = 0;
1457 struct hfi_device *hdev;
1458 u32 *ptr = NULL;
1459
1460 if (!event_notify) {
1461 dprintk(VIDC_WARN, "Got an empty event from hfi\n");
1462 return;
1463 }
1464
1465 inst = get_inst(get_vidc_core(event_notify->device_id),
1466 event_notify->session_id);
1467 if (!inst || !inst->core || !inst->core->device) {
1468 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1469 goto err_bad_event;
1470 }
1471 hdev = inst->core->device;
1472
1473 switch (event_notify->hal_event_type) {
1474 case HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES:
1475 event = V4L2_EVENT_SEQ_CHANGED_SUFFICIENT;
1476
1477 if (msm_comm_get_stream_output_mode(inst) ==
1478 HAL_VIDEO_DECODER_SECONDARY) {
1479 struct hal_frame_size frame_sz;
1480
1481 frame_sz.buffer_type = HAL_BUFFER_OUTPUT2;
1482 frame_sz.width = event_notify->width;
1483 frame_sz.height = event_notify->height;
1484 dprintk(VIDC_DBG,
1485 "Update OPB dimensions to firmware if buffer requirements are sufficient\n");
1486 rc = msm_comm_try_set_prop(inst,
1487 HAL_PARAM_FRAME_SIZE, &frame_sz);
1488 }
1489
1490 dprintk(VIDC_DBG,
1491 "send session_continue after sufficient event\n");
1492 rc = call_hfi_op(hdev, session_continue,
1493 (void *) inst->session);
1494 if (rc) {
1495 dprintk(VIDC_ERR,
1496 "%s - failed to send session_continue\n",
1497 __func__);
1498 goto err_bad_event;
1499 }
1500 break;
1501 case HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES:
1502 event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1503 break;
1504 case HAL_EVENT_RELEASE_BUFFER_REFERENCE:
1505 {
1506 struct v4l2_event buf_event = {0};
1507 struct buffer_info *binfo = NULL, *temp = NULL;
1508 u32 *ptr = NULL;
1509
1510 dprintk(VIDC_DBG, "%s - inst: %pK buffer: %pa extra: %pa\n",
1511 __func__, inst, &event_notify->packet_buffer,
1512 &event_notify->extra_data_buffer);
1513
1514 if (inst->state == MSM_VIDC_CORE_INVALID ||
1515 inst->core->state == VIDC_CORE_INVALID) {
1516 dprintk(VIDC_DBG,
1517 "Event release buf ref received in invalid state - discard\n");
1518 goto err_bad_event;
1519 }
1520
1521 /*
1522 * Get the buffer_info entry for the
1523 * device address.
1524 */
1525 binfo = device_to_uvaddr(&inst->registeredbufs,
1526 event_notify->packet_buffer);
1527 if (!binfo) {
1528 dprintk(VIDC_ERR,
1529 "%s buffer not found in registered list\n",
1530 __func__);
1531 goto err_bad_event;
1532 }
1533
1534 /* Fill event data to be sent to client*/
1535 buf_event.type = V4L2_EVENT_RELEASE_BUFFER_REFERENCE;
1536 ptr = (u32 *)buf_event.u.data;
1537 ptr[0] = binfo->fd[0];
1538 ptr[1] = binfo->buff_off[0];
1539
1540 dprintk(VIDC_DBG,
1541 "RELEASE REFERENCE EVENT FROM F/W - fd = %d offset = %d\n",
1542 ptr[0], ptr[1]);
1543
1544 /* Decrement buffer reference count*/
1545 mutex_lock(&inst->registeredbufs.lock);
1546 list_for_each_entry(temp, &inst->registeredbufs.list,
1547 list) {
1548 if (temp == binfo) {
1549 buf_ref_put(inst, binfo);
1550 break;
1551 }
1552 }
1553
1554 /*
1555 * Release buffer and remove from list
1556 * if reference goes to zero.
1557 */
1558 if (unmap_and_deregister_buf(inst, binfo))
1559 dprintk(VIDC_ERR,
1560 "%s: buffer unmap failed\n", __func__);
1561 mutex_unlock(&inst->registeredbufs.lock);
1562
1563 /*send event to client*/
1564 v4l2_event_queue_fh(&inst->event_handler, &buf_event);
1565 goto err_bad_event;
1566 }
1567 default:
1568 break;
1569 }
1570
1571 /* Bit depth and pic struct changed event are combined into a single
1572 * event (insufficient event) for the userspace. Currently bitdepth
1573 * changes is only for HEVC and interlaced support is for all
1574 * codecs except HEVC
1575 * event data is now as follows:
1576 * u32 *ptr = seq_changed_event.u.data;
1577 * ptr[0] = height
1578 * ptr[1] = width
1579 * ptr[2] = flag to indicate bit depth or/and pic struct changed
1580 * ptr[3] = bit depth
1581 * ptr[4] = pic struct (progressive or interlaced)
1582 * ptr[5] = colour space
1583 */
1584
Chinmay Sawarkarb3c6ccb2017-02-23 18:01:32 -08001585 inst->entropy_mode = msm_comm_hal_to_v4l2(
1586 V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
1587 event_notify->entropy_mode);
1588 inst->profile = msm_comm_hal_to_v4l2(
1589 V4L2_CID_MPEG_VIDEO_H264_PROFILE,
1590 event_notify->profile);
1591 inst->level = msm_comm_hal_to_v4l2(
1592 V4L2_CID_MPEG_VIDEO_H264_LEVEL,
1593 event_notify->level);
1594
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001595 ptr = (u32 *)seq_changed_event.u.data;
1596
1597 if (ptr != NULL) {
1598 ptr[2] = 0x0;
1599 ptr[3] = inst->bit_depth;
1600 ptr[4] = inst->pic_struct;
1601 ptr[5] = inst->colour_space;
1602
1603 if (inst->bit_depth != event_notify->bit_depth) {
1604 inst->bit_depth = event_notify->bit_depth;
1605 ptr[2] |= V4L2_EVENT_BITDEPTH_FLAG;
1606 ptr[3] = inst->bit_depth;
1607 event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1608 dprintk(VIDC_DBG,
1609 "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT due to bit-depth change\n");
1610 }
1611
1612 if (inst->pic_struct != event_notify->pic_struct) {
1613 inst->pic_struct = event_notify->pic_struct;
1614 event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1615 ptr[2] |= V4L2_EVENT_PICSTRUCT_FLAG;
1616 ptr[4] = inst->pic_struct;
1617 dprintk(VIDC_DBG,
1618 "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT due to pic-struct change\n");
1619 }
1620
1621 if (inst->bit_depth == MSM_VIDC_BIT_DEPTH_10
1622 && inst->colour_space !=
1623 event_notify->colour_space) {
1624 inst->colour_space = event_notify->colour_space;
1625 event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1626 ptr[2] |= V4L2_EVENT_COLOUR_SPACE_FLAG;
1627 ptr[5] = inst->colour_space;
1628 dprintk(VIDC_DBG,
1629 "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT due to colour space change\n");
1630 }
1631
1632 }
1633
1634 if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) {
1635 dprintk(VIDC_DBG, "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n");
1636 inst->reconfig_height = event_notify->height;
1637 inst->reconfig_width = event_notify->width;
1638 inst->in_reconfig = true;
1639 } else {
1640 dprintk(VIDC_DBG, "V4L2_EVENT_SEQ_CHANGED_SUFFICIENT\n");
1641 dprintk(VIDC_DBG,
1642 "event_notify->height = %d event_notify->width = %d\n",
1643 event_notify->height,
1644 event_notify->width);
1645 inst->prop.height[OUTPUT_PORT] = event_notify->height;
1646 inst->prop.width[OUTPUT_PORT] = event_notify->width;
1647 }
1648
1649 if (inst->session_type == MSM_VIDC_DECODER)
1650 msm_dcvs_init_load(inst);
1651
1652 rc = msm_vidc_check_session_supported(inst);
1653 if (!rc) {
1654 seq_changed_event.type = event;
1655 if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) {
1656 u32 *ptr = NULL;
1657
1658 ptr = (u32 *)seq_changed_event.u.data;
1659 ptr[0] = event_notify->height;
1660 ptr[1] = event_notify->width;
1661 }
1662 v4l2_event_queue_fh(&inst->event_handler, &seq_changed_event);
1663 } else if (rc == -ENOTSUPP) {
1664 msm_vidc_queue_v4l2_event(inst,
1665 V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED);
1666 } else if (rc == -EBUSY) {
1667 msm_vidc_queue_v4l2_event(inst,
1668 V4L2_EVENT_MSM_VIDC_HW_OVERLOAD);
1669 }
1670
1671err_bad_event:
1672 put_inst(inst);
1673}
1674
1675static void handle_session_prop_info(enum hal_command_response cmd, void *data)
1676{
1677 struct msm_vidc_cb_cmd_done *response = data;
1678 struct getprop_buf *getprop;
1679 struct msm_vidc_inst *inst;
1680
1681 if (!response) {
1682 dprintk(VIDC_ERR,
1683 "Failed to get valid response for prop info\n");
1684 return;
1685 }
1686
1687 inst = get_inst(get_vidc_core(response->device_id),
1688 response->session_id);
1689 if (!inst) {
1690 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1691 return;
1692 }
1693
1694 getprop = kzalloc(sizeof(*getprop), GFP_KERNEL);
1695 if (!getprop) {
1696 dprintk(VIDC_ERR, "%s: getprop kzalloc failed\n", __func__);
1697 goto err_prop_info;
1698 }
1699
1700 getprop->data = kmemdup(&response->data.property,
1701 sizeof(union hal_get_property), GFP_KERNEL);
1702 if (!getprop->data) {
1703 dprintk(VIDC_ERR, "%s: kmemdup failed\n", __func__);
1704 kfree(getprop);
1705 goto err_prop_info;
1706 }
1707
1708 mutex_lock(&inst->pending_getpropq.lock);
1709 list_add_tail(&getprop->list, &inst->pending_getpropq.list);
1710 mutex_unlock(&inst->pending_getpropq.lock);
1711
1712 signal_session_msg_receipt(cmd, inst);
1713err_prop_info:
1714 put_inst(inst);
1715}
1716
1717static void handle_load_resource_done(enum hal_command_response cmd, void *data)
1718{
1719 struct msm_vidc_cb_cmd_done *response = data;
1720 struct msm_vidc_inst *inst;
1721
1722 if (!response) {
1723 dprintk(VIDC_ERR,
1724 "Failed to get valid response for load resource\n");
1725 return;
1726 }
1727
1728 inst = get_inst(get_vidc_core(response->device_id),
1729 response->session_id);
1730 if (!inst) {
1731 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1732 return;
1733 }
1734
1735 if (response->status) {
1736 dprintk(VIDC_ERR,
1737 "Load resource response from FW : %#x\n",
1738 response->status);
1739 msm_comm_generate_session_error(inst);
1740 }
1741
1742 put_inst(inst);
1743}
1744
1745static void handle_start_done(enum hal_command_response cmd, void *data)
1746{
1747 struct msm_vidc_cb_cmd_done *response = data;
1748 struct msm_vidc_inst *inst;
1749
1750 if (!response) {
1751 dprintk(VIDC_ERR, "Failed to get valid response for start\n");
1752 return;
1753 }
1754
1755 inst = get_inst(get_vidc_core(response->device_id),
1756 response->session_id);
1757 if (!inst) {
1758 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1759 return;
1760 }
1761
1762 signal_session_msg_receipt(cmd, inst);
1763 put_inst(inst);
1764}
1765
1766static void handle_stop_done(enum hal_command_response cmd, void *data)
1767{
1768 struct msm_vidc_cb_cmd_done *response = data;
1769 struct msm_vidc_inst *inst;
1770
1771 if (!response) {
1772 dprintk(VIDC_ERR, "Failed to get valid response for stop\n");
1773 return;
1774 }
1775
1776 inst = get_inst(get_vidc_core(response->device_id),
1777 response->session_id);
1778 if (!inst) {
1779 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1780 return;
1781 }
1782
1783 signal_session_msg_receipt(cmd, inst);
1784 put_inst(inst);
1785}
1786
1787static void handle_release_res_done(enum hal_command_response cmd, void *data)
1788{
1789 struct msm_vidc_cb_cmd_done *response = data;
1790 struct msm_vidc_inst *inst;
1791
1792 if (!response) {
1793 dprintk(VIDC_ERR,
1794 "Failed to get valid response for release resource\n");
1795 return;
1796 }
1797
1798 inst = get_inst(get_vidc_core(response->device_id),
1799 response->session_id);
1800 if (!inst) {
1801 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1802 return;
1803 }
1804
1805 signal_session_msg_receipt(cmd, inst);
1806 put_inst(inst);
1807}
1808
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001809void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001810{
1811 struct internal_buf *binfo;
1812 u32 buffers_owned_by_driver = 0;
1813 struct hal_buffer_requirements *output_buf;
1814
1815 output_buf = get_buff_req_buffer(inst, HAL_BUFFER_OUTPUT);
1816
1817 if (!output_buf) {
1818 dprintk(VIDC_DBG,
1819 "This output buffer not required, buffer_type: %x\n",
1820 HAL_BUFFER_OUTPUT);
1821 return;
1822 }
1823 mutex_lock(&inst->outputbufs.lock);
1824 list_for_each_entry(binfo, &inst->outputbufs.list, list) {
1825 if (binfo->buffer_ownership != DRIVER) {
1826 dprintk(VIDC_DBG,
1827 "This buffer is with FW %pa\n",
1828 &binfo->handle->device_addr);
1829 continue;
1830 }
1831 buffers_owned_by_driver++;
1832 }
1833 mutex_unlock(&inst->outputbufs.lock);
1834
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001835 if (buffers_owned_by_driver != output_buf->buffer_count_actual) {
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001836 dprintk(VIDC_WARN,
1837 "OUTPUT Buffer count mismatch %d of %d\n",
1838 buffers_owned_by_driver,
1839 output_buf->buffer_count_actual);
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001840 msm_vidc_handle_hw_error(inst->core);
1841 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001842}
1843
1844int msm_comm_queue_output_buffers(struct msm_vidc_inst *inst)
1845{
1846 struct internal_buf *binfo;
1847 struct hfi_device *hdev;
1848 struct msm_smem *handle;
1849 struct vidc_frame_data frame_data = {0};
1850 struct hal_buffer_requirements *output_buf, *extra_buf;
1851 int rc = 0;
1852
1853 if (!inst || !inst->core || !inst->core->device) {
1854 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
1855 return -EINVAL;
1856 }
1857
1858 hdev = inst->core->device;
1859
1860 output_buf = get_buff_req_buffer(inst, HAL_BUFFER_OUTPUT);
1861 if (!output_buf) {
1862 dprintk(VIDC_DBG,
1863 "This output buffer not required, buffer_type: %x\n",
1864 HAL_BUFFER_OUTPUT);
1865 return 0;
1866 }
1867 dprintk(VIDC_DBG,
1868 "output: num = %d, size = %d\n",
1869 output_buf->buffer_count_actual,
1870 output_buf->buffer_size);
1871
1872 extra_buf = get_buff_req_buffer(inst, HAL_BUFFER_EXTRADATA_OUTPUT);
1873
1874 mutex_lock(&inst->outputbufs.lock);
1875 list_for_each_entry(binfo, &inst->outputbufs.list, list) {
1876 if (binfo->buffer_ownership != DRIVER)
1877 continue;
1878 handle = binfo->handle;
1879 frame_data.alloc_len = output_buf->buffer_size;
1880 frame_data.filled_len = 0;
1881 frame_data.offset = 0;
1882 frame_data.device_addr = handle->device_addr;
1883 frame_data.flags = 0;
1884 frame_data.extradata_addr = handle->device_addr +
1885 output_buf->buffer_size;
1886 frame_data.buffer_type = HAL_BUFFER_OUTPUT;
1887 frame_data.extradata_size = extra_buf ?
1888 extra_buf->buffer_size : 0;
1889 rc = call_hfi_op(hdev, session_ftb,
1890 (void *) inst->session, &frame_data);
1891 binfo->buffer_ownership = FIRMWARE;
1892 }
1893 mutex_unlock(&inst->outputbufs.lock);
1894
1895 return 0;
1896}
1897
1898static void handle_session_flush(enum hal_command_response cmd, void *data)
1899{
1900 struct msm_vidc_cb_cmd_done *response = data;
1901 struct msm_vidc_inst *inst;
1902 struct v4l2_event flush_event = {0};
1903 u32 *ptr = NULL;
1904 enum hal_flush flush_type;
1905 int rc;
1906
1907 if (!response) {
1908 dprintk(VIDC_ERR, "Failed to get valid response for flush\n");
1909 return;
1910 }
1911
1912 inst = get_inst(get_vidc_core(response->device_id),
1913 response->session_id);
1914 if (!inst) {
1915 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1916 return;
1917 }
1918
1919 if (msm_comm_get_stream_output_mode(inst) ==
1920 HAL_VIDEO_DECODER_SECONDARY) {
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001921
1922 if (!(inst->fmts[OUTPUT_PORT].defer_outputs &&
1923 inst->in_reconfig))
1924 msm_comm_validate_output_buffers(inst);
1925
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001926 if (!inst->in_reconfig) {
1927 rc = msm_comm_queue_output_buffers(inst);
1928 if (rc) {
1929 dprintk(VIDC_ERR,
1930 "Failed to queue output buffers: %d\n",
1931 rc);
1932 }
1933 }
1934 }
1935 atomic_dec(&inst->in_flush);
1936 flush_event.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
1937 ptr = (u32 *)flush_event.u.data;
1938
1939 flush_type = response->data.flush_type;
1940 switch (flush_type) {
1941 case HAL_FLUSH_INPUT:
1942 ptr[0] = V4L2_QCOM_CMD_FLUSH_OUTPUT;
1943 break;
1944 case HAL_FLUSH_OUTPUT:
1945 ptr[0] = V4L2_QCOM_CMD_FLUSH_CAPTURE;
1946 break;
1947 case HAL_FLUSH_ALL:
1948 ptr[0] |= V4L2_QCOM_CMD_FLUSH_CAPTURE;
1949 ptr[0] |= V4L2_QCOM_CMD_FLUSH_OUTPUT;
1950 break;
1951 default:
1952 dprintk(VIDC_ERR, "Invalid flush type received!");
1953 goto exit;
1954 }
1955
1956 dprintk(VIDC_DBG,
1957 "Notify flush complete, flush_type: %x\n", flush_type);
1958 v4l2_event_queue_fh(&inst->event_handler, &flush_event);
1959
1960exit:
1961 put_inst(inst);
1962}
1963
1964static void handle_session_error(enum hal_command_response cmd, void *data)
1965{
1966 struct msm_vidc_cb_cmd_done *response = data;
1967 struct hfi_device *hdev = NULL;
1968 struct msm_vidc_inst *inst = NULL;
1969 int event = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
1970
1971 if (!response) {
1972 dprintk(VIDC_ERR,
1973 "Failed to get valid response for session error\n");
1974 return;
1975 }
1976
1977 inst = get_inst(get_vidc_core(response->device_id),
1978 response->session_id);
1979 if (!inst) {
1980 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1981 return;
1982 }
1983
1984 hdev = inst->core->device;
1985 dprintk(VIDC_WARN, "Session error received for session %pK\n", inst);
1986 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
1987
1988 if (response->status == VIDC_ERR_MAX_CLIENTS) {
1989 dprintk(VIDC_WARN, "Too many clients, rejecting %pK", inst);
1990 event = V4L2_EVENT_MSM_VIDC_MAX_CLIENTS;
1991
1992 /*
1993 * Clean the HFI session now. Since inst->state is moved to
1994 * INVALID, forward thread doesn't know FW has valid session
1995 * or not. This is the last place driver knows that there is
1996 * no session in FW. Hence clean HFI session now.
1997 */
1998
1999 msm_comm_session_clean(inst);
2000 } else if (response->status == VIDC_ERR_NOT_SUPPORTED) {
2001 dprintk(VIDC_WARN, "Unsupported bitstream in %pK", inst);
2002 event = V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED;
2003 } else {
2004 dprintk(VIDC_WARN, "Unknown session error (%d) for %pK\n",
2005 response->status, inst);
2006 event = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
2007 }
2008
2009 msm_vidc_queue_v4l2_event(inst, event);
2010 put_inst(inst);
2011}
2012
2013static void msm_comm_clean_notify_client(struct msm_vidc_core *core)
2014{
2015 struct msm_vidc_inst *inst = NULL;
2016
2017 if (!core) {
2018 dprintk(VIDC_ERR, "%s: Invalid params\n", __func__);
2019 return;
2020 }
2021
2022 dprintk(VIDC_WARN, "%s: Core %pK\n", __func__, core);
2023 mutex_lock(&core->lock);
2024 core->state = VIDC_CORE_INVALID;
2025
2026 list_for_each_entry(inst, &core->instances, list) {
2027 mutex_lock(&inst->lock);
2028 inst->state = MSM_VIDC_CORE_INVALID;
2029 mutex_unlock(&inst->lock);
2030 dprintk(VIDC_WARN,
2031 "%s Send sys error for inst %pK\n", __func__, inst);
2032 msm_vidc_queue_v4l2_event(inst,
2033 V4L2_EVENT_MSM_VIDC_SYS_ERROR);
2034 }
2035 mutex_unlock(&core->lock);
2036}
2037
2038static void handle_sys_error(enum hal_command_response cmd, void *data)
2039{
2040 struct msm_vidc_cb_cmd_done *response = data;
2041 struct msm_vidc_core *core = NULL;
2042 struct hfi_device *hdev = NULL;
2043 struct msm_vidc_inst *inst = NULL;
2044 int rc = 0;
2045
2046 subsystem_crashed("venus");
2047 if (!response) {
2048 dprintk(VIDC_ERR,
2049 "Failed to get valid response for sys error\n");
2050 return;
2051 }
2052
2053 core = get_vidc_core(response->device_id);
2054 if (!core) {
2055 dprintk(VIDC_ERR,
2056 "Got SYS_ERR but unable to identify core\n");
2057 return;
2058 }
2059
2060 mutex_lock(&core->lock);
2061 if (core->state == VIDC_CORE_INVALID ||
2062 core->state == VIDC_CORE_UNINIT) {
2063 dprintk(VIDC_ERR,
2064 "%s: Core already moved to state %d\n",
2065 __func__, core->state);
2066 mutex_unlock(&core->lock);
2067 return;
2068 }
2069 mutex_unlock(&core->lock);
2070
2071 dprintk(VIDC_WARN, "SYS_ERROR %d received for core %pK\n", cmd, core);
2072 msm_comm_clean_notify_client(core);
2073
2074 hdev = core->device;
2075 mutex_lock(&core->lock);
2076 if (core->state == VIDC_CORE_INVALID) {
2077 dprintk(VIDC_DBG, "Calling core_release\n");
2078 rc = call_hfi_op(hdev, core_release,
2079 hdev->hfi_device_data);
2080 if (rc) {
2081 dprintk(VIDC_ERR, "core_release failed\n");
2082 mutex_unlock(&core->lock);
2083 return;
2084 }
2085 core->state = VIDC_CORE_UNINIT;
2086 }
2087 mutex_unlock(&core->lock);
2088
2089 msm_vidc_print_running_insts(core);
2090 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
2091 dprintk(VIDC_ERR,
2092 "SYS_ERROR can potentially crash the system\n");
2093
2094 /*
2095 * For SYS_ERROR, there will not be any inst pointer.
2096 * Just grab one of the inst from instances list and
2097 * use it.
2098 */
2099
2100 mutex_lock(&core->lock);
2101 inst = list_first_entry_or_null(&core->instances,
2102 struct msm_vidc_inst, list);
2103 mutex_unlock(&core->lock);
2104
2105 msm_comm_print_debug_info(inst);
2106
2107 msm_vidc_handle_hw_error(core);
2108}
2109
2110void msm_comm_session_clean(struct msm_vidc_inst *inst)
2111{
2112 int rc = 0;
2113 struct hfi_device *hdev = NULL;
2114
2115 if (!inst || !inst->core || !inst->core->device) {
2116 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
2117 return;
2118 }
2119
2120 hdev = inst->core->device;
2121 mutex_lock(&inst->lock);
2122 if (hdev && inst->session) {
2123 dprintk(VIDC_DBG, "cleaning up instance: %pK\n", inst);
2124 rc = call_hfi_op(hdev, session_clean,
2125 (void *)inst->session);
2126 if (rc) {
2127 dprintk(VIDC_ERR,
2128 "Session clean failed :%pK\n", inst);
2129 }
2130 inst->session = NULL;
2131 }
2132 mutex_unlock(&inst->lock);
2133}
2134
2135static void handle_session_close(enum hal_command_response cmd, void *data)
2136{
2137 struct msm_vidc_cb_cmd_done *response = data;
2138 struct msm_vidc_inst *inst;
2139
2140 if (!response) {
2141 dprintk(VIDC_ERR,
2142 "Failed to get valid response for session close\n");
2143 return;
2144 }
2145
2146 inst = get_inst(get_vidc_core(response->device_id),
2147 response->session_id);
2148 if (!inst) {
2149 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
2150 return;
2151 }
2152
2153 signal_session_msg_receipt(cmd, inst);
2154 show_stats(inst);
2155 put_inst(inst);
2156}
2157
2158static struct vb2_buffer *get_vb_from_device_addr(struct buf_queue *bufq,
2159 unsigned long dev_addr)
2160{
2161 struct vb2_buffer *vb = NULL;
2162 struct vb2_queue *q = NULL;
2163 int found = 0;
2164
2165 if (!bufq) {
2166 dprintk(VIDC_ERR, "Invalid parameter\n");
2167 return NULL;
2168 }
2169 q = &bufq->vb2_bufq;
2170 mutex_lock(&bufq->lock);
2171 list_for_each_entry(vb, &q->queued_list, queued_entry) {
2172 if (vb->planes[0].m.userptr == dev_addr &&
2173 vb->state == VB2_BUF_STATE_ACTIVE) {
2174 found = 1;
2175 dprintk(VIDC_DBG, "Found v4l2_buf index : %d\n",
2176 vb->index);
2177 break;
2178 }
2179 }
2180 mutex_unlock(&bufq->lock);
2181 if (!found) {
2182 dprintk(VIDC_DBG,
2183 "Failed to find buffer in queued list: %#lx, qtype = %d\n",
2184 dev_addr, q->type);
2185 vb = NULL;
2186 }
2187 return vb;
2188}
2189
2190static void handle_ebd(enum hal_command_response cmd, void *data)
2191{
2192 struct msm_vidc_cb_data_done *response = data;
2193 struct vb2_buffer *vb;
2194 struct msm_vidc_inst *inst;
2195 struct vidc_hal_ebd *empty_buf_done;
2196 struct vb2_v4l2_buffer *vbuf = NULL;
2197
2198 if (!response) {
2199 dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
2200 return;
2201 }
2202
2203 inst = get_inst(get_vidc_core(response->device_id),
2204 response->session_id);
2205 if (!inst) {
2206 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
2207 return;
2208 }
2209
2210 vb = get_vb_from_device_addr(&inst->bufq[OUTPUT_PORT],
2211 response->input_done.packet_buffer);
2212 if (vb) {
2213 vbuf = to_vb2_v4l2_buffer(vb);
2214 vb->planes[0].bytesused = response->input_done.filled_len;
2215 vb->planes[0].data_offset = response->input_done.offset;
2216 if (vb->planes[0].data_offset > vb->planes[0].length)
2217 dprintk(VIDC_INFO, "data_offset overflow length\n");
2218 if (vb->planes[0].bytesused > vb->planes[0].length)
2219 dprintk(VIDC_INFO, "bytesused overflow length\n");
2220 if (vb->planes[0].m.userptr !=
2221 response->clnt_data)
2222 dprintk(VIDC_INFO, "Client data != bufaddr\n");
2223 empty_buf_done = (struct vidc_hal_ebd *)&response->input_done;
2224 if (empty_buf_done) {
2225 if (empty_buf_done->status == VIDC_ERR_NOT_SUPPORTED) {
2226 dprintk(VIDC_INFO,
2227 "Failed : Unsupported input stream\n");
2228 vbuf->flags |=
2229 V4L2_QCOM_BUF_INPUT_UNSUPPORTED;
2230 }
2231 if (empty_buf_done->status == VIDC_ERR_BITSTREAM_ERR) {
2232 dprintk(VIDC_INFO,
2233 "Failed : Corrupted input stream\n");
2234 vbuf->flags |=
2235 V4L2_QCOM_BUF_DATA_CORRUPT;
2236 }
2237 if (empty_buf_done->flags & HAL_BUFFERFLAG_SYNCFRAME)
2238 vbuf->flags |=
2239 V4L2_QCOM_BUF_FLAG_IDRFRAME |
2240 V4L2_BUF_FLAG_KEYFRAME;
2241 }
2242 dprintk(VIDC_DBG,
2243 "Got ebd from hal: device_addr: %pa, alloc: %d, status: %#x, pic_type: %#x, flags: %#x\n",
2244 &empty_buf_done->packet_buffer,
2245 empty_buf_done->alloc_len, empty_buf_done->status,
2246 empty_buf_done->picture_type, empty_buf_done->flags);
2247
2248 mutex_lock(&inst->bufq[OUTPUT_PORT].lock);
2249 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
2250 mutex_unlock(&inst->bufq[OUTPUT_PORT].lock);
2251 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_EBD);
2252 }
2253
2254 put_inst(inst);
2255}
2256
2257int buf_ref_get(struct msm_vidc_inst *inst, struct buffer_info *binfo)
2258{
2259 int cnt = 0;
2260
2261 if (!inst || !binfo)
2262 return -EINVAL;
2263
2264 atomic_inc(&binfo->ref_count);
2265 cnt = atomic_read(&binfo->ref_count);
2266 if (cnt > 2) {
2267 dprintk(VIDC_DBG, "%s: invalid ref_cnt: %d\n", __func__, cnt);
2268 cnt = -EINVAL;
2269 }
2270 if (cnt == 2)
2271 inst->buffers_held_in_driver++;
2272
2273 dprintk(VIDC_DBG, "REF_GET[%d] fd[0] = %d\n", cnt, binfo->fd[0]);
2274
2275 return cnt;
2276}
2277
2278int buf_ref_put(struct msm_vidc_inst *inst, struct buffer_info *binfo)
2279{
2280 int rc = 0;
2281 int cnt;
2282 bool release_buf = false;
2283 bool qbuf_again = false;
2284
2285 if (!inst || !binfo)
2286 return -EINVAL;
2287
2288 atomic_dec(&binfo->ref_count);
2289 cnt = atomic_read(&binfo->ref_count);
2290 dprintk(VIDC_DBG, "REF_PUT[%d] fd[0] = %d\n", cnt, binfo->fd[0]);
2291 if (!cnt)
2292 release_buf = true;
2293 else if (cnt == 1)
2294 qbuf_again = true;
2295 else {
2296 dprintk(VIDC_DBG, "%s: invalid ref_cnt: %d\n", __func__, cnt);
2297 cnt = -EINVAL;
2298 }
2299
2300 if (cnt < 0)
2301 return cnt;
2302
2303 if (release_buf) {
2304 /*
2305 * We can not delete binfo here as we need to set the user
2306 * virtual address saved in binfo->uvaddr to the dequeued v4l2
2307 * buffer.
2308 *
2309 * We will set the pending_deletion flag to true here and delete
2310 * binfo from registered list in dqbuf after setting the uvaddr.
2311 */
2312 dprintk(VIDC_DBG, "fd[0] = %d -> pending_deletion = true\n",
2313 binfo->fd[0]);
2314 binfo->pending_deletion = true;
2315 } else if (qbuf_again) {
2316 inst->buffers_held_in_driver--;
2317 rc = qbuf_dynamic_buf(inst, binfo);
2318 if (!rc)
2319 return rc;
2320 }
2321 return cnt;
2322}
2323
2324static void handle_dynamic_buffer(struct msm_vidc_inst *inst,
2325 ion_phys_addr_t device_addr, u32 flags)
2326{
2327 struct buffer_info *binfo = NULL, *temp = NULL;
2328
2329 /*
2330 * Update reference count and release OR queue back the buffer,
2331 * only when firmware is not holding a reference.
2332 */
2333 if (inst->buffer_mode_set[CAPTURE_PORT] == HAL_BUFFER_MODE_DYNAMIC) {
2334 binfo = device_to_uvaddr(&inst->registeredbufs, device_addr);
2335 if (!binfo) {
2336 dprintk(VIDC_ERR,
2337 "%s buffer not found in registered list\n",
2338 __func__);
2339 return;
2340 }
2341 if (flags & HAL_BUFFERFLAG_READONLY) {
2342 dprintk(VIDC_DBG,
2343 "FBD fd[0] = %d -> Reference with f/w, addr: %pa\n",
2344 binfo->fd[0], &device_addr);
2345 } else {
2346 dprintk(VIDC_DBG,
2347 "FBD fd[0] = %d -> FBD_ref_released, addr: %pa\n",
2348 binfo->fd[0], &device_addr);
2349
2350 mutex_lock(&inst->registeredbufs.lock);
2351 list_for_each_entry(temp, &inst->registeredbufs.list,
2352 list) {
2353 if (temp == binfo) {
2354 buf_ref_put(inst, binfo);
2355 break;
2356 }
2357 }
2358 mutex_unlock(&inst->registeredbufs.lock);
2359 }
2360 }
2361}
2362
2363static int handle_multi_stream_buffers(struct msm_vidc_inst *inst,
2364 ion_phys_addr_t dev_addr)
2365{
2366 struct internal_buf *binfo;
2367 struct msm_smem *handle;
2368 bool found = false;
2369
2370 mutex_lock(&inst->outputbufs.lock);
2371 list_for_each_entry(binfo, &inst->outputbufs.list, list) {
2372 handle = binfo->handle;
2373 if (handle && dev_addr == handle->device_addr) {
2374 if (binfo->buffer_ownership == DRIVER) {
2375 dprintk(VIDC_ERR,
2376 "FW returned same buffer: %pa\n",
2377 &dev_addr);
2378 break;
2379 }
2380 binfo->buffer_ownership = DRIVER;
2381 found = true;
2382 break;
2383 }
2384 }
2385 mutex_unlock(&inst->outputbufs.lock);
2386
2387 if (!found) {
2388 dprintk(VIDC_ERR,
2389 "Failed to find output buffer in queued list: %pa\n",
2390 &dev_addr);
2391 }
2392
2393 return 0;
2394}
2395
2396enum hal_buffer msm_comm_get_hal_output_buffer(struct msm_vidc_inst *inst)
2397{
2398 if (msm_comm_get_stream_output_mode(inst) ==
2399 HAL_VIDEO_DECODER_SECONDARY)
2400 return HAL_BUFFER_OUTPUT2;
2401 else
2402 return HAL_BUFFER_OUTPUT;
2403}
2404
2405static void handle_fbd(enum hal_command_response cmd, void *data)
2406{
2407 struct msm_vidc_cb_data_done *response = data;
2408 struct msm_vidc_inst *inst;
2409 struct vb2_buffer *vb = NULL;
2410 struct vidc_hal_fbd *fill_buf_done;
2411 enum hal_buffer buffer_type;
2412 int extra_idx = 0;
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002413 u64 time_nsec = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002414 struct vb2_v4l2_buffer *vbuf = NULL;
2415
2416 if (!response) {
2417 dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
2418 return;
2419 }
2420
2421 inst = get_inst(get_vidc_core(response->device_id),
2422 response->session_id);
2423 if (!inst) {
2424 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
2425 return;
2426 }
2427
2428 fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
2429 buffer_type = msm_comm_get_hal_output_buffer(inst);
2430 if (fill_buf_done->buffer_type == buffer_type) {
2431 vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
2432 fill_buf_done->packet_buffer1);
2433 } else {
2434 if (handle_multi_stream_buffers(inst,
2435 fill_buf_done->packet_buffer1))
2436 dprintk(VIDC_ERR,
2437 "Failed : Output buffer not found %pa\n",
2438 &fill_buf_done->packet_buffer1);
2439 goto err_handle_fbd;
2440 }
2441
2442 if (vb) {
2443 vbuf = to_vb2_v4l2_buffer(vb);
Umesh Pandeyd24533d2017-03-14 18:18:18 -07002444 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DROP_FRAME ||
2445 fill_buf_done->flags1 & HAL_BUFFERFLAG_DECODEONLY)
2446 fill_buf_done->filled_len1 = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002447 vb->planes[0].bytesused = fill_buf_done->filled_len1;
2448 vb->planes[0].data_offset = fill_buf_done->offset1;
2449 if (vb->planes[0].data_offset > vb->planes[0].length)
2450 dprintk(VIDC_INFO,
2451 "fbd:Overflow data_offset = %d; length = %d\n",
2452 vb->planes[0].data_offset,
2453 vb->planes[0].length);
2454 if (vb->planes[0].bytesused > vb->planes[0].length)
2455 dprintk(VIDC_INFO,
2456 "fbd:Overflow bytesused = %d; length = %d\n",
2457 vb->planes[0].bytesused,
2458 vb->planes[0].length);
2459 if (!(fill_buf_done->flags1 &
2460 HAL_BUFFERFLAG_TIMESTAMPINVALID)) {
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002461 time_nsec = fill_buf_done->timestamp_hi;
2462 time_nsec = (time_nsec << 32) |
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002463 fill_buf_done->timestamp_lo;
2464 } else {
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002465 time_nsec = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002466 dprintk(VIDC_DBG,
2467 "Set zero timestamp for buffer %pa, filled: %d, (hi:%u, lo:%u)\n",
2468 &fill_buf_done->packet_buffer1,
2469 fill_buf_done->filled_len1,
2470 fill_buf_done->timestamp_hi,
2471 fill_buf_done->timestamp_lo);
2472 }
2473 vbuf->flags = 0;
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002474 vb->timestamp = time_nsec;
2475
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002476 extra_idx =
2477 EXTRADATA_IDX(inst->fmts[CAPTURE_PORT].num_planes);
2478 if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
2479 vb->planes[extra_idx].m.userptr =
2480 (unsigned long)fill_buf_done->extra_data_buffer;
2481 vb->planes[extra_idx].bytesused =
2482 vb->planes[extra_idx].length;
2483 vb->planes[extra_idx].data_offset = 0;
2484 }
2485
2486 handle_dynamic_buffer(inst, fill_buf_done->packet_buffer1,
2487 fill_buf_done->flags1);
2488 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_READONLY)
2489 vbuf->flags |= V4L2_QCOM_BUF_FLAG_READONLY;
2490 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOS)
2491 vbuf->flags |= V4L2_QCOM_BUF_FLAG_EOS;
2492 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_CODECCONFIG)
2493 vbuf->flags &= ~V4L2_QCOM_BUF_FLAG_CODECCONFIG;
2494 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_SYNCFRAME)
2495 vbuf->flags |= V4L2_QCOM_BUF_FLAG_IDRFRAME;
2496 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOSEQ)
2497 vbuf->flags |= V4L2_QCOM_BUF_FLAG_EOSEQ;
Umesh Pandeyd24533d2017-03-14 18:18:18 -07002498 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DECODEONLY ||
2499 fill_buf_done->flags1 & HAL_BUFFERFLAG_DROP_FRAME)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002500 vbuf->flags |= V4L2_QCOM_BUF_FLAG_DECODEONLY;
2501 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DATACORRUPT)
2502 vbuf->flags |= V4L2_QCOM_BUF_DATA_CORRUPT;
2503
2504 switch (fill_buf_done->picture_type) {
2505 case HAL_PICTURE_IDR:
2506 vbuf->flags |= V4L2_QCOM_BUF_FLAG_IDRFRAME;
2507 vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
2508 break;
2509 case HAL_PICTURE_I:
2510 vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
2511 break;
2512 case HAL_PICTURE_P:
2513 vbuf->flags |= V4L2_BUF_FLAG_PFRAME;
2514 break;
2515 case HAL_PICTURE_B:
2516 vbuf->flags |= V4L2_BUF_FLAG_BFRAME;
2517 break;
2518 case HAL_FRAME_NOTCODED:
2519 case HAL_UNUSED_PICT:
2520 /* Do we need to care about these? */
2521 case HAL_FRAME_YUV:
2522 break;
2523 default:
2524 break;
2525 }
2526
2527 inst->count.fbd++;
2528
2529 if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
2530 dprintk(VIDC_DBG,
2531 "extradata: userptr = %pK;"
2532 " bytesused = %d; length = %d\n",
2533 (u8 *)vb->planes[extra_idx].m.userptr,
2534 vb->planes[extra_idx].bytesused,
2535 vb->planes[extra_idx].length);
2536 }
2537 dprintk(VIDC_DBG,
2538 "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",
2539 &fill_buf_done->packet_buffer1, fill_buf_done->alloc_len1,
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002540 fill_buf_done->filled_len1, fill_buf_done->offset1, time_nsec,
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002541 fill_buf_done->flags1, fill_buf_done->start_x_coord,
2542 fill_buf_done->start_y_coord, fill_buf_done->frame_width,
2543 fill_buf_done->frame_height, fill_buf_done->picture_type,
2544 fill_buf_done->mark_data);
2545
2546 mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
2547 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
2548 mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
2549 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FBD);
2550 }
2551
2552err_handle_fbd:
2553 put_inst(inst);
2554}
2555
2556static void handle_seq_hdr_done(enum hal_command_response cmd, void *data)
2557{
2558 struct msm_vidc_cb_data_done *response = data;
2559 struct msm_vidc_inst *inst;
2560 struct vb2_buffer *vb;
2561 struct vidc_hal_fbd *fill_buf_done;
2562 struct vb2_v4l2_buffer *vbuf;
2563
2564 if (!response) {
2565 dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
2566 return;
2567 }
2568
2569 inst = get_inst(get_vidc_core(response->device_id),
2570 response->session_id);
2571 if (!inst) {
2572 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
2573 return;
2574 }
2575
2576 fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
2577 vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
2578 fill_buf_done->packet_buffer1);
2579 if (!vb) {
2580 dprintk(VIDC_ERR,
2581 "Failed to find video buffer for seq_hdr_done: %pa\n",
2582 &fill_buf_done->packet_buffer1);
2583 goto err_seq_hdr_done;
2584 }
2585 vbuf = to_vb2_v4l2_buffer(vb);
Umesh Pandeyd24533d2017-03-14 18:18:18 -07002586 vb->timestamp = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002587
2588 vb->planes[0].bytesused = fill_buf_done->filled_len1;
2589 vb->planes[0].data_offset = fill_buf_done->offset1;
2590
2591 vbuf->flags = V4L2_QCOM_BUF_FLAG_CODECCONFIG;
2592
2593 dprintk(VIDC_DBG, "Filled length = %d; offset = %d; flags %x\n",
2594 vb->planes[0].bytesused,
2595 vb->planes[0].data_offset,
2596 vbuf->flags);
2597 mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
2598 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
2599 mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
2600
2601err_seq_hdr_done:
2602 put_inst(inst);
2603}
2604
2605void handle_cmd_response(enum hal_command_response cmd, void *data)
2606{
2607 dprintk(VIDC_DBG, "Command response = %d\n", cmd);
2608 switch (cmd) {
2609 case HAL_SYS_INIT_DONE:
2610 handle_sys_init_done(cmd, data);
2611 break;
2612 case HAL_SYS_RELEASE_RESOURCE_DONE:
2613 handle_sys_release_res_done(cmd, data);
2614 break;
2615 case HAL_SESSION_INIT_DONE:
2616 handle_session_init_done(cmd, data);
2617 break;
2618 case HAL_SESSION_PROPERTY_INFO:
2619 handle_session_prop_info(cmd, data);
2620 break;
2621 case HAL_SESSION_LOAD_RESOURCE_DONE:
2622 handle_load_resource_done(cmd, data);
2623 break;
2624 case HAL_SESSION_START_DONE:
2625 handle_start_done(cmd, data);
2626 break;
2627 case HAL_SESSION_ETB_DONE:
2628 handle_ebd(cmd, data);
2629 break;
2630 case HAL_SESSION_FTB_DONE:
2631 handle_fbd(cmd, data);
2632 break;
2633 case HAL_SESSION_STOP_DONE:
2634 handle_stop_done(cmd, data);
2635 break;
2636 case HAL_SESSION_RELEASE_RESOURCE_DONE:
2637 handle_release_res_done(cmd, data);
2638 break;
2639 case HAL_SESSION_END_DONE:
2640 case HAL_SESSION_ABORT_DONE:
2641 handle_session_close(cmd, data);
2642 break;
2643 case HAL_SESSION_EVENT_CHANGE:
2644 handle_event_change(cmd, data);
2645 break;
2646 case HAL_SESSION_FLUSH_DONE:
2647 handle_session_flush(cmd, data);
2648 break;
2649 case HAL_SESSION_GET_SEQ_HDR_DONE:
2650 handle_seq_hdr_done(cmd, data);
2651 break;
2652 case HAL_SYS_WATCHDOG_TIMEOUT:
2653 case HAL_SYS_ERROR:
2654 handle_sys_error(cmd, data);
2655 break;
2656 case HAL_SESSION_ERROR:
2657 handle_session_error(cmd, data);
2658 break;
2659 case HAL_SESSION_RELEASE_BUFFER_DONE:
2660 handle_session_release_buf_done(cmd, data);
2661 break;
2662 default:
2663 dprintk(VIDC_DBG, "response unhandled: %d\n", cmd);
2664 break;
2665 }
2666}
2667
2668int msm_comm_scale_clocks(struct msm_vidc_core *core)
2669{
2670 int num_mbs_per_sec, enc_mbs_per_sec, dec_mbs_per_sec;
2671
2672 enc_mbs_per_sec =
2673 msm_comm_get_load(core, MSM_VIDC_ENCODER, LOAD_CALC_NO_QUIRKS);
2674 dec_mbs_per_sec =
2675 msm_comm_get_load(core, MSM_VIDC_DECODER, LOAD_CALC_NO_QUIRKS);
2676
2677 if (enc_mbs_per_sec >= dec_mbs_per_sec) {
2678 /*
2679 * If Encoder load is higher, use that load. Encoder votes for higher
2680 * clock. Since Encoder and Deocder run on parallel cores, this clock
2681 * should suffice decoder usecases.
2682 */
2683 num_mbs_per_sec = enc_mbs_per_sec;
2684 } else {
2685 /*
2686 * If Decoder load is higher, it's tricky to decide clock. Decoder
2687 * higher load might results less clocks than Encoder smaller load.
2688 * At this point driver doesn't know which clock to vote. Hence use
2689 * total load.
2690 */
2691 num_mbs_per_sec = enc_mbs_per_sec + dec_mbs_per_sec;
2692 }
2693
2694 return msm_comm_scale_clocks_load(core, num_mbs_per_sec,
2695 LOAD_CALC_NO_QUIRKS);
2696}
2697
2698int msm_comm_scale_clocks_load(struct msm_vidc_core *core,
2699 int num_mbs_per_sec, enum load_calc_quirks quirks)
2700{
2701 int rc = 0;
2702 struct hfi_device *hdev;
2703 struct msm_vidc_inst *inst = NULL;
2704 unsigned long instant_bitrate = 0;
2705 int num_sessions = 0;
2706 struct vidc_clk_scale_data clk_scale_data = { {0} };
2707 int codec = 0;
2708
2709 if (!core) {
2710 dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core);
2711 return -EINVAL;
2712 }
2713
2714 hdev = core->device;
2715 if (!hdev) {
2716 dprintk(VIDC_ERR, "%s Invalid device handle: %pK\n",
2717 __func__, hdev);
2718 return -EINVAL;
2719 }
2720
2721 mutex_lock(&core->lock);
2722 list_for_each_entry(inst, &core->instances, list) {
2723
2724 codec = inst->session_type == MSM_VIDC_DECODER ?
2725 inst->fmts[OUTPUT_PORT].fourcc :
2726 inst->fmts[CAPTURE_PORT].fourcc;
2727
2728 if (msm_comm_turbo_session(inst))
2729 clk_scale_data.power_mode[num_sessions] =
2730 VIDC_POWER_TURBO;
2731 else if (is_low_power_session(inst))
2732 clk_scale_data.power_mode[num_sessions] =
2733 VIDC_POWER_LOW;
2734 else
2735 clk_scale_data.power_mode[num_sessions] =
2736 VIDC_POWER_NORMAL;
2737
2738 if (inst->dcvs_mode)
2739 clk_scale_data.load[num_sessions] = inst->dcvs.load;
2740 else
2741 clk_scale_data.load[num_sessions] =
2742 msm_comm_get_inst_load(inst, quirks);
2743
2744 clk_scale_data.session[num_sessions] =
2745 VIDC_VOTE_DATA_SESSION_VAL(
2746 get_hal_codec(codec),
2747 get_hal_domain(inst->session_type));
2748 num_sessions++;
2749
2750 if (inst->instant_bitrate > instant_bitrate)
2751 instant_bitrate = inst->instant_bitrate;
2752
2753 }
2754 clk_scale_data.num_sessions = num_sessions;
2755 mutex_unlock(&core->lock);
2756
2757
2758 rc = call_hfi_op(hdev, scale_clocks,
2759 hdev->hfi_device_data, num_mbs_per_sec,
2760 &clk_scale_data, instant_bitrate);
2761 if (rc)
2762 dprintk(VIDC_ERR, "Failed to set clock rate: %d\n", rc);
2763
2764 return rc;
2765}
2766
2767void msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst)
2768{
2769 struct msm_vidc_core *core;
2770 struct hfi_device *hdev;
2771
2772 if (!inst || !inst->core || !inst->core->device) {
2773 dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
2774 return;
2775 }
2776 core = inst->core;
2777 hdev = core->device;
2778
2779 if (msm_comm_scale_clocks(core)) {
2780 dprintk(VIDC_WARN,
2781 "Failed to scale clocks. Performance might be impacted\n");
2782 }
2783 if (msm_comm_vote_bus(core)) {
2784 dprintk(VIDC_WARN,
2785 "Failed to scale DDR bus. Performance might be impacted\n");
2786 }
2787}
2788
2789static inline enum msm_vidc_thermal_level msm_comm_vidc_thermal_level(int level)
2790{
2791 switch (level) {
2792 case 0:
2793 return VIDC_THERMAL_NORMAL;
2794 case 1:
2795 return VIDC_THERMAL_LOW;
2796 case 2:
2797 return VIDC_THERMAL_HIGH;
2798 default:
2799 return VIDC_THERMAL_CRITICAL;
2800 }
2801}
2802
2803static unsigned long msm_comm_get_clock_rate(struct msm_vidc_core *core)
2804{
2805 struct hfi_device *hdev;
2806 unsigned long freq = 0;
2807
2808 if (!core || !core->device) {
2809 dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
2810 return -EINVAL;
2811 }
2812 hdev = core->device;
2813
2814 freq = call_hfi_op(hdev, get_core_clock_rate, hdev->hfi_device_data, 1);
2815 dprintk(VIDC_DBG, "clock freq %ld\n", freq);
2816
2817 return freq;
2818}
2819
2820static bool is_core_turbo(struct msm_vidc_core *core, unsigned long freq)
2821{
2822 int i = 0;
2823 struct msm_vidc_platform_resources *res = &core->resources;
2824 struct load_freq_table *table = res->load_freq_tbl;
2825 u32 max_freq = 0;
2826
2827 for (i = 0; i < res->load_freq_tbl_size; i++) {
2828 if (max_freq < table[i].freq)
2829 max_freq = table[i].freq;
2830 }
2831 return freq >= max_freq;
2832}
2833
2834static bool is_thermal_permissible(struct msm_vidc_core *core)
2835{
2836 enum msm_vidc_thermal_level tl;
2837 unsigned long freq = 0;
2838 bool is_turbo = false;
2839
2840 if (!core->resources.thermal_mitigable)
2841 return true;
2842
2843 if (msm_vidc_thermal_mitigation_disabled) {
2844 dprintk(VIDC_DBG,
2845 "Thermal mitigation not enabled. debugfs %d\n",
2846 msm_vidc_thermal_mitigation_disabled);
2847 return true;
2848 }
2849
2850 tl = msm_comm_vidc_thermal_level(vidc_driver->thermal_level);
2851 freq = msm_comm_get_clock_rate(core);
2852
2853 is_turbo = is_core_turbo(core, freq);
2854 dprintk(VIDC_DBG,
2855 "Core freq %ld Thermal level %d Turbo mode %d\n",
2856 freq, tl, is_turbo);
2857
2858 if (is_turbo && tl >= VIDC_THERMAL_LOW) {
2859 dprintk(VIDC_ERR,
2860 "Video session not allowed. Turbo mode %d Thermal level %d\n",
2861 is_turbo, tl);
2862 return false;
2863 }
2864 return true;
2865}
2866
2867static int msm_comm_session_abort(struct msm_vidc_inst *inst)
2868{
2869 int rc = 0, abort_completion = 0;
2870 struct hfi_device *hdev;
2871
2872 if (!inst || !inst->core || !inst->core->device) {
2873 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
2874 return -EINVAL;
2875 }
2876 hdev = inst->core->device;
2877 abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE);
2878
2879 rc = call_hfi_op(hdev, session_abort, (void *)inst->session);
2880 if (rc) {
2881 dprintk(VIDC_ERR,
2882 "%s session_abort failed rc: %d\n", __func__, rc);
2883 return rc;
2884 }
2885 rc = wait_for_completion_timeout(
2886 &inst->completions[abort_completion],
2887 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
2888 if (!rc) {
2889 dprintk(VIDC_ERR,
2890 "%s: Wait interrupted or timed out [%pK]: %d\n",
2891 __func__, inst, abort_completion);
2892 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
2893 dprintk(VIDC_ERR,
2894 "ABORT timeout can potentially crash the system\n");
2895 msm_comm_print_debug_info(inst);
2896
2897 msm_vidc_handle_hw_error(inst->core);
2898 rc = -EBUSY;
2899 } else {
2900 rc = 0;
2901 }
2902 msm_comm_session_clean(inst);
2903 return rc;
2904}
2905
2906static void handle_thermal_event(struct msm_vidc_core *core)
2907{
2908 int rc = 0;
2909 struct msm_vidc_inst *inst;
2910
2911 if (!core || !core->device) {
2912 dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
2913 return;
2914 }
2915 mutex_lock(&core->lock);
2916 list_for_each_entry(inst, &core->instances, list) {
2917 if (!inst->session)
2918 continue;
2919
2920 mutex_unlock(&core->lock);
2921 if (inst->state >= MSM_VIDC_OPEN_DONE &&
2922 inst->state < MSM_VIDC_CLOSE_DONE) {
2923 dprintk(VIDC_WARN, "%s: abort inst %pK\n",
2924 __func__, inst);
2925 rc = msm_comm_session_abort(inst);
2926 if (rc) {
2927 dprintk(VIDC_ERR,
2928 "%s session_abort failed rc: %d\n",
2929 __func__, rc);
2930 goto err_sess_abort;
2931 }
2932 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
2933 dprintk(VIDC_WARN,
2934 "%s Send sys error for inst %pK\n",
2935 __func__, inst);
2936 msm_vidc_queue_v4l2_event(inst,
2937 V4L2_EVENT_MSM_VIDC_SYS_ERROR);
2938 } else {
2939 msm_comm_generate_session_error(inst);
2940 }
2941 mutex_lock(&core->lock);
2942 }
2943 mutex_unlock(&core->lock);
2944 return;
2945
2946err_sess_abort:
2947 msm_comm_clean_notify_client(core);
2948}
2949
2950void msm_comm_handle_thermal_event(void)
2951{
2952 struct msm_vidc_core *core;
2953
2954 list_for_each_entry(core, &vidc_driver->cores, list) {
2955 if (!is_thermal_permissible(core)) {
2956 dprintk(VIDC_WARN,
2957 "Thermal level critical, stop all active sessions!\n");
2958 handle_thermal_event(core);
2959 }
2960 }
2961}
2962
2963int msm_comm_check_core_init(struct msm_vidc_core *core)
2964{
2965 int rc = 0;
2966 struct hfi_device *hdev;
2967 struct msm_vidc_inst *inst = NULL;
2968
2969 mutex_lock(&core->lock);
2970 if (core->state >= VIDC_CORE_INIT_DONE) {
2971 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
2972 core->id, core->state);
2973 goto exit;
2974 }
2975 dprintk(VIDC_DBG, "Waiting for SYS_INIT_DONE\n");
2976 hdev = (struct hfi_device *)core->device;
2977 rc = wait_for_completion_timeout(
2978 &core->completions[SYS_MSG_INDEX(HAL_SYS_INIT_DONE)],
2979 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
2980 if (!rc) {
2981 dprintk(VIDC_ERR, "%s: Wait interrupted or timed out: %d\n",
2982 __func__, SYS_MSG_INDEX(HAL_SYS_INIT_DONE));
2983 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
2984 dprintk(VIDC_ERR,
2985 "SYS_INIT timeout can potentially crash the system\n");
2986 /*
2987 * For SYS_INIT, there will not be any inst pointer.
2988 * Just grab one of the inst from instances list and
2989 * use it.
2990 */
2991 inst = list_first_entry(&core->instances,
2992 struct msm_vidc_inst, list);
2993
2994 mutex_unlock(&core->lock);
2995 msm_comm_print_debug_info(inst);
2996 mutex_lock(&core->lock);
2997
2998 msm_vidc_handle_hw_error(core);
2999 rc = -EIO;
3000 goto exit;
3001 } else {
3002 core->state = VIDC_CORE_INIT_DONE;
3003 rc = 0;
3004 }
3005 dprintk(VIDC_DBG, "SYS_INIT_DONE!!!\n");
3006exit:
3007 mutex_unlock(&core->lock);
3008 return rc;
3009}
3010
3011static int msm_comm_init_core_done(struct msm_vidc_inst *inst)
3012{
3013 int rc = 0;
3014
3015 rc = msm_comm_check_core_init(inst->core);
3016 if (rc) {
3017 dprintk(VIDC_ERR, "%s - failed to initialize core\n", __func__);
3018 msm_comm_generate_sys_error(inst);
3019 return rc;
3020 }
3021 change_inst_state(inst, MSM_VIDC_CORE_INIT_DONE);
3022 return rc;
3023}
3024
3025static int msm_comm_init_core(struct msm_vidc_inst *inst)
3026{
3027 int rc = 0;
3028 struct hfi_device *hdev;
3029 struct msm_vidc_core *core;
3030
3031 if (!inst || !inst->core || !inst->core->device)
3032 return -EINVAL;
3033
3034 core = inst->core;
3035 hdev = core->device;
3036 mutex_lock(&core->lock);
3037 if (core->state >= VIDC_CORE_INIT) {
3038 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
3039 core->id, core->state);
3040 goto core_already_inited;
3041 }
3042 if (!core->capabilities) {
3043 core->capabilities = kzalloc(VIDC_MAX_SESSIONS *
3044 sizeof(struct msm_vidc_capability), GFP_KERNEL);
3045 if (!core->capabilities) {
3046 dprintk(VIDC_ERR,
3047 "%s: failed to allocate capabilities\n",
3048 __func__);
3049 rc = -ENOMEM;
3050 goto fail_cap_alloc;
3051 }
3052 } else {
3053 dprintk(VIDC_WARN,
3054 "%s: capabilities memory is expected to be freed\n",
3055 __func__);
3056 }
3057
3058 rc = call_hfi_op(hdev, core_init, hdev->hfi_device_data);
3059 if (rc) {
3060 dprintk(VIDC_ERR, "Failed to init core, id = %d\n",
3061 core->id);
3062 goto fail_core_init;
3063 }
3064 core->state = VIDC_CORE_INIT;
3065 core->smmu_fault_handled = false;
3066core_already_inited:
3067 change_inst_state(inst, MSM_VIDC_CORE_INIT);
3068 mutex_unlock(&core->lock);
3069 return rc;
3070
3071fail_core_init:
3072 kfree(core->capabilities);
3073fail_cap_alloc:
3074 core->capabilities = NULL;
3075 core->state = VIDC_CORE_UNINIT;
3076 mutex_unlock(&core->lock);
3077 return rc;
3078}
3079
3080static int msm_vidc_deinit_core(struct msm_vidc_inst *inst)
3081{
3082 struct msm_vidc_core *core;
3083 struct hfi_device *hdev;
3084
3085 if (!inst || !inst->core || !inst->core->device) {
3086 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3087 return -EINVAL;
3088 }
3089
3090 core = inst->core;
3091 hdev = core->device;
3092
3093 mutex_lock(&core->lock);
3094 if (core->state == VIDC_CORE_UNINIT) {
3095 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
3096 core->id, core->state);
3097 goto core_already_uninited;
3098 }
3099 mutex_unlock(&core->lock);
3100
3101 msm_comm_scale_clocks_and_bus(inst);
3102
3103 mutex_lock(&core->lock);
3104
3105 if (!core->resources.never_unload_fw) {
3106 cancel_delayed_work(&core->fw_unload_work);
3107
3108 /*
3109 * Delay unloading of firmware. This is useful
3110 * in avoiding firmware download delays in cases where we
3111 * will have a burst of back to back video playback sessions
3112 * e.g. thumbnail generation.
3113 */
3114 schedule_delayed_work(&core->fw_unload_work,
3115 msecs_to_jiffies(core->state == VIDC_CORE_INVALID ?
3116 0 : msm_vidc_firmware_unload_delay));
3117
3118 dprintk(VIDC_DBG, "firmware unload delayed by %u ms\n",
3119 core->state == VIDC_CORE_INVALID ?
3120 0 : msm_vidc_firmware_unload_delay);
3121 }
3122
3123core_already_uninited:
3124 change_inst_state(inst, MSM_VIDC_CORE_UNINIT);
3125 mutex_unlock(&core->lock);
3126 return 0;
3127}
3128
3129int msm_comm_force_cleanup(struct msm_vidc_inst *inst)
3130{
3131 msm_comm_kill_session(inst);
3132 return msm_vidc_deinit_core(inst);
3133}
3134
3135static int msm_comm_session_init(int flipped_state,
3136 struct msm_vidc_inst *inst)
3137{
3138 int rc = 0;
3139 int fourcc = 0;
3140 struct hfi_device *hdev;
3141
3142 if (!inst || !inst->core || !inst->core->device) {
3143 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3144 return -EINVAL;
3145 }
3146 hdev = inst->core->device;
3147
3148 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) {
3149 dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n",
3150 inst, inst->state);
3151 goto exit;
3152 }
3153 if (inst->session_type == MSM_VIDC_DECODER) {
3154 fourcc = inst->fmts[OUTPUT_PORT].fourcc;
3155 } else if (inst->session_type == MSM_VIDC_ENCODER) {
3156 fourcc = inst->fmts[CAPTURE_PORT].fourcc;
3157 } else {
3158 dprintk(VIDC_ERR, "Invalid session\n");
3159 return -EINVAL;
3160 }
3161
3162 rc = call_hfi_op(hdev, session_init, hdev->hfi_device_data,
3163 inst, get_hal_domain(inst->session_type),
3164 get_hal_codec(fourcc),
3165 &inst->session);
3166
3167 if (rc || !inst->session) {
3168 dprintk(VIDC_ERR,
3169 "Failed to call session init for: %pK, %pK, %d, %d\n",
3170 inst->core->device, inst,
3171 inst->session_type, fourcc);
3172 rc = -EINVAL;
3173 goto exit;
3174 }
3175 change_inst_state(inst, MSM_VIDC_OPEN);
3176exit:
3177 return rc;
3178}
3179
3180static void msm_vidc_print_running_insts(struct msm_vidc_core *core)
3181{
3182 struct msm_vidc_inst *temp;
3183
3184 dprintk(VIDC_ERR, "Running instances:\n");
3185 dprintk(VIDC_ERR, "%4s|%4s|%4s|%4s|%4s\n",
3186 "type", "w", "h", "fps", "prop");
3187
3188 mutex_lock(&core->lock);
3189 list_for_each_entry(temp, &core->instances, list) {
3190 if (temp->state >= MSM_VIDC_OPEN_DONE &&
3191 temp->state < MSM_VIDC_STOP_DONE) {
3192 char properties[4] = "";
3193
3194 if (is_thumbnail_session(temp))
3195 strlcat(properties, "N", sizeof(properties));
3196
3197 if (msm_comm_turbo_session(temp))
3198 strlcat(properties, "T", sizeof(properties));
3199
3200 dprintk(VIDC_ERR, "%4d|%4d|%4d|%4d|%4s\n",
3201 temp->session_type,
3202 max(temp->prop.width[CAPTURE_PORT],
3203 temp->prop.width[OUTPUT_PORT]),
3204 max(temp->prop.height[CAPTURE_PORT],
3205 temp->prop.height[OUTPUT_PORT]),
3206 temp->prop.fps, properties);
3207 }
3208 }
3209 mutex_unlock(&core->lock);
3210}
3211
3212static int msm_vidc_load_resources(int flipped_state,
3213 struct msm_vidc_inst *inst)
3214{
3215 int rc = 0;
3216 struct hfi_device *hdev;
3217 int num_mbs_per_sec = 0, max_load_adj = 0;
3218 struct msm_vidc_core *core;
3219 enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD |
3220 LOAD_CALC_IGNORE_THUMBNAIL_LOAD |
3221 LOAD_CALC_IGNORE_NON_REALTIME_LOAD;
3222
3223 if (!inst || !inst->core || !inst->core->device) {
3224 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3225 return -EINVAL;
3226 }
3227
3228 core = inst->core;
3229 if (core->state == VIDC_CORE_INVALID) {
3230 dprintk(VIDC_ERR,
3231 "Core is in bad state can't do load res\n");
3232 return -EINVAL;
3233 }
3234
3235 if (inst->state == MSM_VIDC_CORE_INVALID) {
3236 dprintk(VIDC_ERR,
3237 "Instance is in invalid state can't do load res\n");
3238 return -EINVAL;
3239 }
3240
3241 num_mbs_per_sec =
3242 msm_comm_get_load(core, MSM_VIDC_DECODER, quirks) +
3243 msm_comm_get_load(core, MSM_VIDC_ENCODER, quirks);
3244
3245 max_load_adj = core->resources.max_load +
3246 inst->capability.mbs_per_frame.max;
3247
3248 if (num_mbs_per_sec > max_load_adj) {
3249 dprintk(VIDC_ERR, "HW is overloaded, needed: %d max: %d\n",
3250 num_mbs_per_sec, max_load_adj);
3251 msm_vidc_print_running_insts(core);
3252 inst->state = MSM_VIDC_CORE_INVALID;
3253 msm_comm_kill_session(inst);
3254 return -EBUSY;
3255 }
3256
3257 hdev = core->device;
3258 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) {
3259 dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n",
3260 inst, inst->state);
3261 goto exit;
3262 }
3263
3264 rc = call_hfi_op(hdev, session_load_res, (void *) inst->session);
3265 if (rc) {
3266 dprintk(VIDC_ERR,
3267 "Failed to send load resources\n");
3268 goto exit;
3269 }
3270 change_inst_state(inst, MSM_VIDC_LOAD_RESOURCES);
3271exit:
3272 return rc;
3273}
3274
3275static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst)
3276{
3277 int rc = 0;
3278 struct hfi_device *hdev;
3279
3280 if (!inst || !inst->core || !inst->core->device) {
3281 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3282 return -EINVAL;
3283 }
3284 if (inst->state == MSM_VIDC_CORE_INVALID ||
3285 inst->core->state == VIDC_CORE_INVALID) {
3286 dprintk(VIDC_ERR,
3287 "Core is in bad state can't do start\n");
3288 return -EINVAL;
3289 }
3290
3291 hdev = inst->core->device;
3292
3293 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) {
3294 dprintk(VIDC_INFO,
3295 "inst: %pK is already in state: %d\n",
3296 inst, inst->state);
3297 goto exit;
3298 }
3299 rc = call_hfi_op(hdev, session_start, (void *) inst->session);
3300 if (rc) {
3301 dprintk(VIDC_ERR,
3302 "Failed to send start\n");
3303 goto exit;
3304 }
3305 change_inst_state(inst, MSM_VIDC_START);
3306exit:
3307 return rc;
3308}
3309
3310static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst)
3311{
3312 int rc = 0;
3313 struct hfi_device *hdev;
3314
3315 if (!inst || !inst->core || !inst->core->device) {
3316 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3317 return -EINVAL;
3318 }
3319 hdev = inst->core->device;
3320
3321 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) {
3322 dprintk(VIDC_INFO,
3323 "inst: %pK is already in state: %d\n",
3324 inst, inst->state);
3325 goto exit;
3326 }
3327 dprintk(VIDC_DBG, "Send Stop to hal\n");
3328 rc = call_hfi_op(hdev, session_stop, (void *) inst->session);
3329 if (rc) {
3330 dprintk(VIDC_ERR, "Failed to send stop\n");
3331 goto exit;
3332 }
3333 change_inst_state(inst, MSM_VIDC_STOP);
3334exit:
3335 return rc;
3336}
3337
3338static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst)
3339{
3340 int rc = 0;
3341 struct hfi_device *hdev;
3342
3343 if (!inst || !inst->core || !inst->core->device) {
3344 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3345 return -EINVAL;
3346 }
3347 hdev = inst->core->device;
3348
3349 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) {
3350 dprintk(VIDC_INFO,
3351 "inst: %pK is already in state: %d\n",
3352 inst, inst->state);
3353 goto exit;
3354 }
3355 dprintk(VIDC_DBG,
3356 "Send release res to hal\n");
3357 rc = call_hfi_op(hdev, session_release_res, (void *) inst->session);
3358 if (rc) {
3359 dprintk(VIDC_ERR,
3360 "Failed to send release resources\n");
3361 goto exit;
3362 }
3363 change_inst_state(inst, MSM_VIDC_RELEASE_RESOURCES);
3364exit:
3365 return rc;
3366}
3367
3368static int msm_comm_session_close(int flipped_state,
3369 struct msm_vidc_inst *inst)
3370{
3371 int rc = 0;
3372 struct hfi_device *hdev;
3373
3374 if (!inst || !inst->core || !inst->core->device) {
3375 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
3376 return -EINVAL;
3377 }
3378 hdev = inst->core->device;
3379 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) {
3380 dprintk(VIDC_INFO,
3381 "inst: %pK is already in state: %d\n",
3382 inst, inst->state);
3383 goto exit;
3384 }
3385 dprintk(VIDC_DBG,
3386 "Send session close to hal\n");
3387 rc = call_hfi_op(hdev, session_end, (void *) inst->session);
3388 if (rc) {
3389 dprintk(VIDC_ERR,
3390 "Failed to send close\n");
3391 goto exit;
3392 }
3393 change_inst_state(inst, MSM_VIDC_CLOSE);
3394exit:
3395 return rc;
3396}
3397
3398int msm_comm_suspend(int core_id)
3399{
3400 struct hfi_device *hdev;
3401 struct msm_vidc_core *core;
3402 int rc = 0;
3403
3404 core = get_vidc_core(core_id);
3405 if (!core) {
3406 dprintk(VIDC_ERR,
3407 "%s: Failed to find core for core_id = %d\n",
3408 __func__, core_id);
3409 return -EINVAL;
3410 }
3411
3412 hdev = (struct hfi_device *)core->device;
3413 if (!hdev) {
3414 dprintk(VIDC_ERR, "%s Invalid device handle\n", __func__);
3415 return -EINVAL;
3416 }
3417
3418 mutex_lock(&core->lock);
3419 if (core->state == VIDC_CORE_INVALID) {
3420 dprintk(VIDC_ERR,
3421 "%s - fw is not in proper state, skip suspend\n",
3422 __func__);
3423 rc = -EINVAL;
3424 goto exit;
3425 }
3426
3427 rc = call_hfi_op(hdev, suspend, hdev->hfi_device_data);
3428 if (rc)
3429 dprintk(VIDC_WARN, "Failed to suspend\n");
3430
3431exit:
3432 mutex_unlock(&core->lock);
3433 return rc;
3434}
3435
3436static int get_flipped_state(int present_state,
3437 int desired_state)
3438{
3439 int flipped_state = present_state;
3440
3441 if (flipped_state < MSM_VIDC_STOP
3442 && desired_state > MSM_VIDC_STOP) {
3443 flipped_state = MSM_VIDC_STOP + (MSM_VIDC_STOP - flipped_state);
3444 flipped_state &= 0xFFFE;
3445 flipped_state = flipped_state - 1;
3446 } else if (flipped_state > MSM_VIDC_STOP
3447 && desired_state < MSM_VIDC_STOP) {
3448 flipped_state = MSM_VIDC_STOP -
3449 (flipped_state - MSM_VIDC_STOP + 1);
3450 flipped_state &= 0xFFFE;
3451 flipped_state = flipped_state - 1;
3452 }
3453 return flipped_state;
3454}
3455
3456struct hal_buffer_requirements *get_buff_req_buffer(
3457 struct msm_vidc_inst *inst, enum hal_buffer buffer_type)
3458{
3459 int i;
3460
3461 for (i = 0; i < HAL_BUFFER_MAX; i++) {
3462 if (inst->buff_req.buffer[i].buffer_type == buffer_type)
3463 return &inst->buff_req.buffer[i];
3464 }
3465 return NULL;
3466}
3467
3468static int set_output_buffers(struct msm_vidc_inst *inst,
3469 enum hal_buffer buffer_type)
3470{
3471 int rc = 0;
3472 struct msm_smem *handle;
3473 struct internal_buf *binfo;
3474 u32 smem_flags = 0, buffer_size;
3475 struct hal_buffer_requirements *output_buf, *extradata_buf;
3476 int i;
3477 struct hfi_device *hdev;
3478 struct hal_buffer_size_minimum b;
3479
3480 hdev = inst->core->device;
3481
3482 output_buf = get_buff_req_buffer(inst, buffer_type);
3483 if (!output_buf) {
3484 dprintk(VIDC_DBG,
3485 "This output buffer not required, buffer_type: %x\n",
3486 buffer_type);
3487 return 0;
3488 }
3489 dprintk(VIDC_DBG,
3490 "output: num = %d, size = %d\n",
3491 output_buf->buffer_count_actual,
3492 output_buf->buffer_size);
3493
3494 buffer_size = output_buf->buffer_size;
3495 b.buffer_type = buffer_type;
3496 b.buffer_size = buffer_size;
3497 rc = call_hfi_op(hdev, session_set_property,
3498 inst->session, HAL_PARAM_BUFFER_SIZE_MINIMUM,
3499 &b);
3500
3501 extradata_buf = get_buff_req_buffer(inst, HAL_BUFFER_EXTRADATA_OUTPUT);
3502 if (extradata_buf) {
3503 dprintk(VIDC_DBG,
3504 "extradata: num = %d, size = %d\n",
3505 extradata_buf->buffer_count_actual,
3506 extradata_buf->buffer_size);
3507 buffer_size += extradata_buf->buffer_size;
3508 } else {
3509 dprintk(VIDC_DBG,
3510 "This extradata buffer not required, buffer_type: %x\n",
3511 buffer_type);
3512 }
3513
3514 if (inst->flags & VIDC_SECURE)
3515 smem_flags |= SMEM_SECURE;
3516
3517 if (output_buf->buffer_size) {
3518 for (i = 0; i < output_buf->buffer_count_actual;
3519 i++) {
3520 handle = msm_comm_smem_alloc(inst,
3521 buffer_size, 1, smem_flags,
3522 buffer_type, 0);
3523 if (!handle) {
3524 dprintk(VIDC_ERR,
3525 "Failed to allocate output memory\n");
3526 rc = -ENOMEM;
3527 goto err_no_mem;
3528 }
3529 rc = msm_comm_smem_cache_operations(inst,
3530 handle, SMEM_CACHE_CLEAN);
3531 if (rc) {
3532 dprintk(VIDC_WARN,
3533 "Failed to clean cache may cause undefined behavior\n");
3534 }
3535 binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
3536 if (!binfo) {
3537 dprintk(VIDC_ERR, "Out of memory\n");
3538 rc = -ENOMEM;
3539 goto fail_kzalloc;
3540 }
3541
3542 binfo->handle = handle;
3543 binfo->buffer_type = buffer_type;
3544 binfo->buffer_ownership = DRIVER;
3545 dprintk(VIDC_DBG, "Output buffer address: %pa\n",
3546 &handle->device_addr);
3547
3548 if (inst->buffer_mode_set[CAPTURE_PORT] ==
3549 HAL_BUFFER_MODE_STATIC) {
3550 struct vidc_buffer_addr_info buffer_info = {0};
3551
3552 buffer_info.buffer_size =
3553 output_buf->buffer_size;
3554 buffer_info.buffer_type = buffer_type;
3555 buffer_info.num_buffers = 1;
3556 buffer_info.align_device_addr =
3557 handle->device_addr;
3558 buffer_info.extradata_addr =
3559 handle->device_addr +
3560 output_buf->buffer_size;
3561 if (extradata_buf)
3562 buffer_info.extradata_size =
3563 extradata_buf->buffer_size;
3564 rc = call_hfi_op(hdev, session_set_buffers,
3565 (void *) inst->session, &buffer_info);
3566 if (rc) {
3567 dprintk(VIDC_ERR,
3568 "%s : session_set_buffers failed\n",
3569 __func__);
3570 goto fail_set_buffers;
3571 }
3572 }
3573 mutex_lock(&inst->outputbufs.lock);
3574 list_add_tail(&binfo->list, &inst->outputbufs.list);
3575 mutex_unlock(&inst->outputbufs.lock);
3576 }
3577 }
3578 return rc;
3579fail_set_buffers:
3580 kfree(binfo);
3581fail_kzalloc:
3582 msm_comm_smem_free(inst, handle);
3583err_no_mem:
3584 return rc;
3585}
3586
3587static inline char *get_buffer_name(enum hal_buffer buffer_type)
3588{
3589 switch (buffer_type) {
3590 case HAL_BUFFER_INPUT: return "input";
3591 case HAL_BUFFER_OUTPUT: return "output";
3592 case HAL_BUFFER_OUTPUT2: return "output_2";
3593 case HAL_BUFFER_EXTRADATA_INPUT: return "input_extra";
3594 case HAL_BUFFER_EXTRADATA_OUTPUT: return "output_extra";
3595 case HAL_BUFFER_EXTRADATA_OUTPUT2: return "output2_extra";
3596 case HAL_BUFFER_INTERNAL_SCRATCH: return "scratch";
3597 case HAL_BUFFER_INTERNAL_SCRATCH_1: return "scratch_1";
3598 case HAL_BUFFER_INTERNAL_SCRATCH_2: return "scratch_2";
3599 case HAL_BUFFER_INTERNAL_PERSIST: return "persist";
3600 case HAL_BUFFER_INTERNAL_PERSIST_1: return "persist_1";
3601 case HAL_BUFFER_INTERNAL_CMD_QUEUE: return "queue";
3602 default: return "????";
3603 }
3604}
3605
3606static int set_internal_buf_on_fw(struct msm_vidc_inst *inst,
3607 enum hal_buffer buffer_type,
3608 struct msm_smem *handle, bool reuse)
3609{
3610 struct vidc_buffer_addr_info buffer_info;
3611 struct hfi_device *hdev;
3612 int rc = 0;
3613
3614 if (!inst || !inst->core || !inst->core->device || !handle) {
3615 dprintk(VIDC_ERR, "%s - invalid params\n", __func__);
3616 return -EINVAL;
3617 }
3618
3619 hdev = inst->core->device;
3620
3621 rc = msm_comm_smem_cache_operations(inst,
3622 handle, SMEM_CACHE_CLEAN);
3623 if (rc) {
3624 dprintk(VIDC_WARN,
3625 "Failed to clean cache. Undefined behavior\n");
3626 }
3627
3628 buffer_info.buffer_size = handle->size;
3629 buffer_info.buffer_type = buffer_type;
3630 buffer_info.num_buffers = 1;
3631 buffer_info.align_device_addr = handle->device_addr;
3632 dprintk(VIDC_DBG, "%s %s buffer : %pa\n",
3633 reuse ? "Reusing" : "Allocated",
3634 get_buffer_name(buffer_type),
3635 &buffer_info.align_device_addr);
3636
3637 rc = call_hfi_op(hdev, session_set_buffers,
3638 (void *) inst->session, &buffer_info);
3639 if (rc) {
3640 dprintk(VIDC_ERR,
3641 "vidc_hal_session_set_buffers failed\n");
3642 return rc;
3643 }
3644 return 0;
3645}
3646
3647static bool reuse_internal_buffers(struct msm_vidc_inst *inst,
3648 enum hal_buffer buffer_type, struct msm_vidc_list *buf_list)
3649{
3650 struct internal_buf *buf;
3651 int rc = 0;
3652 bool reused = false;
3653
3654 if (!inst || !buf_list) {
3655 dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
3656 return false;
3657 }
3658
3659 mutex_lock(&buf_list->lock);
3660 list_for_each_entry(buf, &buf_list->list, list) {
3661 if (!buf->handle) {
3662 reused = false;
3663 break;
3664 }
3665
3666 if (buf->buffer_type != buffer_type)
3667 continue;
3668
3669 /*
3670 * Persist buffer size won't change with resolution. If they
3671 * are in queue means that they are already allocated and
3672 * given to HW. HW can use them without reallocation. These
3673 * buffers are not released as part of port reconfig. So
3674 * driver no need to set them again.
3675 */
3676
3677 if (buffer_type != HAL_BUFFER_INTERNAL_PERSIST
3678 && buffer_type != HAL_BUFFER_INTERNAL_PERSIST_1) {
3679
3680 rc = set_internal_buf_on_fw(inst, buffer_type,
3681 buf->handle, true);
3682 if (rc) {
3683 dprintk(VIDC_ERR,
3684 "%s: session_set_buffers failed\n",
3685 __func__);
3686 reused = false;
3687 break;
3688 }
3689 }
3690 reused = true;
3691 dprintk(VIDC_DBG,
3692 "Re-using internal buffer type : %d\n", buffer_type);
3693 }
3694 mutex_unlock(&buf_list->lock);
3695 return reused;
3696}
3697
3698static int allocate_and_set_internal_bufs(struct msm_vidc_inst *inst,
3699 struct hal_buffer_requirements *internal_bufreq,
3700 struct msm_vidc_list *buf_list)
3701{
3702 struct msm_smem *handle;
3703 struct internal_buf *binfo;
3704 u32 smem_flags = 0;
3705 int rc = 0;
3706 int i = 0;
3707
3708 if (!inst || !internal_bufreq || !buf_list)
3709 return -EINVAL;
3710
3711 if (!internal_bufreq->buffer_size)
3712 return 0;
3713
3714 if (inst->flags & VIDC_SECURE)
3715 smem_flags |= SMEM_SECURE;
3716
3717 for (i = 0; i < internal_bufreq->buffer_count_actual; i++) {
3718 handle = msm_comm_smem_alloc(inst, internal_bufreq->buffer_size,
3719 1, smem_flags, internal_bufreq->buffer_type, 0);
3720 if (!handle) {
3721 dprintk(VIDC_ERR,
3722 "Failed to allocate scratch memory\n");
3723 rc = -ENOMEM;
3724 goto err_no_mem;
3725 }
3726
3727 binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
3728 if (!binfo) {
3729 dprintk(VIDC_ERR, "Out of memory\n");
3730 rc = -ENOMEM;
3731 goto fail_kzalloc;
3732 }
3733
3734 binfo->handle = handle;
3735 binfo->buffer_type = internal_bufreq->buffer_type;
3736
3737 rc = set_internal_buf_on_fw(inst, internal_bufreq->buffer_type,
3738 handle, false);
3739 if (rc)
3740 goto fail_set_buffers;
3741
3742 mutex_lock(&buf_list->lock);
3743 list_add_tail(&binfo->list, &buf_list->list);
3744 mutex_unlock(&buf_list->lock);
3745 }
3746 return rc;
3747
3748fail_set_buffers:
3749 kfree(binfo);
3750fail_kzalloc:
3751 msm_comm_smem_free(inst, handle);
3752err_no_mem:
3753 return rc;
3754
3755}
3756
3757static int set_internal_buffers(struct msm_vidc_inst *inst,
3758 enum hal_buffer buffer_type, struct msm_vidc_list *buf_list)
3759{
3760 struct hal_buffer_requirements *internal_buf;
3761
3762 internal_buf = get_buff_req_buffer(inst, buffer_type);
3763 if (!internal_buf) {
3764 dprintk(VIDC_DBG,
3765 "This internal buffer not required, buffer_type: %x\n",
3766 buffer_type);
3767 return 0;
3768 }
3769
3770 dprintk(VIDC_DBG, "Buffer type %s: num = %d, size = %d\n",
3771 get_buffer_name(buffer_type),
3772 internal_buf->buffer_count_actual, internal_buf->buffer_size);
3773
3774 /*
3775 * Try reusing existing internal buffers first.
3776 * If it's not possible to reuse, allocate new buffers.
3777 */
3778 if (reuse_internal_buffers(inst, buffer_type, buf_list))
3779 return 0;
3780
3781 return allocate_and_set_internal_bufs(inst, internal_buf,
3782 buf_list);
3783}
3784
3785int msm_comm_try_state(struct msm_vidc_inst *inst, int state)
3786{
3787 int rc = 0;
3788 int flipped_state;
3789 struct msm_vidc_core *core;
3790
3791 if (!inst) {
3792 dprintk(VIDC_ERR,
3793 "Invalid instance pointer = %pK\n", inst);
3794 return -EINVAL;
3795 }
3796 dprintk(VIDC_DBG,
3797 "Trying to move inst: %pK from: %#x to %#x\n",
3798 inst, inst->state, state);
3799 core = inst->core;
3800 if (!core) {
3801 dprintk(VIDC_ERR,
3802 "Invalid core pointer = %pK\n", inst);
3803 return -EINVAL;
3804 }
3805 mutex_lock(&inst->sync_lock);
3806 if (inst->state == MSM_VIDC_CORE_INVALID ||
3807 core->state == VIDC_CORE_INVALID) {
3808 dprintk(VIDC_ERR,
3809 "Core is in bad state can't change the state\n");
3810 rc = -EINVAL;
3811 goto exit;
3812 }
3813 flipped_state = get_flipped_state(inst->state, state);
3814 dprintk(VIDC_DBG,
3815 "flipped_state = %#x\n", flipped_state);
3816 switch (flipped_state) {
3817 case MSM_VIDC_CORE_UNINIT_DONE:
3818 case MSM_VIDC_CORE_INIT:
3819 rc = msm_comm_init_core(inst);
3820 if (rc || state <= get_flipped_state(inst->state, state))
3821 break;
3822 case MSM_VIDC_CORE_INIT_DONE:
3823 rc = msm_comm_init_core_done(inst);
3824 if (rc || state <= get_flipped_state(inst->state, state))
3825 break;
3826 case MSM_VIDC_OPEN:
3827 rc = msm_comm_session_init(flipped_state, inst);
3828 if (rc || state <= get_flipped_state(inst->state, state))
3829 break;
3830 case MSM_VIDC_OPEN_DONE:
3831 rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE,
3832 HAL_SESSION_INIT_DONE);
3833 if (rc || state <= get_flipped_state(inst->state, state))
3834 break;
3835 case MSM_VIDC_LOAD_RESOURCES:
3836 rc = msm_vidc_load_resources(flipped_state, inst);
3837 if (rc || state <= get_flipped_state(inst->state, state))
3838 break;
3839 case MSM_VIDC_LOAD_RESOURCES_DONE:
3840 case MSM_VIDC_START:
3841 rc = msm_vidc_start(flipped_state, inst);
3842 if (rc || state <= get_flipped_state(inst->state, state))
3843 break;
3844 case MSM_VIDC_START_DONE:
3845 rc = wait_for_state(inst, flipped_state, MSM_VIDC_START_DONE,
3846 HAL_SESSION_START_DONE);
3847 if (rc || state <= get_flipped_state(inst->state, state))
3848 break;
3849 case MSM_VIDC_STOP:
3850 rc = msm_vidc_stop(flipped_state, inst);
3851 if (rc || state <= get_flipped_state(inst->state, state))
3852 break;
3853 case MSM_VIDC_STOP_DONE:
3854 rc = wait_for_state(inst, flipped_state, MSM_VIDC_STOP_DONE,
3855 HAL_SESSION_STOP_DONE);
3856 if (rc || state <= get_flipped_state(inst->state, state))
3857 break;
3858 dprintk(VIDC_DBG, "Moving to Stop Done state\n");
3859 case MSM_VIDC_RELEASE_RESOURCES:
3860 rc = msm_vidc_release_res(flipped_state, inst);
3861 if (rc || state <= get_flipped_state(inst->state, state))
3862 break;
3863 case MSM_VIDC_RELEASE_RESOURCES_DONE:
3864 rc = wait_for_state(inst, flipped_state,
3865 MSM_VIDC_RELEASE_RESOURCES_DONE,
3866 HAL_SESSION_RELEASE_RESOURCE_DONE);
3867 if (rc || state <= get_flipped_state(inst->state, state))
3868 break;
3869 dprintk(VIDC_DBG,
3870 "Moving to release resources done state\n");
3871 case MSM_VIDC_CLOSE:
3872 rc = msm_comm_session_close(flipped_state, inst);
3873 if (rc || state <= get_flipped_state(inst->state, state))
3874 break;
3875 case MSM_VIDC_CLOSE_DONE:
3876 rc = wait_for_state(inst, flipped_state, MSM_VIDC_CLOSE_DONE,
3877 HAL_SESSION_END_DONE);
3878 if (rc || state <= get_flipped_state(inst->state, state))
3879 break;
3880 msm_comm_session_clean(inst);
3881 case MSM_VIDC_CORE_UNINIT:
3882 case MSM_VIDC_CORE_INVALID:
3883 dprintk(VIDC_DBG, "Sending core uninit\n");
3884 rc = msm_vidc_deinit_core(inst);
3885 if (rc || state == get_flipped_state(inst->state, state))
3886 break;
3887 default:
3888 dprintk(VIDC_ERR, "State not recognized\n");
3889 rc = -EINVAL;
3890 break;
3891 }
3892exit:
3893 mutex_unlock(&inst->sync_lock);
3894 if (rc)
3895 dprintk(VIDC_ERR,
3896 "Failed to move from state: %d to %d\n",
3897 inst->state, state);
3898 else
3899 trace_msm_vidc_common_state_change((void *)inst,
3900 inst->state, state);
3901 return rc;
3902}
3903
3904int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd)
3905{
3906 struct msm_vidc_inst *inst = instance;
3907 struct v4l2_decoder_cmd *dec = NULL;
3908 struct v4l2_encoder_cmd *enc = NULL;
3909 struct msm_vidc_core *core;
3910 int which_cmd = 0, flags = 0, rc = 0;
3911
3912 if (!inst || !inst->core || !cmd) {
3913 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
3914 return -EINVAL;
3915 }
3916 core = inst->core;
3917 if (inst->session_type == MSM_VIDC_ENCODER) {
3918 enc = (struct v4l2_encoder_cmd *)cmd;
3919 which_cmd = enc->cmd;
3920 flags = enc->flags;
3921 } else if (inst->session_type == MSM_VIDC_DECODER) {
3922 dec = (struct v4l2_decoder_cmd *)cmd;
3923 which_cmd = dec->cmd;
3924 flags = dec->flags;
3925 }
3926
3927
3928 switch (which_cmd) {
3929 case V4L2_QCOM_CMD_FLUSH:
3930 if (core->state != VIDC_CORE_INVALID &&
3931 inst->state == MSM_VIDC_CORE_INVALID) {
3932 rc = msm_comm_kill_session(inst);
3933 if (rc)
3934 dprintk(VIDC_ERR,
3935 "Fail to clean session: %d\n",
3936 rc);
3937 }
3938 rc = msm_comm_flush(inst, flags);
3939 if (rc) {
3940 dprintk(VIDC_ERR,
3941 "Failed to flush buffers: %d\n", rc);
3942 }
3943 break;
3944 case V4L2_DEC_QCOM_CMD_RECONFIG_HINT:
3945 {
3946 u32 *ptr = NULL;
3947 struct hal_buffer_requirements *output_buf;
3948
3949 rc = msm_comm_try_get_bufreqs(inst);
3950 if (rc) {
3951 dprintk(VIDC_ERR,
3952 "Getting buffer requirements failed: %d\n",
3953 rc);
3954 break;
3955 }
3956
3957 output_buf = get_buff_req_buffer(inst,
3958 msm_comm_get_hal_output_buffer(inst));
3959 if (output_buf) {
3960 if (dec) {
3961 ptr = (u32 *)dec->raw.data;
3962 ptr[0] = output_buf->buffer_size;
3963 ptr[1] = output_buf->buffer_count_actual;
3964 dprintk(VIDC_DBG,
3965 "Reconfig hint, size is %u, count is %u\n",
3966 ptr[0], ptr[1]);
3967 } else {
3968 dprintk(VIDC_ERR, "Null decoder\n");
3969 }
3970 } else {
3971 dprintk(VIDC_DBG,
3972 "This output buffer not required, buffer_type: %x\n",
3973 HAL_BUFFER_OUTPUT);
3974 }
3975 break;
3976 }
3977 default:
3978 dprintk(VIDC_ERR, "Unknown Command %d\n", which_cmd);
3979 rc = -ENOTSUPP;
3980 break;
3981 }
3982 return rc;
3983}
3984
3985static void populate_frame_data(struct vidc_frame_data *data,
3986 const struct vb2_buffer *vb, struct msm_vidc_inst *inst)
3987{
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003988 int extra_idx;
3989 enum v4l2_buf_type type = vb->type;
3990 enum vidc_ports port = type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
3991 OUTPUT_PORT : CAPTURE_PORT;
3992 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
3993
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003994 data->alloc_len = vb->planes[0].length;
3995 data->device_addr = vb->planes[0].m.userptr;
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08003996 data->timestamp = vb->timestamp;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003997 data->flags = 0;
3998 data->clnt_data = data->device_addr;
3999
4000 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
4001 bool pic_decoding_mode = msm_comm_g_ctrl_for_id(inst,
4002 V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE);
4003
4004 data->buffer_type = HAL_BUFFER_INPUT;
4005 data->filled_len = vb->planes[0].bytesused;
4006 data->offset = vb->planes[0].data_offset;
4007
4008 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_EOS)
4009 data->flags |= HAL_BUFFERFLAG_EOS;
4010
4011 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
4012 data->flags |= HAL_BUFFERFLAG_CODECCONFIG;
4013
4014 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY)
4015 data->flags |= HAL_BUFFERFLAG_DECODEONLY;
4016
4017 if (vbuf->flags & V4L2_QCOM_BUF_TIMESTAMP_INVALID)
4018 data->timestamp = LLONG_MAX;
4019
4020 /* XXX: This is a dirty hack necessitated by the firmware,
4021 * which refuses to issue FBDs for non I-frames in Picture Type
4022 * Decoding mode, unless we pass in non-zero value in mark_data
4023 * and mark_target.
4024 */
4025 data->mark_data = data->mark_target =
4026 pic_decoding_mode ? 0xdeadbeef : 0;
4027
4028 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
4029 data->buffer_type = msm_comm_get_hal_output_buffer(inst);
4030 }
4031
4032 extra_idx = EXTRADATA_IDX(inst->fmts[port].num_planes);
4033 if (extra_idx && extra_idx < VIDEO_MAX_PLANES &&
4034 vb->planes[extra_idx].m.userptr) {
4035 data->extradata_addr = vb->planes[extra_idx].m.userptr;
4036 data->extradata_size = vb->planes[extra_idx].length;
4037 data->flags |= HAL_BUFFERFLAG_EXTRADATA;
4038 }
4039}
4040
4041static unsigned int count_single_batch(struct msm_vidc_list *list,
4042 enum v4l2_buf_type type)
4043{
4044 struct vb2_buf_entry *buf;
4045 int count = 0;
4046 struct vb2_v4l2_buffer *vbuf = NULL;
4047
4048 mutex_lock(&list->lock);
4049 list_for_each_entry(buf, &list->list, list) {
4050 if (buf->vb->type != type)
4051 continue;
4052
4053 ++count;
4054
4055 vbuf = to_vb2_v4l2_buffer(buf->vb);
4056 if (!(vbuf->flags & V4L2_MSM_BUF_FLAG_DEFER))
4057 goto found_batch;
4058 }
4059 /* don't have a full batch */
4060 count = 0;
4061
4062found_batch:
4063 mutex_unlock(&list->lock);
4064 return count;
4065}
4066
4067static unsigned int count_buffers(struct msm_vidc_list *list,
4068 enum v4l2_buf_type type)
4069{
4070 struct vb2_buf_entry *buf;
4071 int count = 0;
4072
4073 mutex_lock(&list->lock);
4074 list_for_each_entry(buf, &list->list, list) {
4075 if (buf->vb->type != type)
4076 continue;
4077
4078 ++count;
4079 }
4080 mutex_unlock(&list->lock);
4081
4082 return count;
4083}
4084
4085static void log_frame(struct msm_vidc_inst *inst, struct vidc_frame_data *data,
4086 enum v4l2_buf_type type)
4087{
4088 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
4089 dprintk(VIDC_DBG,
4090 "Sending etb (%pa) to hal: filled: %d, ts: %lld, flags = %#x\n",
4091 &data->device_addr, data->filled_len,
4092 data->timestamp, data->flags);
4093 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_ETB);
4094
4095 if (msm_vidc_bitrate_clock_scaling &&
4096 inst->session_type == MSM_VIDC_DECODER &&
4097 !inst->dcvs_mode)
4098 inst->instant_bitrate =
4099 data->filled_len * 8 * inst->prop.fps;
4100 else
4101 inst->instant_bitrate = 0;
4102 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
4103 dprintk(VIDC_DBG,
4104 "Sending ftb (%pa) to hal: size: %d, ts: %lld, flags = %#x\n",
4105 &data->device_addr, data->alloc_len,
4106 data->timestamp, data->flags);
4107 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FTB);
4108 }
4109
4110 msm_dcvs_check_and_scale_clocks(inst,
4111 type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
4112
4113 if (msm_vidc_bitrate_clock_scaling && !inst->dcvs_mode &&
4114 type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
4115 inst->session_type == MSM_VIDC_DECODER)
4116 if (msm_comm_scale_clocks(inst->core))
4117 dprintk(VIDC_WARN,
4118 "Failed to scale clocks. Performance might be impacted\n");
4119
4120 if (msm_comm_vote_bus(inst->core))
4121 dprintk(VIDC_WARN,
4122 "Failed to scale bus. Performance might be impacted\n");
4123}
4124
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004125/*
4126 * Attempts to queue `vb` to hardware. If, for various reasons, the buffer
4127 * cannot be queued to hardware, the buffer will be staged for commit in the
4128 * pending queue. Once the hardware reaches a good state (or if `vb` is NULL,
4129 * the subsequent *_qbuf will commit the previously staged buffers to hardware.
4130 */
4131int msm_comm_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb)
4132{
4133 int rc = 0, capture_count, output_count;
4134 struct msm_vidc_core *core;
4135 struct hfi_device *hdev;
4136 struct {
4137 struct vidc_frame_data *data;
4138 int count;
4139 } etbs, ftbs;
4140 bool defer = false, batch_mode;
4141 struct vb2_buf_entry *temp, *next;
4142 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
4143
4144 if (!inst) {
4145 dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__);
4146 return -EINVAL;
4147 }
4148
4149 core = inst->core;
4150 hdev = core->device;
4151
4152 if (inst->state == MSM_VIDC_CORE_INVALID ||
4153 core->state == VIDC_CORE_INVALID ||
4154 core->state == VIDC_CORE_UNINIT) {
4155 dprintk(VIDC_ERR, "Core is in bad state. Can't Queue\n");
4156 return -EINVAL;
4157 }
4158
4159 /*
4160 * Stick the buffer into the pendinq, we'll pop it out later on
4161 * if we want to commit it to hardware
4162 */
4163 if (vb) {
4164 temp = kzalloc(sizeof(*temp), GFP_KERNEL);
4165 if (!temp) {
4166 dprintk(VIDC_ERR, "Out of memory\n");
4167 goto err_no_mem;
4168 }
4169
4170 temp->vb = vb;
4171 mutex_lock(&inst->pendingq.lock);
4172 list_add_tail(&temp->list, &inst->pendingq.list);
4173 mutex_unlock(&inst->pendingq.lock);
4174 }
4175
4176 batch_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_VIDC_QBUF_MODE)
4177 == V4L2_VIDC_QBUF_BATCHED;
4178 capture_count = (batch_mode ? &count_single_batch : &count_buffers)
4179 (&inst->pendingq, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
4180 output_count = (batch_mode ? &count_single_batch : &count_buffers)
4181 (&inst->pendingq, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
4182
4183 /*
4184 * Somewhat complicated logic to prevent queuing the buffer to hardware.
4185 * Don't queue if:
4186 * 1) Hardware isn't ready (that's simple)
4187 */
4188 defer = defer ?: inst->state != MSM_VIDC_START_DONE;
4189
4190 /*
4191 * 2) The client explicitly tells us not to because it wants this
4192 * buffer to be batched with future frames. The batch size (on both
4193 * capabilities) is completely determined by the client.
4194 */
4195 defer = defer ?: vbuf && vbuf->flags & V4L2_MSM_BUF_FLAG_DEFER;
4196
4197 /* 3) If we're in batch mode, we must have full batches of both types */
4198 defer = defer ?: batch_mode && (!output_count || !capture_count);
4199
4200 if (defer) {
4201 dprintk(VIDC_DBG, "Deferring queue of %pK\n", vb);
4202 return 0;
4203 }
4204
4205 dprintk(VIDC_DBG, "%sing %d etbs and %d ftbs\n",
4206 batch_mode ? "Batch" : "Process",
4207 output_count, capture_count);
4208
4209 etbs.data = kcalloc(output_count, sizeof(*etbs.data), GFP_KERNEL);
4210 ftbs.data = kcalloc(capture_count, sizeof(*ftbs.data), GFP_KERNEL);
4211 /*
4212 * Note that it's perfectly normal for (e|f)tbs.data to be NULL if
4213 * we're not in batch mode (i.e. (output|capture)_count == 0)
4214 */
4215 if ((!etbs.data && output_count) ||
4216 (!ftbs.data && capture_count)) {
4217 dprintk(VIDC_ERR, "Failed to alloc memory for batching\n");
4218 kfree(etbs.data);
4219 etbs.data = NULL;
4220
4221 kfree(ftbs.data);
4222 ftbs.data = NULL;
4223 goto err_no_mem;
4224 }
4225
4226 etbs.count = ftbs.count = 0;
4227
4228 /*
4229 * Try to collect all pending buffers into 2 batches of ftb and etb
4230 * Note that these "batches" might be empty if we're no in batching mode
4231 * and the pendingq is empty
4232 */
4233 mutex_lock(&inst->pendingq.lock);
4234 list_for_each_entry_safe(temp, next, &inst->pendingq.list, list) {
4235 struct vidc_frame_data *frame_data = NULL;
4236
4237 switch (temp->vb->type) {
4238 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
4239 if (ftbs.count < capture_count && ftbs.data)
4240 frame_data = &ftbs.data[ftbs.count++];
4241 break;
4242 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
4243 if (etbs.count < output_count && etbs.data)
4244 frame_data = &etbs.data[etbs.count++];
4245 break;
4246 default:
4247 break;
4248 }
4249
4250 if (!frame_data)
4251 continue;
4252
4253 populate_frame_data(frame_data, temp->vb, inst);
4254
4255 list_del(&temp->list);
4256 kfree(temp);
4257 }
4258 mutex_unlock(&inst->pendingq.lock);
4259
4260 /* Finally commit all our frame(s) to H/W */
4261 if (batch_mode) {
4262 int ftb_index = 0, c = 0;
4263
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004264 ftb_index = c;
4265 rc = call_hfi_op(hdev, session_process_batch, inst->session,
4266 etbs.count, etbs.data,
4267 ftbs.count - ftb_index, &ftbs.data[ftb_index]);
4268 if (rc) {
4269 dprintk(VIDC_ERR,
4270 "Failed to queue batch of %d ETBs and %d FTBs\n",
4271 etbs.count, ftbs.count);
4272 goto err_bad_input;
4273 }
4274
4275 for (c = ftb_index; c < ftbs.count; ++c) {
4276 log_frame(inst, &ftbs.data[c],
4277 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
4278 }
4279
4280 for (c = 0; c < etbs.count; ++c) {
4281 log_frame(inst, &etbs.data[c],
4282 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
4283 }
4284 }
4285
4286 if (!batch_mode && etbs.count) {
4287 int c = 0;
4288
4289 for (c = 0; c < etbs.count; ++c) {
4290 struct vidc_frame_data *frame_data = &etbs.data[c];
4291
4292 rc = call_hfi_op(hdev, session_etb, inst->session,
4293 frame_data);
4294 if (rc) {
4295 dprintk(VIDC_ERR, "Failed to issue etb: %d\n",
4296 rc);
4297 goto err_bad_input;
4298 }
4299
4300 log_frame(inst, frame_data,
4301 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
4302 }
4303 }
4304
4305 if (!batch_mode && ftbs.count) {
4306 int c = 0;
4307
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004308 for (; c < ftbs.count; ++c) {
4309 struct vidc_frame_data *frame_data = &ftbs.data[c];
4310
4311 rc = call_hfi_op(hdev, session_ftb,
4312 inst->session, frame_data);
4313 if (rc) {
4314 dprintk(VIDC_ERR, "Failed to issue ftb: %d\n",
4315 rc);
4316 goto err_bad_input;
4317 }
4318
4319 log_frame(inst, frame_data,
4320 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
4321 }
4322 }
4323
4324err_bad_input:
4325 if (rc)
4326 dprintk(VIDC_ERR, "Failed to queue buffer\n");
4327
4328 kfree(etbs.data);
4329 kfree(ftbs.data);
4330err_no_mem:
4331 return rc;
4332}
4333
4334int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst)
4335{
4336 int rc = 0, i = 0;
4337 union hal_get_property hprop;
4338
4339 rc = msm_comm_try_get_prop(inst, HAL_PARAM_GET_BUFFER_REQUIREMENTS,
4340 &hprop);
4341 if (rc) {
4342 dprintk(VIDC_ERR, "Failed getting buffer requirements: %d", rc);
4343 return rc;
4344 }
4345
4346 dprintk(VIDC_DBG, "Buffer requirements:\n");
4347 dprintk(VIDC_DBG, "%15s %8s %8s\n", "buffer type", "count", "size");
4348 for (i = 0; i < HAL_BUFFER_MAX; i++) {
4349 struct hal_buffer_requirements req = hprop.buf_req.buffer[i];
4350
4351 inst->buff_req.buffer[i] = req;
4352 dprintk(VIDC_DBG, "%15s %8d %8d\n",
4353 get_buffer_name(req.buffer_type),
4354 req.buffer_count_actual, req.buffer_size);
4355 }
4356
4357 dprintk(VIDC_PROF, "Input buffers: %d, Output buffers: %d\n",
4358 inst->buff_req.buffer[0].buffer_count_actual,
4359 inst->buff_req.buffer[1].buffer_count_actual);
4360 return rc;
4361}
4362
4363int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
4364 union hal_get_property *hprop)
4365{
4366 int rc = 0;
4367 struct hfi_device *hdev;
4368 struct getprop_buf *buf;
4369
4370 if (!inst || !inst->core || !inst->core->device) {
4371 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4372 return -EINVAL;
4373 }
4374
4375 hdev = inst->core->device;
4376 mutex_lock(&inst->sync_lock);
4377 if (inst->state < MSM_VIDC_OPEN_DONE ||
4378 inst->state >= MSM_VIDC_CLOSE) {
4379
4380 /* No need to check inst->state == MSM_VIDC_INVALID since
4381 * INVALID is > CLOSE_DONE. When core went to INVALID state,
4382 * we put all the active instances in INVALID. So > CLOSE_DONE
4383 * is enough check to have.
4384 */
4385
4386 dprintk(VIDC_ERR,
4387 "In Wrong state to call Buf Req: Inst %pK or Core %pK\n",
4388 inst, inst->core);
4389 rc = -EAGAIN;
4390 mutex_unlock(&inst->sync_lock);
4391 goto exit;
4392 }
4393 mutex_unlock(&inst->sync_lock);
4394
4395 switch (ptype) {
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004396 case HAL_PARAM_GET_BUFFER_REQUIREMENTS:
4397 rc = call_hfi_op(hdev, session_get_buf_req, inst->session);
4398 break;
4399 default:
4400 rc = -EAGAIN;
4401 break;
4402 }
4403
4404 if (rc) {
4405 dprintk(VIDC_ERR, "Can't query hardware for property: %d\n",
4406 rc);
4407 goto exit;
4408 }
4409
4410 rc = wait_for_completion_timeout(&inst->completions[
4411 SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO)],
4412 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
4413 if (!rc) {
4414 dprintk(VIDC_ERR,
4415 "%s: Wait interrupted or timed out [%pK]: %d\n",
4416 __func__, inst,
4417 SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO));
4418 inst->state = MSM_VIDC_CORE_INVALID;
4419 msm_comm_kill_session(inst);
4420 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
4421 dprintk(VIDC_ERR,
4422 "SESS_PROP timeout can potentially crash the system\n");
4423 if (inst->core->resources.debug_timeout)
4424 msm_comm_print_debug_info(inst);
4425
4426 msm_vidc_handle_hw_error(inst->core);
4427 rc = -ETIMEDOUT;
4428 goto exit;
4429 } else {
4430 /* wait_for_completion_timeout returns jiffies before expiry */
4431 rc = 0;
4432 }
4433
4434 mutex_lock(&inst->pending_getpropq.lock);
4435 if (!list_empty(&inst->pending_getpropq.list)) {
4436 buf = list_first_entry(&inst->pending_getpropq.list,
4437 struct getprop_buf, list);
4438 *hprop = *(union hal_get_property *)buf->data;
4439 kfree(buf->data);
4440 list_del(&buf->list);
4441 kfree(buf);
4442 } else {
4443 dprintk(VIDC_ERR, "%s getprop list empty\n", __func__);
4444 rc = -EINVAL;
4445 }
4446 mutex_unlock(&inst->pending_getpropq.lock);
4447exit:
4448 return rc;
4449}
4450
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004451int msm_comm_release_output_buffers(struct msm_vidc_inst *inst,
4452 bool force_release)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004453{
4454 struct msm_smem *handle;
4455 struct internal_buf *buf, *dummy;
4456 struct vidc_buffer_addr_info buffer_info;
4457 int rc = 0;
4458 struct msm_vidc_core *core;
4459 struct hfi_device *hdev;
4460
4461 if (!inst) {
4462 dprintk(VIDC_ERR,
4463 "Invalid instance pointer = %pK\n", inst);
4464 return -EINVAL;
4465 }
4466 mutex_lock(&inst->outputbufs.lock);
4467 if (list_empty(&inst->outputbufs.list)) {
4468 dprintk(VIDC_DBG, "%s - No OUTPUT buffers allocated\n",
4469 __func__);
4470 mutex_unlock(&inst->outputbufs.lock);
4471 return 0;
4472 }
4473 mutex_unlock(&inst->outputbufs.lock);
4474
4475 core = inst->core;
4476 if (!core) {
4477 dprintk(VIDC_ERR,
4478 "Invalid core pointer = %pK\n", core);
4479 return -EINVAL;
4480 }
4481 hdev = core->device;
4482 if (!hdev) {
4483 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4484 return -EINVAL;
4485 }
4486 mutex_lock(&inst->outputbufs.lock);
4487 list_for_each_entry_safe(buf, dummy, &inst->outputbufs.list, list) {
4488 handle = buf->handle;
4489 if (!handle) {
4490 dprintk(VIDC_ERR, "%s - invalid handle\n", __func__);
4491 goto exit;
4492 }
4493
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004494 if ((buf->buffer_ownership == FIRMWARE) && !force_release) {
4495 dprintk(VIDC_INFO, "DPB is with f/w. Can't free it\n");
4496 continue;
4497 }
4498
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004499 buffer_info.buffer_size = handle->size;
4500 buffer_info.buffer_type = buf->buffer_type;
4501 buffer_info.num_buffers = 1;
4502 buffer_info.align_device_addr = handle->device_addr;
4503 if (inst->buffer_mode_set[CAPTURE_PORT] ==
4504 HAL_BUFFER_MODE_STATIC &&
4505 inst->state != MSM_VIDC_CORE_INVALID &&
4506 core->state != VIDC_CORE_INVALID) {
4507 buffer_info.response_required = false;
4508 rc = call_hfi_op(hdev, session_release_buffers,
4509 (void *)inst->session, &buffer_info);
4510 if (rc) {
4511 dprintk(VIDC_WARN,
4512 "Rel output buf fail:%pa, %d\n",
4513 &buffer_info.align_device_addr,
4514 buffer_info.buffer_size);
4515 }
4516 }
4517
4518 list_del(&buf->list);
4519 msm_comm_smem_free(inst, buf->handle);
4520 kfree(buf);
4521 }
4522
4523exit:
4524 mutex_unlock(&inst->outputbufs.lock);
4525 return rc;
4526}
4527
4528static enum hal_buffer scratch_buf_sufficient(struct msm_vidc_inst *inst,
4529 enum hal_buffer buffer_type)
4530{
4531 struct hal_buffer_requirements *bufreq = NULL;
4532 struct internal_buf *buf;
4533 int count = 0;
4534
4535 if (!inst) {
4536 dprintk(VIDC_ERR, "%s - invalid param\n", __func__);
4537 goto not_sufficient;
4538 }
4539
4540 bufreq = get_buff_req_buffer(inst, buffer_type);
4541 if (!bufreq)
4542 goto not_sufficient;
4543
4544 /* Check if current scratch buffers are sufficient */
4545 mutex_lock(&inst->scratchbufs.lock);
4546
4547 list_for_each_entry(buf, &inst->scratchbufs.list, list) {
4548 if (!buf->handle) {
4549 dprintk(VIDC_ERR, "%s: invalid buf handle\n", __func__);
4550 mutex_unlock(&inst->scratchbufs.lock);
4551 goto not_sufficient;
4552 }
4553 if (buf->buffer_type == buffer_type &&
4554 buf->handle->size >= bufreq->buffer_size)
4555 count++;
4556 }
4557 mutex_unlock(&inst->scratchbufs.lock);
4558
4559 if (count != bufreq->buffer_count_actual)
4560 goto not_sufficient;
4561
4562 dprintk(VIDC_DBG,
4563 "Existing scratch buffer is sufficient for buffer type %#x\n",
4564 buffer_type);
4565
4566 return buffer_type;
4567
4568not_sufficient:
4569 return HAL_BUFFER_NONE;
4570}
4571
4572int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst,
4573 bool check_for_reuse)
4574{
4575 struct msm_smem *handle;
4576 struct internal_buf *buf, *dummy;
4577 struct vidc_buffer_addr_info buffer_info;
4578 int rc = 0;
4579 struct msm_vidc_core *core;
4580 struct hfi_device *hdev;
4581 enum hal_buffer sufficiency = HAL_BUFFER_NONE;
4582
4583 if (!inst) {
4584 dprintk(VIDC_ERR,
4585 "Invalid instance pointer = %pK\n", inst);
4586 return -EINVAL;
4587 }
4588 core = inst->core;
4589 if (!core) {
4590 dprintk(VIDC_ERR,
4591 "Invalid core pointer = %pK\n", core);
4592 return -EINVAL;
4593 }
4594 hdev = core->device;
4595 if (!hdev) {
4596 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4597 return -EINVAL;
4598 }
4599
4600 if (check_for_reuse) {
4601 sufficiency |= scratch_buf_sufficient(inst,
4602 HAL_BUFFER_INTERNAL_SCRATCH);
4603
4604 sufficiency |= scratch_buf_sufficient(inst,
4605 HAL_BUFFER_INTERNAL_SCRATCH_1);
4606
4607 sufficiency |= scratch_buf_sufficient(inst,
4608 HAL_BUFFER_INTERNAL_SCRATCH_2);
4609 }
4610
4611 mutex_lock(&inst->scratchbufs.lock);
4612 list_for_each_entry_safe(buf, dummy, &inst->scratchbufs.list, list) {
4613 if (!buf->handle) {
4614 dprintk(VIDC_ERR, "%s - buf->handle NULL\n", __func__);
4615 rc = -EINVAL;
4616 goto exit;
4617 }
4618
4619 handle = buf->handle;
4620 buffer_info.buffer_size = handle->size;
4621 buffer_info.buffer_type = buf->buffer_type;
4622 buffer_info.num_buffers = 1;
4623 buffer_info.align_device_addr = handle->device_addr;
4624 if (inst->state != MSM_VIDC_CORE_INVALID &&
4625 core->state != VIDC_CORE_INVALID) {
4626 buffer_info.response_required = true;
4627 rc = call_hfi_op(hdev, session_release_buffers,
4628 (void *)inst->session, &buffer_info);
4629 if (rc) {
4630 dprintk(VIDC_WARN,
4631 "Rel scrtch buf fail:%pa, %d\n",
4632 &buffer_info.align_device_addr,
4633 buffer_info.buffer_size);
4634 }
4635 mutex_unlock(&inst->scratchbufs.lock);
4636 rc = wait_for_sess_signal_receipt(inst,
4637 HAL_SESSION_RELEASE_BUFFER_DONE);
4638 if (rc) {
4639 change_inst_state(inst,
4640 MSM_VIDC_CORE_INVALID);
4641 msm_comm_kill_session(inst);
4642 }
4643 mutex_lock(&inst->scratchbufs.lock);
4644 }
4645
4646 /*If scratch buffers can be reused, do not free the buffers*/
4647 if (sufficiency & buf->buffer_type)
4648 continue;
4649
4650 list_del(&buf->list);
4651 msm_comm_smem_free(inst, buf->handle);
4652 kfree(buf);
4653 }
4654
4655exit:
4656 mutex_unlock(&inst->scratchbufs.lock);
4657 return rc;
4658}
4659
4660int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst)
4661{
4662 struct msm_smem *handle;
4663 struct list_head *ptr, *next;
4664 struct internal_buf *buf;
4665 struct vidc_buffer_addr_info buffer_info;
4666 int rc = 0;
4667 struct msm_vidc_core *core;
4668 struct hfi_device *hdev;
4669
4670 if (!inst) {
4671 dprintk(VIDC_ERR,
4672 "Invalid instance pointer = %pK\n", inst);
4673 return -EINVAL;
4674 }
4675 core = inst->core;
4676 if (!core) {
4677 dprintk(VIDC_ERR,
4678 "Invalid core pointer = %pK\n", core);
4679 return -EINVAL;
4680 }
4681 hdev = core->device;
4682 if (!hdev) {
4683 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4684 return -EINVAL;
4685 }
4686
4687 mutex_lock(&inst->persistbufs.lock);
4688 list_for_each_safe(ptr, next, &inst->persistbufs.list) {
4689 buf = list_entry(ptr, struct internal_buf, list);
4690 handle = buf->handle;
4691 buffer_info.buffer_size = handle->size;
4692 buffer_info.buffer_type = buf->buffer_type;
4693 buffer_info.num_buffers = 1;
4694 buffer_info.align_device_addr = handle->device_addr;
4695 if (inst->state != MSM_VIDC_CORE_INVALID &&
4696 core->state != VIDC_CORE_INVALID) {
4697 buffer_info.response_required = true;
4698 rc = call_hfi_op(hdev, session_release_buffers,
4699 (void *)inst->session, &buffer_info);
4700 if (rc) {
4701 dprintk(VIDC_WARN,
4702 "Rel prst buf fail:%pa, %d\n",
4703 &buffer_info.align_device_addr,
4704 buffer_info.buffer_size);
4705 }
4706 mutex_unlock(&inst->persistbufs.lock);
4707 rc = wait_for_sess_signal_receipt(inst,
4708 HAL_SESSION_RELEASE_BUFFER_DONE);
4709 if (rc) {
4710 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
4711 msm_comm_kill_session(inst);
4712 }
4713 mutex_lock(&inst->persistbufs.lock);
4714 }
4715 list_del(&buf->list);
4716 msm_comm_smem_free(inst, buf->handle);
4717 kfree(buf);
4718 }
4719 mutex_unlock(&inst->persistbufs.lock);
4720 return rc;
4721}
4722
4723int msm_comm_try_set_prop(struct msm_vidc_inst *inst,
4724 enum hal_property ptype, void *pdata)
4725{
4726 int rc = 0;
4727 struct hfi_device *hdev;
4728
4729 if (!inst) {
4730 dprintk(VIDC_ERR, "Invalid input: %pK\n", inst);
4731 return -EINVAL;
4732 }
4733
4734 if (!inst->core || !inst->core->device) {
4735 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4736 return -EINVAL;
4737 }
4738 hdev = inst->core->device;
4739
4740 mutex_lock(&inst->sync_lock);
4741 if (inst->state < MSM_VIDC_OPEN_DONE || inst->state >= MSM_VIDC_CLOSE) {
4742 dprintk(VIDC_ERR, "Not in proper state to set property\n");
4743 rc = -EAGAIN;
4744 goto exit;
4745 }
4746 rc = call_hfi_op(hdev, session_set_property, (void *)inst->session,
4747 ptype, pdata);
4748 if (rc)
4749 dprintk(VIDC_ERR, "Failed to set hal property for framesize\n");
4750exit:
4751 mutex_unlock(&inst->sync_lock);
4752 return rc;
4753}
4754
4755int msm_comm_set_output_buffers(struct msm_vidc_inst *inst)
4756{
4757 int rc = 0;
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004758 bool force_release = true;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004759
4760 if (!inst || !inst->core || !inst->core->device) {
4761 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4762 return -EINVAL;
4763 }
4764
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004765 if (inst->fmts[OUTPUT_PORT].defer_outputs)
4766 force_release = false;
4767
4768 if (msm_comm_release_output_buffers(inst, force_release))
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004769 dprintk(VIDC_WARN, "Failed to release output buffers\n");
4770
4771 rc = set_output_buffers(inst, HAL_BUFFER_OUTPUT);
4772 if (rc)
4773 goto error;
4774 return rc;
4775error:
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004776 msm_comm_release_output_buffers(inst, true);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004777 return rc;
4778}
4779
4780int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst)
4781{
4782 int rc = 0;
4783
4784 if (!inst || !inst->core || !inst->core->device) {
4785 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4786 return -EINVAL;
4787 }
4788
4789 if (msm_comm_release_scratch_buffers(inst, true))
4790 dprintk(VIDC_WARN, "Failed to release scratch buffers\n");
4791
4792 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH,
4793 &inst->scratchbufs);
4794 if (rc)
4795 goto error;
4796
4797 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_1,
4798 &inst->scratchbufs);
4799 if (rc)
4800 goto error;
4801
4802 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_2,
4803 &inst->scratchbufs);
4804 if (rc)
4805 goto error;
4806
4807 return rc;
4808error:
4809 msm_comm_release_scratch_buffers(inst, false);
4810 return rc;
4811}
4812
4813int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst)
4814{
4815 int rc = 0;
4816
4817 if (!inst || !inst->core || !inst->core->device) {
4818 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4819 return -EINVAL;
4820 }
4821
4822 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST,
4823 &inst->persistbufs);
4824 if (rc)
4825 goto error;
4826
4827 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST_1,
4828 &inst->persistbufs);
4829 if (rc)
4830 goto error;
4831 return rc;
4832error:
4833 msm_comm_release_persist_buffers(inst);
4834 return rc;
4835}
4836
4837static void msm_comm_flush_in_invalid_state(struct msm_vidc_inst *inst)
4838{
4839 struct list_head *ptr, *next;
4840 enum vidc_ports ports[] = {OUTPUT_PORT, CAPTURE_PORT};
4841 int c = 0;
4842
4843 for (c = 0; c < ARRAY_SIZE(ports); ++c) {
4844 enum vidc_ports port = ports[c];
4845
4846 dprintk(VIDC_DBG, "Flushing buffers of type %d in bad state\n",
4847 port);
4848 mutex_lock(&inst->bufq[port].lock);
4849 list_for_each_safe(ptr, next, &inst->bufq[port].
4850 vb2_bufq.queued_list) {
4851 struct vb2_buffer *vb = container_of(ptr,
4852 struct vb2_buffer, queued_entry);
4853
4854 vb->planes[0].bytesused = 0;
4855 vb->planes[0].data_offset = 0;
4856
4857 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
4858 }
4859 mutex_unlock(&inst->bufq[port].lock);
4860 }
4861
4862 msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_FLUSH_DONE);
4863}
4864
4865void msm_comm_flush_dynamic_buffers(struct msm_vidc_inst *inst)
4866{
4867 struct buffer_info *binfo = NULL;
4868
4869 if (inst->buffer_mode_set[CAPTURE_PORT] != HAL_BUFFER_MODE_DYNAMIC)
4870 return;
4871
4872 /*
4873 * dynamic buffer mode:- if flush is called during seek
4874 * driver should not queue any new buffer it has been holding.
4875 *
4876 * Each dynamic o/p buffer can have one of following ref_count:
4877 * ref_count : 0 - f/w has released reference and sent fbd back.
4878 * The buffer has been returned back to client.
4879 *
4880 * ref_count : 1 - f/w is holding reference. f/w may have released
4881 * fbd as read_only OR fbd is pending. f/w will
4882 * release reference before sending flush_done.
4883 *
4884 * ref_count : 2 - f/w is holding reference, f/w has released fbd as
4885 * read_only, which client has queued back to driver.
4886 * driver holds this buffer and will queue back
4887 * only when f/w releases the reference. During
4888 * flush_done, f/w will release the reference but driver
4889 * should not queue back the buffer to f/w.
4890 * Flush all buffers with ref_count 2.
4891 */
4892 mutex_lock(&inst->registeredbufs.lock);
4893 if (!list_empty(&inst->registeredbufs.list)) {
4894 struct v4l2_event buf_event = {0};
4895 u32 *ptr = NULL;
4896
4897 list_for_each_entry(binfo, &inst->registeredbufs.list, list) {
4898 if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
4899 atomic_read(&binfo->ref_count) == 2) {
4900
4901 atomic_dec(&binfo->ref_count);
4902 buf_event.type =
4903 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER;
4904 ptr = (u32 *)buf_event.u.data;
4905 ptr[0] = binfo->fd[0];
4906 ptr[1] = binfo->buff_off[0];
4907 ptr[2] = binfo->uvaddr[0];
4908 ptr[3] = (u32) binfo->timestamp.tv_sec;
4909 ptr[4] = (u32) binfo->timestamp.tv_usec;
4910 ptr[5] = binfo->v4l2_index;
4911 dprintk(VIDC_DBG,
4912 "released buffer held in driver before issuing flush: %pa fd[0]: %d\n",
4913 &binfo->device_addr[0], binfo->fd[0]);
4914 /*send event to client*/
4915 v4l2_event_queue_fh(&inst->event_handler,
4916 &buf_event);
4917 }
4918 }
4919 }
4920 mutex_unlock(&inst->registeredbufs.lock);
4921}
4922
4923void msm_comm_flush_pending_dynamic_buffers(struct msm_vidc_inst *inst)
4924{
4925 struct buffer_info *binfo = NULL;
4926
4927 if (!inst)
4928 return;
4929
4930 if (inst->buffer_mode_set[CAPTURE_PORT] != HAL_BUFFER_MODE_DYNAMIC)
4931 return;
4932
4933 if (list_empty(&inst->pendingq.list) ||
4934 list_empty(&inst->registeredbufs.list))
4935 return;
4936
4937 /*
4938 * Dynamic Buffer mode - Since pendingq is not empty
4939 * no output buffers have been sent to firmware yet.
4940 * Hence remove reference to all pendingq o/p buffers
4941 * before flushing them.
4942 */
4943
4944 mutex_lock(&inst->registeredbufs.lock);
4945 list_for_each_entry(binfo, &inst->registeredbufs.list, list) {
4946 if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
4947 dprintk(VIDC_DBG,
4948 "%s: binfo = %pK device_addr = %pa\n",
4949 __func__, binfo, &binfo->device_addr[0]);
4950 buf_ref_put(inst, binfo);
4951 }
4952 }
4953 mutex_unlock(&inst->registeredbufs.lock);
4954}
4955
4956int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags)
4957{
4958 int rc = 0;
4959 bool ip_flush = false;
4960 bool op_flush = false;
4961 struct vb2_buf_entry *temp, *next;
4962 struct mutex *lock;
4963 struct msm_vidc_core *core;
4964 struct hfi_device *hdev;
4965
4966 if (!inst) {
4967 dprintk(VIDC_ERR,
4968 "Invalid instance pointer = %pK\n", inst);
4969 return -EINVAL;
4970 }
4971 core = inst->core;
4972 if (!core) {
4973 dprintk(VIDC_ERR,
4974 "Invalid core pointer = %pK\n", core);
4975 return -EINVAL;
4976 }
4977 hdev = core->device;
4978 if (!hdev) {
4979 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4980 return -EINVAL;
4981 }
4982
4983 ip_flush = flags & V4L2_QCOM_CMD_FLUSH_OUTPUT;
4984 op_flush = flags & V4L2_QCOM_CMD_FLUSH_CAPTURE;
4985
4986 if (ip_flush && !op_flush) {
4987 dprintk(VIDC_INFO, "Input only flush not supported\n");
4988 return 0;
4989 }
4990
4991 msm_comm_flush_dynamic_buffers(inst);
4992
4993 if (inst->state == MSM_VIDC_CORE_INVALID ||
4994 core->state == VIDC_CORE_INVALID ||
4995 core->state == VIDC_CORE_UNINIT) {
4996 dprintk(VIDC_ERR,
4997 "Core %pK and inst %pK are in bad state\n",
4998 core, inst);
4999 msm_comm_flush_in_invalid_state(inst);
5000 return 0;
5001 }
5002
5003 if (inst->in_reconfig && !ip_flush && op_flush) {
5004 mutex_lock(&inst->pendingq.lock);
5005 if (!list_empty(&inst->pendingq.list)) {
5006 /*
5007 * Execution can never reach here since port reconfig
5008 * wont happen unless pendingq is emptied out
5009 * (both pendingq and flush being secured with same
5010 * lock). Printing a message here incase this breaks.
5011 */
5012 dprintk(VIDC_WARN,
5013 "FLUSH BUG: Pending q not empty! It should be empty\n");
5014 }
5015 mutex_unlock(&inst->pendingq.lock);
5016 atomic_inc(&inst->in_flush);
5017 dprintk(VIDC_DBG, "Send flush Output to firmware\n");
5018 rc = call_hfi_op(hdev, session_flush, inst->session,
5019 HAL_FLUSH_OUTPUT);
5020 } else {
5021 msm_comm_flush_pending_dynamic_buffers(inst);
5022 /*
5023 * If flush is called after queueing buffers but before
5024 * streamon driver should flush the pending queue
5025 */
5026 mutex_lock(&inst->pendingq.lock);
5027 list_for_each_entry_safe(temp, next,
5028 &inst->pendingq.list, list) {
5029 enum v4l2_buf_type type = temp->vb->type;
5030
5031 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
5032 lock = &inst->bufq[CAPTURE_PORT].lock;
5033 else
5034 lock = &inst->bufq[OUTPUT_PORT].lock;
5035
5036 temp->vb->planes[0].bytesused = 0;
5037
5038 mutex_lock(lock);
5039 vb2_buffer_done(temp->vb, VB2_BUF_STATE_DONE);
5040 msm_vidc_debugfs_update(inst,
5041 type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ?
5042 MSM_VIDC_DEBUGFS_EVENT_FBD :
5043 MSM_VIDC_DEBUGFS_EVENT_EBD);
5044 list_del(&temp->list);
5045 mutex_unlock(lock);
5046
5047 kfree(temp);
5048 }
5049 mutex_unlock(&inst->pendingq.lock);
5050
5051 /*Do not send flush in case of session_error */
5052 if (!(inst->state == MSM_VIDC_CORE_INVALID &&
5053 core->state != VIDC_CORE_INVALID)) {
5054 atomic_inc(&inst->in_flush);
5055 dprintk(VIDC_DBG, "Send flush all to firmware\n");
5056 rc = call_hfi_op(hdev, session_flush, inst->session,
5057 HAL_FLUSH_ALL);
5058 }
5059 }
5060
5061 return rc;
5062}
5063
5064
5065enum hal_extradata_id msm_comm_get_hal_extradata_index(
5066 enum v4l2_mpeg_vidc_extradata index)
5067{
5068 int ret = 0;
5069
5070 switch (index) {
5071 case V4L2_MPEG_VIDC_EXTRADATA_NONE:
5072 ret = HAL_EXTRADATA_NONE;
5073 break;
5074 case V4L2_MPEG_VIDC_EXTRADATA_MB_QUANTIZATION:
5075 ret = HAL_EXTRADATA_MB_QUANTIZATION;
5076 break;
5077 case V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO:
5078 ret = HAL_EXTRADATA_INTERLACE_VIDEO;
5079 break;
5080 case V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP:
5081 ret = HAL_EXTRADATA_TIMESTAMP;
5082 break;
5083 case V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING:
5084 ret = HAL_EXTRADATA_S3D_FRAME_PACKING;
5085 break;
5086 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE:
5087 ret = HAL_EXTRADATA_FRAME_RATE;
5088 break;
5089 case V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW:
5090 ret = HAL_EXTRADATA_PANSCAN_WINDOW;
5091 break;
5092 case V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
5093 ret = HAL_EXTRADATA_RECOVERY_POINT_SEI;
5094 break;
5095 case V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO:
5096 ret = HAL_EXTRADATA_MULTISLICE_INFO;
5097 break;
5098 case V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB:
5099 ret = HAL_EXTRADATA_NUM_CONCEALED_MB;
5100 break;
5101 case V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER:
5102 ret = HAL_EXTRADATA_METADATA_FILLER;
5103 break;
5104 case V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO:
5105 ret = HAL_EXTRADATA_ASPECT_RATIO;
5106 break;
5107 case V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP:
5108 ret = HAL_EXTRADATA_INPUT_CROP;
5109 break;
5110 case V4L2_MPEG_VIDC_EXTRADATA_DIGITAL_ZOOM:
5111 ret = HAL_EXTRADATA_DIGITAL_ZOOM;
5112 break;
5113 case V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP:
5114 ret = HAL_EXTRADATA_MPEG2_SEQDISP;
5115 break;
5116 case V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA:
5117 ret = HAL_EXTRADATA_STREAM_USERDATA;
5118 break;
5119 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP:
5120 ret = HAL_EXTRADATA_FRAME_QP;
5121 break;
5122 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO:
5123 ret = HAL_EXTRADATA_FRAME_BITS_INFO;
5124 break;
5125 case V4L2_MPEG_VIDC_EXTRADATA_LTR:
5126 ret = HAL_EXTRADATA_LTR_INFO;
5127 break;
5128 case V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI:
5129 ret = HAL_EXTRADATA_METADATA_MBI;
5130 break;
5131 case V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI:
5132 ret = HAL_EXTRADATA_VQZIP_SEI;
5133 break;
5134 case V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS:
5135 ret = HAL_EXTRADATA_YUV_STATS;
5136 break;
5137 case V4L2_MPEG_VIDC_EXTRADATA_ROI_QP:
5138 ret = HAL_EXTRADATA_ROI_QP;
5139 break;
5140 case V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP:
5141 ret = HAL_EXTRADATA_OUTPUT_CROP;
5142 break;
5143 case V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI:
5144 ret = HAL_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI;
5145 break;
5146 case V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI:
5147 ret = HAL_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI;
5148 break;
5149 case V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO:
5150 ret = HAL_EXTRADATA_PQ_INFO;
5151 break;
5152
5153 case V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY:
5154 ret = HAL_EXTRADATA_VUI_DISPLAY_INFO;
5155 break;
5156 case V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE:
5157 ret = HAL_EXTRADATA_VPX_COLORSPACE;
5158 break;
5159 default:
5160 dprintk(VIDC_WARN, "Extradata not found: %d\n", index);
5161 break;
5162 }
5163 return ret;
5164};
5165
5166int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
5167 enum hal_ssr_trigger_type type)
5168{
5169 int rc = 0;
5170 struct hfi_device *hdev;
5171
5172 if (!core || !core->device) {
5173 dprintk(VIDC_WARN, "Invalid parameters: %pK\n", core);
5174 return -EINVAL;
5175 }
5176 hdev = core->device;
5177 if (core->state == VIDC_CORE_INIT_DONE) {
5178 /*
5179 * In current implementation user-initiated SSR triggers
5180 * a fatal error from hardware. However, there is no way
5181 * to know if fatal error is due to SSR or not. Handle
5182 * user SSR as non-fatal.
5183 */
5184 mutex_lock(&core->lock);
5185 core->resources.debug_timeout = false;
5186 mutex_unlock(&core->lock);
5187 rc = call_hfi_op(hdev, core_trigger_ssr,
5188 hdev->hfi_device_data, type);
5189 }
5190
5191 return rc;
5192}
5193
5194static int msm_vidc_load_supported(struct msm_vidc_inst *inst)
5195{
5196 int num_mbs_per_sec = 0, max_load_adj = 0;
5197 enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD |
5198 LOAD_CALC_IGNORE_THUMBNAIL_LOAD |
5199 LOAD_CALC_IGNORE_NON_REALTIME_LOAD;
5200
5201 if (inst->state == MSM_VIDC_OPEN_DONE) {
5202 max_load_adj = inst->core->resources.max_load +
5203 inst->capability.mbs_per_frame.max;
5204 num_mbs_per_sec = msm_comm_get_load(inst->core,
5205 MSM_VIDC_DECODER, quirks);
5206 num_mbs_per_sec += msm_comm_get_load(inst->core,
5207 MSM_VIDC_ENCODER, quirks);
5208 if (num_mbs_per_sec > max_load_adj) {
5209 dprintk(VIDC_ERR,
5210 "H/W is overloaded. needed: %d max: %d\n",
5211 num_mbs_per_sec,
5212 max_load_adj);
5213 msm_vidc_print_running_insts(inst->core);
5214 return -EBUSY;
5215 }
5216 }
5217 return 0;
5218}
5219
5220int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst)
5221{
5222 u32 x_min, x_max, y_min, y_max;
5223 u32 input_height, input_width, output_height, output_width;
5224
5225 input_height = inst->prop.height[OUTPUT_PORT];
5226 input_width = inst->prop.width[OUTPUT_PORT];
5227 output_height = inst->prop.height[CAPTURE_PORT];
5228 output_width = inst->prop.width[CAPTURE_PORT];
5229
5230 if (!input_height || !input_width || !output_height || !output_width) {
5231 dprintk(VIDC_ERR,
5232 "Invalid : Input height = %d width = %d",
5233 input_height, input_width);
5234 dprintk(VIDC_ERR,
5235 " output height = %d width = %d\n",
5236 output_height, output_width);
5237 return -ENOTSUPP;
5238 }
5239
5240 if (!inst->capability.scale_x.min ||
5241 !inst->capability.scale_x.max ||
5242 !inst->capability.scale_y.min ||
5243 !inst->capability.scale_y.max) {
5244
5245 if (input_width * input_height !=
5246 output_width * output_height) {
5247 dprintk(VIDC_ERR,
5248 "%s: scaling is not supported (%dx%d != %dx%d)\n",
5249 __func__, input_width, input_height,
5250 output_width, output_height);
5251 return -ENOTSUPP;
5252 }
5253
5254 dprintk(VIDC_DBG, "%s: supported WxH = %dx%d\n",
5255 __func__, input_width, input_height);
5256 return 0;
5257 }
5258
5259 x_min = (1<<16)/inst->capability.scale_x.min;
5260 y_min = (1<<16)/inst->capability.scale_y.min;
5261 x_max = inst->capability.scale_x.max >> 16;
5262 y_max = inst->capability.scale_y.max >> 16;
5263
5264 if (input_height > output_height) {
5265 if (input_height > x_min * output_height) {
5266 dprintk(VIDC_ERR,
5267 "Unsupported height downscale ratio %d vs %d\n",
5268 input_height/output_height, x_min);
5269 return -ENOTSUPP;
5270 }
5271 } else {
5272 if (output_height > x_max * input_height) {
5273 dprintk(VIDC_ERR,
5274 "Unsupported height upscale ratio %d vs %d\n",
5275 input_height/output_height, x_max);
5276 return -ENOTSUPP;
5277 }
5278 }
5279 if (input_width > output_width) {
5280 if (input_width > y_min * output_width) {
5281 dprintk(VIDC_ERR,
5282 "Unsupported width downscale ratio %d vs %d\n",
5283 input_width/output_width, y_min);
5284 return -ENOTSUPP;
5285 }
5286 } else {
5287 if (output_width > y_max * input_width) {
5288 dprintk(VIDC_ERR,
5289 "Unsupported width upscale ratio %d vs %d\n",
5290 input_width/output_width, y_max);
5291 return -ENOTSUPP;
5292 }
5293 }
5294 return 0;
5295}
5296
5297int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
5298{
5299 struct msm_vidc_capability *capability;
5300 int rc = 0;
5301 struct hfi_device *hdev;
5302 struct msm_vidc_core *core;
5303
5304 if (!inst || !inst->core || !inst->core->device) {
5305 dprintk(VIDC_WARN, "%s: Invalid parameter\n", __func__);
5306 return -EINVAL;
5307 }
5308 capability = &inst->capability;
5309 hdev = inst->core->device;
5310 core = inst->core;
5311 rc = msm_vidc_load_supported(inst);
5312 if (rc) {
5313 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
5314 msm_comm_kill_session(inst);
5315 dprintk(VIDC_WARN,
5316 "%s: Hardware is overloaded\n", __func__);
5317 return rc;
5318 }
5319
5320 if (!is_thermal_permissible(core)) {
5321 dprintk(VIDC_WARN,
5322 "Thermal level critical, stop all active sessions!\n");
5323 return -ENOTSUPP;
5324 }
5325
5326 if (!rc)
5327 msm_dcvs_try_enable(inst);
5328
5329 if (!rc) {
5330 if (inst->prop.width[CAPTURE_PORT] < capability->width.min ||
5331 inst->prop.height[CAPTURE_PORT] <
5332 capability->height.min) {
5333 dprintk(VIDC_ERR,
5334 "Unsupported WxH = (%u)x(%u), min supported is - (%u)x(%u)\n",
5335 inst->prop.width[CAPTURE_PORT],
5336 inst->prop.height[CAPTURE_PORT],
5337 capability->width.min,
5338 capability->height.min);
5339 rc = -ENOTSUPP;
5340 }
5341 if (!rc && inst->prop.width[CAPTURE_PORT] >
5342 capability->width.max) {
5343 dprintk(VIDC_ERR,
5344 "Unsupported width = %u supported max width = %u",
5345 inst->prop.width[CAPTURE_PORT],
5346 capability->width.max);
5347 rc = -ENOTSUPP;
5348 }
5349
5350 if (!rc && inst->prop.height[CAPTURE_PORT]
5351 * inst->prop.width[CAPTURE_PORT] >
5352 capability->width.max * capability->height.max) {
5353 dprintk(VIDC_ERR,
5354 "Unsupported WxH = (%u)x(%u), max supported is - (%u)x(%u)\n",
5355 inst->prop.width[CAPTURE_PORT],
5356 inst->prop.height[CAPTURE_PORT],
5357 capability->width.max, capability->height.max);
5358 rc = -ENOTSUPP;
5359 }
5360 }
5361 if (rc) {
5362 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
5363 msm_comm_kill_session(inst);
5364 dprintk(VIDC_ERR,
5365 "%s: Resolution unsupported\n", __func__);
5366 }
5367 return rc;
5368}
5369
5370static void msm_comm_generate_session_error(struct msm_vidc_inst *inst)
5371{
5372 enum hal_command_response cmd = HAL_SESSION_ERROR;
5373 struct msm_vidc_cb_cmd_done response = {0};
5374
5375 dprintk(VIDC_WARN, "msm_comm_generate_session_error\n");
5376 if (!inst || !inst->core) {
5377 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5378 return;
5379 }
5380
5381 response.session_id = inst;
5382 response.status = VIDC_ERR_FAIL;
5383 handle_session_error(cmd, (void *)&response);
5384}
5385
5386static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst)
5387{
5388 struct msm_vidc_core *core;
5389 enum hal_command_response cmd = HAL_SYS_ERROR;
5390 struct msm_vidc_cb_cmd_done response = {0};
5391
5392 if (!inst || !inst->core) {
5393 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5394 return;
5395 }
5396 core = inst->core;
5397 response.device_id = (u32) core->id;
5398 handle_sys_error(cmd, (void *) &response);
5399
5400}
5401
5402int msm_comm_kill_session(struct msm_vidc_inst *inst)
5403{
5404 int rc = 0;
5405
5406 if (!inst || !inst->core || !inst->core->device) {
5407 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5408 return -EINVAL;
5409 } else if (!inst->session) {
5410 /* There's no hfi session to kill */
5411 return 0;
5412 }
5413
5414 /*
5415 * We're internally forcibly killing the session, if fw is aware of
5416 * the session send session_abort to firmware to clean up and release
5417 * the session, else just kill the session inside the driver.
5418 */
5419 if ((inst->state >= MSM_VIDC_OPEN_DONE &&
5420 inst->state < MSM_VIDC_CLOSE_DONE) ||
5421 inst->state == MSM_VIDC_CORE_INVALID) {
5422 if (msm_comm_session_abort(inst)) {
5423 msm_comm_generate_sys_error(inst);
5424 return 0;
5425 }
5426 change_inst_state(inst, MSM_VIDC_CLOSE_DONE);
5427 msm_comm_generate_session_error(inst);
5428 } else {
5429 dprintk(VIDC_WARN,
5430 "Inactive session %pK, triggering an internal session error\n",
5431 inst);
5432 msm_comm_generate_session_error(inst);
5433
5434 }
5435
5436 return rc;
5437}
5438
5439struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst,
5440 size_t size, u32 align, u32 flags,
5441 enum hal_buffer buffer_type, int map_kernel)
5442{
5443 struct msm_smem *m = NULL;
5444
5445 if (!inst || !inst->core) {
5446 dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst);
5447 return NULL;
5448 }
5449 m = msm_smem_alloc(inst->mem_client, size, align,
5450 flags, buffer_type, map_kernel);
5451 return m;
5452}
5453
5454void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem)
5455{
5456 if (!inst || !inst->core || !mem) {
5457 dprintk(VIDC_ERR,
5458 "%s: invalid params: %pK %pK\n", __func__, inst, mem);
5459 return;
5460 }
5461 msm_smem_free(inst->mem_client, mem);
5462}
5463
5464int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst,
5465 struct msm_smem *mem, enum smem_cache_ops cache_ops)
5466{
5467 if (!inst || !mem) {
5468 dprintk(VIDC_ERR,
5469 "%s: invalid params: %pK %pK\n", __func__, inst, mem);
5470 return -EINVAL;
5471 }
5472 return msm_smem_cache_operations(inst->mem_client, mem, cache_ops);
5473}
5474
5475struct msm_smem *msm_comm_smem_user_to_kernel(struct msm_vidc_inst *inst,
5476 int fd, u32 offset, enum hal_buffer buffer_type)
5477{
5478 struct msm_smem *m = NULL;
5479
5480 if (!inst || !inst->core) {
5481 dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst);
5482 return NULL;
5483 }
5484
5485 if (inst->state == MSM_VIDC_CORE_INVALID) {
5486 dprintk(VIDC_ERR, "Core in Invalid state, returning from %s\n",
5487 __func__);
5488 return NULL;
5489 }
5490
5491 m = msm_smem_user_to_kernel(inst->mem_client,
5492 fd, offset, buffer_type);
5493 return m;
5494}
5495
5496void msm_vidc_fw_unload_handler(struct work_struct *work)
5497{
5498 struct msm_vidc_core *core = NULL;
5499 struct hfi_device *hdev = NULL;
5500 int rc = 0;
5501
5502 core = container_of(work, struct msm_vidc_core, fw_unload_work.work);
5503 if (!core || !core->device) {
5504 dprintk(VIDC_ERR, "%s - invalid work or core handle\n",
5505 __func__);
5506 return;
5507 }
5508
5509 hdev = core->device;
5510
5511 mutex_lock(&core->lock);
5512 if (list_empty(&core->instances) &&
5513 core->state != VIDC_CORE_UNINIT) {
5514 if (core->state > VIDC_CORE_INIT) {
5515 dprintk(VIDC_DBG, "Calling vidc_hal_core_release\n");
5516 rc = call_hfi_op(hdev, core_release,
5517 hdev->hfi_device_data);
5518 if (rc) {
5519 dprintk(VIDC_ERR,
5520 "Failed to release core, id = %d\n",
5521 core->id);
5522 mutex_unlock(&core->lock);
5523 return;
5524 }
5525 }
5526 core->state = VIDC_CORE_UNINIT;
5527 kfree(core->capabilities);
5528 core->capabilities = NULL;
5529 }
5530 mutex_unlock(&core->lock);
5531}
5532
5533int msm_comm_set_color_format(struct msm_vidc_inst *inst,
5534 enum hal_buffer buffer_type, int fourcc)
5535{
5536 struct hal_uncompressed_format_select hal_fmt = {0};
5537 enum hal_uncompressed_format format = HAL_UNUSED_COLOR;
5538 int rc = 0;
5539 struct hfi_device *hdev;
5540
5541 if (!inst || !inst->core || !inst->core->device) {
5542 dprintk(VIDC_ERR, "%s - invalid param\n", __func__);
5543 return -EINVAL;
5544 }
5545
5546 hdev = inst->core->device;
5547
5548 format = get_hal_uncompressed(fourcc);
5549 if (format == HAL_UNUSED_COLOR) {
5550 dprintk(VIDC_ERR, "Using unsupported colorformat %#x\n",
5551 fourcc);
5552 rc = -ENOTSUPP;
5553 goto exit;
5554 }
5555
5556 hal_fmt.buffer_type = buffer_type;
5557 hal_fmt.format = format;
5558
5559 rc = call_hfi_op(hdev, session_set_property, inst->session,
5560 HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT, &hal_fmt);
5561 if (rc)
5562 dprintk(VIDC_ERR,
5563 "Failed to set input color format\n");
5564 else
5565 dprintk(VIDC_DBG, "Setting uncompressed colorformat to %#x\n",
5566 format);
5567
5568exit:
5569 return rc;
5570}
5571
5572int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
5573{
5574 u32 property_id = 0;
5575 u64 us_per_frame = 0;
5576 void *pdata;
5577 int rc = 0, fps = 0;
5578 struct hal_frame_rate frame_rate;
5579 struct hfi_device *hdev;
5580
5581 if (!inst || !inst->core || !inst->core->device || !a) {
5582 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
5583 return -EINVAL;
5584 }
5585
5586 hdev = inst->core->device;
5587 property_id = HAL_CONFIG_FRAME_RATE;
5588
5589 if (a->parm.output.timeperframe.denominator) {
5590 switch (a->type) {
5591 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
5592 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
5593 us_per_frame = a->parm.output.timeperframe.numerator *
5594 (u64)USEC_PER_SEC;
5595 do_div(us_per_frame, a->parm.output.
5596 timeperframe.denominator);
5597 break;
5598 default:
5599 dprintk(VIDC_ERR,
5600 "Scale clocks : Unknown buffer type %d\n",
5601 a->type);
5602 break;
5603 }
5604 }
5605
5606 if (!us_per_frame) {
5607 dprintk(VIDC_ERR,
5608 "Failed to scale clocks : time between frames is 0\n");
5609 rc = -EINVAL;
5610 goto exit;
5611 }
5612
5613 fps = USEC_PER_SEC;
5614 do_div(fps, us_per_frame);
5615
5616 if (fps % 15 == 14 || fps % 24 == 23)
5617 fps = fps + 1;
5618 else if ((fps > 1) && (fps % 24 == 1 || fps % 15 == 1))
5619 fps = fps - 1;
5620
Praneeth Paladugue1679112017-01-27 10:07:15 -08005621 if (fps < inst->capability.frame_rate.min ||
5622 fps > inst->capability.frame_rate.max) {
5623 dprintk(VIDC_ERR,
5624 "FPS is out of limits : fps = %d Min = %d, Max = %d\n",
5625 fps, inst->capability.frame_rate.min,
5626 inst->capability.frame_rate.max);
5627 rc = -EINVAL;
5628 goto exit;
5629 }
5630
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08005631 if (inst->prop.fps != fps) {
5632 dprintk(VIDC_PROF, "reported fps changed for %pK: %d->%d\n",
5633 inst, inst->prop.fps, fps);
5634 inst->prop.fps = fps;
5635 frame_rate.frame_rate = inst->prop.fps * BIT(16);
5636 frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
5637 pdata = &frame_rate;
5638 if (inst->session_type == MSM_VIDC_ENCODER) {
5639 rc = call_hfi_op(hdev, session_set_property,
5640 inst->session, property_id, pdata);
5641
5642 if (rc)
5643 dprintk(VIDC_WARN,
5644 "Failed to set frame rate %d\n", rc);
5645 } else {
5646 msm_dcvs_init_load(inst);
5647 }
5648 msm_comm_scale_clocks_and_bus(inst);
5649 msm_dcvs_try_enable(inst);
5650 }
5651exit:
5652 return rc;
5653}
5654
5655void msm_comm_print_inst_info(struct msm_vidc_inst *inst)
5656{
5657 struct buffer_info *temp;
5658 struct internal_buf *buf;
5659 int i = 0;
5660 bool is_decode = false;
5661 enum vidc_ports port;
5662 bool is_secure = false;
5663
5664 if (!inst) {
5665 dprintk(VIDC_ERR, "%s - invalid param %pK\n",
5666 __func__, inst);
5667 return;
5668 }
5669
5670 is_decode = inst->session_type == MSM_VIDC_DECODER;
5671 port = is_decode ? OUTPUT_PORT : CAPTURE_PORT;
5672 is_secure = inst->flags & VIDC_SECURE;
5673 dprintk(VIDC_ERR,
5674 "%s session, %s, Codec type: %s HxW: %d x %d fps: %d bitrate: %d bit-depth: %s\n",
5675 is_decode ? "Decode" : "Encode",
5676 is_secure ? "Secure" : "Non-Secure",
5677 inst->fmts[port].name,
5678 inst->prop.height[port], inst->prop.width[port],
5679 inst->prop.fps, inst->prop.bitrate,
5680 !inst->bit_depth ? "8" : "10");
5681
5682 dprintk(VIDC_ERR,
5683 "---Buffer details for inst: %pK of type: %d---\n",
5684 inst, inst->session_type);
5685 mutex_lock(&inst->registeredbufs.lock);
5686 dprintk(VIDC_ERR, "registered buffer list:\n");
5687 list_for_each_entry(temp, &inst->registeredbufs.list, list)
5688 for (i = 0; i < temp->num_planes; i++)
5689 dprintk(VIDC_ERR,
5690 "type: %d plane: %d addr: %pa size: %d\n",
5691 temp->type, i, &temp->device_addr[i],
5692 temp->size[i]);
5693
5694 mutex_unlock(&inst->registeredbufs.lock);
5695
5696 mutex_lock(&inst->scratchbufs.lock);
5697 dprintk(VIDC_ERR, "scratch buffer list:\n");
5698 list_for_each_entry(buf, &inst->scratchbufs.list, list)
5699 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5700 buf->buffer_type, &buf->handle->device_addr,
5701 buf->handle->size);
5702 mutex_unlock(&inst->scratchbufs.lock);
5703
5704 mutex_lock(&inst->persistbufs.lock);
5705 dprintk(VIDC_ERR, "persist buffer list:\n");
5706 list_for_each_entry(buf, &inst->persistbufs.list, list)
5707 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5708 buf->buffer_type, &buf->handle->device_addr,
5709 buf->handle->size);
5710 mutex_unlock(&inst->persistbufs.lock);
5711
5712 mutex_lock(&inst->outputbufs.lock);
5713 dprintk(VIDC_ERR, "dpb buffer list:\n");
5714 list_for_each_entry(buf, &inst->outputbufs.list, list)
5715 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5716 buf->buffer_type, &buf->handle->device_addr,
5717 buf->handle->size);
5718 mutex_unlock(&inst->outputbufs.lock);
5719}
5720
5721static void msm_comm_print_debug_info(struct msm_vidc_inst *inst)
5722{
5723 struct msm_vidc_core *core = NULL;
5724 struct msm_vidc_inst *temp = NULL;
5725
5726 if (!inst || !inst->core) {
5727 dprintk(VIDC_ERR, "%s - invalid param %pK %pK\n",
5728 __func__, inst, core);
5729 return;
5730 }
5731 core = inst->core;
5732
5733 dprintk(VIDC_ERR, "Venus core frequency = %lu",
5734 msm_comm_get_clock_rate(core));
5735 mutex_lock(&core->lock);
5736 dprintk(VIDC_ERR, "Printing instance info that caused Error\n");
5737 msm_comm_print_inst_info(inst);
5738 dprintk(VIDC_ERR, "Printing remaining instances info\n");
5739 list_for_each_entry(temp, &core->instances, list) {
5740 /* inst already printed above. Hence don't repeat.*/
5741 if (temp == inst)
5742 continue;
5743 msm_comm_print_inst_info(temp);
5744 }
5745 mutex_unlock(&core->lock);
5746}