summaryrefslogtreecommitdiff
path: root/drivers/frame_provider/decoder/vc1/vvc1.c (plain)
blob: 1616893c87e6e83e2cb235b282211ba0cd6a1a31
1/*
2 * drivers/amlogic/amports/vvc1.c
3 *
4 * Copyright (C) 2015 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#define DEBUG
18#include <linux/kernel.h>
19#include <linux/types.h>
20#include <linux/errno.h>
21#include <linux/module.h>
22#include <linux/interrupt.h>
23#include <linux/timer.h>
24#include <linux/kfifo.h>
25#include <linux/platform_device.h>
26#include <linux/amlogic/media/utils/amstream.h>
27#include <linux/amlogic/media/frame_sync/ptsserv.h>
28#include <linux/amlogic/media/canvas/canvas.h>
29#include <linux/amlogic/media/canvas/canvas_mgr.h>
30#include <linux/amlogic/media/vfm/vframe.h>
31#include <linux/amlogic/media/vfm/vframe_provider.h>
32#include <linux/amlogic/media/vfm/vframe_receiver.h>
33
34#include <linux/amlogic/media/utils/vdec_reg.h>
35#include "../utils/amvdec.h"
36#include "../utils/vdec.h"
37#include <linux/amlogic/media/registers/register.h>
38#include "../../../stream_input/amports/amports_priv.h"
39#include "../utils/decoder_mmu_box.h"
40#include "../utils/decoder_bmmu_box.h"
41#include <linux/amlogic/media/codec_mm/codec_mm.h>
42#include <linux/amlogic/media/codec_mm/configs.h>
43#include "../utils/firmware.h"
44#include <linux/amlogic/tee.h>
45#include <linux/delay.h>
46
47
48
49#define DRIVER_NAME "amvdec_vc1"
50#define MODULE_NAME "amvdec_vc1"
51
52#define DEBUG_PTS
53#if 1 /* //MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
54#define NV21
55#endif
56
57#define VC1_MAX_SUPPORT_SIZE (1920*1088)
58
59#define I_PICTURE 0
60#define P_PICTURE 1
61#define B_PICTURE 2
62
63#define ORI_BUFFER_START_ADDR 0x01000000
64
65#define INTERLACE_FLAG 0x80
66#define BOTTOM_FIELD_FIRST_FLAG 0x40
67
68/* protocol registers */
69#define VC1_PIC_RATIO AV_SCRATCH_0
70#define VC1_ERROR_COUNT AV_SCRATCH_6
71#define VC1_SOS_COUNT AV_SCRATCH_7
72#define VC1_BUFFERIN AV_SCRATCH_8
73#define VC1_BUFFEROUT AV_SCRATCH_9
74#define VC1_REPEAT_COUNT AV_SCRATCH_A
75#define VC1_TIME_STAMP AV_SCRATCH_B
76#define VC1_OFFSET_REG AV_SCRATCH_C
77#define MEM_OFFSET_REG AV_SCRATCH_F
78
79#define VF_POOL_SIZE 16
80#define DECODE_BUFFER_NUM_MAX 4
81#define WORKSPACE_SIZE (2 * SZ_1M)
82#define MAX_BMMU_BUFFER_NUM (DECODE_BUFFER_NUM_MAX + 1)
83#define VF_BUFFER_IDX(n) (1 + n)
84#define DCAC_BUFF_START_ADDR 0x01f00000
85
86
87#define PUT_INTERVAL (HZ/100)
88
89#if 1 /* /MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
90/* TODO: move to register headers */
91#define VPP_VD1_POSTBLEND (1 << 10)
92#define MEM_FIFO_CNT_BIT 16
93#define MEM_LEVEL_CNT_BIT 18
94#endif
95static struct vdec_info *gvs;
96
97static struct vframe_s *vvc1_vf_peek(void *);
98static struct vframe_s *vvc1_vf_get(void *);
99static void vvc1_vf_put(struct vframe_s *, void *);
100static int vvc1_vf_states(struct vframe_states *states, void *);
101static int vvc1_event_cb(int type, void *data, void *private_data);
102
103static int vvc1_prot_init(void);
104static void vvc1_local_init(void);
105
106static const char vvc1_dec_id[] = "vvc1-dev";
107
108#define PROVIDER_NAME "decoder.vc1"
109static const struct vframe_operations_s vvc1_vf_provider = {
110 .peek = vvc1_vf_peek,
111 .get = vvc1_vf_get,
112 .put = vvc1_vf_put,
113 .event_cb = vvc1_event_cb,
114 .vf_states = vvc1_vf_states,
115};
116static void *mm_blk_handle;
117static struct vframe_provider_s vvc1_vf_prov;
118
119static DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
120static DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
121static DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE);
122
123static struct vframe_s vfpool[VF_POOL_SIZE];
124static struct vframe_s vfpool2[VF_POOL_SIZE];
125static int cur_pool_idx;
126
127static s32 vfbuf_use[DECODE_BUFFER_NUM_MAX];
128static struct timer_list recycle_timer;
129static u32 stat;
130static u32 buf_size = 32 * 1024 * 1024;
131static u32 buf_offset;
132static u32 avi_flag;
133static u32 vvc1_ratio;
134static u32 vvc1_format;
135
136static u32 intra_output;
137static u32 frame_width, frame_height, frame_dur;
138static u32 saved_resolution;
139static u32 pts_by_offset = 1;
140static u32 total_frame;
141static u32 next_pts;
142static u64 next_pts_us64;
143static bool is_reset;
144static struct work_struct set_clk_work;
145static struct work_struct error_wd_work;
146
147#ifdef DEBUG_PTS
148static u32 pts_hit, pts_missed, pts_i_hit, pts_i_missed;
149#endif
150static DEFINE_SPINLOCK(lock);
151
152static struct dec_sysinfo vvc1_amstream_dec_info;
153
154struct frm_s {
155 int state;
156 u32 start_pts;
157 int num;
158 u32 end_pts;
159 u32 rate;
160 u32 trymax;
161};
162
163static struct frm_s frm;
164
165enum {
166 RATE_MEASURE_START_PTS = 0,
167 RATE_MEASURE_END_PTS,
168 RATE_MEASURE_DONE
169};
170#define RATE_MEASURE_NUM 8
171#define RATE_CORRECTION_THRESHOLD 5
172#define RATE_24_FPS 3755 /* 23.97 */
173#define RATE_30_FPS 3003 /* 29.97 */
174#define DUR2PTS(x) ((x)*90/96)
175#define PTS2DUR(x) ((x)*96/90)
176
177static inline int pool_index(struct vframe_s *vf)
178{
179 if ((vf >= &vfpool[0]) && (vf <= &vfpool[VF_POOL_SIZE - 1]))
180 return 0;
181 else if ((vf >= &vfpool2[0]) && (vf <= &vfpool2[VF_POOL_SIZE - 1]))
182 return 1;
183 else
184 return -1;
185}
186
187static inline bool close_to(int a, int b, int m)
188{
189 return abs(a - b) < m;
190}
191
192static inline u32 index2canvas(u32 index)
193{
194 const u32 canvas_tab[DECODE_BUFFER_NUM_MAX] = {
195#if 1 /* ALWASY.MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
196 0x010100, 0x030302, 0x050504, 0x070706/*,
197 0x090908, 0x0b0b0a, 0x0d0d0c, 0x0f0f0e*/
198#else
199 0x020100, 0x050403, 0x080706, 0x0b0a09
200#endif
201 };
202
203 return canvas_tab[index];
204}
205
206static void set_aspect_ratio(struct vframe_s *vf, unsigned int pixel_ratio)
207{
208 int ar = 0;
209
210 if (vvc1_ratio == 0) {
211 /* always stretch to 16:9 */
212 vf->ratio_control |= (0x90 << DISP_RATIO_ASPECT_RATIO_BIT);
213 } else if (pixel_ratio > 0x0f) {
214 ar = (vvc1_amstream_dec_info.height * (pixel_ratio & 0xff) *
215 vvc1_ratio) / (vvc1_amstream_dec_info.width *
216 (pixel_ratio >> 8));
217 } else {
218 switch (pixel_ratio) {
219 case 0:
220 ar = (vvc1_amstream_dec_info.height * vvc1_ratio) /
221 vvc1_amstream_dec_info.width;
222 break;
223 case 1:
224 ar = (vf->height * vvc1_ratio) / vf->width;
225 break;
226 case 2:
227 ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 12);
228 break;
229 case 3:
230 ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 10);
231 break;
232 case 4:
233 ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 16);
234 break;
235 case 5:
236 ar = (vf->height * 33 * vvc1_ratio) / (vf->width * 40);
237 break;
238 case 6:
239 ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 24);
240 break;
241 case 7:
242 ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 20);
243 break;
244 case 8:
245 ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 32);
246 break;
247 case 9:
248 ar = (vf->height * 33 * vvc1_ratio) / (vf->width * 80);
249 break;
250 case 10:
251 ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 18);
252 break;
253 case 11:
254 ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 15);
255 break;
256 case 12:
257 ar = (vf->height * 33 * vvc1_ratio) / (vf->width * 64);
258 break;
259 case 13:
260 ar = (vf->height * 99 * vvc1_ratio) /
261 (vf->width * 160);
262 break;
263 default:
264 ar = (vf->height * vvc1_ratio) / vf->width;
265 break;
266 }
267 }
268
269 ar = min(ar, DISP_RATIO_ASPECT_RATIO_MAX);
270
271 vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
272 /*vf->ratio_control |= DISP_RATIO_FORCECONFIG | DISP_RATIO_KEEPRATIO;*/
273}
274
275static irqreturn_t vvc1_isr(int irq, void *dev_id)
276{
277 u32 reg;
278 struct vframe_s *vf = NULL;
279 u32 repeat_count;
280 u32 picture_type;
281 u32 buffer_index;
282 unsigned int pts, pts_valid = 0, offset = 0;
283 u32 v_width, v_height;
284 u64 pts_us64 = 0;
285 u32 frame_size;
286
287 reg = READ_VREG(VC1_BUFFEROUT);
288
289 if (reg) {
290 v_width = READ_VREG(AV_SCRATCH_J);
291 v_height = READ_VREG(AV_SCRATCH_K);
292
293 if (v_width && v_width <= 4096
294 && (v_width != vvc1_amstream_dec_info.width)) {
295 pr_info("frame width changed %d to %d\n",
296 vvc1_amstream_dec_info.width, v_width);
297 vvc1_amstream_dec_info.width = v_width;
298 frame_width = v_width;
299 }
300 if (v_height && v_height <= 4096
301 && (v_height != vvc1_amstream_dec_info.height)) {
302 pr_info("frame height changed %d to %d\n",
303 vvc1_amstream_dec_info.height, v_height);
304 vvc1_amstream_dec_info.height = v_height;
305 frame_height = v_height;
306 }
307
308 if (pts_by_offset) {
309 offset = READ_VREG(VC1_OFFSET_REG);
310 if (pts_lookup_offset_us64(
311 PTS_TYPE_VIDEO,
312 offset, &pts, &frame_size,
313 0, &pts_us64) == 0) {
314 pts_valid = 1;
315#ifdef DEBUG_PTS
316 pts_hit++;
317#endif
318 } else {
319#ifdef DEBUG_PTS
320 pts_missed++;
321#endif
322 }
323 }
324
325 repeat_count = READ_VREG(VC1_REPEAT_COUNT);
326 buffer_index = ((reg & 0x7) - 1) & 3;
327 picture_type = (reg >> 3) & 7;
328
329 if (buffer_index >= DECODE_BUFFER_NUM_MAX) {
330 pr_info("fatal error, invalid buffer index.");
331 return IRQ_HANDLED;
332 }
333
334 if ((intra_output == 0) && (picture_type != 0)) {
335 WRITE_VREG(VC1_BUFFERIN, ~(1 << buffer_index));
336 WRITE_VREG(VC1_BUFFEROUT, 0);
337 WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
338
339 return IRQ_HANDLED;
340 }
341
342 intra_output = 1;
343
344#ifdef DEBUG_PTS
345 if (picture_type == I_PICTURE) {
346 /* pr_info("I offset 0x%x,
347 *pts_valid %d\n", offset, pts_valid);
348 */
349 if (!pts_valid)
350 pts_i_missed++;
351 else
352 pts_i_hit++;
353 }
354#endif
355
356 if ((pts_valid) && (frm.state != RATE_MEASURE_DONE)) {
357 if (frm.state == RATE_MEASURE_START_PTS) {
358 frm.start_pts = pts;
359 frm.state = RATE_MEASURE_END_PTS;
360 frm.trymax = RATE_MEASURE_NUM;
361 } else if (frm.state == RATE_MEASURE_END_PTS) {
362 if (frm.num >= frm.trymax) {
363 frm.end_pts = pts;
364 frm.rate = (frm.end_pts -
365 frm.start_pts) / frm.num;
366 pr_info("frate before=%d,%d,num=%d\n",
367 frm.rate,
368 DUR2PTS(vvc1_amstream_dec_info.rate),
369 frm.num);
370 /* check if measured rate is same as
371 * settings from upper layer
372 * and correct it if necessary
373 */
374 if ((close_to(frm.rate, RATE_30_FPS,
375 RATE_CORRECTION_THRESHOLD) &&
376 close_to(
377 DUR2PTS(
378 vvc1_amstream_dec_info.rate),
379 RATE_24_FPS,
380 RATE_CORRECTION_THRESHOLD))
381 ||
382 (close_to(
383 frm.rate, RATE_24_FPS,
384 RATE_CORRECTION_THRESHOLD)
385 &&
386 close_to(DUR2PTS(
387 vvc1_amstream_dec_info.rate),
388 RATE_30_FPS,
389 RATE_CORRECTION_THRESHOLD))) {
390 pr_info(
391 "vvc1: frate from %d to %d\n",
392 vvc1_amstream_dec_info.rate,
393 PTS2DUR(frm.rate));
394
395 vvc1_amstream_dec_info.rate =
396 PTS2DUR(frm.rate);
397 frm.state = RATE_MEASURE_DONE;
398 } else if (close_to(frm.rate,
399 DUR2PTS(
400 vvc1_amstream_dec_info.rate),
401 RATE_CORRECTION_THRESHOLD))
402 frm.state = RATE_MEASURE_DONE;
403 else {
404
405/* maybe still have problem,
406 * try next double frames....
407 */
408 frm.state = RATE_MEASURE_DONE;
409 frm.start_pts = pts;
410 frm.state =
411 RATE_MEASURE_END_PTS;
412 /*60 fps*60 S */
413 frm.num = 0;
414 }
415 }
416 }
417 }
418
419 if (frm.state != RATE_MEASURE_DONE)
420 frm.num += (repeat_count > 1) ? repeat_count : 1;
421 if (vvc1_amstream_dec_info.rate == 0)
422 vvc1_amstream_dec_info.rate = PTS2DUR(frm.rate);
423
424 if (reg & INTERLACE_FLAG) { /* interlace */
425 if (kfifo_get(&newframe_q, &vf) == 0) {
426 pr_info
427 ("fatal error, no available buffer slot.");
428 return IRQ_HANDLED;
429 }
430 vf->signal_type = 0;
431 vf->index = buffer_index;
432 vf->width = vvc1_amstream_dec_info.width;
433 vf->height = vvc1_amstream_dec_info.height;
434 vf->bufWidth = 1920;
435 vf->flag = 0;
436
437 if (pts_valid) {
438 vf->pts = pts;
439 vf->pts_us64 = pts_us64;
440 if ((repeat_count > 1) && avi_flag) {
441 vf->duration =
442 vvc1_amstream_dec_info.rate *
443 repeat_count >> 1;
444 next_pts = pts +
445 (vvc1_amstream_dec_info.rate *
446 repeat_count >> 1) * 15 / 16;
447 next_pts_us64 = pts_us64 +
448 ((vvc1_amstream_dec_info.rate *
449 repeat_count >> 1) * 15 / 16) *
450 100 / 9;
451 } else {
452 vf->duration =
453 vvc1_amstream_dec_info.rate >> 1;
454 next_pts = 0;
455 next_pts_us64 = 0;
456 }
457 } else {
458 vf->pts = next_pts;
459 vf->pts_us64 = next_pts_us64;
460 if ((repeat_count > 1) && avi_flag) {
461 vf->duration =
462 vvc1_amstream_dec_info.rate *
463 repeat_count >> 1;
464 if (next_pts != 0) {
465 next_pts += ((vf->duration) -
466 ((vf->duration) >> 4));
467 }
468 if (next_pts_us64 != 0) {
469 next_pts_us64 +=
470 ((vf->duration) -
471 ((vf->duration) >> 4)) *
472 100 / 9;
473 }
474 } else {
475 vf->duration =
476 vvc1_amstream_dec_info.rate >> 1;
477 next_pts = 0;
478 next_pts_us64 = 0;
479 }
480 }
481
482 vf->duration_pulldown = 0;
483 vf->type = (reg & BOTTOM_FIELD_FIRST_FLAG) ?
484 VIDTYPE_INTERLACE_BOTTOM : VIDTYPE_INTERLACE_TOP;
485#ifdef NV21
486 vf->type |= VIDTYPE_VIU_NV21;
487#endif
488 vf->canvas0Addr = vf->canvas1Addr =
489 index2canvas(buffer_index);
490 vf->orientation = 0;
491 vf->type_original = vf->type;
492 set_aspect_ratio(vf, READ_VREG(VC1_PIC_RATIO));
493
494 vfbuf_use[buffer_index]++;
495 vf->mem_handle =
496 decoder_bmmu_box_get_mem_handle(
497 mm_blk_handle,
498 buffer_index);
499
500 kfifo_put(&display_q, (const struct vframe_s *)vf);
501 ATRACE_COUNTER(MODULE_NAME, vf->pts);
502
503 vf_notify_receiver(
504 PROVIDER_NAME,
505 VFRAME_EVENT_PROVIDER_VFRAME_READY,
506 NULL);
507
508 if (kfifo_get(&newframe_q, &vf) == 0) {
509 pr_info
510 ("fatal error, no available buffer slot.");
511 return IRQ_HANDLED;
512 }
513 vf->signal_type = 0;
514 vf->index = buffer_index;
515 vf->width = vvc1_amstream_dec_info.width;
516 vf->height = vvc1_amstream_dec_info.height;
517 vf->bufWidth = 1920;
518 vf->flag = 0;
519
520 vf->pts = next_pts;
521 vf->pts_us64 = next_pts_us64;
522 if ((repeat_count > 1) && avi_flag) {
523 vf->duration =
524 vvc1_amstream_dec_info.rate *
525 repeat_count >> 1;
526 if (next_pts != 0) {
527 next_pts +=
528 ((vf->duration) -
529 ((vf->duration) >> 4));
530 }
531 if (next_pts_us64 != 0) {
532 next_pts_us64 += ((vf->duration) -
533 ((vf->duration) >> 4)) * 100 / 9;
534 }
535 } else {
536 vf->duration =
537 vvc1_amstream_dec_info.rate >> 1;
538 next_pts = 0;
539 next_pts_us64 = 0;
540 }
541
542 vf->duration_pulldown = 0;
543 vf->type = (reg & BOTTOM_FIELD_FIRST_FLAG) ?
544 VIDTYPE_INTERLACE_TOP : VIDTYPE_INTERLACE_BOTTOM;
545#ifdef NV21
546 vf->type |= VIDTYPE_VIU_NV21;
547#endif
548 vf->canvas0Addr = vf->canvas1Addr =
549 index2canvas(buffer_index);
550 vf->orientation = 0;
551 vf->type_original = vf->type;
552 set_aspect_ratio(vf, READ_VREG(VC1_PIC_RATIO));
553
554 vfbuf_use[buffer_index]++;
555 vf->mem_handle =
556 decoder_bmmu_box_get_mem_handle(
557 mm_blk_handle,
558 buffer_index);
559
560 kfifo_put(&display_q, (const struct vframe_s *)vf);
561 ATRACE_COUNTER(MODULE_NAME, vf->pts);
562
563 vf_notify_receiver(
564 PROVIDER_NAME,
565 VFRAME_EVENT_PROVIDER_VFRAME_READY,
566 NULL);
567 } else { /* progressive */
568 if (kfifo_get(&newframe_q, &vf) == 0) {
569 pr_info
570 ("fatal error, no available buffer slot.");
571 return IRQ_HANDLED;
572 }
573 vf->signal_type = 0;
574 vf->index = buffer_index;
575 vf->width = vvc1_amstream_dec_info.width;
576 vf->height = vvc1_amstream_dec_info.height;
577 vf->bufWidth = 1920;
578 vf->flag = 0;
579
580 if (pts_valid) {
581 vf->pts = pts;
582 vf->pts_us64 = pts_us64;
583 if ((repeat_count > 1) && avi_flag) {
584 vf->duration =
585 vvc1_amstream_dec_info.rate *
586 repeat_count;
587 next_pts =
588 pts +
589 (vvc1_amstream_dec_info.rate *
590 repeat_count) * 15 / 16;
591 next_pts_us64 = pts_us64 +
592 ((vvc1_amstream_dec_info.rate *
593 repeat_count) * 15 / 16) *
594 100 / 9;
595 } else {
596 vf->duration =
597 vvc1_amstream_dec_info.rate;
598 next_pts = 0;
599 next_pts_us64 = 0;
600 }
601 } else {
602 vf->pts = next_pts;
603 vf->pts_us64 = next_pts_us64;
604 if ((repeat_count > 1) && avi_flag) {
605 vf->duration =
606 vvc1_amstream_dec_info.rate *
607 repeat_count;
608 if (next_pts != 0) {
609 next_pts += ((vf->duration) -
610 ((vf->duration) >> 4));
611 }
612 if (next_pts_us64 != 0) {
613 next_pts_us64 +=
614 ((vf->duration) -
615 ((vf->duration) >> 4)) *
616 100 / 9;
617 }
618 } else {
619 vf->duration =
620 vvc1_amstream_dec_info.rate;
621 next_pts = 0;
622 next_pts_us64 = 0;
623 }
624 }
625
626 vf->duration_pulldown = 0;
627#ifdef NV21
628 vf->type =
629 VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD |
630 VIDTYPE_VIU_NV21;
631#else
632 vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
633#endif
634 vf->canvas0Addr = vf->canvas1Addr =
635 index2canvas(buffer_index);
636 vf->orientation = 0;
637 vf->type_original = vf->type;
638 set_aspect_ratio(vf, READ_VREG(VC1_PIC_RATIO));
639
640 vfbuf_use[buffer_index]++;
641 vf->mem_handle =
642 decoder_bmmu_box_get_mem_handle(
643 mm_blk_handle,
644 buffer_index);
645 kfifo_put(&display_q, (const struct vframe_s *)vf);
646 ATRACE_COUNTER(MODULE_NAME, vf->pts);
647
648 vf_notify_receiver(PROVIDER_NAME,
649 VFRAME_EVENT_PROVIDER_VFRAME_READY,
650 NULL);
651 }
652 frame_dur = vvc1_amstream_dec_info.rate;
653 total_frame++;
654
655 /*count info*/
656 gvs->frame_dur = frame_dur;
657 vdec_count_info(gvs, 0, offset);
658
659 /* pr_info("PicType = %d, PTS = 0x%x, repeat
660 *count %d\n", picture_type, vf->pts, repeat_count);
661 */
662 WRITE_VREG(VC1_BUFFEROUT, 0);
663 }
664
665 WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
666
667 return IRQ_HANDLED;
668}
669
670static struct vframe_s *vvc1_vf_peek(void *op_arg)
671{
672 struct vframe_s *vf;
673
674 if (kfifo_peek(&display_q, &vf))
675 return vf;
676
677 return NULL;
678}
679
680static struct vframe_s *vvc1_vf_get(void *op_arg)
681{
682 struct vframe_s *vf;
683
684 if (kfifo_get(&display_q, &vf))
685 return vf;
686
687 return NULL;
688}
689
690static void vvc1_vf_put(struct vframe_s *vf, void *op_arg)
691{
692 if (pool_index(vf) == cur_pool_idx)
693 kfifo_put(&recycle_q, (const struct vframe_s *)vf);
694}
695
696static int vvc1_vf_states(struct vframe_states *states, void *op_arg)
697{
698 unsigned long flags;
699
700 spin_lock_irqsave(&lock, flags);
701
702 states->vf_pool_size = VF_POOL_SIZE;
703 states->buf_free_num = kfifo_len(&newframe_q);
704 states->buf_avail_num = kfifo_len(&display_q);
705 states->buf_recycle_num = kfifo_len(&recycle_q);
706
707 spin_unlock_irqrestore(&lock, flags);
708
709 return 0;
710}
711
712static int vvc1_event_cb(int type, void *data, void *private_data)
713{
714 if (type & VFRAME_EVENT_RECEIVER_RESET) {
715 unsigned long flags;
716
717 amvdec_stop();
718#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
719 vf_light_unreg_provider(&vvc1_vf_prov);
720#endif
721 spin_lock_irqsave(&lock, flags);
722 vvc1_local_init();
723 vvc1_prot_init();
724 spin_unlock_irqrestore(&lock, flags);
725#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
726 vf_reg_provider(&vvc1_vf_prov);
727#endif
728 amvdec_start();
729 }
730 return 0;
731}
732
733int vvc1_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
734{
735 if (!(stat & STAT_VDEC_RUN))
736 return -1;
737
738 vstatus->frame_width = vvc1_amstream_dec_info.width;
739 vstatus->frame_height = vvc1_amstream_dec_info.height;
740 if (vvc1_amstream_dec_info.rate != 0)
741 vstatus->frame_rate = 96000 / vvc1_amstream_dec_info.rate;
742 else
743 vstatus->frame_rate = -1;
744 vstatus->error_count = READ_VREG(AV_SCRATCH_C);
745 vstatus->status = stat;
746 vstatus->bit_rate = gvs->bit_rate;
747 vstatus->frame_dur = vvc1_amstream_dec_info.rate;
748 vstatus->frame_data = gvs->frame_data;
749 vstatus->total_data = gvs->total_data;
750 vstatus->frame_count = gvs->frame_count;
751 vstatus->error_frame_count = gvs->error_frame_count;
752 vstatus->drop_frame_count = gvs->drop_frame_count;
753 vstatus->total_data = gvs->total_data;
754 vstatus->samp_cnt = gvs->samp_cnt;
755 vstatus->offset = gvs->offset;
756 snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
757 "%s", DRIVER_NAME);
758
759 return 0;
760}
761
762int vvc1_set_isreset(struct vdec_s *vdec, int isreset)
763{
764 is_reset = isreset;
765 return 0;
766}
767
768static int vvc1_vdec_info_init(void)
769{
770 gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
771 if (NULL == gvs) {
772 pr_info("the struct of vdec status malloc failed.\n");
773 return -ENOMEM;
774 }
775 return 0;
776}
777
778/****************************************/
779static int vvc1_canvas_init(void)
780{
781 int i, ret;
782 u32 canvas_width, canvas_height;
783 u32 alloc_size, decbuf_size, decbuf_y_size, decbuf_uv_size;
784 unsigned long buf_start;
785
786 if (buf_size <= 0x00400000) {
787 /* SD only */
788 canvas_width = 768;
789 canvas_height = 576;
790 decbuf_y_size = 0x80000;
791 decbuf_uv_size = 0x20000;
792 decbuf_size = 0x100000;
793 } else {
794 /* HD & SD */
795 canvas_width = 1920;
796 canvas_height = 1088;
797 decbuf_y_size = 0x200000;
798 decbuf_uv_size = 0x80000;
799 decbuf_size = 0x300000;
800 }
801
802 for (i = 0; i < MAX_BMMU_BUFFER_NUM; i++) {
803 /* workspace mem */
804 if (i == (MAX_BMMU_BUFFER_NUM - 1))
805 alloc_size = WORKSPACE_SIZE;
806 else
807 alloc_size = decbuf_size;
808
809 ret = decoder_bmmu_box_alloc_buf_phy(mm_blk_handle, i,
810 alloc_size, DRIVER_NAME, &buf_start);
811 if (ret < 0)
812 return ret;
813 if (i == (MAX_BMMU_BUFFER_NUM - 1)) {
814 buf_offset = buf_start - DCAC_BUFF_START_ADDR;
815 continue;
816 }
817
818#ifdef NV21
819 canvas_config(2 * i + 0,
820 buf_start,
821 canvas_width, canvas_height,
822 CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
823 canvas_config(2 * i + 1,
824 buf_start +
825 decbuf_y_size, canvas_width,
826 canvas_height / 2, CANVAS_ADDR_NOWRAP,
827 CANVAS_BLKMODE_32X32);
828#else
829 canvas_config(3 * i + 0,
830 buf_start,
831 canvas_width, canvas_height,
832 CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
833 canvas_config(3 * i + 1,
834 buf_start +
835 decbuf_y_size, canvas_width / 2,
836 canvas_height / 2, CANVAS_ADDR_NOWRAP,
837 CANVAS_BLKMODE_32X32);
838 canvas_config(3 * i + 2,
839 buf_start +
840 decbuf_y_size + decbuf_uv_size,
841 canvas_width / 2, canvas_height / 2,
842 CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
843#endif
844
845 }
846 return 0;
847}
848
849static int vvc1_prot_init(void)
850{
851 int r;
852#if 1 /* /MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
853 WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
854 WRITE_VREG(DOS_SW_RESET0, 0);
855
856 READ_VREG(DOS_SW_RESET0);
857
858 WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
859 WRITE_VREG(DOS_SW_RESET0, 0);
860
861 WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8));
862 WRITE_VREG(DOS_SW_RESET0, 0);
863
864#else
865 WRITE_RESET_REG(RESET0_REGISTER,
866 RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
867 READ_RESET_REG(RESET0_REGISTER);
868 WRITE_RESET_REG(RESET0_REGISTER,
869 RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
870
871 WRITE_RESET_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK);
872#endif
873
874 WRITE_VREG(POWER_CTL_VLD, 0x10);
875 WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2);
876 WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6);
877
878 r = vvc1_canvas_init();
879
880 /* index v << 16 | u << 8 | y */
881#ifdef NV21
882 WRITE_VREG(AV_SCRATCH_0, 0x010100);
883 WRITE_VREG(AV_SCRATCH_1, 0x030302);
884 WRITE_VREG(AV_SCRATCH_2, 0x050504);
885 WRITE_VREG(AV_SCRATCH_3, 0x070706);
886/* WRITE_VREG(AV_SCRATCH_G, 0x090908);
887 WRITE_VREG(AV_SCRATCH_H, 0x0b0b0a);
888 WRITE_VREG(AV_SCRATCH_I, 0x0d0d0c);
889 WRITE_VREG(AV_SCRATCH_J, 0x0f0f0e);*/
890#else
891 WRITE_VREG(AV_SCRATCH_0, 0x020100);
892 WRITE_VREG(AV_SCRATCH_1, 0x050403);
893 WRITE_VREG(AV_SCRATCH_2, 0x080706);
894 WRITE_VREG(AV_SCRATCH_3, 0x0b0a09);
895 WRITE_VREG(AV_SCRATCH_G, 0x090908);
896 WRITE_VREG(AV_SCRATCH_H, 0x0b0b0a);
897 WRITE_VREG(AV_SCRATCH_I, 0x0d0d0c);
898 WRITE_VREG(AV_SCRATCH_J, 0x0f0f0e);
899#endif
900
901 /* notify ucode the buffer offset */
902 WRITE_VREG(AV_SCRATCH_F, buf_offset);
903
904 /* disable PSCALE for hardware sharing */
905 WRITE_VREG(PSCALE_CTRL, 0);
906
907 WRITE_VREG(VC1_SOS_COUNT, 0);
908 WRITE_VREG(VC1_BUFFERIN, 0);
909 WRITE_VREG(VC1_BUFFEROUT, 0);
910
911 /* clear mailbox interrupt */
912 WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
913
914 /* enable mailbox interrupt */
915 WRITE_VREG(ASSIST_MBOX1_MASK, 1);
916
917#ifdef NV21
918 SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
919#endif
920 return r;
921}
922
923static void vvc1_local_init(void)
924{
925 int i;
926
927 /* vvc1_ratio = vvc1_amstream_dec_info.ratio; */
928 vvc1_ratio = 0x100;
929
930 avi_flag = (unsigned long) vvc1_amstream_dec_info.param;
931
932 total_frame = 0;
933
934 next_pts = 0;
935
936 next_pts_us64 = 0;
937 saved_resolution = 0;
938 frame_width = frame_height = frame_dur = 0;
939#ifdef DEBUG_PTS
940 pts_hit = pts_missed = pts_i_hit = pts_i_missed = 0;
941#endif
942
943 memset(&frm, 0, sizeof(frm));
944
945 for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++)
946 vfbuf_use[i] = 0;
947
948 INIT_KFIFO(display_q);
949 INIT_KFIFO(recycle_q);
950 INIT_KFIFO(newframe_q);
951 cur_pool_idx ^= 1;
952 for (i = 0; i < VF_POOL_SIZE; i++) {
953 const struct vframe_s *vf;
954
955 if (cur_pool_idx == 0) {
956 vf = &vfpool[i];
957 vfpool[i].index = DECODE_BUFFER_NUM_MAX;
958 } else {
959 vf = &vfpool2[i];
960 vfpool2[i].index = DECODE_BUFFER_NUM_MAX;
961 }
962 kfifo_put(&newframe_q, (const struct vframe_s *)vf);
963 }
964 if (mm_blk_handle) {
965 decoder_bmmu_box_free(mm_blk_handle);
966 mm_blk_handle = NULL;
967 }
968
969 mm_blk_handle = decoder_bmmu_box_alloc_box(
970 DRIVER_NAME,
971 0,
972 MAX_BMMU_BUFFER_NUM,
973 4 + PAGE_SHIFT,
974 CODEC_MM_FLAGS_CMA_CLEAR |
975 CODEC_MM_FLAGS_FOR_VDECODER);
976}
977
978#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
979static void vvc1_ppmgr_reset(void)
980{
981 vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL);
982
983 vvc1_local_init();
984
985 /* vf_notify_receiver(PROVIDER_NAME,
986 * VFRAME_EVENT_PROVIDER_START,NULL);
987 */
988
989 pr_info("vvc1dec: vf_ppmgr_reset\n");
990}
991#endif
992
993static void vvc1_set_clk(struct work_struct *work)
994{
995 int fps = 96000 / frame_dur;
996
997 saved_resolution = frame_width * frame_height * fps;
998 vdec_source_changed(VFORMAT_VC1,
999 frame_width, frame_height, fps);
1000
1001}
1002
1003static void error_do_work(struct work_struct *work)
1004{
1005 amvdec_stop();
1006 msleep(20);
1007#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
1008 vvc1_ppmgr_reset();
1009#else
1010 vf_light_unreg_provider(&vvc1_vf_prov);
1011 vvc1_local_init();
1012 vf_reg_provider(&vvc1_vf_prov);
1013#endif
1014 vvc1_prot_init();
1015 amvdec_start();
1016}
1017
1018
1019static void vvc1_put_timer_func(unsigned long arg)
1020{
1021 struct timer_list *timer = (struct timer_list *)arg;
1022
1023 if (READ_VREG(VC1_SOS_COUNT) > 10)
1024 schedule_work(&error_wd_work);
1025
1026 while (!kfifo_is_empty(&recycle_q) && (READ_VREG(VC1_BUFFERIN) == 0)) {
1027 struct vframe_s *vf;
1028
1029 if (kfifo_get(&recycle_q, &vf)) {
1030 if ((vf->index < DECODE_BUFFER_NUM_MAX) &&
1031 (--vfbuf_use[vf->index] == 0)) {
1032 WRITE_VREG(VC1_BUFFERIN, ~(1 << vf->index));
1033 vf->index = DECODE_BUFFER_NUM_MAX;
1034 }
1035 if (pool_index(vf) == cur_pool_idx)
1036 kfifo_put(&newframe_q, (const struct vframe_s *)vf);
1037 }
1038 }
1039
1040 if (frame_dur > 0 && saved_resolution !=
1041 frame_width * frame_height * (96000 / frame_dur))
1042 schedule_work(&set_clk_work);
1043 timer->expires = jiffies + PUT_INTERVAL;
1044
1045 add_timer(timer);
1046}
1047
1048static s32 vvc1_init(void)
1049{
1050 int ret = -1;
1051 char *buf = vmalloc(0x1000 * 16);
1052 int fw_type = VIDEO_DEC_VC1;
1053
1054 if (IS_ERR_OR_NULL(buf))
1055 return -ENOMEM;
1056
1057 pr_info("vvc1_init, format %d\n", vvc1_amstream_dec_info.format);
1058 init_timer(&recycle_timer);
1059
1060 stat |= STAT_TIMER_INIT;
1061
1062 intra_output = 0;
1063 amvdec_enable();
1064
1065 vvc1_local_init();
1066
1067 if (vvc1_amstream_dec_info.format == VIDEO_DEC_FORMAT_WMV3) {
1068 pr_info("WMV3 dec format\n");
1069 vvc1_format = VIDEO_DEC_FORMAT_WMV3;
1070 WRITE_VREG(AV_SCRATCH_4, 0);
1071 } else if (vvc1_amstream_dec_info.format == VIDEO_DEC_FORMAT_WVC1) {
1072 pr_info("WVC1 dec format\n");
1073 vvc1_format = VIDEO_DEC_FORMAT_WVC1;
1074 WRITE_VREG(AV_SCRATCH_4, 1);
1075 } else
1076 pr_info("not supported VC1 format\n");
1077
1078 if (get_firmware_data(fw_type, buf) < 0) {
1079 amvdec_disable();
1080 pr_err("get firmware fail.");
1081 vfree(buf);
1082 return -1;
1083 }
1084
1085 ret = amvdec_loadmc_ex(VFORMAT_VC1, NULL, buf);
1086 if (ret < 0) {
1087 amvdec_disable();
1088 vfree(buf);
1089 pr_err("VC1: the %s fw loading failed, err: %x\n",
1090 tee_enabled() ? "TEE" : "local", ret);
1091 return -EBUSY;
1092 }
1093
1094 vfree(buf);
1095
1096 stat |= STAT_MC_LOAD;
1097
1098 /* enable AMRISC side protocol */
1099 ret = vvc1_prot_init();
1100 if (ret < 0)
1101 return ret;
1102
1103 if (vdec_request_irq(VDEC_IRQ_1, vvc1_isr,
1104 "vvc1-irq", (void *)vvc1_dec_id)) {
1105 amvdec_disable();
1106
1107 pr_info("vvc1 irq register error.\n");
1108 return -ENOENT;
1109 }
1110
1111 stat |= STAT_ISR_REG;
1112#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
1113 vf_provider_init(&vvc1_vf_prov,
1114 PROVIDER_NAME, &vvc1_vf_provider, NULL);
1115 vf_reg_provider(&vvc1_vf_prov);
1116 vf_notify_receiver(PROVIDER_NAME,
1117 VFRAME_EVENT_PROVIDER_START, NULL);
1118#else
1119 vf_provider_init(&vvc1_vf_prov,
1120 PROVIDER_NAME, &vvc1_vf_provider, NULL);
1121 vf_reg_provider(&vvc1_vf_prov);
1122#endif
1123
1124 if (!is_reset)
1125 vf_notify_receiver(PROVIDER_NAME,
1126 VFRAME_EVENT_PROVIDER_FR_HINT,
1127 (void *)
1128 ((unsigned long)vvc1_amstream_dec_info.rate));
1129
1130 stat |= STAT_VF_HOOK;
1131
1132 recycle_timer.data = (ulong)&recycle_timer;
1133 recycle_timer.function = vvc1_put_timer_func;
1134 recycle_timer.expires = jiffies + PUT_INTERVAL;
1135
1136 add_timer(&recycle_timer);
1137
1138 stat |= STAT_TIMER_ARM;
1139
1140 amvdec_start();
1141
1142 stat |= STAT_VDEC_RUN;
1143
1144 return 0;
1145}
1146
1147static int amvdec_vc1_probe(struct platform_device *pdev)
1148{
1149 struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
1150
1151 if (pdata == NULL) {
1152 pr_info("amvdec_vc1 memory resource undefined.\n");
1153 return -EFAULT;
1154 }
1155
1156 if (pdata->sys_info) {
1157 vvc1_amstream_dec_info = *pdata->sys_info;
1158
1159 if ((vvc1_amstream_dec_info.height != 0) &&
1160 (vvc1_amstream_dec_info.width >
1161 (VC1_MAX_SUPPORT_SIZE/vvc1_amstream_dec_info.height))) {
1162 pr_info("amvdec_vc1: over size, unsupport: %d * %d\n",
1163 vvc1_amstream_dec_info.width,
1164 vvc1_amstream_dec_info.height);
1165 return -EFAULT;
1166 }
1167 }
1168 pdata->dec_status = vvc1_dec_status;
1169 pdata->set_isreset = vvc1_set_isreset;
1170 is_reset = 0;
1171
1172 vvc1_vdec_info_init();
1173
1174 INIT_WORK(&error_wd_work, error_do_work);
1175 INIT_WORK(&set_clk_work, vvc1_set_clk);
1176 if (vvc1_init() < 0) {
1177 pr_info("amvdec_vc1 init failed.\n");
1178 kfree(gvs);
1179 gvs = NULL;
1180 pdata->dec_status = NULL;
1181 return -ENODEV;
1182 }
1183
1184 return 0;
1185}
1186
1187static int amvdec_vc1_remove(struct platform_device *pdev)
1188{
1189 cancel_work_sync(&error_wd_work);
1190 if (stat & STAT_VDEC_RUN) {
1191 amvdec_stop();
1192 stat &= ~STAT_VDEC_RUN;
1193 }
1194
1195 if (stat & STAT_ISR_REG) {
1196 vdec_free_irq(VDEC_IRQ_1, (void *)vvc1_dec_id);
1197 stat &= ~STAT_ISR_REG;
1198 }
1199
1200 if (stat & STAT_TIMER_ARM) {
1201 del_timer_sync(&recycle_timer);
1202 stat &= ~STAT_TIMER_ARM;
1203 }
1204
1205 cancel_work_sync(&set_clk_work);
1206 if (stat & STAT_VF_HOOK) {
1207 if (!is_reset)
1208 vf_notify_receiver(PROVIDER_NAME,
1209 VFRAME_EVENT_PROVIDER_FR_END_HINT,
1210 NULL);
1211
1212 vf_unreg_provider(&vvc1_vf_prov);
1213 stat &= ~STAT_VF_HOOK;
1214 }
1215
1216 amvdec_disable();
1217
1218 if (mm_blk_handle) {
1219 decoder_bmmu_box_free(mm_blk_handle);
1220 mm_blk_handle = NULL;
1221 }
1222
1223#ifdef DEBUG_PTS
1224 pr_debug("pts hit %d, pts missed %d, i hit %d, missed %d\n", pts_hit,
1225 pts_missed, pts_i_hit, pts_i_missed);
1226 pr_debug("total frame %d, avi_flag %d, rate %d\n",
1227 total_frame, avi_flag,
1228 vvc1_amstream_dec_info.rate);
1229#endif
1230 kfree(gvs);
1231 gvs = NULL;
1232
1233 return 0;
1234}
1235
1236/****************************************/
1237#ifdef CONFIG_PM
1238static int vc1_suspend(struct device *dev)
1239{
1240 amvdec_suspend(to_platform_device(dev), dev->power.power_state);
1241 return 0;
1242}
1243
1244static int vc1_resume(struct device *dev)
1245{
1246 amvdec_resume(to_platform_device(dev));
1247 return 0;
1248}
1249
1250static const struct dev_pm_ops vc1_pm_ops = {
1251 SET_SYSTEM_SLEEP_PM_OPS(vc1_suspend, vc1_resume)
1252};
1253#endif
1254
1255static struct platform_driver amvdec_vc1_driver = {
1256 .probe = amvdec_vc1_probe,
1257 .remove = amvdec_vc1_remove,
1258 .driver = {
1259 .name = DRIVER_NAME,
1260#ifdef CONFIG_PM
1261 .pm = &vc1_pm_ops,
1262#endif
1263 }
1264};
1265
1266#if defined(CONFIG_ARCH_MESON) /*meson1 only support progressive */
1267static struct codec_profile_t amvdec_vc1_profile = {
1268 .name = "vc1",
1269 .profile = "progressive, wmv3"
1270};
1271#else
1272static struct codec_profile_t amvdec_vc1_profile = {
1273 .name = "vc1",
1274 .profile = "progressive, interlace, wmv3"
1275};
1276#endif
1277
1278static int __init amvdec_vc1_driver_init_module(void)
1279{
1280 pr_debug("amvdec_vc1 module init\n");
1281
1282 if (platform_driver_register(&amvdec_vc1_driver)) {
1283 pr_err("failed to register amvdec_vc1 driver\n");
1284 return -ENODEV;
1285 }
1286 vcodec_profile_register(&amvdec_vc1_profile);
1287 return 0;
1288}
1289
1290static void __exit amvdec_vc1_driver_remove_module(void)
1291{
1292 pr_debug("amvdec_vc1 module remove.\n");
1293
1294 platform_driver_unregister(&amvdec_vc1_driver);
1295}
1296
1297/****************************************/
1298module_init(amvdec_vc1_driver_init_module);
1299module_exit(amvdec_vc1_driver_remove_module);
1300
1301MODULE_DESCRIPTION("AMLOGIC VC1 Video Decoder Driver");
1302MODULE_LICENSE("GPL");
1303MODULE_AUTHOR("Qi Wang <qi.wang@amlogic.com>");
1304