blob: fb90fdf7b4f3f0744ce43a90f28ae851dc48b15a [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#ifndef _MSM_VIDC_INTERNAL_H_
15#define _MSM_VIDC_INTERNAL_H_
16
17#include <linux/atomic.h>
18#include <linux/list.h>
19#include <linux/time.h>
20#include <linux/types.h>
21#include <linux/completion.h>
22#include <linux/wait.h>
23#include <linux/workqueue.h>
24#include <linux/msm-bus.h>
25#include <linux/msm-bus-board.h>
26#include <linux/kref.h>
27#include <media/v4l2-dev.h>
28#include <media/v4l2-device.h>
29#include <media/v4l2-ioctl.h>
30#include <media/v4l2-event.h>
31#include <media/v4l2-ctrls.h>
32#include <media/videobuf2-core.h>
33#include <media/videobuf2-v4l2.h>
34#include <media/msm_vidc.h>
35#include <media/msm_media_info.h>
36
37#include "vidc_hfi_api.h"
38
39#define MSM_VIDC_DRV_NAME "msm_vidc_driver"
40#define MSM_VIDC_VERSION KERNEL_VERSION(0, 0, 1)
41#define MAX_DEBUGFS_NAME 50
42#define DEFAULT_TIMEOUT 3
43#define DEFAULT_HEIGHT 1088
44#define DEFAULT_WIDTH 1920
45#define MIN_SUPPORTED_WIDTH 32
46#define MIN_SUPPORTED_HEIGHT 32
47#define DEFAULT_FPS 15
48
49/* Maintains the number of FTB's between each FBD over a window */
50#define DCVS_FTB_WINDOW 32
51
52#define V4L2_EVENT_VIDC_BASE 10
53
54#define SYS_MSG_START HAL_SYS_INIT_DONE
55#define SYS_MSG_END HAL_SYS_ERROR
56#define SESSION_MSG_START HAL_SESSION_EVENT_CHANGE
57#define SESSION_MSG_END HAL_SESSION_ERROR
58#define SYS_MSG_INDEX(__msg) (__msg - SYS_MSG_START)
59#define SESSION_MSG_INDEX(__msg) (__msg - SESSION_MSG_START)
60
61
62#define MAX_NAME_LENGTH 64
63
64#define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0)
65
66#define NUM_MBS_PER_SEC(__height, __width, __fps) \
67 (NUM_MBS_PER_FRAME(__height, __width) * __fps)
68
69#define NUM_MBS_PER_FRAME(__height, __width) \
70 ((ALIGN(__height, 16) / 16) * (ALIGN(__width, 16) / 16))
71
72enum vidc_ports {
73 OUTPUT_PORT,
74 CAPTURE_PORT,
75 MAX_PORT_NUM
76};
77
78enum vidc_core_state {
79 VIDC_CORE_UNINIT = 0,
80 VIDC_CORE_INIT,
81 VIDC_CORE_INIT_DONE,
82 VIDC_CORE_INVALID
83};
84
85/*
86 * Do not change the enum values unless
87 * you know what you are doing
88 */
89enum instance_state {
90 MSM_VIDC_CORE_UNINIT_DONE = 0x0001,
91 MSM_VIDC_CORE_INIT,
92 MSM_VIDC_CORE_INIT_DONE,
93 MSM_VIDC_OPEN,
94 MSM_VIDC_OPEN_DONE,
95 MSM_VIDC_LOAD_RESOURCES,
96 MSM_VIDC_LOAD_RESOURCES_DONE,
97 MSM_VIDC_START,
98 MSM_VIDC_START_DONE,
99 MSM_VIDC_STOP,
100 MSM_VIDC_STOP_DONE,
101 MSM_VIDC_RELEASE_RESOURCES,
102 MSM_VIDC_RELEASE_RESOURCES_DONE,
103 MSM_VIDC_CLOSE,
104 MSM_VIDC_CLOSE_DONE,
105 MSM_VIDC_CORE_UNINIT,
106 MSM_VIDC_CORE_INVALID
107};
108
109struct buf_info {
110 struct list_head list;
111 struct vb2_buffer *buf;
112};
113
114struct msm_vidc_list {
115 struct list_head list;
116 struct mutex lock;
117};
118
119static inline void INIT_MSM_VIDC_LIST(struct msm_vidc_list *mlist)
120{
121 mutex_init(&mlist->lock);
122 INIT_LIST_HEAD(&mlist->list);
123}
124
125static inline void DEINIT_MSM_VIDC_LIST(struct msm_vidc_list *mlist)
126{
127 mutex_destroy(&mlist->lock);
128}
129
130enum buffer_owner {
131 DRIVER,
132 FIRMWARE,
133 CLIENT,
134 MAX_OWNER
135};
136
137struct internal_buf {
138 struct list_head list;
139 enum hal_buffer buffer_type;
140 struct msm_smem *handle;
141 enum buffer_owner buffer_ownership;
142};
143
144struct msm_vidc_format {
145 char name[MAX_NAME_LENGTH];
146 u8 description[32];
147 u32 fourcc;
148 int num_planes;
149 int type;
150 u32 (*get_frame_size)(int plane, u32 height, u32 width);
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -0800151 bool defer_outputs;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800152};
153
154struct msm_vidc_drv {
155 struct mutex lock;
156 struct list_head cores;
157 int num_cores;
158 struct dentry *debugfs_root;
159 int thermal_level;
160 u32 platform_version;
161};
162
163struct msm_video_device {
164 int type;
165 struct video_device vdev;
166};
167
168struct session_prop {
169 u32 width[MAX_PORT_NUM];
170 u32 height[MAX_PORT_NUM];
171 u32 fps;
172 u32 bitrate;
173};
174
175struct buf_queue {
176 struct vb2_queue vb2_bufq;
177 struct mutex lock;
178 unsigned int plane_sizes[VB2_MAX_PLANES];
179};
180
181enum profiling_points {
182 SYS_INIT = 0,
183 SESSION_INIT,
184 LOAD_RESOURCES,
185 FRAME_PROCESSING,
186 FW_IDLE,
187 MAX_PROFILING_POINTS,
188};
189
190struct buf_count {
191 int etb;
192 int ftb;
193 int fbd;
194 int ebd;
195};
196
197struct dcvs_stats {
198 int num_ftb[DCVS_FTB_WINDOW];
199 bool transition_turbo;
200 int ftb_index;
201 int ftb_counter;
202 bool prev_freq_lowered;
203 bool prev_freq_increased;
204 int threshold_disp_buf_high;
205 int threshold_disp_buf_low;
206 int load;
207 int load_low;
208 int load_high;
209 int min_threshold;
210 int max_threshold;
211 int etb_counter;
212 bool is_power_save_mode;
213 unsigned int extra_buffer_count;
214 u32 supported_codecs;
215};
216
217struct profile_data {
218 int start;
219 int stop;
220 int cumulative;
221 char name[64];
222 int sampling;
223 int average;
224};
225
226struct msm_vidc_debug {
227 struct profile_data pdata[MAX_PROFILING_POINTS];
228 int profile;
229 int samples;
230};
231
232enum msm_vidc_modes {
233 VIDC_SECURE = BIT(0),
234 VIDC_TURBO = BIT(1),
235 VIDC_THUMBNAIL = BIT(2),
236 VIDC_LOW_POWER = BIT(3),
237 VIDC_REALTIME = BIT(4),
238};
239
240struct msm_vidc_core {
241 struct list_head list;
242 struct mutex lock;
243 int id;
244 struct hfi_device *device;
245 struct msm_video_device vdev[MSM_VIDC_MAX_DEVICES];
246 struct v4l2_device v4l2_dev;
247 struct list_head instances;
248 struct dentry *debugfs_root;
249 enum vidc_core_state state;
250 struct completion completions[SYS_MSG_END - SYS_MSG_START + 1];
251 enum msm_vidc_hfi_type hfi_type;
252 struct msm_vidc_platform_resources resources;
253 u32 enc_codec_supported;
254 u32 dec_codec_supported;
255 u32 codec_count;
256 struct msm_vidc_capability *capabilities;
257 struct delayed_work fw_unload_work;
258 bool smmu_fault_handled;
259};
260
261struct msm_vidc_inst {
262 struct list_head list;
263 struct mutex sync_lock, lock;
264 struct msm_vidc_core *core;
265 enum session_type session_type;
266 void *session;
267 struct session_prop prop;
268 enum instance_state state;
269 struct msm_vidc_format fmts[MAX_PORT_NUM];
270 struct buf_queue bufq[MAX_PORT_NUM];
271 struct msm_vidc_list pendingq;
272 struct msm_vidc_list scratchbufs;
273 struct msm_vidc_list persistbufs;
274 struct msm_vidc_list pending_getpropq;
275 struct msm_vidc_list outputbufs;
276 struct msm_vidc_list registeredbufs;
277 struct buffer_requirements buff_req;
278 void *mem_client;
279 struct v4l2_ctrl_handler ctrl_handler;
280 struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1];
281 struct v4l2_ctrl **cluster;
282 struct v4l2_fh event_handler;
283 struct msm_smem *extradata_handle;
284 bool in_reconfig;
285 u32 reconfig_width;
286 u32 reconfig_height;
287 struct dentry *debugfs_root;
288 void *priv;
289 struct msm_vidc_debug debug;
290 struct buf_count count;
291 struct dcvs_stats dcvs;
292 enum msm_vidc_modes flags;
293 struct msm_vidc_capability capability;
294 u32 buffer_size_limit;
295 enum buffer_mode_type buffer_mode_set[MAX_PORT_NUM];
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800296 struct v4l2_ctrl **ctrls;
297 bool dcvs_mode;
298 enum msm_vidc_pixel_depth bit_depth;
299 struct kref kref;
300 unsigned long instant_bitrate;
301 u32 buffers_held_in_driver;
302 atomic_t in_flush;
303 u32 pic_struct;
304 u32 colour_space;
305 u32 operating_rate;
306};
307
308extern struct msm_vidc_drv *vidc_driver;
309
310struct msm_vidc_ctrl_cluster {
311 struct v4l2_ctrl **cluster;
312 struct list_head list;
313};
314
315struct msm_vidc_ctrl {
316 u32 id;
317 char name[MAX_NAME_LENGTH];
318 enum v4l2_ctrl_type type;
319 s32 minimum;
320 s32 maximum;
321 s32 default_value;
322 u32 step;
323 u32 menu_skip_mask;
324 u32 flags;
325 const char * const *qmenu;
326};
327
328void handle_cmd_response(enum hal_command_response cmd, void *data);
329int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
330 enum hal_ssr_trigger_type type);
331int msm_vidc_check_session_supported(struct msm_vidc_inst *inst);
332int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst);
333void msm_vidc_queue_v4l2_event(struct msm_vidc_inst *inst, int event_type);
334
335struct buffer_info {
336 struct list_head list;
337 int type;
338 int num_planes;
339 int fd[VIDEO_MAX_PLANES];
340 int buff_off[VIDEO_MAX_PLANES];
341 int size[VIDEO_MAX_PLANES];
342 unsigned long uvaddr[VIDEO_MAX_PLANES];
343 ion_phys_addr_t device_addr[VIDEO_MAX_PLANES];
344 struct msm_smem *handle[VIDEO_MAX_PLANES];
345 enum v4l2_memory memory;
346 u32 v4l2_index;
347 bool pending_deletion;
348 atomic_t ref_count;
349 bool dequeued;
350 bool inactive;
351 bool mapped[VIDEO_MAX_PLANES];
352 int same_fd_ref[VIDEO_MAX_PLANES];
353 struct timeval timestamp;
354};
355
356struct buffer_info *device_to_uvaddr(struct msm_vidc_list *buf_list,
357 ion_phys_addr_t device_addr);
358int buf_ref_get(struct msm_vidc_inst *inst, struct buffer_info *binfo);
359int buf_ref_put(struct msm_vidc_inst *inst, struct buffer_info *binfo);
360int output_buffer_cache_invalidate(struct msm_vidc_inst *inst,
361 struct buffer_info *binfo);
362int qbuf_dynamic_buf(struct msm_vidc_inst *inst,
363 struct buffer_info *binfo);
364int unmap_and_deregister_buf(struct msm_vidc_inst *inst,
365 struct buffer_info *binfo);
366
367void msm_comm_handle_thermal_event(void);
368void *msm_smem_new_client(enum smem_type mtype,
369 void *platform_resources, enum session_type stype);
370struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags,
371 enum hal_buffer buffer_type, int map_kernel);
372void msm_smem_free(void *clt, struct msm_smem *mem);
373void msm_smem_delete_client(void *clt);
374int msm_smem_cache_operations(void *clt, struct msm_smem *mem,
375 enum smem_cache_ops);
376struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset,
377 enum hal_buffer buffer_type);
378struct context_bank_info *msm_smem_get_context_bank(void *clt,
379 bool is_secure, enum hal_buffer buffer_type);
380void msm_vidc_fw_unload_handler(struct work_struct *work);
381bool msm_smem_compare_buffers(void *clt, int fd, void *priv);
382/*
383 * XXX: normally should be in msm_vidc.h, but that's meant for public APIs,
384 * whereas this is private
385 */
386int msm_vidc_destroy(struct msm_vidc_inst *inst);
387#endif