blob: 54c5903e29fb8c6c43e1988b8d8594191cf71e26
1 | /* |
2 | * drivers/amlogic/media/frame_provider/decoder/utils/vdec.h |
3 | * |
4 | * Copyright (C) 2016 Amlogic, Inc. All rights reserved. |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, but WITHOUT |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
14 | * more details. |
15 | * |
16 | */ |
17 | |
18 | #ifndef VDEC_H |
19 | #define VDEC_H |
20 | #include <linux/amlogic/media/utils/amports_config.h> |
21 | #include <linux/interrupt.h> |
22 | #include <linux/platform_device.h> |
23 | #include <linux/list.h> |
24 | #include <linux/completion.h> |
25 | #include <linux/irqreturn.h> |
26 | |
27 | #include <linux/amlogic/media/utils/amstream.h> |
28 | #include <linux/amlogic/media/vfm/vframe.h> |
29 | #include <linux/amlogic/media/vfm/vframe_provider.h> |
30 | #include <linux/amlogic/media/vfm/vframe_receiver.h> |
31 | #define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_VDEC |
32 | #include <trace/events/meson_atrace.h> |
33 | /*#define CONFIG_AM_VDEC_DV*/ |
34 | #include "../../../stream_input/amports/streambuf.h" |
35 | #include "../../../stream_input/amports/stream_buffer_base.h" |
36 | |
37 | #include "vdec_input.h" |
38 | #include "frame_check.h" |
39 | #include "vdec_sync.h" |
40 | |
41 | s32 vdec_dev_register(void); |
42 | s32 vdec_dev_unregister(void); |
43 | |
44 | int vdec_source_changed(int format, int width, int height, int fps); |
45 | int vdec2_source_changed(int format, int width, int height, int fps); |
46 | int hevc_source_changed(int format, int width, int height, int fps); |
47 | struct device *get_vdec_device(void); |
48 | int vdec_module_init(void); |
49 | void vdec_module_exit(void); |
50 | |
51 | #define MAX_INSTANCE_MUN 9 |
52 | |
53 | #define VDEC_DEBUG_SUPPORT |
54 | |
55 | #define DEC_FLAG_HEVC_WORKAROUND 0x01 |
56 | |
57 | #define VDEC_FIFO_ALIGN 8 |
58 | |
59 | enum vdec_type_e { |
60 | VDEC_1 = 0, |
61 | VDEC_HCODEC, |
62 | VDEC_2, |
63 | VDEC_HEVC, |
64 | VDEC_HEVCB, |
65 | VDEC_MAX |
66 | }; |
67 | |
68 | #define CORE_MASK_VDEC_1 (1 << VDEC_1) |
69 | #define CORE_MASK_HCODEC (1 << VDEC_HCODEC) |
70 | #define CORE_MASK_VDEC_2 (1 << VDEC_2) |
71 | #define CORE_MASK_HEVC (1 << VDEC_HEVC) |
72 | #define CORE_MASK_HEVC_FRONT (1 << VDEC_HEVC) |
73 | #define CORE_MASK_HEVC_BACK (1 << VDEC_HEVCB) |
74 | #define CORE_MASK_COMBINE (1UL << 31) |
75 | |
76 | extern void vdec2_power_mode(int level); |
77 | extern void vdec_poweron(enum vdec_type_e core); |
78 | extern void vdec_poweroff(enum vdec_type_e core); |
79 | extern bool vdec_on(enum vdec_type_e core); |
80 | extern void vdec_power_reset(void); |
81 | |
82 | /*irq num as same as .dts*/ |
83 | |
84 | /* |
85 | * interrupts = <0 3 1 |
86 | * 0 23 1 |
87 | * 0 32 1 |
88 | * 0 43 1 |
89 | * 0 44 1 |
90 | * 0 45 1>; |
91 | * interrupt-names = "vsync", |
92 | * "demux", |
93 | * "parser", |
94 | * "mailbox_0", |
95 | * "mailbox_1", |
96 | * "mailbox_2"; |
97 | */ |
98 | enum vdec_irq_num { |
99 | VSYNC_IRQ = 0, |
100 | DEMUX_IRQ, |
101 | PARSER_IRQ, |
102 | VDEC_IRQ_0, |
103 | VDEC_IRQ_1, |
104 | VDEC_IRQ_2, |
105 | VDEC_IRQ_HEVC_BACK, |
106 | VDEC_IRQ_MAX, |
107 | }; |
108 | |
109 | enum vdec_fr_hint_state { |
110 | VDEC_NO_NEED_HINT = 0, |
111 | VDEC_NEED_HINT, |
112 | VDEC_HINTED, |
113 | }; |
114 | extern s32 vdec_request_threaded_irq(enum vdec_irq_num num, |
115 | irq_handler_t handler, |
116 | irq_handler_t thread_fn, |
117 | unsigned long irqflags, |
118 | const char *devname, void *dev); |
119 | extern s32 vdec_request_irq(enum vdec_irq_num num, irq_handler_t handler, |
120 | const char *devname, void *dev); |
121 | extern void vdec_free_irq(enum vdec_irq_num num, void *dev); |
122 | |
123 | extern void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size); |
124 | unsigned int get_vdec_clk_config_settings(void); |
125 | void update_vdec_clk_config_settings(unsigned int config); |
126 | //unsigned int get_mmu_mode(void);//DEBUG_TMP |
127 | //extern void vdec_fill_frame_info(struct vframe_qos_s *vframe_qos, int debug); |
128 | extern void vdec_fill_vdec_frame(struct vdec_s *vdec, |
129 | struct vframe_qos_s *vframe_qos, |
130 | struct vdec_info *vinfo, |
131 | struct vframe_s *vf, u32 hw_dec_time); |
132 | extern void vdec_set_vframe_comm(struct vdec_s *vdec, char *n); |
133 | |
134 | |
135 | struct vdec_s; |
136 | enum vformat_t; |
137 | |
138 | /* stream based with single instance decoder driver */ |
139 | #define VDEC_TYPE_SINGLE 0 |
140 | |
141 | /* stream based with multi-instance decoder with HW resouce sharing */ |
142 | #define VDEC_TYPE_STREAM_PARSER 1 |
143 | |
144 | /* frame based with multi-instance decoder, input block list based */ |
145 | #define VDEC_TYPE_FRAME_BLOCK 2 |
146 | |
147 | /* frame based with multi-instance decoder, single circular input block */ |
148 | #define VDEC_TYPE_FRAME_CIRCULAR 3 |
149 | |
150 | /* decoder status: uninitialized */ |
151 | #define VDEC_STATUS_UNINITIALIZED 0 |
152 | |
153 | /* decoder status: before the decoder can start consuming data */ |
154 | #define VDEC_STATUS_DISCONNECTED 1 |
155 | |
156 | /* decoder status: decoder should become disconnected once it's not active */ |
157 | #define VDEC_STATUS_CONNECTED 2 |
158 | |
159 | /* decoder status: decoder owns HW resource and is running */ |
160 | #define VDEC_STATUS_ACTIVE 3 |
161 | |
162 | #define VDEC_PROVIDER_NAME_SIZE 16 |
163 | #define VDEC_RECEIVER_NAME_SIZE 16 |
164 | #define VDEC_MAP_NAME_SIZE 90 |
165 | |
166 | #define VDEC_FLAG_OTHER_INPUT_CONTEXT 0x0 |
167 | #define VDEC_FLAG_SELF_INPUT_CONTEXT 0x01 |
168 | |
169 | #define VDEC_NEED_MORE_DATA_RUN 0x01 |
170 | #define VDEC_NEED_MORE_DATA_DIRTY 0x02 |
171 | #define VDEC_NEED_MORE_DATA 0x04 |
172 | |
173 | struct vdec_s { |
174 | u32 magic; |
175 | struct list_head list; |
176 | unsigned long core_mask; |
177 | unsigned long active_mask; |
178 | unsigned long sched_mask; |
179 | int id; |
180 | |
181 | struct vdec_s *master; |
182 | struct vdec_s *slave; |
183 | struct stream_port_s *port; |
184 | struct stream_buf_s vbuf; |
185 | int status; |
186 | int next_status; |
187 | int type; |
188 | int port_flag; |
189 | int format; |
190 | u32 pts; |
191 | u64 pts64; |
192 | bool pts_valid; |
193 | u64 timestamp; |
194 | bool timestamp_valid; |
195 | int flag; |
196 | int sched; |
197 | int need_more_data; |
198 | u32 canvas_mode; |
199 | |
200 | struct completion inactive_done; |
201 | |
202 | /* config (temp) */ |
203 | unsigned long mem_start; |
204 | unsigned long mem_end; |
205 | |
206 | void *mm_blk_handle; |
207 | |
208 | struct device *cma_dev; |
209 | struct platform_device *dev; |
210 | struct dec_sysinfo sys_info_store; |
211 | struct dec_sysinfo *sys_info; |
212 | |
213 | /* input */ |
214 | struct vdec_input_s input; |
215 | |
216 | /*frame check*/ |
217 | struct pic_check_mgr_t vfc; |
218 | |
219 | /* mc cache */ |
220 | u32 mc[4096 * 4]; |
221 | bool mc_loaded; |
222 | u32 mc_type; |
223 | /* frame provider/receiver interface */ |
224 | char vf_provider_name[VDEC_PROVIDER_NAME_SIZE]; |
225 | struct vframe_provider_s vframe_provider; |
226 | char *vf_receiver_name; |
227 | char vfm_map_id[VDEC_MAP_NAME_SIZE]; |
228 | char vfm_map_chain[VDEC_MAP_NAME_SIZE]; |
229 | int vf_receiver_inst; |
230 | enum FRAME_BASE_VIDEO_PATH frame_base_video_path; |
231 | enum vdec_fr_hint_state fr_hint_state; |
232 | bool use_vfm_path; |
233 | char config[PAGE_SIZE]; |
234 | int config_len; |
235 | bool is_reset; |
236 | bool dolby_meta_with_el; |
237 | |
238 | /* canvas */ |
239 | int (*get_canvas)(unsigned int index, unsigned int base); |
240 | int (*get_canvas_ex)(int type, int id); |
241 | void (*free_canvas_ex)(int index, int id); |
242 | |
243 | int (*dec_status)(struct vdec_s *vdec, struct vdec_info *vstatus); |
244 | int (*set_trickmode)(struct vdec_s *vdec, unsigned long trickmode); |
245 | int (*set_isreset)(struct vdec_s *vdec, int isreset); |
246 | void (*vdec_fps_detec)(int id); |
247 | |
248 | unsigned long (*run_ready)(struct vdec_s *vdec, unsigned long mask); |
249 | void (*run)(struct vdec_s *vdec, unsigned long mask, |
250 | void (*callback)(struct vdec_s *, void *), void *); |
251 | void (*reset)(struct vdec_s *vdec); |
252 | void (*dump_state)(struct vdec_s *vdec); |
253 | irqreturn_t (*irq_handler)(struct vdec_s *vdec, int irq); |
254 | irqreturn_t (*threaded_irq_handler)(struct vdec_s *vdec, int irq); |
255 | |
256 | int (*user_data_read)(struct vdec_s *vdec, |
257 | struct userdata_param_t *puserdata_para); |
258 | void (*reset_userdata_fifo)(struct vdec_s *vdec, int bInit); |
259 | void (*wakeup_userdata_poll)(struct vdec_s *vdec); |
260 | /* private */ |
261 | void *private; /* decoder per instance specific data */ |
262 | #ifdef VDEC_DEBUG_SUPPORT |
263 | u64 profile_start_clk[VDEC_MAX]; |
264 | u64 total_clk[VDEC_MAX]; |
265 | u32 check_count[VDEC_MAX]; |
266 | u32 not_run_ready_count[VDEC_MAX]; |
267 | u32 input_underrun_count[VDEC_MAX]; |
268 | u32 run_count[VDEC_MAX]; |
269 | u64 run_clk[VDEC_MAX]; |
270 | u64 start_run_clk[VDEC_MAX]; |
271 | #endif |
272 | atomic_t inirq_thread_flag; |
273 | atomic_t inirq_flag; |
274 | atomic_t inrelease; |
275 | int parallel_dec; |
276 | struct vdec_frames_s *mvfrm; |
277 | struct vdec_sync sync; |
278 | }; |
279 | |
280 | /* common decoder vframe provider name to use default vfm path */ |
281 | #define VFM_DEC_PROVIDER_NAME "decoder" |
282 | #define VFM_DEC_DVBL_PROVIDER_NAME "dvbldec" |
283 | #define VFM_DEC_DVEL_PROVIDER_NAME "dveldec" |
284 | |
285 | #define hw_to_vdec(hw) ((struct vdec_s *) \ |
286 | (platform_get_drvdata(hw->platform_dev))) |
287 | |
288 | #define canvas_y(canvas) ((canvas) & 0xff) |
289 | #define canvas_u(canvas) (((canvas) >> 8) & 0xff) |
290 | #define canvas_v(canvas) (((canvas) >> 16) & 0xff) |
291 | #define canvas_y2(canvas) (((canvas) >> 16) & 0xff) |
292 | #define canvas_u2(canvas) (((canvas) >> 24) & 0xff) |
293 | |
294 | #define vdec_frame_based(vdec) \ |
295 | (((vdec)->type == VDEC_TYPE_FRAME_BLOCK) || \ |
296 | ((vdec)->type == VDEC_TYPE_FRAME_CIRCULAR)) |
297 | #define vdec_stream_based(vdec) \ |
298 | (((vdec)->type == VDEC_TYPE_STREAM_PARSER) || \ |
299 | ((vdec)->type == VDEC_TYPE_SINGLE)) |
300 | #define vdec_single(vdec) \ |
301 | ((vdec)->type == VDEC_TYPE_SINGLE) |
302 | #define vdec_dual(vdec) \ |
303 | (((vdec)->port->type & PORT_TYPE_DUALDEC) ||\ |
304 | (vdec_get_debug_flags() & 0x100)) |
305 | #define vdec_secure(vdec) \ |
306 | (((vdec)->port_flag & PORT_FLAG_DRM)) |
307 | |
308 | /* construct vdec strcture */ |
309 | extern struct vdec_s *vdec_create(struct stream_port_s *port, |
310 | struct vdec_s *master); |
311 | |
312 | /* set video format */ |
313 | extern int vdec_set_format(struct vdec_s *vdec, int format); |
314 | |
315 | /* set PTS */ |
316 | extern int vdec_set_pts(struct vdec_s *vdec, u32 pts); |
317 | |
318 | extern int vdec_set_pts64(struct vdec_s *vdec, u64 pts64); |
319 | |
320 | /* set vfm map when use frame base decoder */ |
321 | extern int vdec_set_video_path(struct vdec_s *vdec, int video_path); |
322 | |
323 | /* set receive id when receive is ionvideo or amlvideo */ |
324 | extern int vdec_set_receive_id(struct vdec_s *vdec, int receive_id); |
325 | |
326 | /* add frame data to input chain */ |
327 | extern int vdec_write_vframe(struct vdec_s *vdec, const char *buf, |
328 | size_t count); |
329 | |
330 | extern int vdec_write_vframe_with_dma(struct vdec_s *vdec, |
331 | ulong addr, size_t count, u32 handle); |
332 | |
333 | /* mark the vframe_chunk as consumed */ |
334 | extern void vdec_vframe_dirty(struct vdec_s *vdec, |
335 | struct vframe_chunk_s *chunk); |
336 | |
337 | /* prepare decoder input */ |
338 | extern int vdec_prepare_input(struct vdec_s *vdec, struct vframe_chunk_s **p); |
339 | |
340 | /* clean decoder input */ |
341 | extern void vdec_clean_input(struct vdec_s *vdec); |
342 | |
343 | /* sync decoder input */ |
344 | extern int vdec_sync_input(struct vdec_s *vdec); |
345 | |
346 | /* enable decoder input */ |
347 | extern void vdec_enable_input(struct vdec_s *vdec); |
348 | |
349 | /* set decoder input prepare level */ |
350 | extern void vdec_set_prepare_level(struct vdec_s *vdec, int level); |
351 | |
352 | /* set vdec input */ |
353 | extern int vdec_set_input_buffer(struct vdec_s *vdec, u32 start, u32 size); |
354 | |
355 | /* check if decoder can get more input */ |
356 | extern bool vdec_has_more_input(struct vdec_s *vdec); |
357 | |
358 | /* allocate input chain |
359 | * register vdec_device |
360 | * create output, vfm or create ionvideo output |
361 | * insert vdec to vdec_manager for scheduling |
362 | */ |
363 | extern int vdec_connect(struct vdec_s *vdec); |
364 | |
365 | /* remove vdec from vdec_manager scheduling |
366 | * release input chain |
367 | * disconnect video output from ionvideo |
368 | */ |
369 | extern int vdec_disconnect(struct vdec_s *vdec); |
370 | |
371 | /* release vdec structure */ |
372 | extern int vdec_destroy(struct vdec_s *vdec); |
373 | |
374 | /* reset vdec */ |
375 | extern int vdec_reset(struct vdec_s *vdec); |
376 | |
377 | extern int vdec_v4l2_reset(struct vdec_s *vdec, int flag); |
378 | |
379 | extern void vdec_set_status(struct vdec_s *vdec, int status); |
380 | |
381 | extern void vdec_set_next_status(struct vdec_s *vdec, int status); |
382 | |
383 | extern int vdec_set_decinfo(struct vdec_s *vdec, struct dec_sysinfo *p); |
384 | |
385 | extern int vdec_init(struct vdec_s *vdec, int is_4k); |
386 | |
387 | extern void vdec_release(struct vdec_s *vdec); |
388 | |
389 | extern int vdec_status(struct vdec_s *vdec, struct vdec_info *vstatus); |
390 | |
391 | extern int vdec_set_trickmode(struct vdec_s *vdec, unsigned long trickmode); |
392 | |
393 | extern int vdec_set_isreset(struct vdec_s *vdec, int isreset); |
394 | |
395 | extern int vdec_set_dv_metawithel(struct vdec_s *vdec, int isdvmetawithel); |
396 | |
397 | extern void vdec_set_no_powerdown(int flag); |
398 | |
399 | extern int vdec_is_support_4k(void); |
400 | extern void vdec_set_flag(struct vdec_s *vdec, u32 flag); |
401 | |
402 | extern void vdec_set_eos(struct vdec_s *vdec, bool eos); |
403 | |
404 | extern void vdec_set_next_sched(struct vdec_s *vdec, struct vdec_s *next_vdec); |
405 | |
406 | extern const char *vdec_status_str(struct vdec_s *vdec); |
407 | |
408 | extern const char *vdec_type_str(struct vdec_s *vdec); |
409 | |
410 | extern const char *vdec_device_name_str(struct vdec_s *vdec); |
411 | |
412 | extern void vdec_schedule_work(struct work_struct *work); |
413 | |
414 | extern void vdec_count_info(struct vdec_info *vs, unsigned int err, |
415 | unsigned int offset); |
416 | |
417 | extern bool vdec_need_more_data(struct vdec_s *vdec); |
418 | |
419 | extern void vdec_reset_core(struct vdec_s *vdec); |
420 | |
421 | extern void hevc_reset_core(struct vdec_s *vdec); |
422 | |
423 | extern void vdec_set_suspend_clk(int mode, int hevc); |
424 | |
425 | extern unsigned long vdec_ready_to_run(struct vdec_s *vdec, unsigned long mask); |
426 | |
427 | extern void vdec_prepare_run(struct vdec_s *vdec, unsigned long mask); |
428 | |
429 | extern void vdec_core_request(struct vdec_s *vdec, unsigned long mask); |
430 | |
431 | extern int vdec_core_release(struct vdec_s *vdec, unsigned long mask); |
432 | |
433 | extern bool vdec_core_with_input(unsigned long mask); |
434 | |
435 | extern void vdec_core_finish_run(struct vdec_s *vdec, unsigned long mask); |
436 | |
437 | #ifdef VDEC_DEBUG_SUPPORT |
438 | extern void vdec_set_step_mode(void); |
439 | #endif |
440 | extern void hevc_mmu_dma_check(struct vdec_s *vdec); |
441 | int vdec_read_user_data(struct vdec_s *vdec, |
442 | struct userdata_param_t *p_userdata_param); |
443 | |
444 | int vdec_wakeup_userdata_poll(struct vdec_s *vdec); |
445 | |
446 | void vdec_reset_userdata_fifo(struct vdec_s *vdec, int bInit); |
447 | |
448 | struct vdec_s *vdec_get_vdec_by_id(int vdec_id); |
449 | |
450 | #ifdef VDEC_DEBUG_SUPPORT |
451 | extern void vdec_set_step_mode(void); |
452 | #endif |
453 | int vdec_get_debug_flags(void); |
454 | |
455 | void VDEC_PRINT_FUN_LINENO(const char *fun, int line); |
456 | |
457 | |
458 | unsigned char is_mult_inc(unsigned int); |
459 | |
460 | int vdec_get_status(struct vdec_s *vdec); |
461 | |
462 | void vdec_set_timestamp(struct vdec_s *vdec, u64 timestamp); |
463 | |
464 | extern u32 vdec_get_frame_vdec(struct vdec_s *vdec, struct vframe_counter_s *tmpbuf); |
465 | |
466 | int vdec_get_frame_num(struct vdec_s *vdec); |
467 | |
468 | int show_stream_buffer_status(char *buf, |
469 | int (*callback) (struct stream_buf_s *, char *)); |
470 | |
471 | bool is_support_no_parser(void); |
472 | |
473 | #endif /* VDEC_H */ |
474 |