blob: 4f5309de11002c209df4421dba9993f8f549da42 [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);
2444 vb->planes[0].bytesused = fill_buf_done->filled_len1;
2445 vb->planes[0].data_offset = fill_buf_done->offset1;
2446 if (vb->planes[0].data_offset > vb->planes[0].length)
2447 dprintk(VIDC_INFO,
2448 "fbd:Overflow data_offset = %d; length = %d\n",
2449 vb->planes[0].data_offset,
2450 vb->planes[0].length);
2451 if (vb->planes[0].bytesused > vb->planes[0].length)
2452 dprintk(VIDC_INFO,
2453 "fbd:Overflow bytesused = %d; length = %d\n",
2454 vb->planes[0].bytesused,
2455 vb->planes[0].length);
2456 if (!(fill_buf_done->flags1 &
2457 HAL_BUFFERFLAG_TIMESTAMPINVALID)) {
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002458 time_nsec = fill_buf_done->timestamp_hi;
2459 time_nsec = (time_nsec << 32) |
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002460 fill_buf_done->timestamp_lo;
2461 } else {
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002462 time_nsec = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002463 dprintk(VIDC_DBG,
2464 "Set zero timestamp for buffer %pa, filled: %d, (hi:%u, lo:%u)\n",
2465 &fill_buf_done->packet_buffer1,
2466 fill_buf_done->filled_len1,
2467 fill_buf_done->timestamp_hi,
2468 fill_buf_done->timestamp_lo);
2469 }
2470 vbuf->flags = 0;
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002471 vb->timestamp = time_nsec;
2472
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002473 extra_idx =
2474 EXTRADATA_IDX(inst->fmts[CAPTURE_PORT].num_planes);
2475 if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
2476 vb->planes[extra_idx].m.userptr =
2477 (unsigned long)fill_buf_done->extra_data_buffer;
2478 vb->planes[extra_idx].bytesused =
2479 vb->planes[extra_idx].length;
2480 vb->planes[extra_idx].data_offset = 0;
2481 }
2482
2483 handle_dynamic_buffer(inst, fill_buf_done->packet_buffer1,
2484 fill_buf_done->flags1);
2485 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_READONLY)
2486 vbuf->flags |= V4L2_QCOM_BUF_FLAG_READONLY;
2487 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOS)
2488 vbuf->flags |= V4L2_QCOM_BUF_FLAG_EOS;
2489 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_CODECCONFIG)
2490 vbuf->flags &= ~V4L2_QCOM_BUF_FLAG_CODECCONFIG;
2491 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_SYNCFRAME)
2492 vbuf->flags |= V4L2_QCOM_BUF_FLAG_IDRFRAME;
2493 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOSEQ)
2494 vbuf->flags |= V4L2_QCOM_BUF_FLAG_EOSEQ;
2495 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DECODEONLY)
2496 vbuf->flags |= V4L2_QCOM_BUF_FLAG_DECODEONLY;
2497 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DATACORRUPT)
2498 vbuf->flags |= V4L2_QCOM_BUF_DATA_CORRUPT;
2499
2500 switch (fill_buf_done->picture_type) {
2501 case HAL_PICTURE_IDR:
2502 vbuf->flags |= V4L2_QCOM_BUF_FLAG_IDRFRAME;
2503 vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
2504 break;
2505 case HAL_PICTURE_I:
2506 vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
2507 break;
2508 case HAL_PICTURE_P:
2509 vbuf->flags |= V4L2_BUF_FLAG_PFRAME;
2510 break;
2511 case HAL_PICTURE_B:
2512 vbuf->flags |= V4L2_BUF_FLAG_BFRAME;
2513 break;
2514 case HAL_FRAME_NOTCODED:
2515 case HAL_UNUSED_PICT:
2516 /* Do we need to care about these? */
2517 case HAL_FRAME_YUV:
2518 break;
2519 default:
2520 break;
2521 }
2522
2523 inst->count.fbd++;
2524
2525 if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
2526 dprintk(VIDC_DBG,
2527 "extradata: userptr = %pK;"
2528 " bytesused = %d; length = %d\n",
2529 (u8 *)vb->planes[extra_idx].m.userptr,
2530 vb->planes[extra_idx].bytesused,
2531 vb->planes[extra_idx].length);
2532 }
2533 dprintk(VIDC_DBG,
2534 "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",
2535 &fill_buf_done->packet_buffer1, fill_buf_done->alloc_len1,
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002536 fill_buf_done->filled_len1, fill_buf_done->offset1, time_nsec,
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002537 fill_buf_done->flags1, fill_buf_done->start_x_coord,
2538 fill_buf_done->start_y_coord, fill_buf_done->frame_width,
2539 fill_buf_done->frame_height, fill_buf_done->picture_type,
2540 fill_buf_done->mark_data);
2541
2542 mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
2543 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
2544 mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
2545 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FBD);
2546 }
2547
2548err_handle_fbd:
2549 put_inst(inst);
2550}
2551
2552static void handle_seq_hdr_done(enum hal_command_response cmd, void *data)
2553{
2554 struct msm_vidc_cb_data_done *response = data;
2555 struct msm_vidc_inst *inst;
2556 struct vb2_buffer *vb;
2557 struct vidc_hal_fbd *fill_buf_done;
2558 struct vb2_v4l2_buffer *vbuf;
2559
2560 if (!response) {
2561 dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
2562 return;
2563 }
2564
2565 inst = get_inst(get_vidc_core(response->device_id),
2566 response->session_id);
2567 if (!inst) {
2568 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
2569 return;
2570 }
2571
2572 fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
2573 vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
2574 fill_buf_done->packet_buffer1);
2575 if (!vb) {
2576 dprintk(VIDC_ERR,
2577 "Failed to find video buffer for seq_hdr_done: %pa\n",
2578 &fill_buf_done->packet_buffer1);
2579 goto err_seq_hdr_done;
2580 }
2581 vbuf = to_vb2_v4l2_buffer(vb);
2582// vb->timestamp = (u64) ns_to_timeval(0);
2583
2584 vb->planes[0].bytesused = fill_buf_done->filled_len1;
2585 vb->planes[0].data_offset = fill_buf_done->offset1;
2586
2587 vbuf->flags = V4L2_QCOM_BUF_FLAG_CODECCONFIG;
2588
2589 dprintk(VIDC_DBG, "Filled length = %d; offset = %d; flags %x\n",
2590 vb->planes[0].bytesused,
2591 vb->planes[0].data_offset,
2592 vbuf->flags);
2593 mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
2594 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
2595 mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
2596
2597err_seq_hdr_done:
2598 put_inst(inst);
2599}
2600
2601void handle_cmd_response(enum hal_command_response cmd, void *data)
2602{
2603 dprintk(VIDC_DBG, "Command response = %d\n", cmd);
2604 switch (cmd) {
2605 case HAL_SYS_INIT_DONE:
2606 handle_sys_init_done(cmd, data);
2607 break;
2608 case HAL_SYS_RELEASE_RESOURCE_DONE:
2609 handle_sys_release_res_done(cmd, data);
2610 break;
2611 case HAL_SESSION_INIT_DONE:
2612 handle_session_init_done(cmd, data);
2613 break;
2614 case HAL_SESSION_PROPERTY_INFO:
2615 handle_session_prop_info(cmd, data);
2616 break;
2617 case HAL_SESSION_LOAD_RESOURCE_DONE:
2618 handle_load_resource_done(cmd, data);
2619 break;
2620 case HAL_SESSION_START_DONE:
2621 handle_start_done(cmd, data);
2622 break;
2623 case HAL_SESSION_ETB_DONE:
2624 handle_ebd(cmd, data);
2625 break;
2626 case HAL_SESSION_FTB_DONE:
2627 handle_fbd(cmd, data);
2628 break;
2629 case HAL_SESSION_STOP_DONE:
2630 handle_stop_done(cmd, data);
2631 break;
2632 case HAL_SESSION_RELEASE_RESOURCE_DONE:
2633 handle_release_res_done(cmd, data);
2634 break;
2635 case HAL_SESSION_END_DONE:
2636 case HAL_SESSION_ABORT_DONE:
2637 handle_session_close(cmd, data);
2638 break;
2639 case HAL_SESSION_EVENT_CHANGE:
2640 handle_event_change(cmd, data);
2641 break;
2642 case HAL_SESSION_FLUSH_DONE:
2643 handle_session_flush(cmd, data);
2644 break;
2645 case HAL_SESSION_GET_SEQ_HDR_DONE:
2646 handle_seq_hdr_done(cmd, data);
2647 break;
2648 case HAL_SYS_WATCHDOG_TIMEOUT:
2649 case HAL_SYS_ERROR:
2650 handle_sys_error(cmd, data);
2651 break;
2652 case HAL_SESSION_ERROR:
2653 handle_session_error(cmd, data);
2654 break;
2655 case HAL_SESSION_RELEASE_BUFFER_DONE:
2656 handle_session_release_buf_done(cmd, data);
2657 break;
2658 default:
2659 dprintk(VIDC_DBG, "response unhandled: %d\n", cmd);
2660 break;
2661 }
2662}
2663
2664int msm_comm_scale_clocks(struct msm_vidc_core *core)
2665{
2666 int num_mbs_per_sec, enc_mbs_per_sec, dec_mbs_per_sec;
2667
2668 enc_mbs_per_sec =
2669 msm_comm_get_load(core, MSM_VIDC_ENCODER, LOAD_CALC_NO_QUIRKS);
2670 dec_mbs_per_sec =
2671 msm_comm_get_load(core, MSM_VIDC_DECODER, LOAD_CALC_NO_QUIRKS);
2672
2673 if (enc_mbs_per_sec >= dec_mbs_per_sec) {
2674 /*
2675 * If Encoder load is higher, use that load. Encoder votes for higher
2676 * clock. Since Encoder and Deocder run on parallel cores, this clock
2677 * should suffice decoder usecases.
2678 */
2679 num_mbs_per_sec = enc_mbs_per_sec;
2680 } else {
2681 /*
2682 * If Decoder load is higher, it's tricky to decide clock. Decoder
2683 * higher load might results less clocks than Encoder smaller load.
2684 * At this point driver doesn't know which clock to vote. Hence use
2685 * total load.
2686 */
2687 num_mbs_per_sec = enc_mbs_per_sec + dec_mbs_per_sec;
2688 }
2689
2690 return msm_comm_scale_clocks_load(core, num_mbs_per_sec,
2691 LOAD_CALC_NO_QUIRKS);
2692}
2693
2694int msm_comm_scale_clocks_load(struct msm_vidc_core *core,
2695 int num_mbs_per_sec, enum load_calc_quirks quirks)
2696{
2697 int rc = 0;
2698 struct hfi_device *hdev;
2699 struct msm_vidc_inst *inst = NULL;
2700 unsigned long instant_bitrate = 0;
2701 int num_sessions = 0;
2702 struct vidc_clk_scale_data clk_scale_data = { {0} };
2703 int codec = 0;
2704
2705 if (!core) {
2706 dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core);
2707 return -EINVAL;
2708 }
2709
2710 hdev = core->device;
2711 if (!hdev) {
2712 dprintk(VIDC_ERR, "%s Invalid device handle: %pK\n",
2713 __func__, hdev);
2714 return -EINVAL;
2715 }
2716
2717 mutex_lock(&core->lock);
2718 list_for_each_entry(inst, &core->instances, list) {
2719
2720 codec = inst->session_type == MSM_VIDC_DECODER ?
2721 inst->fmts[OUTPUT_PORT].fourcc :
2722 inst->fmts[CAPTURE_PORT].fourcc;
2723
2724 if (msm_comm_turbo_session(inst))
2725 clk_scale_data.power_mode[num_sessions] =
2726 VIDC_POWER_TURBO;
2727 else if (is_low_power_session(inst))
2728 clk_scale_data.power_mode[num_sessions] =
2729 VIDC_POWER_LOW;
2730 else
2731 clk_scale_data.power_mode[num_sessions] =
2732 VIDC_POWER_NORMAL;
2733
2734 if (inst->dcvs_mode)
2735 clk_scale_data.load[num_sessions] = inst->dcvs.load;
2736 else
2737 clk_scale_data.load[num_sessions] =
2738 msm_comm_get_inst_load(inst, quirks);
2739
2740 clk_scale_data.session[num_sessions] =
2741 VIDC_VOTE_DATA_SESSION_VAL(
2742 get_hal_codec(codec),
2743 get_hal_domain(inst->session_type));
2744 num_sessions++;
2745
2746 if (inst->instant_bitrate > instant_bitrate)
2747 instant_bitrate = inst->instant_bitrate;
2748
2749 }
2750 clk_scale_data.num_sessions = num_sessions;
2751 mutex_unlock(&core->lock);
2752
2753
2754 rc = call_hfi_op(hdev, scale_clocks,
2755 hdev->hfi_device_data, num_mbs_per_sec,
2756 &clk_scale_data, instant_bitrate);
2757 if (rc)
2758 dprintk(VIDC_ERR, "Failed to set clock rate: %d\n", rc);
2759
2760 return rc;
2761}
2762
2763void msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst)
2764{
2765 struct msm_vidc_core *core;
2766 struct hfi_device *hdev;
2767
2768 if (!inst || !inst->core || !inst->core->device) {
2769 dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
2770 return;
2771 }
2772 core = inst->core;
2773 hdev = core->device;
2774
2775 if (msm_comm_scale_clocks(core)) {
2776 dprintk(VIDC_WARN,
2777 "Failed to scale clocks. Performance might be impacted\n");
2778 }
2779 if (msm_comm_vote_bus(core)) {
2780 dprintk(VIDC_WARN,
2781 "Failed to scale DDR bus. Performance might be impacted\n");
2782 }
2783}
2784
2785static inline enum msm_vidc_thermal_level msm_comm_vidc_thermal_level(int level)
2786{
2787 switch (level) {
2788 case 0:
2789 return VIDC_THERMAL_NORMAL;
2790 case 1:
2791 return VIDC_THERMAL_LOW;
2792 case 2:
2793 return VIDC_THERMAL_HIGH;
2794 default:
2795 return VIDC_THERMAL_CRITICAL;
2796 }
2797}
2798
2799static unsigned long msm_comm_get_clock_rate(struct msm_vidc_core *core)
2800{
2801 struct hfi_device *hdev;
2802 unsigned long freq = 0;
2803
2804 if (!core || !core->device) {
2805 dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
2806 return -EINVAL;
2807 }
2808 hdev = core->device;
2809
2810 freq = call_hfi_op(hdev, get_core_clock_rate, hdev->hfi_device_data, 1);
2811 dprintk(VIDC_DBG, "clock freq %ld\n", freq);
2812
2813 return freq;
2814}
2815
2816static bool is_core_turbo(struct msm_vidc_core *core, unsigned long freq)
2817{
2818 int i = 0;
2819 struct msm_vidc_platform_resources *res = &core->resources;
2820 struct load_freq_table *table = res->load_freq_tbl;
2821 u32 max_freq = 0;
2822
2823 for (i = 0; i < res->load_freq_tbl_size; i++) {
2824 if (max_freq < table[i].freq)
2825 max_freq = table[i].freq;
2826 }
2827 return freq >= max_freq;
2828}
2829
2830static bool is_thermal_permissible(struct msm_vidc_core *core)
2831{
2832 enum msm_vidc_thermal_level tl;
2833 unsigned long freq = 0;
2834 bool is_turbo = false;
2835
2836 if (!core->resources.thermal_mitigable)
2837 return true;
2838
2839 if (msm_vidc_thermal_mitigation_disabled) {
2840 dprintk(VIDC_DBG,
2841 "Thermal mitigation not enabled. debugfs %d\n",
2842 msm_vidc_thermal_mitigation_disabled);
2843 return true;
2844 }
2845
2846 tl = msm_comm_vidc_thermal_level(vidc_driver->thermal_level);
2847 freq = msm_comm_get_clock_rate(core);
2848
2849 is_turbo = is_core_turbo(core, freq);
2850 dprintk(VIDC_DBG,
2851 "Core freq %ld Thermal level %d Turbo mode %d\n",
2852 freq, tl, is_turbo);
2853
2854 if (is_turbo && tl >= VIDC_THERMAL_LOW) {
2855 dprintk(VIDC_ERR,
2856 "Video session not allowed. Turbo mode %d Thermal level %d\n",
2857 is_turbo, tl);
2858 return false;
2859 }
2860 return true;
2861}
2862
2863static int msm_comm_session_abort(struct msm_vidc_inst *inst)
2864{
2865 int rc = 0, abort_completion = 0;
2866 struct hfi_device *hdev;
2867
2868 if (!inst || !inst->core || !inst->core->device) {
2869 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
2870 return -EINVAL;
2871 }
2872 hdev = inst->core->device;
2873 abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE);
2874
2875 rc = call_hfi_op(hdev, session_abort, (void *)inst->session);
2876 if (rc) {
2877 dprintk(VIDC_ERR,
2878 "%s session_abort failed rc: %d\n", __func__, rc);
2879 return rc;
2880 }
2881 rc = wait_for_completion_timeout(
2882 &inst->completions[abort_completion],
2883 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
2884 if (!rc) {
2885 dprintk(VIDC_ERR,
2886 "%s: Wait interrupted or timed out [%pK]: %d\n",
2887 __func__, inst, abort_completion);
2888 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
2889 dprintk(VIDC_ERR,
2890 "ABORT timeout can potentially crash the system\n");
2891 msm_comm_print_debug_info(inst);
2892
2893 msm_vidc_handle_hw_error(inst->core);
2894 rc = -EBUSY;
2895 } else {
2896 rc = 0;
2897 }
2898 msm_comm_session_clean(inst);
2899 return rc;
2900}
2901
2902static void handle_thermal_event(struct msm_vidc_core *core)
2903{
2904 int rc = 0;
2905 struct msm_vidc_inst *inst;
2906
2907 if (!core || !core->device) {
2908 dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
2909 return;
2910 }
2911 mutex_lock(&core->lock);
2912 list_for_each_entry(inst, &core->instances, list) {
2913 if (!inst->session)
2914 continue;
2915
2916 mutex_unlock(&core->lock);
2917 if (inst->state >= MSM_VIDC_OPEN_DONE &&
2918 inst->state < MSM_VIDC_CLOSE_DONE) {
2919 dprintk(VIDC_WARN, "%s: abort inst %pK\n",
2920 __func__, inst);
2921 rc = msm_comm_session_abort(inst);
2922 if (rc) {
2923 dprintk(VIDC_ERR,
2924 "%s session_abort failed rc: %d\n",
2925 __func__, rc);
2926 goto err_sess_abort;
2927 }
2928 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
2929 dprintk(VIDC_WARN,
2930 "%s Send sys error for inst %pK\n",
2931 __func__, inst);
2932 msm_vidc_queue_v4l2_event(inst,
2933 V4L2_EVENT_MSM_VIDC_SYS_ERROR);
2934 } else {
2935 msm_comm_generate_session_error(inst);
2936 }
2937 mutex_lock(&core->lock);
2938 }
2939 mutex_unlock(&core->lock);
2940 return;
2941
2942err_sess_abort:
2943 msm_comm_clean_notify_client(core);
2944}
2945
2946void msm_comm_handle_thermal_event(void)
2947{
2948 struct msm_vidc_core *core;
2949
2950 list_for_each_entry(core, &vidc_driver->cores, list) {
2951 if (!is_thermal_permissible(core)) {
2952 dprintk(VIDC_WARN,
2953 "Thermal level critical, stop all active sessions!\n");
2954 handle_thermal_event(core);
2955 }
2956 }
2957}
2958
2959int msm_comm_check_core_init(struct msm_vidc_core *core)
2960{
2961 int rc = 0;
2962 struct hfi_device *hdev;
2963 struct msm_vidc_inst *inst = NULL;
2964
2965 mutex_lock(&core->lock);
2966 if (core->state >= VIDC_CORE_INIT_DONE) {
2967 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
2968 core->id, core->state);
2969 goto exit;
2970 }
2971 dprintk(VIDC_DBG, "Waiting for SYS_INIT_DONE\n");
2972 hdev = (struct hfi_device *)core->device;
2973 rc = wait_for_completion_timeout(
2974 &core->completions[SYS_MSG_INDEX(HAL_SYS_INIT_DONE)],
2975 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
2976 if (!rc) {
2977 dprintk(VIDC_ERR, "%s: Wait interrupted or timed out: %d\n",
2978 __func__, SYS_MSG_INDEX(HAL_SYS_INIT_DONE));
2979 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
2980 dprintk(VIDC_ERR,
2981 "SYS_INIT timeout can potentially crash the system\n");
2982 /*
2983 * For SYS_INIT, there will not be any inst pointer.
2984 * Just grab one of the inst from instances list and
2985 * use it.
2986 */
2987 inst = list_first_entry(&core->instances,
2988 struct msm_vidc_inst, list);
2989
2990 mutex_unlock(&core->lock);
2991 msm_comm_print_debug_info(inst);
2992 mutex_lock(&core->lock);
2993
2994 msm_vidc_handle_hw_error(core);
2995 rc = -EIO;
2996 goto exit;
2997 } else {
2998 core->state = VIDC_CORE_INIT_DONE;
2999 rc = 0;
3000 }
3001 dprintk(VIDC_DBG, "SYS_INIT_DONE!!!\n");
3002exit:
3003 mutex_unlock(&core->lock);
3004 return rc;
3005}
3006
3007static int msm_comm_init_core_done(struct msm_vidc_inst *inst)
3008{
3009 int rc = 0;
3010
3011 rc = msm_comm_check_core_init(inst->core);
3012 if (rc) {
3013 dprintk(VIDC_ERR, "%s - failed to initialize core\n", __func__);
3014 msm_comm_generate_sys_error(inst);
3015 return rc;
3016 }
3017 change_inst_state(inst, MSM_VIDC_CORE_INIT_DONE);
3018 return rc;
3019}
3020
3021static int msm_comm_init_core(struct msm_vidc_inst *inst)
3022{
3023 int rc = 0;
3024 struct hfi_device *hdev;
3025 struct msm_vidc_core *core;
3026
3027 if (!inst || !inst->core || !inst->core->device)
3028 return -EINVAL;
3029
3030 core = inst->core;
3031 hdev = core->device;
3032 mutex_lock(&core->lock);
3033 if (core->state >= VIDC_CORE_INIT) {
3034 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
3035 core->id, core->state);
3036 goto core_already_inited;
3037 }
3038 if (!core->capabilities) {
3039 core->capabilities = kzalloc(VIDC_MAX_SESSIONS *
3040 sizeof(struct msm_vidc_capability), GFP_KERNEL);
3041 if (!core->capabilities) {
3042 dprintk(VIDC_ERR,
3043 "%s: failed to allocate capabilities\n",
3044 __func__);
3045 rc = -ENOMEM;
3046 goto fail_cap_alloc;
3047 }
3048 } else {
3049 dprintk(VIDC_WARN,
3050 "%s: capabilities memory is expected to be freed\n",
3051 __func__);
3052 }
3053
3054 rc = call_hfi_op(hdev, core_init, hdev->hfi_device_data);
3055 if (rc) {
3056 dprintk(VIDC_ERR, "Failed to init core, id = %d\n",
3057 core->id);
3058 goto fail_core_init;
3059 }
3060 core->state = VIDC_CORE_INIT;
3061 core->smmu_fault_handled = false;
3062core_already_inited:
3063 change_inst_state(inst, MSM_VIDC_CORE_INIT);
3064 mutex_unlock(&core->lock);
3065 return rc;
3066
3067fail_core_init:
3068 kfree(core->capabilities);
3069fail_cap_alloc:
3070 core->capabilities = NULL;
3071 core->state = VIDC_CORE_UNINIT;
3072 mutex_unlock(&core->lock);
3073 return rc;
3074}
3075
3076static int msm_vidc_deinit_core(struct msm_vidc_inst *inst)
3077{
3078 struct msm_vidc_core *core;
3079 struct hfi_device *hdev;
3080
3081 if (!inst || !inst->core || !inst->core->device) {
3082 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3083 return -EINVAL;
3084 }
3085
3086 core = inst->core;
3087 hdev = core->device;
3088
3089 mutex_lock(&core->lock);
3090 if (core->state == VIDC_CORE_UNINIT) {
3091 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
3092 core->id, core->state);
3093 goto core_already_uninited;
3094 }
3095 mutex_unlock(&core->lock);
3096
3097 msm_comm_scale_clocks_and_bus(inst);
3098
3099 mutex_lock(&core->lock);
3100
3101 if (!core->resources.never_unload_fw) {
3102 cancel_delayed_work(&core->fw_unload_work);
3103
3104 /*
3105 * Delay unloading of firmware. This is useful
3106 * in avoiding firmware download delays in cases where we
3107 * will have a burst of back to back video playback sessions
3108 * e.g. thumbnail generation.
3109 */
3110 schedule_delayed_work(&core->fw_unload_work,
3111 msecs_to_jiffies(core->state == VIDC_CORE_INVALID ?
3112 0 : msm_vidc_firmware_unload_delay));
3113
3114 dprintk(VIDC_DBG, "firmware unload delayed by %u ms\n",
3115 core->state == VIDC_CORE_INVALID ?
3116 0 : msm_vidc_firmware_unload_delay);
3117 }
3118
3119core_already_uninited:
3120 change_inst_state(inst, MSM_VIDC_CORE_UNINIT);
3121 mutex_unlock(&core->lock);
3122 return 0;
3123}
3124
3125int msm_comm_force_cleanup(struct msm_vidc_inst *inst)
3126{
3127 msm_comm_kill_session(inst);
3128 return msm_vidc_deinit_core(inst);
3129}
3130
3131static int msm_comm_session_init(int flipped_state,
3132 struct msm_vidc_inst *inst)
3133{
3134 int rc = 0;
3135 int fourcc = 0;
3136 struct hfi_device *hdev;
3137
3138 if (!inst || !inst->core || !inst->core->device) {
3139 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3140 return -EINVAL;
3141 }
3142 hdev = inst->core->device;
3143
3144 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) {
3145 dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n",
3146 inst, inst->state);
3147 goto exit;
3148 }
3149 if (inst->session_type == MSM_VIDC_DECODER) {
3150 fourcc = inst->fmts[OUTPUT_PORT].fourcc;
3151 } else if (inst->session_type == MSM_VIDC_ENCODER) {
3152 fourcc = inst->fmts[CAPTURE_PORT].fourcc;
3153 } else {
3154 dprintk(VIDC_ERR, "Invalid session\n");
3155 return -EINVAL;
3156 }
3157
3158 rc = call_hfi_op(hdev, session_init, hdev->hfi_device_data,
3159 inst, get_hal_domain(inst->session_type),
3160 get_hal_codec(fourcc),
3161 &inst->session);
3162
3163 if (rc || !inst->session) {
3164 dprintk(VIDC_ERR,
3165 "Failed to call session init for: %pK, %pK, %d, %d\n",
3166 inst->core->device, inst,
3167 inst->session_type, fourcc);
3168 rc = -EINVAL;
3169 goto exit;
3170 }
3171 change_inst_state(inst, MSM_VIDC_OPEN);
3172exit:
3173 return rc;
3174}
3175
3176static void msm_vidc_print_running_insts(struct msm_vidc_core *core)
3177{
3178 struct msm_vidc_inst *temp;
3179
3180 dprintk(VIDC_ERR, "Running instances:\n");
3181 dprintk(VIDC_ERR, "%4s|%4s|%4s|%4s|%4s\n",
3182 "type", "w", "h", "fps", "prop");
3183
3184 mutex_lock(&core->lock);
3185 list_for_each_entry(temp, &core->instances, list) {
3186 if (temp->state >= MSM_VIDC_OPEN_DONE &&
3187 temp->state < MSM_VIDC_STOP_DONE) {
3188 char properties[4] = "";
3189
3190 if (is_thumbnail_session(temp))
3191 strlcat(properties, "N", sizeof(properties));
3192
3193 if (msm_comm_turbo_session(temp))
3194 strlcat(properties, "T", sizeof(properties));
3195
3196 dprintk(VIDC_ERR, "%4d|%4d|%4d|%4d|%4s\n",
3197 temp->session_type,
3198 max(temp->prop.width[CAPTURE_PORT],
3199 temp->prop.width[OUTPUT_PORT]),
3200 max(temp->prop.height[CAPTURE_PORT],
3201 temp->prop.height[OUTPUT_PORT]),
3202 temp->prop.fps, properties);
3203 }
3204 }
3205 mutex_unlock(&core->lock);
3206}
3207
3208static int msm_vidc_load_resources(int flipped_state,
3209 struct msm_vidc_inst *inst)
3210{
3211 int rc = 0;
3212 struct hfi_device *hdev;
3213 int num_mbs_per_sec = 0, max_load_adj = 0;
3214 struct msm_vidc_core *core;
3215 enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD |
3216 LOAD_CALC_IGNORE_THUMBNAIL_LOAD |
3217 LOAD_CALC_IGNORE_NON_REALTIME_LOAD;
3218
3219 if (!inst || !inst->core || !inst->core->device) {
3220 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3221 return -EINVAL;
3222 }
3223
3224 core = inst->core;
3225 if (core->state == VIDC_CORE_INVALID) {
3226 dprintk(VIDC_ERR,
3227 "Core is in bad state can't do load res\n");
3228 return -EINVAL;
3229 }
3230
3231 if (inst->state == MSM_VIDC_CORE_INVALID) {
3232 dprintk(VIDC_ERR,
3233 "Instance is in invalid state can't do load res\n");
3234 return -EINVAL;
3235 }
3236
3237 num_mbs_per_sec =
3238 msm_comm_get_load(core, MSM_VIDC_DECODER, quirks) +
3239 msm_comm_get_load(core, MSM_VIDC_ENCODER, quirks);
3240
3241 max_load_adj = core->resources.max_load +
3242 inst->capability.mbs_per_frame.max;
3243
3244 if (num_mbs_per_sec > max_load_adj) {
3245 dprintk(VIDC_ERR, "HW is overloaded, needed: %d max: %d\n",
3246 num_mbs_per_sec, max_load_adj);
3247 msm_vidc_print_running_insts(core);
3248 inst->state = MSM_VIDC_CORE_INVALID;
3249 msm_comm_kill_session(inst);
3250 return -EBUSY;
3251 }
3252
3253 hdev = core->device;
3254 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) {
3255 dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n",
3256 inst, inst->state);
3257 goto exit;
3258 }
3259
3260 rc = call_hfi_op(hdev, session_load_res, (void *) inst->session);
3261 if (rc) {
3262 dprintk(VIDC_ERR,
3263 "Failed to send load resources\n");
3264 goto exit;
3265 }
3266 change_inst_state(inst, MSM_VIDC_LOAD_RESOURCES);
3267exit:
3268 return rc;
3269}
3270
3271static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst)
3272{
3273 int rc = 0;
3274 struct hfi_device *hdev;
3275
3276 if (!inst || !inst->core || !inst->core->device) {
3277 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3278 return -EINVAL;
3279 }
3280 if (inst->state == MSM_VIDC_CORE_INVALID ||
3281 inst->core->state == VIDC_CORE_INVALID) {
3282 dprintk(VIDC_ERR,
3283 "Core is in bad state can't do start\n");
3284 return -EINVAL;
3285 }
3286
3287 hdev = inst->core->device;
3288
3289 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) {
3290 dprintk(VIDC_INFO,
3291 "inst: %pK is already in state: %d\n",
3292 inst, inst->state);
3293 goto exit;
3294 }
3295 rc = call_hfi_op(hdev, session_start, (void *) inst->session);
3296 if (rc) {
3297 dprintk(VIDC_ERR,
3298 "Failed to send start\n");
3299 goto exit;
3300 }
3301 change_inst_state(inst, MSM_VIDC_START);
3302exit:
3303 return rc;
3304}
3305
3306static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst)
3307{
3308 int rc = 0;
3309 struct hfi_device *hdev;
3310
3311 if (!inst || !inst->core || !inst->core->device) {
3312 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3313 return -EINVAL;
3314 }
3315 hdev = inst->core->device;
3316
3317 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) {
3318 dprintk(VIDC_INFO,
3319 "inst: %pK is already in state: %d\n",
3320 inst, inst->state);
3321 goto exit;
3322 }
3323 dprintk(VIDC_DBG, "Send Stop to hal\n");
3324 rc = call_hfi_op(hdev, session_stop, (void *) inst->session);
3325 if (rc) {
3326 dprintk(VIDC_ERR, "Failed to send stop\n");
3327 goto exit;
3328 }
3329 change_inst_state(inst, MSM_VIDC_STOP);
3330exit:
3331 return rc;
3332}
3333
3334static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst)
3335{
3336 int rc = 0;
3337 struct hfi_device *hdev;
3338
3339 if (!inst || !inst->core || !inst->core->device) {
3340 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3341 return -EINVAL;
3342 }
3343 hdev = inst->core->device;
3344
3345 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) {
3346 dprintk(VIDC_INFO,
3347 "inst: %pK is already in state: %d\n",
3348 inst, inst->state);
3349 goto exit;
3350 }
3351 dprintk(VIDC_DBG,
3352 "Send release res to hal\n");
3353 rc = call_hfi_op(hdev, session_release_res, (void *) inst->session);
3354 if (rc) {
3355 dprintk(VIDC_ERR,
3356 "Failed to send release resources\n");
3357 goto exit;
3358 }
3359 change_inst_state(inst, MSM_VIDC_RELEASE_RESOURCES);
3360exit:
3361 return rc;
3362}
3363
3364static int msm_comm_session_close(int flipped_state,
3365 struct msm_vidc_inst *inst)
3366{
3367 int rc = 0;
3368 struct hfi_device *hdev;
3369
3370 if (!inst || !inst->core || !inst->core->device) {
3371 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
3372 return -EINVAL;
3373 }
3374 hdev = inst->core->device;
3375 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) {
3376 dprintk(VIDC_INFO,
3377 "inst: %pK is already in state: %d\n",
3378 inst, inst->state);
3379 goto exit;
3380 }
3381 dprintk(VIDC_DBG,
3382 "Send session close to hal\n");
3383 rc = call_hfi_op(hdev, session_end, (void *) inst->session);
3384 if (rc) {
3385 dprintk(VIDC_ERR,
3386 "Failed to send close\n");
3387 goto exit;
3388 }
3389 change_inst_state(inst, MSM_VIDC_CLOSE);
3390exit:
3391 return rc;
3392}
3393
3394int msm_comm_suspend(int core_id)
3395{
3396 struct hfi_device *hdev;
3397 struct msm_vidc_core *core;
3398 int rc = 0;
3399
3400 core = get_vidc_core(core_id);
3401 if (!core) {
3402 dprintk(VIDC_ERR,
3403 "%s: Failed to find core for core_id = %d\n",
3404 __func__, core_id);
3405 return -EINVAL;
3406 }
3407
3408 hdev = (struct hfi_device *)core->device;
3409 if (!hdev) {
3410 dprintk(VIDC_ERR, "%s Invalid device handle\n", __func__);
3411 return -EINVAL;
3412 }
3413
3414 mutex_lock(&core->lock);
3415 if (core->state == VIDC_CORE_INVALID) {
3416 dprintk(VIDC_ERR,
3417 "%s - fw is not in proper state, skip suspend\n",
3418 __func__);
3419 rc = -EINVAL;
3420 goto exit;
3421 }
3422
3423 rc = call_hfi_op(hdev, suspend, hdev->hfi_device_data);
3424 if (rc)
3425 dprintk(VIDC_WARN, "Failed to suspend\n");
3426
3427exit:
3428 mutex_unlock(&core->lock);
3429 return rc;
3430}
3431
3432static int get_flipped_state(int present_state,
3433 int desired_state)
3434{
3435 int flipped_state = present_state;
3436
3437 if (flipped_state < MSM_VIDC_STOP
3438 && desired_state > MSM_VIDC_STOP) {
3439 flipped_state = MSM_VIDC_STOP + (MSM_VIDC_STOP - flipped_state);
3440 flipped_state &= 0xFFFE;
3441 flipped_state = flipped_state - 1;
3442 } else if (flipped_state > MSM_VIDC_STOP
3443 && desired_state < MSM_VIDC_STOP) {
3444 flipped_state = MSM_VIDC_STOP -
3445 (flipped_state - MSM_VIDC_STOP + 1);
3446 flipped_state &= 0xFFFE;
3447 flipped_state = flipped_state - 1;
3448 }
3449 return flipped_state;
3450}
3451
3452struct hal_buffer_requirements *get_buff_req_buffer(
3453 struct msm_vidc_inst *inst, enum hal_buffer buffer_type)
3454{
3455 int i;
3456
3457 for (i = 0; i < HAL_BUFFER_MAX; i++) {
3458 if (inst->buff_req.buffer[i].buffer_type == buffer_type)
3459 return &inst->buff_req.buffer[i];
3460 }
3461 return NULL;
3462}
3463
3464static int set_output_buffers(struct msm_vidc_inst *inst,
3465 enum hal_buffer buffer_type)
3466{
3467 int rc = 0;
3468 struct msm_smem *handle;
3469 struct internal_buf *binfo;
3470 u32 smem_flags = 0, buffer_size;
3471 struct hal_buffer_requirements *output_buf, *extradata_buf;
3472 int i;
3473 struct hfi_device *hdev;
3474 struct hal_buffer_size_minimum b;
3475
3476 hdev = inst->core->device;
3477
3478 output_buf = get_buff_req_buffer(inst, buffer_type);
3479 if (!output_buf) {
3480 dprintk(VIDC_DBG,
3481 "This output buffer not required, buffer_type: %x\n",
3482 buffer_type);
3483 return 0;
3484 }
3485 dprintk(VIDC_DBG,
3486 "output: num = %d, size = %d\n",
3487 output_buf->buffer_count_actual,
3488 output_buf->buffer_size);
3489
3490 buffer_size = output_buf->buffer_size;
3491 b.buffer_type = buffer_type;
3492 b.buffer_size = buffer_size;
3493 rc = call_hfi_op(hdev, session_set_property,
3494 inst->session, HAL_PARAM_BUFFER_SIZE_MINIMUM,
3495 &b);
3496
3497 extradata_buf = get_buff_req_buffer(inst, HAL_BUFFER_EXTRADATA_OUTPUT);
3498 if (extradata_buf) {
3499 dprintk(VIDC_DBG,
3500 "extradata: num = %d, size = %d\n",
3501 extradata_buf->buffer_count_actual,
3502 extradata_buf->buffer_size);
3503 buffer_size += extradata_buf->buffer_size;
3504 } else {
3505 dprintk(VIDC_DBG,
3506 "This extradata buffer not required, buffer_type: %x\n",
3507 buffer_type);
3508 }
3509
3510 if (inst->flags & VIDC_SECURE)
3511 smem_flags |= SMEM_SECURE;
3512
3513 if (output_buf->buffer_size) {
3514 for (i = 0; i < output_buf->buffer_count_actual;
3515 i++) {
3516 handle = msm_comm_smem_alloc(inst,
3517 buffer_size, 1, smem_flags,
3518 buffer_type, 0);
3519 if (!handle) {
3520 dprintk(VIDC_ERR,
3521 "Failed to allocate output memory\n");
3522 rc = -ENOMEM;
3523 goto err_no_mem;
3524 }
3525 rc = msm_comm_smem_cache_operations(inst,
3526 handle, SMEM_CACHE_CLEAN);
3527 if (rc) {
3528 dprintk(VIDC_WARN,
3529 "Failed to clean cache may cause undefined behavior\n");
3530 }
3531 binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
3532 if (!binfo) {
3533 dprintk(VIDC_ERR, "Out of memory\n");
3534 rc = -ENOMEM;
3535 goto fail_kzalloc;
3536 }
3537
3538 binfo->handle = handle;
3539 binfo->buffer_type = buffer_type;
3540 binfo->buffer_ownership = DRIVER;
3541 dprintk(VIDC_DBG, "Output buffer address: %pa\n",
3542 &handle->device_addr);
3543
3544 if (inst->buffer_mode_set[CAPTURE_PORT] ==
3545 HAL_BUFFER_MODE_STATIC) {
3546 struct vidc_buffer_addr_info buffer_info = {0};
3547
3548 buffer_info.buffer_size =
3549 output_buf->buffer_size;
3550 buffer_info.buffer_type = buffer_type;
3551 buffer_info.num_buffers = 1;
3552 buffer_info.align_device_addr =
3553 handle->device_addr;
3554 buffer_info.extradata_addr =
3555 handle->device_addr +
3556 output_buf->buffer_size;
3557 if (extradata_buf)
3558 buffer_info.extradata_size =
3559 extradata_buf->buffer_size;
3560 rc = call_hfi_op(hdev, session_set_buffers,
3561 (void *) inst->session, &buffer_info);
3562 if (rc) {
3563 dprintk(VIDC_ERR,
3564 "%s : session_set_buffers failed\n",
3565 __func__);
3566 goto fail_set_buffers;
3567 }
3568 }
3569 mutex_lock(&inst->outputbufs.lock);
3570 list_add_tail(&binfo->list, &inst->outputbufs.list);
3571 mutex_unlock(&inst->outputbufs.lock);
3572 }
3573 }
3574 return rc;
3575fail_set_buffers:
3576 kfree(binfo);
3577fail_kzalloc:
3578 msm_comm_smem_free(inst, handle);
3579err_no_mem:
3580 return rc;
3581}
3582
3583static inline char *get_buffer_name(enum hal_buffer buffer_type)
3584{
3585 switch (buffer_type) {
3586 case HAL_BUFFER_INPUT: return "input";
3587 case HAL_BUFFER_OUTPUT: return "output";
3588 case HAL_BUFFER_OUTPUT2: return "output_2";
3589 case HAL_BUFFER_EXTRADATA_INPUT: return "input_extra";
3590 case HAL_BUFFER_EXTRADATA_OUTPUT: return "output_extra";
3591 case HAL_BUFFER_EXTRADATA_OUTPUT2: return "output2_extra";
3592 case HAL_BUFFER_INTERNAL_SCRATCH: return "scratch";
3593 case HAL_BUFFER_INTERNAL_SCRATCH_1: return "scratch_1";
3594 case HAL_BUFFER_INTERNAL_SCRATCH_2: return "scratch_2";
3595 case HAL_BUFFER_INTERNAL_PERSIST: return "persist";
3596 case HAL_BUFFER_INTERNAL_PERSIST_1: return "persist_1";
3597 case HAL_BUFFER_INTERNAL_CMD_QUEUE: return "queue";
3598 default: return "????";
3599 }
3600}
3601
3602static int set_internal_buf_on_fw(struct msm_vidc_inst *inst,
3603 enum hal_buffer buffer_type,
3604 struct msm_smem *handle, bool reuse)
3605{
3606 struct vidc_buffer_addr_info buffer_info;
3607 struct hfi_device *hdev;
3608 int rc = 0;
3609
3610 if (!inst || !inst->core || !inst->core->device || !handle) {
3611 dprintk(VIDC_ERR, "%s - invalid params\n", __func__);
3612 return -EINVAL;
3613 }
3614
3615 hdev = inst->core->device;
3616
3617 rc = msm_comm_smem_cache_operations(inst,
3618 handle, SMEM_CACHE_CLEAN);
3619 if (rc) {
3620 dprintk(VIDC_WARN,
3621 "Failed to clean cache. Undefined behavior\n");
3622 }
3623
3624 buffer_info.buffer_size = handle->size;
3625 buffer_info.buffer_type = buffer_type;
3626 buffer_info.num_buffers = 1;
3627 buffer_info.align_device_addr = handle->device_addr;
3628 dprintk(VIDC_DBG, "%s %s buffer : %pa\n",
3629 reuse ? "Reusing" : "Allocated",
3630 get_buffer_name(buffer_type),
3631 &buffer_info.align_device_addr);
3632
3633 rc = call_hfi_op(hdev, session_set_buffers,
3634 (void *) inst->session, &buffer_info);
3635 if (rc) {
3636 dprintk(VIDC_ERR,
3637 "vidc_hal_session_set_buffers failed\n");
3638 return rc;
3639 }
3640 return 0;
3641}
3642
3643static bool reuse_internal_buffers(struct msm_vidc_inst *inst,
3644 enum hal_buffer buffer_type, struct msm_vidc_list *buf_list)
3645{
3646 struct internal_buf *buf;
3647 int rc = 0;
3648 bool reused = false;
3649
3650 if (!inst || !buf_list) {
3651 dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
3652 return false;
3653 }
3654
3655 mutex_lock(&buf_list->lock);
3656 list_for_each_entry(buf, &buf_list->list, list) {
3657 if (!buf->handle) {
3658 reused = false;
3659 break;
3660 }
3661
3662 if (buf->buffer_type != buffer_type)
3663 continue;
3664
3665 /*
3666 * Persist buffer size won't change with resolution. If they
3667 * are in queue means that they are already allocated and
3668 * given to HW. HW can use them without reallocation. These
3669 * buffers are not released as part of port reconfig. So
3670 * driver no need to set them again.
3671 */
3672
3673 if (buffer_type != HAL_BUFFER_INTERNAL_PERSIST
3674 && buffer_type != HAL_BUFFER_INTERNAL_PERSIST_1) {
3675
3676 rc = set_internal_buf_on_fw(inst, buffer_type,
3677 buf->handle, true);
3678 if (rc) {
3679 dprintk(VIDC_ERR,
3680 "%s: session_set_buffers failed\n",
3681 __func__);
3682 reused = false;
3683 break;
3684 }
3685 }
3686 reused = true;
3687 dprintk(VIDC_DBG,
3688 "Re-using internal buffer type : %d\n", buffer_type);
3689 }
3690 mutex_unlock(&buf_list->lock);
3691 return reused;
3692}
3693
3694static int allocate_and_set_internal_bufs(struct msm_vidc_inst *inst,
3695 struct hal_buffer_requirements *internal_bufreq,
3696 struct msm_vidc_list *buf_list)
3697{
3698 struct msm_smem *handle;
3699 struct internal_buf *binfo;
3700 u32 smem_flags = 0;
3701 int rc = 0;
3702 int i = 0;
3703
3704 if (!inst || !internal_bufreq || !buf_list)
3705 return -EINVAL;
3706
3707 if (!internal_bufreq->buffer_size)
3708 return 0;
3709
3710 if (inst->flags & VIDC_SECURE)
3711 smem_flags |= SMEM_SECURE;
3712
3713 for (i = 0; i < internal_bufreq->buffer_count_actual; i++) {
3714 handle = msm_comm_smem_alloc(inst, internal_bufreq->buffer_size,
3715 1, smem_flags, internal_bufreq->buffer_type, 0);
3716 if (!handle) {
3717 dprintk(VIDC_ERR,
3718 "Failed to allocate scratch memory\n");
3719 rc = -ENOMEM;
3720 goto err_no_mem;
3721 }
3722
3723 binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
3724 if (!binfo) {
3725 dprintk(VIDC_ERR, "Out of memory\n");
3726 rc = -ENOMEM;
3727 goto fail_kzalloc;
3728 }
3729
3730 binfo->handle = handle;
3731 binfo->buffer_type = internal_bufreq->buffer_type;
3732
3733 rc = set_internal_buf_on_fw(inst, internal_bufreq->buffer_type,
3734 handle, false);
3735 if (rc)
3736 goto fail_set_buffers;
3737
3738 mutex_lock(&buf_list->lock);
3739 list_add_tail(&binfo->list, &buf_list->list);
3740 mutex_unlock(&buf_list->lock);
3741 }
3742 return rc;
3743
3744fail_set_buffers:
3745 kfree(binfo);
3746fail_kzalloc:
3747 msm_comm_smem_free(inst, handle);
3748err_no_mem:
3749 return rc;
3750
3751}
3752
3753static int set_internal_buffers(struct msm_vidc_inst *inst,
3754 enum hal_buffer buffer_type, struct msm_vidc_list *buf_list)
3755{
3756 struct hal_buffer_requirements *internal_buf;
3757
3758 internal_buf = get_buff_req_buffer(inst, buffer_type);
3759 if (!internal_buf) {
3760 dprintk(VIDC_DBG,
3761 "This internal buffer not required, buffer_type: %x\n",
3762 buffer_type);
3763 return 0;
3764 }
3765
3766 dprintk(VIDC_DBG, "Buffer type %s: num = %d, size = %d\n",
3767 get_buffer_name(buffer_type),
3768 internal_buf->buffer_count_actual, internal_buf->buffer_size);
3769
3770 /*
3771 * Try reusing existing internal buffers first.
3772 * If it's not possible to reuse, allocate new buffers.
3773 */
3774 if (reuse_internal_buffers(inst, buffer_type, buf_list))
3775 return 0;
3776
3777 return allocate_and_set_internal_bufs(inst, internal_buf,
3778 buf_list);
3779}
3780
3781int msm_comm_try_state(struct msm_vidc_inst *inst, int state)
3782{
3783 int rc = 0;
3784 int flipped_state;
3785 struct msm_vidc_core *core;
3786
3787 if (!inst) {
3788 dprintk(VIDC_ERR,
3789 "Invalid instance pointer = %pK\n", inst);
3790 return -EINVAL;
3791 }
3792 dprintk(VIDC_DBG,
3793 "Trying to move inst: %pK from: %#x to %#x\n",
3794 inst, inst->state, state);
3795 core = inst->core;
3796 if (!core) {
3797 dprintk(VIDC_ERR,
3798 "Invalid core pointer = %pK\n", inst);
3799 return -EINVAL;
3800 }
3801 mutex_lock(&inst->sync_lock);
3802 if (inst->state == MSM_VIDC_CORE_INVALID ||
3803 core->state == VIDC_CORE_INVALID) {
3804 dprintk(VIDC_ERR,
3805 "Core is in bad state can't change the state\n");
3806 rc = -EINVAL;
3807 goto exit;
3808 }
3809 flipped_state = get_flipped_state(inst->state, state);
3810 dprintk(VIDC_DBG,
3811 "flipped_state = %#x\n", flipped_state);
3812 switch (flipped_state) {
3813 case MSM_VIDC_CORE_UNINIT_DONE:
3814 case MSM_VIDC_CORE_INIT:
3815 rc = msm_comm_init_core(inst);
3816 if (rc || state <= get_flipped_state(inst->state, state))
3817 break;
3818 case MSM_VIDC_CORE_INIT_DONE:
3819 rc = msm_comm_init_core_done(inst);
3820 if (rc || state <= get_flipped_state(inst->state, state))
3821 break;
3822 case MSM_VIDC_OPEN:
3823 rc = msm_comm_session_init(flipped_state, inst);
3824 if (rc || state <= get_flipped_state(inst->state, state))
3825 break;
3826 case MSM_VIDC_OPEN_DONE:
3827 rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE,
3828 HAL_SESSION_INIT_DONE);
3829 if (rc || state <= get_flipped_state(inst->state, state))
3830 break;
3831 case MSM_VIDC_LOAD_RESOURCES:
3832 rc = msm_vidc_load_resources(flipped_state, inst);
3833 if (rc || state <= get_flipped_state(inst->state, state))
3834 break;
3835 case MSM_VIDC_LOAD_RESOURCES_DONE:
3836 case MSM_VIDC_START:
3837 rc = msm_vidc_start(flipped_state, inst);
3838 if (rc || state <= get_flipped_state(inst->state, state))
3839 break;
3840 case MSM_VIDC_START_DONE:
3841 rc = wait_for_state(inst, flipped_state, MSM_VIDC_START_DONE,
3842 HAL_SESSION_START_DONE);
3843 if (rc || state <= get_flipped_state(inst->state, state))
3844 break;
3845 case MSM_VIDC_STOP:
3846 rc = msm_vidc_stop(flipped_state, inst);
3847 if (rc || state <= get_flipped_state(inst->state, state))
3848 break;
3849 case MSM_VIDC_STOP_DONE:
3850 rc = wait_for_state(inst, flipped_state, MSM_VIDC_STOP_DONE,
3851 HAL_SESSION_STOP_DONE);
3852 if (rc || state <= get_flipped_state(inst->state, state))
3853 break;
3854 dprintk(VIDC_DBG, "Moving to Stop Done state\n");
3855 case MSM_VIDC_RELEASE_RESOURCES:
3856 rc = msm_vidc_release_res(flipped_state, inst);
3857 if (rc || state <= get_flipped_state(inst->state, state))
3858 break;
3859 case MSM_VIDC_RELEASE_RESOURCES_DONE:
3860 rc = wait_for_state(inst, flipped_state,
3861 MSM_VIDC_RELEASE_RESOURCES_DONE,
3862 HAL_SESSION_RELEASE_RESOURCE_DONE);
3863 if (rc || state <= get_flipped_state(inst->state, state))
3864 break;
3865 dprintk(VIDC_DBG,
3866 "Moving to release resources done state\n");
3867 case MSM_VIDC_CLOSE:
3868 rc = msm_comm_session_close(flipped_state, inst);
3869 if (rc || state <= get_flipped_state(inst->state, state))
3870 break;
3871 case MSM_VIDC_CLOSE_DONE:
3872 rc = wait_for_state(inst, flipped_state, MSM_VIDC_CLOSE_DONE,
3873 HAL_SESSION_END_DONE);
3874 if (rc || state <= get_flipped_state(inst->state, state))
3875 break;
3876 msm_comm_session_clean(inst);
3877 case MSM_VIDC_CORE_UNINIT:
3878 case MSM_VIDC_CORE_INVALID:
3879 dprintk(VIDC_DBG, "Sending core uninit\n");
3880 rc = msm_vidc_deinit_core(inst);
3881 if (rc || state == get_flipped_state(inst->state, state))
3882 break;
3883 default:
3884 dprintk(VIDC_ERR, "State not recognized\n");
3885 rc = -EINVAL;
3886 break;
3887 }
3888exit:
3889 mutex_unlock(&inst->sync_lock);
3890 if (rc)
3891 dprintk(VIDC_ERR,
3892 "Failed to move from state: %d to %d\n",
3893 inst->state, state);
3894 else
3895 trace_msm_vidc_common_state_change((void *)inst,
3896 inst->state, state);
3897 return rc;
3898}
3899
3900int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd)
3901{
3902 struct msm_vidc_inst *inst = instance;
3903 struct v4l2_decoder_cmd *dec = NULL;
3904 struct v4l2_encoder_cmd *enc = NULL;
3905 struct msm_vidc_core *core;
3906 int which_cmd = 0, flags = 0, rc = 0;
3907
3908 if (!inst || !inst->core || !cmd) {
3909 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
3910 return -EINVAL;
3911 }
3912 core = inst->core;
3913 if (inst->session_type == MSM_VIDC_ENCODER) {
3914 enc = (struct v4l2_encoder_cmd *)cmd;
3915 which_cmd = enc->cmd;
3916 flags = enc->flags;
3917 } else if (inst->session_type == MSM_VIDC_DECODER) {
3918 dec = (struct v4l2_decoder_cmd *)cmd;
3919 which_cmd = dec->cmd;
3920 flags = dec->flags;
3921 }
3922
3923
3924 switch (which_cmd) {
3925 case V4L2_QCOM_CMD_FLUSH:
3926 if (core->state != VIDC_CORE_INVALID &&
3927 inst->state == MSM_VIDC_CORE_INVALID) {
3928 rc = msm_comm_kill_session(inst);
3929 if (rc)
3930 dprintk(VIDC_ERR,
3931 "Fail to clean session: %d\n",
3932 rc);
3933 }
3934 rc = msm_comm_flush(inst, flags);
3935 if (rc) {
3936 dprintk(VIDC_ERR,
3937 "Failed to flush buffers: %d\n", rc);
3938 }
3939 break;
3940 case V4L2_DEC_QCOM_CMD_RECONFIG_HINT:
3941 {
3942 u32 *ptr = NULL;
3943 struct hal_buffer_requirements *output_buf;
3944
3945 rc = msm_comm_try_get_bufreqs(inst);
3946 if (rc) {
3947 dprintk(VIDC_ERR,
3948 "Getting buffer requirements failed: %d\n",
3949 rc);
3950 break;
3951 }
3952
3953 output_buf = get_buff_req_buffer(inst,
3954 msm_comm_get_hal_output_buffer(inst));
3955 if (output_buf) {
3956 if (dec) {
3957 ptr = (u32 *)dec->raw.data;
3958 ptr[0] = output_buf->buffer_size;
3959 ptr[1] = output_buf->buffer_count_actual;
3960 dprintk(VIDC_DBG,
3961 "Reconfig hint, size is %u, count is %u\n",
3962 ptr[0], ptr[1]);
3963 } else {
3964 dprintk(VIDC_ERR, "Null decoder\n");
3965 }
3966 } else {
3967 dprintk(VIDC_DBG,
3968 "This output buffer not required, buffer_type: %x\n",
3969 HAL_BUFFER_OUTPUT);
3970 }
3971 break;
3972 }
3973 default:
3974 dprintk(VIDC_ERR, "Unknown Command %d\n", which_cmd);
3975 rc = -ENOTSUPP;
3976 break;
3977 }
3978 return rc;
3979}
3980
3981static void populate_frame_data(struct vidc_frame_data *data,
3982 const struct vb2_buffer *vb, struct msm_vidc_inst *inst)
3983{
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003984 int extra_idx;
3985 enum v4l2_buf_type type = vb->type;
3986 enum vidc_ports port = type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
3987 OUTPUT_PORT : CAPTURE_PORT;
3988 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
3989
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003990 data->alloc_len = vb->planes[0].length;
3991 data->device_addr = vb->planes[0].m.userptr;
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08003992 data->timestamp = vb->timestamp;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003993 data->flags = 0;
3994 data->clnt_data = data->device_addr;
3995
3996 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
3997 bool pic_decoding_mode = msm_comm_g_ctrl_for_id(inst,
3998 V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE);
3999
4000 data->buffer_type = HAL_BUFFER_INPUT;
4001 data->filled_len = vb->planes[0].bytesused;
4002 data->offset = vb->planes[0].data_offset;
4003
4004 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_EOS)
4005 data->flags |= HAL_BUFFERFLAG_EOS;
4006
4007 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
4008 data->flags |= HAL_BUFFERFLAG_CODECCONFIG;
4009
4010 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY)
4011 data->flags |= HAL_BUFFERFLAG_DECODEONLY;
4012
4013 if (vbuf->flags & V4L2_QCOM_BUF_TIMESTAMP_INVALID)
4014 data->timestamp = LLONG_MAX;
4015
4016 /* XXX: This is a dirty hack necessitated by the firmware,
4017 * which refuses to issue FBDs for non I-frames in Picture Type
4018 * Decoding mode, unless we pass in non-zero value in mark_data
4019 * and mark_target.
4020 */
4021 data->mark_data = data->mark_target =
4022 pic_decoding_mode ? 0xdeadbeef : 0;
4023
4024 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
4025 data->buffer_type = msm_comm_get_hal_output_buffer(inst);
4026 }
4027
4028 extra_idx = EXTRADATA_IDX(inst->fmts[port].num_planes);
4029 if (extra_idx && extra_idx < VIDEO_MAX_PLANES &&
4030 vb->planes[extra_idx].m.userptr) {
4031 data->extradata_addr = vb->planes[extra_idx].m.userptr;
4032 data->extradata_size = vb->planes[extra_idx].length;
4033 data->flags |= HAL_BUFFERFLAG_EXTRADATA;
4034 }
4035}
4036
4037static unsigned int count_single_batch(struct msm_vidc_list *list,
4038 enum v4l2_buf_type type)
4039{
4040 struct vb2_buf_entry *buf;
4041 int count = 0;
4042 struct vb2_v4l2_buffer *vbuf = NULL;
4043
4044 mutex_lock(&list->lock);
4045 list_for_each_entry(buf, &list->list, list) {
4046 if (buf->vb->type != type)
4047 continue;
4048
4049 ++count;
4050
4051 vbuf = to_vb2_v4l2_buffer(buf->vb);
4052 if (!(vbuf->flags & V4L2_MSM_BUF_FLAG_DEFER))
4053 goto found_batch;
4054 }
4055 /* don't have a full batch */
4056 count = 0;
4057
4058found_batch:
4059 mutex_unlock(&list->lock);
4060 return count;
4061}
4062
4063static unsigned int count_buffers(struct msm_vidc_list *list,
4064 enum v4l2_buf_type type)
4065{
4066 struct vb2_buf_entry *buf;
4067 int count = 0;
4068
4069 mutex_lock(&list->lock);
4070 list_for_each_entry(buf, &list->list, list) {
4071 if (buf->vb->type != type)
4072 continue;
4073
4074 ++count;
4075 }
4076 mutex_unlock(&list->lock);
4077
4078 return count;
4079}
4080
4081static void log_frame(struct msm_vidc_inst *inst, struct vidc_frame_data *data,
4082 enum v4l2_buf_type type)
4083{
4084 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
4085 dprintk(VIDC_DBG,
4086 "Sending etb (%pa) to hal: filled: %d, ts: %lld, flags = %#x\n",
4087 &data->device_addr, data->filled_len,
4088 data->timestamp, data->flags);
4089 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_ETB);
4090
4091 if (msm_vidc_bitrate_clock_scaling &&
4092 inst->session_type == MSM_VIDC_DECODER &&
4093 !inst->dcvs_mode)
4094 inst->instant_bitrate =
4095 data->filled_len * 8 * inst->prop.fps;
4096 else
4097 inst->instant_bitrate = 0;
4098 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
4099 dprintk(VIDC_DBG,
4100 "Sending ftb (%pa) to hal: size: %d, ts: %lld, flags = %#x\n",
4101 &data->device_addr, data->alloc_len,
4102 data->timestamp, data->flags);
4103 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FTB);
4104 }
4105
4106 msm_dcvs_check_and_scale_clocks(inst,
4107 type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
4108
4109 if (msm_vidc_bitrate_clock_scaling && !inst->dcvs_mode &&
4110 type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
4111 inst->session_type == MSM_VIDC_DECODER)
4112 if (msm_comm_scale_clocks(inst->core))
4113 dprintk(VIDC_WARN,
4114 "Failed to scale clocks. Performance might be impacted\n");
4115
4116 if (msm_comm_vote_bus(inst->core))
4117 dprintk(VIDC_WARN,
4118 "Failed to scale bus. Performance might be impacted\n");
4119}
4120
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004121/*
4122 * Attempts to queue `vb` to hardware. If, for various reasons, the buffer
4123 * cannot be queued to hardware, the buffer will be staged for commit in the
4124 * pending queue. Once the hardware reaches a good state (or if `vb` is NULL,
4125 * the subsequent *_qbuf will commit the previously staged buffers to hardware.
4126 */
4127int msm_comm_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb)
4128{
4129 int rc = 0, capture_count, output_count;
4130 struct msm_vidc_core *core;
4131 struct hfi_device *hdev;
4132 struct {
4133 struct vidc_frame_data *data;
4134 int count;
4135 } etbs, ftbs;
4136 bool defer = false, batch_mode;
4137 struct vb2_buf_entry *temp, *next;
4138 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
4139
4140 if (!inst) {
4141 dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__);
4142 return -EINVAL;
4143 }
4144
4145 core = inst->core;
4146 hdev = core->device;
4147
4148 if (inst->state == MSM_VIDC_CORE_INVALID ||
4149 core->state == VIDC_CORE_INVALID ||
4150 core->state == VIDC_CORE_UNINIT) {
4151 dprintk(VIDC_ERR, "Core is in bad state. Can't Queue\n");
4152 return -EINVAL;
4153 }
4154
4155 /*
4156 * Stick the buffer into the pendinq, we'll pop it out later on
4157 * if we want to commit it to hardware
4158 */
4159 if (vb) {
4160 temp = kzalloc(sizeof(*temp), GFP_KERNEL);
4161 if (!temp) {
4162 dprintk(VIDC_ERR, "Out of memory\n");
4163 goto err_no_mem;
4164 }
4165
4166 temp->vb = vb;
4167 mutex_lock(&inst->pendingq.lock);
4168 list_add_tail(&temp->list, &inst->pendingq.list);
4169 mutex_unlock(&inst->pendingq.lock);
4170 }
4171
4172 batch_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_VIDC_QBUF_MODE)
4173 == V4L2_VIDC_QBUF_BATCHED;
4174 capture_count = (batch_mode ? &count_single_batch : &count_buffers)
4175 (&inst->pendingq, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
4176 output_count = (batch_mode ? &count_single_batch : &count_buffers)
4177 (&inst->pendingq, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
4178
4179 /*
4180 * Somewhat complicated logic to prevent queuing the buffer to hardware.
4181 * Don't queue if:
4182 * 1) Hardware isn't ready (that's simple)
4183 */
4184 defer = defer ?: inst->state != MSM_VIDC_START_DONE;
4185
4186 /*
4187 * 2) The client explicitly tells us not to because it wants this
4188 * buffer to be batched with future frames. The batch size (on both
4189 * capabilities) is completely determined by the client.
4190 */
4191 defer = defer ?: vbuf && vbuf->flags & V4L2_MSM_BUF_FLAG_DEFER;
4192
4193 /* 3) If we're in batch mode, we must have full batches of both types */
4194 defer = defer ?: batch_mode && (!output_count || !capture_count);
4195
4196 if (defer) {
4197 dprintk(VIDC_DBG, "Deferring queue of %pK\n", vb);
4198 return 0;
4199 }
4200
4201 dprintk(VIDC_DBG, "%sing %d etbs and %d ftbs\n",
4202 batch_mode ? "Batch" : "Process",
4203 output_count, capture_count);
4204
4205 etbs.data = kcalloc(output_count, sizeof(*etbs.data), GFP_KERNEL);
4206 ftbs.data = kcalloc(capture_count, sizeof(*ftbs.data), GFP_KERNEL);
4207 /*
4208 * Note that it's perfectly normal for (e|f)tbs.data to be NULL if
4209 * we're not in batch mode (i.e. (output|capture)_count == 0)
4210 */
4211 if ((!etbs.data && output_count) ||
4212 (!ftbs.data && capture_count)) {
4213 dprintk(VIDC_ERR, "Failed to alloc memory for batching\n");
4214 kfree(etbs.data);
4215 etbs.data = NULL;
4216
4217 kfree(ftbs.data);
4218 ftbs.data = NULL;
4219 goto err_no_mem;
4220 }
4221
4222 etbs.count = ftbs.count = 0;
4223
4224 /*
4225 * Try to collect all pending buffers into 2 batches of ftb and etb
4226 * Note that these "batches" might be empty if we're no in batching mode
4227 * and the pendingq is empty
4228 */
4229 mutex_lock(&inst->pendingq.lock);
4230 list_for_each_entry_safe(temp, next, &inst->pendingq.list, list) {
4231 struct vidc_frame_data *frame_data = NULL;
4232
4233 switch (temp->vb->type) {
4234 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
4235 if (ftbs.count < capture_count && ftbs.data)
4236 frame_data = &ftbs.data[ftbs.count++];
4237 break;
4238 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
4239 if (etbs.count < output_count && etbs.data)
4240 frame_data = &etbs.data[etbs.count++];
4241 break;
4242 default:
4243 break;
4244 }
4245
4246 if (!frame_data)
4247 continue;
4248
4249 populate_frame_data(frame_data, temp->vb, inst);
4250
4251 list_del(&temp->list);
4252 kfree(temp);
4253 }
4254 mutex_unlock(&inst->pendingq.lock);
4255
4256 /* Finally commit all our frame(s) to H/W */
4257 if (batch_mode) {
4258 int ftb_index = 0, c = 0;
4259
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004260 ftb_index = c;
4261 rc = call_hfi_op(hdev, session_process_batch, inst->session,
4262 etbs.count, etbs.data,
4263 ftbs.count - ftb_index, &ftbs.data[ftb_index]);
4264 if (rc) {
4265 dprintk(VIDC_ERR,
4266 "Failed to queue batch of %d ETBs and %d FTBs\n",
4267 etbs.count, ftbs.count);
4268 goto err_bad_input;
4269 }
4270
4271 for (c = ftb_index; c < ftbs.count; ++c) {
4272 log_frame(inst, &ftbs.data[c],
4273 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
4274 }
4275
4276 for (c = 0; c < etbs.count; ++c) {
4277 log_frame(inst, &etbs.data[c],
4278 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
4279 }
4280 }
4281
4282 if (!batch_mode && etbs.count) {
4283 int c = 0;
4284
4285 for (c = 0; c < etbs.count; ++c) {
4286 struct vidc_frame_data *frame_data = &etbs.data[c];
4287
4288 rc = call_hfi_op(hdev, session_etb, inst->session,
4289 frame_data);
4290 if (rc) {
4291 dprintk(VIDC_ERR, "Failed to issue etb: %d\n",
4292 rc);
4293 goto err_bad_input;
4294 }
4295
4296 log_frame(inst, frame_data,
4297 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
4298 }
4299 }
4300
4301 if (!batch_mode && ftbs.count) {
4302 int c = 0;
4303
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004304 for (; c < ftbs.count; ++c) {
4305 struct vidc_frame_data *frame_data = &ftbs.data[c];
4306
4307 rc = call_hfi_op(hdev, session_ftb,
4308 inst->session, frame_data);
4309 if (rc) {
4310 dprintk(VIDC_ERR, "Failed to issue ftb: %d\n",
4311 rc);
4312 goto err_bad_input;
4313 }
4314
4315 log_frame(inst, frame_data,
4316 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
4317 }
4318 }
4319
4320err_bad_input:
4321 if (rc)
4322 dprintk(VIDC_ERR, "Failed to queue buffer\n");
4323
4324 kfree(etbs.data);
4325 kfree(ftbs.data);
4326err_no_mem:
4327 return rc;
4328}
4329
4330int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst)
4331{
4332 int rc = 0, i = 0;
4333 union hal_get_property hprop;
4334
4335 rc = msm_comm_try_get_prop(inst, HAL_PARAM_GET_BUFFER_REQUIREMENTS,
4336 &hprop);
4337 if (rc) {
4338 dprintk(VIDC_ERR, "Failed getting buffer requirements: %d", rc);
4339 return rc;
4340 }
4341
4342 dprintk(VIDC_DBG, "Buffer requirements:\n");
4343 dprintk(VIDC_DBG, "%15s %8s %8s\n", "buffer type", "count", "size");
4344 for (i = 0; i < HAL_BUFFER_MAX; i++) {
4345 struct hal_buffer_requirements req = hprop.buf_req.buffer[i];
4346
4347 inst->buff_req.buffer[i] = req;
4348 dprintk(VIDC_DBG, "%15s %8d %8d\n",
4349 get_buffer_name(req.buffer_type),
4350 req.buffer_count_actual, req.buffer_size);
4351 }
4352
4353 dprintk(VIDC_PROF, "Input buffers: %d, Output buffers: %d\n",
4354 inst->buff_req.buffer[0].buffer_count_actual,
4355 inst->buff_req.buffer[1].buffer_count_actual);
4356 return rc;
4357}
4358
4359int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
4360 union hal_get_property *hprop)
4361{
4362 int rc = 0;
4363 struct hfi_device *hdev;
4364 struct getprop_buf *buf;
4365
4366 if (!inst || !inst->core || !inst->core->device) {
4367 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4368 return -EINVAL;
4369 }
4370
4371 hdev = inst->core->device;
4372 mutex_lock(&inst->sync_lock);
4373 if (inst->state < MSM_VIDC_OPEN_DONE ||
4374 inst->state >= MSM_VIDC_CLOSE) {
4375
4376 /* No need to check inst->state == MSM_VIDC_INVALID since
4377 * INVALID is > CLOSE_DONE. When core went to INVALID state,
4378 * we put all the active instances in INVALID. So > CLOSE_DONE
4379 * is enough check to have.
4380 */
4381
4382 dprintk(VIDC_ERR,
4383 "In Wrong state to call Buf Req: Inst %pK or Core %pK\n",
4384 inst, inst->core);
4385 rc = -EAGAIN;
4386 mutex_unlock(&inst->sync_lock);
4387 goto exit;
4388 }
4389 mutex_unlock(&inst->sync_lock);
4390
4391 switch (ptype) {
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004392 case HAL_PARAM_GET_BUFFER_REQUIREMENTS:
4393 rc = call_hfi_op(hdev, session_get_buf_req, inst->session);
4394 break;
4395 default:
4396 rc = -EAGAIN;
4397 break;
4398 }
4399
4400 if (rc) {
4401 dprintk(VIDC_ERR, "Can't query hardware for property: %d\n",
4402 rc);
4403 goto exit;
4404 }
4405
4406 rc = wait_for_completion_timeout(&inst->completions[
4407 SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO)],
4408 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
4409 if (!rc) {
4410 dprintk(VIDC_ERR,
4411 "%s: Wait interrupted or timed out [%pK]: %d\n",
4412 __func__, inst,
4413 SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO));
4414 inst->state = MSM_VIDC_CORE_INVALID;
4415 msm_comm_kill_session(inst);
4416 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
4417 dprintk(VIDC_ERR,
4418 "SESS_PROP timeout can potentially crash the system\n");
4419 if (inst->core->resources.debug_timeout)
4420 msm_comm_print_debug_info(inst);
4421
4422 msm_vidc_handle_hw_error(inst->core);
4423 rc = -ETIMEDOUT;
4424 goto exit;
4425 } else {
4426 /* wait_for_completion_timeout returns jiffies before expiry */
4427 rc = 0;
4428 }
4429
4430 mutex_lock(&inst->pending_getpropq.lock);
4431 if (!list_empty(&inst->pending_getpropq.list)) {
4432 buf = list_first_entry(&inst->pending_getpropq.list,
4433 struct getprop_buf, list);
4434 *hprop = *(union hal_get_property *)buf->data;
4435 kfree(buf->data);
4436 list_del(&buf->list);
4437 kfree(buf);
4438 } else {
4439 dprintk(VIDC_ERR, "%s getprop list empty\n", __func__);
4440 rc = -EINVAL;
4441 }
4442 mutex_unlock(&inst->pending_getpropq.lock);
4443exit:
4444 return rc;
4445}
4446
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004447int msm_comm_release_output_buffers(struct msm_vidc_inst *inst,
4448 bool force_release)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004449{
4450 struct msm_smem *handle;
4451 struct internal_buf *buf, *dummy;
4452 struct vidc_buffer_addr_info buffer_info;
4453 int rc = 0;
4454 struct msm_vidc_core *core;
4455 struct hfi_device *hdev;
4456
4457 if (!inst) {
4458 dprintk(VIDC_ERR,
4459 "Invalid instance pointer = %pK\n", inst);
4460 return -EINVAL;
4461 }
4462 mutex_lock(&inst->outputbufs.lock);
4463 if (list_empty(&inst->outputbufs.list)) {
4464 dprintk(VIDC_DBG, "%s - No OUTPUT buffers allocated\n",
4465 __func__);
4466 mutex_unlock(&inst->outputbufs.lock);
4467 return 0;
4468 }
4469 mutex_unlock(&inst->outputbufs.lock);
4470
4471 core = inst->core;
4472 if (!core) {
4473 dprintk(VIDC_ERR,
4474 "Invalid core pointer = %pK\n", core);
4475 return -EINVAL;
4476 }
4477 hdev = core->device;
4478 if (!hdev) {
4479 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4480 return -EINVAL;
4481 }
4482 mutex_lock(&inst->outputbufs.lock);
4483 list_for_each_entry_safe(buf, dummy, &inst->outputbufs.list, list) {
4484 handle = buf->handle;
4485 if (!handle) {
4486 dprintk(VIDC_ERR, "%s - invalid handle\n", __func__);
4487 goto exit;
4488 }
4489
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004490 if ((buf->buffer_ownership == FIRMWARE) && !force_release) {
4491 dprintk(VIDC_INFO, "DPB is with f/w. Can't free it\n");
4492 continue;
4493 }
4494
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004495 buffer_info.buffer_size = handle->size;
4496 buffer_info.buffer_type = buf->buffer_type;
4497 buffer_info.num_buffers = 1;
4498 buffer_info.align_device_addr = handle->device_addr;
4499 if (inst->buffer_mode_set[CAPTURE_PORT] ==
4500 HAL_BUFFER_MODE_STATIC &&
4501 inst->state != MSM_VIDC_CORE_INVALID &&
4502 core->state != VIDC_CORE_INVALID) {
4503 buffer_info.response_required = false;
4504 rc = call_hfi_op(hdev, session_release_buffers,
4505 (void *)inst->session, &buffer_info);
4506 if (rc) {
4507 dprintk(VIDC_WARN,
4508 "Rel output buf fail:%pa, %d\n",
4509 &buffer_info.align_device_addr,
4510 buffer_info.buffer_size);
4511 }
4512 }
4513
4514 list_del(&buf->list);
4515 msm_comm_smem_free(inst, buf->handle);
4516 kfree(buf);
4517 }
4518
4519exit:
4520 mutex_unlock(&inst->outputbufs.lock);
4521 return rc;
4522}
4523
4524static enum hal_buffer scratch_buf_sufficient(struct msm_vidc_inst *inst,
4525 enum hal_buffer buffer_type)
4526{
4527 struct hal_buffer_requirements *bufreq = NULL;
4528 struct internal_buf *buf;
4529 int count = 0;
4530
4531 if (!inst) {
4532 dprintk(VIDC_ERR, "%s - invalid param\n", __func__);
4533 goto not_sufficient;
4534 }
4535
4536 bufreq = get_buff_req_buffer(inst, buffer_type);
4537 if (!bufreq)
4538 goto not_sufficient;
4539
4540 /* Check if current scratch buffers are sufficient */
4541 mutex_lock(&inst->scratchbufs.lock);
4542
4543 list_for_each_entry(buf, &inst->scratchbufs.list, list) {
4544 if (!buf->handle) {
4545 dprintk(VIDC_ERR, "%s: invalid buf handle\n", __func__);
4546 mutex_unlock(&inst->scratchbufs.lock);
4547 goto not_sufficient;
4548 }
4549 if (buf->buffer_type == buffer_type &&
4550 buf->handle->size >= bufreq->buffer_size)
4551 count++;
4552 }
4553 mutex_unlock(&inst->scratchbufs.lock);
4554
4555 if (count != bufreq->buffer_count_actual)
4556 goto not_sufficient;
4557
4558 dprintk(VIDC_DBG,
4559 "Existing scratch buffer is sufficient for buffer type %#x\n",
4560 buffer_type);
4561
4562 return buffer_type;
4563
4564not_sufficient:
4565 return HAL_BUFFER_NONE;
4566}
4567
4568int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst,
4569 bool check_for_reuse)
4570{
4571 struct msm_smem *handle;
4572 struct internal_buf *buf, *dummy;
4573 struct vidc_buffer_addr_info buffer_info;
4574 int rc = 0;
4575 struct msm_vidc_core *core;
4576 struct hfi_device *hdev;
4577 enum hal_buffer sufficiency = HAL_BUFFER_NONE;
4578
4579 if (!inst) {
4580 dprintk(VIDC_ERR,
4581 "Invalid instance pointer = %pK\n", inst);
4582 return -EINVAL;
4583 }
4584 core = inst->core;
4585 if (!core) {
4586 dprintk(VIDC_ERR,
4587 "Invalid core pointer = %pK\n", core);
4588 return -EINVAL;
4589 }
4590 hdev = core->device;
4591 if (!hdev) {
4592 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4593 return -EINVAL;
4594 }
4595
4596 if (check_for_reuse) {
4597 sufficiency |= scratch_buf_sufficient(inst,
4598 HAL_BUFFER_INTERNAL_SCRATCH);
4599
4600 sufficiency |= scratch_buf_sufficient(inst,
4601 HAL_BUFFER_INTERNAL_SCRATCH_1);
4602
4603 sufficiency |= scratch_buf_sufficient(inst,
4604 HAL_BUFFER_INTERNAL_SCRATCH_2);
4605 }
4606
4607 mutex_lock(&inst->scratchbufs.lock);
4608 list_for_each_entry_safe(buf, dummy, &inst->scratchbufs.list, list) {
4609 if (!buf->handle) {
4610 dprintk(VIDC_ERR, "%s - buf->handle NULL\n", __func__);
4611 rc = -EINVAL;
4612 goto exit;
4613 }
4614
4615 handle = buf->handle;
4616 buffer_info.buffer_size = handle->size;
4617 buffer_info.buffer_type = buf->buffer_type;
4618 buffer_info.num_buffers = 1;
4619 buffer_info.align_device_addr = handle->device_addr;
4620 if (inst->state != MSM_VIDC_CORE_INVALID &&
4621 core->state != VIDC_CORE_INVALID) {
4622 buffer_info.response_required = true;
4623 rc = call_hfi_op(hdev, session_release_buffers,
4624 (void *)inst->session, &buffer_info);
4625 if (rc) {
4626 dprintk(VIDC_WARN,
4627 "Rel scrtch buf fail:%pa, %d\n",
4628 &buffer_info.align_device_addr,
4629 buffer_info.buffer_size);
4630 }
4631 mutex_unlock(&inst->scratchbufs.lock);
4632 rc = wait_for_sess_signal_receipt(inst,
4633 HAL_SESSION_RELEASE_BUFFER_DONE);
4634 if (rc) {
4635 change_inst_state(inst,
4636 MSM_VIDC_CORE_INVALID);
4637 msm_comm_kill_session(inst);
4638 }
4639 mutex_lock(&inst->scratchbufs.lock);
4640 }
4641
4642 /*If scratch buffers can be reused, do not free the buffers*/
4643 if (sufficiency & buf->buffer_type)
4644 continue;
4645
4646 list_del(&buf->list);
4647 msm_comm_smem_free(inst, buf->handle);
4648 kfree(buf);
4649 }
4650
4651exit:
4652 mutex_unlock(&inst->scratchbufs.lock);
4653 return rc;
4654}
4655
4656int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst)
4657{
4658 struct msm_smem *handle;
4659 struct list_head *ptr, *next;
4660 struct internal_buf *buf;
4661 struct vidc_buffer_addr_info buffer_info;
4662 int rc = 0;
4663 struct msm_vidc_core *core;
4664 struct hfi_device *hdev;
4665
4666 if (!inst) {
4667 dprintk(VIDC_ERR,
4668 "Invalid instance pointer = %pK\n", inst);
4669 return -EINVAL;
4670 }
4671 core = inst->core;
4672 if (!core) {
4673 dprintk(VIDC_ERR,
4674 "Invalid core pointer = %pK\n", core);
4675 return -EINVAL;
4676 }
4677 hdev = core->device;
4678 if (!hdev) {
4679 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4680 return -EINVAL;
4681 }
4682
4683 mutex_lock(&inst->persistbufs.lock);
4684 list_for_each_safe(ptr, next, &inst->persistbufs.list) {
4685 buf = list_entry(ptr, struct internal_buf, list);
4686 handle = buf->handle;
4687 buffer_info.buffer_size = handle->size;
4688 buffer_info.buffer_type = buf->buffer_type;
4689 buffer_info.num_buffers = 1;
4690 buffer_info.align_device_addr = handle->device_addr;
4691 if (inst->state != MSM_VIDC_CORE_INVALID &&
4692 core->state != VIDC_CORE_INVALID) {
4693 buffer_info.response_required = true;
4694 rc = call_hfi_op(hdev, session_release_buffers,
4695 (void *)inst->session, &buffer_info);
4696 if (rc) {
4697 dprintk(VIDC_WARN,
4698 "Rel prst buf fail:%pa, %d\n",
4699 &buffer_info.align_device_addr,
4700 buffer_info.buffer_size);
4701 }
4702 mutex_unlock(&inst->persistbufs.lock);
4703 rc = wait_for_sess_signal_receipt(inst,
4704 HAL_SESSION_RELEASE_BUFFER_DONE);
4705 if (rc) {
4706 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
4707 msm_comm_kill_session(inst);
4708 }
4709 mutex_lock(&inst->persistbufs.lock);
4710 }
4711 list_del(&buf->list);
4712 msm_comm_smem_free(inst, buf->handle);
4713 kfree(buf);
4714 }
4715 mutex_unlock(&inst->persistbufs.lock);
4716 return rc;
4717}
4718
4719int msm_comm_try_set_prop(struct msm_vidc_inst *inst,
4720 enum hal_property ptype, void *pdata)
4721{
4722 int rc = 0;
4723 struct hfi_device *hdev;
4724
4725 if (!inst) {
4726 dprintk(VIDC_ERR, "Invalid input: %pK\n", inst);
4727 return -EINVAL;
4728 }
4729
4730 if (!inst->core || !inst->core->device) {
4731 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4732 return -EINVAL;
4733 }
4734 hdev = inst->core->device;
4735
4736 mutex_lock(&inst->sync_lock);
4737 if (inst->state < MSM_VIDC_OPEN_DONE || inst->state >= MSM_VIDC_CLOSE) {
4738 dprintk(VIDC_ERR, "Not in proper state to set property\n");
4739 rc = -EAGAIN;
4740 goto exit;
4741 }
4742 rc = call_hfi_op(hdev, session_set_property, (void *)inst->session,
4743 ptype, pdata);
4744 if (rc)
4745 dprintk(VIDC_ERR, "Failed to set hal property for framesize\n");
4746exit:
4747 mutex_unlock(&inst->sync_lock);
4748 return rc;
4749}
4750
4751int msm_comm_set_output_buffers(struct msm_vidc_inst *inst)
4752{
4753 int rc = 0;
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004754 bool force_release = true;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004755
4756 if (!inst || !inst->core || !inst->core->device) {
4757 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4758 return -EINVAL;
4759 }
4760
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004761 if (inst->fmts[OUTPUT_PORT].defer_outputs)
4762 force_release = false;
4763
4764 if (msm_comm_release_output_buffers(inst, force_release))
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004765 dprintk(VIDC_WARN, "Failed to release output buffers\n");
4766
4767 rc = set_output_buffers(inst, HAL_BUFFER_OUTPUT);
4768 if (rc)
4769 goto error;
4770 return rc;
4771error:
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004772 msm_comm_release_output_buffers(inst, true);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004773 return rc;
4774}
4775
4776int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst)
4777{
4778 int rc = 0;
4779
4780 if (!inst || !inst->core || !inst->core->device) {
4781 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4782 return -EINVAL;
4783 }
4784
4785 if (msm_comm_release_scratch_buffers(inst, true))
4786 dprintk(VIDC_WARN, "Failed to release scratch buffers\n");
4787
4788 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH,
4789 &inst->scratchbufs);
4790 if (rc)
4791 goto error;
4792
4793 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_1,
4794 &inst->scratchbufs);
4795 if (rc)
4796 goto error;
4797
4798 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_2,
4799 &inst->scratchbufs);
4800 if (rc)
4801 goto error;
4802
4803 return rc;
4804error:
4805 msm_comm_release_scratch_buffers(inst, false);
4806 return rc;
4807}
4808
4809int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst)
4810{
4811 int rc = 0;
4812
4813 if (!inst || !inst->core || !inst->core->device) {
4814 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4815 return -EINVAL;
4816 }
4817
4818 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST,
4819 &inst->persistbufs);
4820 if (rc)
4821 goto error;
4822
4823 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST_1,
4824 &inst->persistbufs);
4825 if (rc)
4826 goto error;
4827 return rc;
4828error:
4829 msm_comm_release_persist_buffers(inst);
4830 return rc;
4831}
4832
4833static void msm_comm_flush_in_invalid_state(struct msm_vidc_inst *inst)
4834{
4835 struct list_head *ptr, *next;
4836 enum vidc_ports ports[] = {OUTPUT_PORT, CAPTURE_PORT};
4837 int c = 0;
4838
4839 for (c = 0; c < ARRAY_SIZE(ports); ++c) {
4840 enum vidc_ports port = ports[c];
4841
4842 dprintk(VIDC_DBG, "Flushing buffers of type %d in bad state\n",
4843 port);
4844 mutex_lock(&inst->bufq[port].lock);
4845 list_for_each_safe(ptr, next, &inst->bufq[port].
4846 vb2_bufq.queued_list) {
4847 struct vb2_buffer *vb = container_of(ptr,
4848 struct vb2_buffer, queued_entry);
4849
4850 vb->planes[0].bytesused = 0;
4851 vb->planes[0].data_offset = 0;
4852
4853 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
4854 }
4855 mutex_unlock(&inst->bufq[port].lock);
4856 }
4857
4858 msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_FLUSH_DONE);
4859}
4860
4861void msm_comm_flush_dynamic_buffers(struct msm_vidc_inst *inst)
4862{
4863 struct buffer_info *binfo = NULL;
4864
4865 if (inst->buffer_mode_set[CAPTURE_PORT] != HAL_BUFFER_MODE_DYNAMIC)
4866 return;
4867
4868 /*
4869 * dynamic buffer mode:- if flush is called during seek
4870 * driver should not queue any new buffer it has been holding.
4871 *
4872 * Each dynamic o/p buffer can have one of following ref_count:
4873 * ref_count : 0 - f/w has released reference and sent fbd back.
4874 * The buffer has been returned back to client.
4875 *
4876 * ref_count : 1 - f/w is holding reference. f/w may have released
4877 * fbd as read_only OR fbd is pending. f/w will
4878 * release reference before sending flush_done.
4879 *
4880 * ref_count : 2 - f/w is holding reference, f/w has released fbd as
4881 * read_only, which client has queued back to driver.
4882 * driver holds this buffer and will queue back
4883 * only when f/w releases the reference. During
4884 * flush_done, f/w will release the reference but driver
4885 * should not queue back the buffer to f/w.
4886 * Flush all buffers with ref_count 2.
4887 */
4888 mutex_lock(&inst->registeredbufs.lock);
4889 if (!list_empty(&inst->registeredbufs.list)) {
4890 struct v4l2_event buf_event = {0};
4891 u32 *ptr = NULL;
4892
4893 list_for_each_entry(binfo, &inst->registeredbufs.list, list) {
4894 if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
4895 atomic_read(&binfo->ref_count) == 2) {
4896
4897 atomic_dec(&binfo->ref_count);
4898 buf_event.type =
4899 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER;
4900 ptr = (u32 *)buf_event.u.data;
4901 ptr[0] = binfo->fd[0];
4902 ptr[1] = binfo->buff_off[0];
4903 ptr[2] = binfo->uvaddr[0];
4904 ptr[3] = (u32) binfo->timestamp.tv_sec;
4905 ptr[4] = (u32) binfo->timestamp.tv_usec;
4906 ptr[5] = binfo->v4l2_index;
4907 dprintk(VIDC_DBG,
4908 "released buffer held in driver before issuing flush: %pa fd[0]: %d\n",
4909 &binfo->device_addr[0], binfo->fd[0]);
4910 /*send event to client*/
4911 v4l2_event_queue_fh(&inst->event_handler,
4912 &buf_event);
4913 }
4914 }
4915 }
4916 mutex_unlock(&inst->registeredbufs.lock);
4917}
4918
4919void msm_comm_flush_pending_dynamic_buffers(struct msm_vidc_inst *inst)
4920{
4921 struct buffer_info *binfo = NULL;
4922
4923 if (!inst)
4924 return;
4925
4926 if (inst->buffer_mode_set[CAPTURE_PORT] != HAL_BUFFER_MODE_DYNAMIC)
4927 return;
4928
4929 if (list_empty(&inst->pendingq.list) ||
4930 list_empty(&inst->registeredbufs.list))
4931 return;
4932
4933 /*
4934 * Dynamic Buffer mode - Since pendingq is not empty
4935 * no output buffers have been sent to firmware yet.
4936 * Hence remove reference to all pendingq o/p buffers
4937 * before flushing them.
4938 */
4939
4940 mutex_lock(&inst->registeredbufs.lock);
4941 list_for_each_entry(binfo, &inst->registeredbufs.list, list) {
4942 if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
4943 dprintk(VIDC_DBG,
4944 "%s: binfo = %pK device_addr = %pa\n",
4945 __func__, binfo, &binfo->device_addr[0]);
4946 buf_ref_put(inst, binfo);
4947 }
4948 }
4949 mutex_unlock(&inst->registeredbufs.lock);
4950}
4951
4952int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags)
4953{
4954 int rc = 0;
4955 bool ip_flush = false;
4956 bool op_flush = false;
4957 struct vb2_buf_entry *temp, *next;
4958 struct mutex *lock;
4959 struct msm_vidc_core *core;
4960 struct hfi_device *hdev;
4961
4962 if (!inst) {
4963 dprintk(VIDC_ERR,
4964 "Invalid instance pointer = %pK\n", inst);
4965 return -EINVAL;
4966 }
4967 core = inst->core;
4968 if (!core) {
4969 dprintk(VIDC_ERR,
4970 "Invalid core pointer = %pK\n", core);
4971 return -EINVAL;
4972 }
4973 hdev = core->device;
4974 if (!hdev) {
4975 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4976 return -EINVAL;
4977 }
4978
4979 ip_flush = flags & V4L2_QCOM_CMD_FLUSH_OUTPUT;
4980 op_flush = flags & V4L2_QCOM_CMD_FLUSH_CAPTURE;
4981
4982 if (ip_flush && !op_flush) {
4983 dprintk(VIDC_INFO, "Input only flush not supported\n");
4984 return 0;
4985 }
4986
4987 msm_comm_flush_dynamic_buffers(inst);
4988
4989 if (inst->state == MSM_VIDC_CORE_INVALID ||
4990 core->state == VIDC_CORE_INVALID ||
4991 core->state == VIDC_CORE_UNINIT) {
4992 dprintk(VIDC_ERR,
4993 "Core %pK and inst %pK are in bad state\n",
4994 core, inst);
4995 msm_comm_flush_in_invalid_state(inst);
4996 return 0;
4997 }
4998
4999 if (inst->in_reconfig && !ip_flush && op_flush) {
5000 mutex_lock(&inst->pendingq.lock);
5001 if (!list_empty(&inst->pendingq.list)) {
5002 /*
5003 * Execution can never reach here since port reconfig
5004 * wont happen unless pendingq is emptied out
5005 * (both pendingq and flush being secured with same
5006 * lock). Printing a message here incase this breaks.
5007 */
5008 dprintk(VIDC_WARN,
5009 "FLUSH BUG: Pending q not empty! It should be empty\n");
5010 }
5011 mutex_unlock(&inst->pendingq.lock);
5012 atomic_inc(&inst->in_flush);
5013 dprintk(VIDC_DBG, "Send flush Output to firmware\n");
5014 rc = call_hfi_op(hdev, session_flush, inst->session,
5015 HAL_FLUSH_OUTPUT);
5016 } else {
5017 msm_comm_flush_pending_dynamic_buffers(inst);
5018 /*
5019 * If flush is called after queueing buffers but before
5020 * streamon driver should flush the pending queue
5021 */
5022 mutex_lock(&inst->pendingq.lock);
5023 list_for_each_entry_safe(temp, next,
5024 &inst->pendingq.list, list) {
5025 enum v4l2_buf_type type = temp->vb->type;
5026
5027 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
5028 lock = &inst->bufq[CAPTURE_PORT].lock;
5029 else
5030 lock = &inst->bufq[OUTPUT_PORT].lock;
5031
5032 temp->vb->planes[0].bytesused = 0;
5033
5034 mutex_lock(lock);
5035 vb2_buffer_done(temp->vb, VB2_BUF_STATE_DONE);
5036 msm_vidc_debugfs_update(inst,
5037 type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ?
5038 MSM_VIDC_DEBUGFS_EVENT_FBD :
5039 MSM_VIDC_DEBUGFS_EVENT_EBD);
5040 list_del(&temp->list);
5041 mutex_unlock(lock);
5042
5043 kfree(temp);
5044 }
5045 mutex_unlock(&inst->pendingq.lock);
5046
5047 /*Do not send flush in case of session_error */
5048 if (!(inst->state == MSM_VIDC_CORE_INVALID &&
5049 core->state != VIDC_CORE_INVALID)) {
5050 atomic_inc(&inst->in_flush);
5051 dprintk(VIDC_DBG, "Send flush all to firmware\n");
5052 rc = call_hfi_op(hdev, session_flush, inst->session,
5053 HAL_FLUSH_ALL);
5054 }
5055 }
5056
5057 return rc;
5058}
5059
5060
5061enum hal_extradata_id msm_comm_get_hal_extradata_index(
5062 enum v4l2_mpeg_vidc_extradata index)
5063{
5064 int ret = 0;
5065
5066 switch (index) {
5067 case V4L2_MPEG_VIDC_EXTRADATA_NONE:
5068 ret = HAL_EXTRADATA_NONE;
5069 break;
5070 case V4L2_MPEG_VIDC_EXTRADATA_MB_QUANTIZATION:
5071 ret = HAL_EXTRADATA_MB_QUANTIZATION;
5072 break;
5073 case V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO:
5074 ret = HAL_EXTRADATA_INTERLACE_VIDEO;
5075 break;
5076 case V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP:
5077 ret = HAL_EXTRADATA_TIMESTAMP;
5078 break;
5079 case V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING:
5080 ret = HAL_EXTRADATA_S3D_FRAME_PACKING;
5081 break;
5082 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE:
5083 ret = HAL_EXTRADATA_FRAME_RATE;
5084 break;
5085 case V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW:
5086 ret = HAL_EXTRADATA_PANSCAN_WINDOW;
5087 break;
5088 case V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
5089 ret = HAL_EXTRADATA_RECOVERY_POINT_SEI;
5090 break;
5091 case V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO:
5092 ret = HAL_EXTRADATA_MULTISLICE_INFO;
5093 break;
5094 case V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB:
5095 ret = HAL_EXTRADATA_NUM_CONCEALED_MB;
5096 break;
5097 case V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER:
5098 ret = HAL_EXTRADATA_METADATA_FILLER;
5099 break;
5100 case V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO:
5101 ret = HAL_EXTRADATA_ASPECT_RATIO;
5102 break;
5103 case V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP:
5104 ret = HAL_EXTRADATA_INPUT_CROP;
5105 break;
5106 case V4L2_MPEG_VIDC_EXTRADATA_DIGITAL_ZOOM:
5107 ret = HAL_EXTRADATA_DIGITAL_ZOOM;
5108 break;
5109 case V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP:
5110 ret = HAL_EXTRADATA_MPEG2_SEQDISP;
5111 break;
5112 case V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA:
5113 ret = HAL_EXTRADATA_STREAM_USERDATA;
5114 break;
5115 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP:
5116 ret = HAL_EXTRADATA_FRAME_QP;
5117 break;
5118 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO:
5119 ret = HAL_EXTRADATA_FRAME_BITS_INFO;
5120 break;
5121 case V4L2_MPEG_VIDC_EXTRADATA_LTR:
5122 ret = HAL_EXTRADATA_LTR_INFO;
5123 break;
5124 case V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI:
5125 ret = HAL_EXTRADATA_METADATA_MBI;
5126 break;
5127 case V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI:
5128 ret = HAL_EXTRADATA_VQZIP_SEI;
5129 break;
5130 case V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS:
5131 ret = HAL_EXTRADATA_YUV_STATS;
5132 break;
5133 case V4L2_MPEG_VIDC_EXTRADATA_ROI_QP:
5134 ret = HAL_EXTRADATA_ROI_QP;
5135 break;
5136 case V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP:
5137 ret = HAL_EXTRADATA_OUTPUT_CROP;
5138 break;
5139 case V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI:
5140 ret = HAL_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI;
5141 break;
5142 case V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI:
5143 ret = HAL_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI;
5144 break;
5145 case V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO:
5146 ret = HAL_EXTRADATA_PQ_INFO;
5147 break;
5148
5149 case V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY:
5150 ret = HAL_EXTRADATA_VUI_DISPLAY_INFO;
5151 break;
5152 case V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE:
5153 ret = HAL_EXTRADATA_VPX_COLORSPACE;
5154 break;
5155 default:
5156 dprintk(VIDC_WARN, "Extradata not found: %d\n", index);
5157 break;
5158 }
5159 return ret;
5160};
5161
5162int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
5163 enum hal_ssr_trigger_type type)
5164{
5165 int rc = 0;
5166 struct hfi_device *hdev;
5167
5168 if (!core || !core->device) {
5169 dprintk(VIDC_WARN, "Invalid parameters: %pK\n", core);
5170 return -EINVAL;
5171 }
5172 hdev = core->device;
5173 if (core->state == VIDC_CORE_INIT_DONE) {
5174 /*
5175 * In current implementation user-initiated SSR triggers
5176 * a fatal error from hardware. However, there is no way
5177 * to know if fatal error is due to SSR or not. Handle
5178 * user SSR as non-fatal.
5179 */
5180 mutex_lock(&core->lock);
5181 core->resources.debug_timeout = false;
5182 mutex_unlock(&core->lock);
5183 rc = call_hfi_op(hdev, core_trigger_ssr,
5184 hdev->hfi_device_data, type);
5185 }
5186
5187 return rc;
5188}
5189
5190static int msm_vidc_load_supported(struct msm_vidc_inst *inst)
5191{
5192 int num_mbs_per_sec = 0, max_load_adj = 0;
5193 enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD |
5194 LOAD_CALC_IGNORE_THUMBNAIL_LOAD |
5195 LOAD_CALC_IGNORE_NON_REALTIME_LOAD;
5196
5197 if (inst->state == MSM_VIDC_OPEN_DONE) {
5198 max_load_adj = inst->core->resources.max_load +
5199 inst->capability.mbs_per_frame.max;
5200 num_mbs_per_sec = msm_comm_get_load(inst->core,
5201 MSM_VIDC_DECODER, quirks);
5202 num_mbs_per_sec += msm_comm_get_load(inst->core,
5203 MSM_VIDC_ENCODER, quirks);
5204 if (num_mbs_per_sec > max_load_adj) {
5205 dprintk(VIDC_ERR,
5206 "H/W is overloaded. needed: %d max: %d\n",
5207 num_mbs_per_sec,
5208 max_load_adj);
5209 msm_vidc_print_running_insts(inst->core);
5210 return -EBUSY;
5211 }
5212 }
5213 return 0;
5214}
5215
5216int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst)
5217{
5218 u32 x_min, x_max, y_min, y_max;
5219 u32 input_height, input_width, output_height, output_width;
5220
5221 input_height = inst->prop.height[OUTPUT_PORT];
5222 input_width = inst->prop.width[OUTPUT_PORT];
5223 output_height = inst->prop.height[CAPTURE_PORT];
5224 output_width = inst->prop.width[CAPTURE_PORT];
5225
5226 if (!input_height || !input_width || !output_height || !output_width) {
5227 dprintk(VIDC_ERR,
5228 "Invalid : Input height = %d width = %d",
5229 input_height, input_width);
5230 dprintk(VIDC_ERR,
5231 " output height = %d width = %d\n",
5232 output_height, output_width);
5233 return -ENOTSUPP;
5234 }
5235
5236 if (!inst->capability.scale_x.min ||
5237 !inst->capability.scale_x.max ||
5238 !inst->capability.scale_y.min ||
5239 !inst->capability.scale_y.max) {
5240
5241 if (input_width * input_height !=
5242 output_width * output_height) {
5243 dprintk(VIDC_ERR,
5244 "%s: scaling is not supported (%dx%d != %dx%d)\n",
5245 __func__, input_width, input_height,
5246 output_width, output_height);
5247 return -ENOTSUPP;
5248 }
5249
5250 dprintk(VIDC_DBG, "%s: supported WxH = %dx%d\n",
5251 __func__, input_width, input_height);
5252 return 0;
5253 }
5254
5255 x_min = (1<<16)/inst->capability.scale_x.min;
5256 y_min = (1<<16)/inst->capability.scale_y.min;
5257 x_max = inst->capability.scale_x.max >> 16;
5258 y_max = inst->capability.scale_y.max >> 16;
5259
5260 if (input_height > output_height) {
5261 if (input_height > x_min * output_height) {
5262 dprintk(VIDC_ERR,
5263 "Unsupported height downscale ratio %d vs %d\n",
5264 input_height/output_height, x_min);
5265 return -ENOTSUPP;
5266 }
5267 } else {
5268 if (output_height > x_max * input_height) {
5269 dprintk(VIDC_ERR,
5270 "Unsupported height upscale ratio %d vs %d\n",
5271 input_height/output_height, x_max);
5272 return -ENOTSUPP;
5273 }
5274 }
5275 if (input_width > output_width) {
5276 if (input_width > y_min * output_width) {
5277 dprintk(VIDC_ERR,
5278 "Unsupported width downscale ratio %d vs %d\n",
5279 input_width/output_width, y_min);
5280 return -ENOTSUPP;
5281 }
5282 } else {
5283 if (output_width > y_max * input_width) {
5284 dprintk(VIDC_ERR,
5285 "Unsupported width upscale ratio %d vs %d\n",
5286 input_width/output_width, y_max);
5287 return -ENOTSUPP;
5288 }
5289 }
5290 return 0;
5291}
5292
5293int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
5294{
5295 struct msm_vidc_capability *capability;
5296 int rc = 0;
5297 struct hfi_device *hdev;
5298 struct msm_vidc_core *core;
5299
5300 if (!inst || !inst->core || !inst->core->device) {
5301 dprintk(VIDC_WARN, "%s: Invalid parameter\n", __func__);
5302 return -EINVAL;
5303 }
5304 capability = &inst->capability;
5305 hdev = inst->core->device;
5306 core = inst->core;
5307 rc = msm_vidc_load_supported(inst);
5308 if (rc) {
5309 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
5310 msm_comm_kill_session(inst);
5311 dprintk(VIDC_WARN,
5312 "%s: Hardware is overloaded\n", __func__);
5313 return rc;
5314 }
5315
5316 if (!is_thermal_permissible(core)) {
5317 dprintk(VIDC_WARN,
5318 "Thermal level critical, stop all active sessions!\n");
5319 return -ENOTSUPP;
5320 }
5321
5322 if (!rc)
5323 msm_dcvs_try_enable(inst);
5324
5325 if (!rc) {
5326 if (inst->prop.width[CAPTURE_PORT] < capability->width.min ||
5327 inst->prop.height[CAPTURE_PORT] <
5328 capability->height.min) {
5329 dprintk(VIDC_ERR,
5330 "Unsupported WxH = (%u)x(%u), min supported is - (%u)x(%u)\n",
5331 inst->prop.width[CAPTURE_PORT],
5332 inst->prop.height[CAPTURE_PORT],
5333 capability->width.min,
5334 capability->height.min);
5335 rc = -ENOTSUPP;
5336 }
5337 if (!rc && inst->prop.width[CAPTURE_PORT] >
5338 capability->width.max) {
5339 dprintk(VIDC_ERR,
5340 "Unsupported width = %u supported max width = %u",
5341 inst->prop.width[CAPTURE_PORT],
5342 capability->width.max);
5343 rc = -ENOTSUPP;
5344 }
5345
5346 if (!rc && inst->prop.height[CAPTURE_PORT]
5347 * inst->prop.width[CAPTURE_PORT] >
5348 capability->width.max * capability->height.max) {
5349 dprintk(VIDC_ERR,
5350 "Unsupported WxH = (%u)x(%u), max supported is - (%u)x(%u)\n",
5351 inst->prop.width[CAPTURE_PORT],
5352 inst->prop.height[CAPTURE_PORT],
5353 capability->width.max, capability->height.max);
5354 rc = -ENOTSUPP;
5355 }
5356 }
5357 if (rc) {
5358 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
5359 msm_comm_kill_session(inst);
5360 dprintk(VIDC_ERR,
5361 "%s: Resolution unsupported\n", __func__);
5362 }
5363 return rc;
5364}
5365
5366static void msm_comm_generate_session_error(struct msm_vidc_inst *inst)
5367{
5368 enum hal_command_response cmd = HAL_SESSION_ERROR;
5369 struct msm_vidc_cb_cmd_done response = {0};
5370
5371 dprintk(VIDC_WARN, "msm_comm_generate_session_error\n");
5372 if (!inst || !inst->core) {
5373 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5374 return;
5375 }
5376
5377 response.session_id = inst;
5378 response.status = VIDC_ERR_FAIL;
5379 handle_session_error(cmd, (void *)&response);
5380}
5381
5382static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst)
5383{
5384 struct msm_vidc_core *core;
5385 enum hal_command_response cmd = HAL_SYS_ERROR;
5386 struct msm_vidc_cb_cmd_done response = {0};
5387
5388 if (!inst || !inst->core) {
5389 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5390 return;
5391 }
5392 core = inst->core;
5393 response.device_id = (u32) core->id;
5394 handle_sys_error(cmd, (void *) &response);
5395
5396}
5397
5398int msm_comm_kill_session(struct msm_vidc_inst *inst)
5399{
5400 int rc = 0;
5401
5402 if (!inst || !inst->core || !inst->core->device) {
5403 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5404 return -EINVAL;
5405 } else if (!inst->session) {
5406 /* There's no hfi session to kill */
5407 return 0;
5408 }
5409
5410 /*
5411 * We're internally forcibly killing the session, if fw is aware of
5412 * the session send session_abort to firmware to clean up and release
5413 * the session, else just kill the session inside the driver.
5414 */
5415 if ((inst->state >= MSM_VIDC_OPEN_DONE &&
5416 inst->state < MSM_VIDC_CLOSE_DONE) ||
5417 inst->state == MSM_VIDC_CORE_INVALID) {
5418 if (msm_comm_session_abort(inst)) {
5419 msm_comm_generate_sys_error(inst);
5420 return 0;
5421 }
5422 change_inst_state(inst, MSM_VIDC_CLOSE_DONE);
5423 msm_comm_generate_session_error(inst);
5424 } else {
5425 dprintk(VIDC_WARN,
5426 "Inactive session %pK, triggering an internal session error\n",
5427 inst);
5428 msm_comm_generate_session_error(inst);
5429
5430 }
5431
5432 return rc;
5433}
5434
5435struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst,
5436 size_t size, u32 align, u32 flags,
5437 enum hal_buffer buffer_type, int map_kernel)
5438{
5439 struct msm_smem *m = NULL;
5440
5441 if (!inst || !inst->core) {
5442 dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst);
5443 return NULL;
5444 }
5445 m = msm_smem_alloc(inst->mem_client, size, align,
5446 flags, buffer_type, map_kernel);
5447 return m;
5448}
5449
5450void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem)
5451{
5452 if (!inst || !inst->core || !mem) {
5453 dprintk(VIDC_ERR,
5454 "%s: invalid params: %pK %pK\n", __func__, inst, mem);
5455 return;
5456 }
5457 msm_smem_free(inst->mem_client, mem);
5458}
5459
5460int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst,
5461 struct msm_smem *mem, enum smem_cache_ops cache_ops)
5462{
5463 if (!inst || !mem) {
5464 dprintk(VIDC_ERR,
5465 "%s: invalid params: %pK %pK\n", __func__, inst, mem);
5466 return -EINVAL;
5467 }
5468 return msm_smem_cache_operations(inst->mem_client, mem, cache_ops);
5469}
5470
5471struct msm_smem *msm_comm_smem_user_to_kernel(struct msm_vidc_inst *inst,
5472 int fd, u32 offset, enum hal_buffer buffer_type)
5473{
5474 struct msm_smem *m = NULL;
5475
5476 if (!inst || !inst->core) {
5477 dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst);
5478 return NULL;
5479 }
5480
5481 if (inst->state == MSM_VIDC_CORE_INVALID) {
5482 dprintk(VIDC_ERR, "Core in Invalid state, returning from %s\n",
5483 __func__);
5484 return NULL;
5485 }
5486
5487 m = msm_smem_user_to_kernel(inst->mem_client,
5488 fd, offset, buffer_type);
5489 return m;
5490}
5491
5492void msm_vidc_fw_unload_handler(struct work_struct *work)
5493{
5494 struct msm_vidc_core *core = NULL;
5495 struct hfi_device *hdev = NULL;
5496 int rc = 0;
5497
5498 core = container_of(work, struct msm_vidc_core, fw_unload_work.work);
5499 if (!core || !core->device) {
5500 dprintk(VIDC_ERR, "%s - invalid work or core handle\n",
5501 __func__);
5502 return;
5503 }
5504
5505 hdev = core->device;
5506
5507 mutex_lock(&core->lock);
5508 if (list_empty(&core->instances) &&
5509 core->state != VIDC_CORE_UNINIT) {
5510 if (core->state > VIDC_CORE_INIT) {
5511 dprintk(VIDC_DBG, "Calling vidc_hal_core_release\n");
5512 rc = call_hfi_op(hdev, core_release,
5513 hdev->hfi_device_data);
5514 if (rc) {
5515 dprintk(VIDC_ERR,
5516 "Failed to release core, id = %d\n",
5517 core->id);
5518 mutex_unlock(&core->lock);
5519 return;
5520 }
5521 }
5522 core->state = VIDC_CORE_UNINIT;
5523 kfree(core->capabilities);
5524 core->capabilities = NULL;
5525 }
5526 mutex_unlock(&core->lock);
5527}
5528
5529int msm_comm_set_color_format(struct msm_vidc_inst *inst,
5530 enum hal_buffer buffer_type, int fourcc)
5531{
5532 struct hal_uncompressed_format_select hal_fmt = {0};
5533 enum hal_uncompressed_format format = HAL_UNUSED_COLOR;
5534 int rc = 0;
5535 struct hfi_device *hdev;
5536
5537 if (!inst || !inst->core || !inst->core->device) {
5538 dprintk(VIDC_ERR, "%s - invalid param\n", __func__);
5539 return -EINVAL;
5540 }
5541
5542 hdev = inst->core->device;
5543
5544 format = get_hal_uncompressed(fourcc);
5545 if (format == HAL_UNUSED_COLOR) {
5546 dprintk(VIDC_ERR, "Using unsupported colorformat %#x\n",
5547 fourcc);
5548 rc = -ENOTSUPP;
5549 goto exit;
5550 }
5551
5552 hal_fmt.buffer_type = buffer_type;
5553 hal_fmt.format = format;
5554
5555 rc = call_hfi_op(hdev, session_set_property, inst->session,
5556 HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT, &hal_fmt);
5557 if (rc)
5558 dprintk(VIDC_ERR,
5559 "Failed to set input color format\n");
5560 else
5561 dprintk(VIDC_DBG, "Setting uncompressed colorformat to %#x\n",
5562 format);
5563
5564exit:
5565 return rc;
5566}
5567
5568int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
5569{
5570 u32 property_id = 0;
5571 u64 us_per_frame = 0;
5572 void *pdata;
5573 int rc = 0, fps = 0;
5574 struct hal_frame_rate frame_rate;
5575 struct hfi_device *hdev;
5576
5577 if (!inst || !inst->core || !inst->core->device || !a) {
5578 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
5579 return -EINVAL;
5580 }
5581
5582 hdev = inst->core->device;
5583 property_id = HAL_CONFIG_FRAME_RATE;
5584
5585 if (a->parm.output.timeperframe.denominator) {
5586 switch (a->type) {
5587 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
5588 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
5589 us_per_frame = a->parm.output.timeperframe.numerator *
5590 (u64)USEC_PER_SEC;
5591 do_div(us_per_frame, a->parm.output.
5592 timeperframe.denominator);
5593 break;
5594 default:
5595 dprintk(VIDC_ERR,
5596 "Scale clocks : Unknown buffer type %d\n",
5597 a->type);
5598 break;
5599 }
5600 }
5601
5602 if (!us_per_frame) {
5603 dprintk(VIDC_ERR,
5604 "Failed to scale clocks : time between frames is 0\n");
5605 rc = -EINVAL;
5606 goto exit;
5607 }
5608
5609 fps = USEC_PER_SEC;
5610 do_div(fps, us_per_frame);
5611
5612 if (fps % 15 == 14 || fps % 24 == 23)
5613 fps = fps + 1;
5614 else if ((fps > 1) && (fps % 24 == 1 || fps % 15 == 1))
5615 fps = fps - 1;
5616
Praneeth Paladugue1679112017-01-27 10:07:15 -08005617 if (fps < inst->capability.frame_rate.min ||
5618 fps > inst->capability.frame_rate.max) {
5619 dprintk(VIDC_ERR,
5620 "FPS is out of limits : fps = %d Min = %d, Max = %d\n",
5621 fps, inst->capability.frame_rate.min,
5622 inst->capability.frame_rate.max);
5623 rc = -EINVAL;
5624 goto exit;
5625 }
5626
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08005627 if (inst->prop.fps != fps) {
5628 dprintk(VIDC_PROF, "reported fps changed for %pK: %d->%d\n",
5629 inst, inst->prop.fps, fps);
5630 inst->prop.fps = fps;
5631 frame_rate.frame_rate = inst->prop.fps * BIT(16);
5632 frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
5633 pdata = &frame_rate;
5634 if (inst->session_type == MSM_VIDC_ENCODER) {
5635 rc = call_hfi_op(hdev, session_set_property,
5636 inst->session, property_id, pdata);
5637
5638 if (rc)
5639 dprintk(VIDC_WARN,
5640 "Failed to set frame rate %d\n", rc);
5641 } else {
5642 msm_dcvs_init_load(inst);
5643 }
5644 msm_comm_scale_clocks_and_bus(inst);
5645 msm_dcvs_try_enable(inst);
5646 }
5647exit:
5648 return rc;
5649}
5650
5651void msm_comm_print_inst_info(struct msm_vidc_inst *inst)
5652{
5653 struct buffer_info *temp;
5654 struct internal_buf *buf;
5655 int i = 0;
5656 bool is_decode = false;
5657 enum vidc_ports port;
5658 bool is_secure = false;
5659
5660 if (!inst) {
5661 dprintk(VIDC_ERR, "%s - invalid param %pK\n",
5662 __func__, inst);
5663 return;
5664 }
5665
5666 is_decode = inst->session_type == MSM_VIDC_DECODER;
5667 port = is_decode ? OUTPUT_PORT : CAPTURE_PORT;
5668 is_secure = inst->flags & VIDC_SECURE;
5669 dprintk(VIDC_ERR,
5670 "%s session, %s, Codec type: %s HxW: %d x %d fps: %d bitrate: %d bit-depth: %s\n",
5671 is_decode ? "Decode" : "Encode",
5672 is_secure ? "Secure" : "Non-Secure",
5673 inst->fmts[port].name,
5674 inst->prop.height[port], inst->prop.width[port],
5675 inst->prop.fps, inst->prop.bitrate,
5676 !inst->bit_depth ? "8" : "10");
5677
5678 dprintk(VIDC_ERR,
5679 "---Buffer details for inst: %pK of type: %d---\n",
5680 inst, inst->session_type);
5681 mutex_lock(&inst->registeredbufs.lock);
5682 dprintk(VIDC_ERR, "registered buffer list:\n");
5683 list_for_each_entry(temp, &inst->registeredbufs.list, list)
5684 for (i = 0; i < temp->num_planes; i++)
5685 dprintk(VIDC_ERR,
5686 "type: %d plane: %d addr: %pa size: %d\n",
5687 temp->type, i, &temp->device_addr[i],
5688 temp->size[i]);
5689
5690 mutex_unlock(&inst->registeredbufs.lock);
5691
5692 mutex_lock(&inst->scratchbufs.lock);
5693 dprintk(VIDC_ERR, "scratch buffer list:\n");
5694 list_for_each_entry(buf, &inst->scratchbufs.list, list)
5695 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5696 buf->buffer_type, &buf->handle->device_addr,
5697 buf->handle->size);
5698 mutex_unlock(&inst->scratchbufs.lock);
5699
5700 mutex_lock(&inst->persistbufs.lock);
5701 dprintk(VIDC_ERR, "persist buffer list:\n");
5702 list_for_each_entry(buf, &inst->persistbufs.list, list)
5703 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5704 buf->buffer_type, &buf->handle->device_addr,
5705 buf->handle->size);
5706 mutex_unlock(&inst->persistbufs.lock);
5707
5708 mutex_lock(&inst->outputbufs.lock);
5709 dprintk(VIDC_ERR, "dpb buffer list:\n");
5710 list_for_each_entry(buf, &inst->outputbufs.list, list)
5711 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5712 buf->buffer_type, &buf->handle->device_addr,
5713 buf->handle->size);
5714 mutex_unlock(&inst->outputbufs.lock);
5715}
5716
5717static void msm_comm_print_debug_info(struct msm_vidc_inst *inst)
5718{
5719 struct msm_vidc_core *core = NULL;
5720 struct msm_vidc_inst *temp = NULL;
5721
5722 if (!inst || !inst->core) {
5723 dprintk(VIDC_ERR, "%s - invalid param %pK %pK\n",
5724 __func__, inst, core);
5725 return;
5726 }
5727 core = inst->core;
5728
5729 dprintk(VIDC_ERR, "Venus core frequency = %lu",
5730 msm_comm_get_clock_rate(core));
5731 mutex_lock(&core->lock);
5732 dprintk(VIDC_ERR, "Printing instance info that caused Error\n");
5733 msm_comm_print_inst_info(inst);
5734 dprintk(VIDC_ERR, "Printing remaining instances info\n");
5735 list_for_each_entry(temp, &core->instances, list) {
5736 /* inst already printed above. Hence don't repeat.*/
5737 if (temp == inst)
5738 continue;
5739 msm_comm_print_inst_info(temp);
5740 }
5741 mutex_unlock(&core->lock);
5742}