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