summaryrefslogtreecommitdiff
path: root/drivers/frame_provider/decoder/vc1/vvc1.c (plain)
blob: 3904fd55ee05424a2007a504eb205e3e1433b74a
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(bool is_reset);
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 kfifo_put(&display_q, (const struct vframe_s *)vf);
500 ATRACE_COUNTER(MODULE_NAME, vf->pts);
501
502 vf_notify_receiver(
503 PROVIDER_NAME,
504 VFRAME_EVENT_PROVIDER_VFRAME_READY,
505 NULL);
506
507 if (kfifo_get(&newframe_q, &vf) == 0) {
508 pr_info
509 ("fatal error, no available buffer slot.");
510 return IRQ_HANDLED;
511 }
512 vf->signal_type = 0;
513 vf->index = buffer_index;
514 vf->width = vvc1_amstream_dec_info.width;
515 vf->height = vvc1_amstream_dec_info.height;
516 vf->bufWidth = 1920;
517 vf->flag = 0;
518
519 vf->pts = next_pts;
520 vf->pts_us64 = next_pts_us64;
521 if ((repeat_count > 1) && avi_flag) {
522 vf->duration =
523 vvc1_amstream_dec_info.rate *
524 repeat_count >> 1;
525 if (next_pts != 0) {
526 next_pts +=
527 ((vf->duration) -
528 ((vf->duration) >> 4));
529 }
530 if (next_pts_us64 != 0) {
531 next_pts_us64 += ((vf->duration) -
532 ((vf->duration) >> 4)) * 100 / 9;
533 }
534 } else {
535 vf->duration =
536 vvc1_amstream_dec_info.rate >> 1;
537 next_pts = 0;
538 next_pts_us64 = 0;
539 }
540
541 vf->duration_pulldown = 0;
542 vf->type = (reg & BOTTOM_FIELD_FIRST_FLAG) ?
543 VIDTYPE_INTERLACE_TOP : VIDTYPE_INTERLACE_BOTTOM;
544#ifdef NV21
545 vf->type |= VIDTYPE_VIU_NV21;
546#endif
547 vf->canvas0Addr = vf->canvas1Addr =
548 index2canvas(buffer_index);
549 vf->orientation = 0;
550 vf->type_original = vf->type;
551 set_aspect_ratio(vf, READ_VREG(VC1_PIC_RATIO));
552
553 vfbuf_use[buffer_index]++;
554 vf->mem_handle =
555 decoder_bmmu_box_get_mem_handle(
556 mm_blk_handle,
557 buffer_index);
558 kfifo_put(&display_q, (const struct vframe_s *)vf);
559 ATRACE_COUNTER(MODULE_NAME, vf->pts);
560
561 vf_notify_receiver(
562 PROVIDER_NAME,
563 VFRAME_EVENT_PROVIDER_VFRAME_READY,
564 NULL);
565 } else { /* progressive */
566 if (kfifo_get(&newframe_q, &vf) == 0) {
567 pr_info
568 ("fatal error, no available buffer slot.");
569 return IRQ_HANDLED;
570 }
571 vf->signal_type = 0;
572 vf->index = buffer_index;
573 vf->width = vvc1_amstream_dec_info.width;
574 vf->height = vvc1_amstream_dec_info.height;
575 vf->bufWidth = 1920;
576 vf->flag = 0;
577
578 if (pts_valid) {
579 vf->pts = pts;
580 vf->pts_us64 = pts_us64;
581 if ((repeat_count > 1) && avi_flag) {
582 vf->duration =
583 vvc1_amstream_dec_info.rate *
584 repeat_count;
585 next_pts =
586 pts +
587 (vvc1_amstream_dec_info.rate *
588 repeat_count) * 15 / 16;
589 next_pts_us64 = pts_us64 +
590 ((vvc1_amstream_dec_info.rate *
591 repeat_count) * 15 / 16) *
592 100 / 9;
593 } else {
594 vf->duration =
595 vvc1_amstream_dec_info.rate;
596 next_pts = 0;
597 next_pts_us64 = 0;
598 }
599 } else {
600 vf->pts = next_pts;
601 vf->pts_us64 = next_pts_us64;
602 if ((repeat_count > 1) && avi_flag) {
603 vf->duration =
604 vvc1_amstream_dec_info.rate *
605 repeat_count;
606 if (next_pts != 0) {
607 next_pts += ((vf->duration) -
608 ((vf->duration) >> 4));
609 }
610 if (next_pts_us64 != 0) {
611 next_pts_us64 +=
612 ((vf->duration) -
613 ((vf->duration) >> 4)) *
614 100 / 9;
615 }
616 } else {
617 vf->duration =
618 vvc1_amstream_dec_info.rate;
619 next_pts = 0;
620 next_pts_us64 = 0;
621 }
622 }
623
624 vf->duration_pulldown = 0;
625#ifdef NV21
626 vf->type =
627 VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD |
628 VIDTYPE_VIU_NV21;
629#else
630 vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
631#endif
632 vf->canvas0Addr = vf->canvas1Addr =
633 index2canvas(buffer_index);
634 vf->orientation = 0;
635 vf->type_original = vf->type;
636 set_aspect_ratio(vf, READ_VREG(VC1_PIC_RATIO));
637
638 vfbuf_use[buffer_index]++;
639 vf->mem_handle =
640 decoder_bmmu_box_get_mem_handle(
641 mm_blk_handle,
642 buffer_index);
643
644 kfifo_put(&display_q, (const struct vframe_s *)vf);
645 ATRACE_COUNTER(MODULE_NAME, vf->pts);
646
647 vf_notify_receiver(PROVIDER_NAME,
648 VFRAME_EVENT_PROVIDER_VFRAME_READY,
649 NULL);
650 }
651 frame_dur = vvc1_amstream_dec_info.rate;
652 total_frame++;
653
654 /*count info*/
655 gvs->frame_dur = frame_dur;
656 vdec_count_info(gvs, 0, offset);
657
658 /* pr_info("PicType = %d, PTS = 0x%x, repeat
659 *count %d\n", picture_type, vf->pts, repeat_count);
660 */
661 WRITE_VREG(VC1_BUFFEROUT, 0);
662 }
663
664 WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
665
666 return IRQ_HANDLED;
667}
668
669static struct vframe_s *vvc1_vf_peek(void *op_arg)
670{
671 struct vframe_s *vf;
672
673 if (kfifo_peek(&display_q, &vf))
674 return vf;
675
676 return NULL;
677}
678
679static struct vframe_s *vvc1_vf_get(void *op_arg)
680{
681 struct vframe_s *vf;
682
683 if (kfifo_get(&display_q, &vf))
684 return vf;
685
686 return NULL;
687}
688
689static void vvc1_vf_put(struct vframe_s *vf, void *op_arg)
690{
691 if (pool_index(vf) == cur_pool_idx)
692 kfifo_put(&recycle_q, (const struct vframe_s *)vf);
693}
694
695static int vvc1_vf_states(struct vframe_states *states, void *op_arg)
696{
697 unsigned long flags;
698
699 spin_lock_irqsave(&lock, flags);
700
701 states->vf_pool_size = VF_POOL_SIZE;
702 states->buf_free_num = kfifo_len(&newframe_q);
703 states->buf_avail_num = kfifo_len(&display_q);
704 states->buf_recycle_num = kfifo_len(&recycle_q);
705
706 spin_unlock_irqrestore(&lock, flags);
707
708 return 0;
709}
710
711static int vvc1_event_cb(int type, void *data, void *private_data)
712{
713 if (type & VFRAME_EVENT_RECEIVER_RESET) {
714 unsigned long flags;
715
716 amvdec_stop();
717#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
718 vf_light_unreg_provider(&vvc1_vf_prov);
719#endif
720 spin_lock_irqsave(&lock, flags);
721 vvc1_local_init(true);
722 vvc1_prot_init();
723 spin_unlock_irqrestore(&lock, flags);
724#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
725 vf_reg_provider(&vvc1_vf_prov);
726#endif
727 amvdec_start();
728 }
729 return 0;
730}
731
732int vvc1_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
733{
734 if (!(stat & STAT_VDEC_RUN))
735 return -1;
736
737 vstatus->frame_width = vvc1_amstream_dec_info.width;
738 vstatus->frame_height = vvc1_amstream_dec_info.height;
739 if (vvc1_amstream_dec_info.rate != 0)
740 vstatus->frame_rate = 96000 / vvc1_amstream_dec_info.rate;
741 else
742 vstatus->frame_rate = -1;
743 vstatus->error_count = READ_VREG(AV_SCRATCH_C);
744 vstatus->status = stat;
745 vstatus->bit_rate = gvs->bit_rate;
746 vstatus->frame_dur = vvc1_amstream_dec_info.rate;
747 vstatus->frame_data = gvs->frame_data;
748 vstatus->total_data = gvs->total_data;
749 vstatus->frame_count = gvs->frame_count;
750 vstatus->error_frame_count = gvs->error_frame_count;
751 vstatus->drop_frame_count = gvs->drop_frame_count;
752 vstatus->total_data = gvs->total_data;
753 vstatus->samp_cnt = gvs->samp_cnt;
754 vstatus->offset = gvs->offset;
755 snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
756 "%s", DRIVER_NAME);
757
758 return 0;
759}
760
761int vvc1_set_isreset(struct vdec_s *vdec, int isreset)
762{
763 is_reset = isreset;
764 return 0;
765}
766
767static int vvc1_vdec_info_init(void)
768{
769 gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
770 if (NULL == gvs) {
771 pr_info("the struct of vdec status malloc failed.\n");
772 return -ENOMEM;
773 }
774 return 0;
775}
776
777/****************************************/
778static int vvc1_canvas_init(void)
779{
780 int i, ret;
781 u32 canvas_width, canvas_height;
782 u32 alloc_size, decbuf_size, decbuf_y_size, decbuf_uv_size;
783 unsigned long buf_start;
784
785 if (buf_size <= 0x00400000) {
786 /* SD only */
787 canvas_width = 768;
788 canvas_height = 576;
789 decbuf_y_size = 0x80000;
790 decbuf_uv_size = 0x20000;
791 decbuf_size = 0x100000;
792 } else {
793 /* HD & SD */
794 canvas_width = 1920;
795 canvas_height = 1088;
796 decbuf_y_size = 0x200000;
797 decbuf_uv_size = 0x80000;
798 decbuf_size = 0x300000;
799 }
800
801 for (i = 0; i < MAX_BMMU_BUFFER_NUM; i++) {
802 /* workspace mem */
803 if (i == (MAX_BMMU_BUFFER_NUM - 1))
804 alloc_size = WORKSPACE_SIZE;
805 else
806 alloc_size = decbuf_size;
807
808 ret = decoder_bmmu_box_alloc_buf_phy(mm_blk_handle, i,
809 alloc_size, DRIVER_NAME, &buf_start);
810 if (ret < 0)
811 return ret;
812 if (i == (MAX_BMMU_BUFFER_NUM - 1)) {
813 buf_offset = buf_start - DCAC_BUFF_START_ADDR;
814 continue;
815 }
816
817#ifdef NV21
818 canvas_config(2 * i + 0,
819 buf_start,
820 canvas_width, canvas_height,
821 CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
822 canvas_config(2 * i + 1,
823 buf_start +
824 decbuf_y_size, canvas_width,
825 canvas_height / 2, CANVAS_ADDR_NOWRAP,
826 CANVAS_BLKMODE_32X32);
827#else
828 canvas_config(3 * i + 0,
829 buf_start,
830 canvas_width, canvas_height,
831 CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
832 canvas_config(3 * i + 1,
833 buf_start +
834 decbuf_y_size, canvas_width / 2,
835 canvas_height / 2, CANVAS_ADDR_NOWRAP,
836 CANVAS_BLKMODE_32X32);
837 canvas_config(3 * i + 2,
838 buf_start +
839 decbuf_y_size + decbuf_uv_size,
840 canvas_width / 2, canvas_height / 2,
841 CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
842#endif
843
844 }
845 return 0;
846}
847
848static int vvc1_prot_init(void)
849{
850 int r;
851#if 1 /* /MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
852 WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
853 WRITE_VREG(DOS_SW_RESET0, 0);
854
855 READ_VREG(DOS_SW_RESET0);
856
857 WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
858 WRITE_VREG(DOS_SW_RESET0, 0);
859
860 WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8));
861 WRITE_VREG(DOS_SW_RESET0, 0);
862
863#else
864 WRITE_RESET_REG(RESET0_REGISTER,
865 RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
866 READ_RESET_REG(RESET0_REGISTER);
867 WRITE_RESET_REG(RESET0_REGISTER,
868 RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
869
870 WRITE_RESET_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK);
871#endif
872
873 WRITE_VREG(POWER_CTL_VLD, 0x10);
874 WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2);
875 WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6);
876
877 r = vvc1_canvas_init();
878
879 /* index v << 16 | u << 8 | y */
880#ifdef NV21
881 WRITE_VREG(AV_SCRATCH_0, 0x010100);
882 WRITE_VREG(AV_SCRATCH_1, 0x030302);
883 WRITE_VREG(AV_SCRATCH_2, 0x050504);
884 WRITE_VREG(AV_SCRATCH_3, 0x070706);
885/* WRITE_VREG(AV_SCRATCH_G, 0x090908);
886 WRITE_VREG(AV_SCRATCH_H, 0x0b0b0a);
887 WRITE_VREG(AV_SCRATCH_I, 0x0d0d0c);
888 WRITE_VREG(AV_SCRATCH_J, 0x0f0f0e);*/
889#else
890 WRITE_VREG(AV_SCRATCH_0, 0x020100);
891 WRITE_VREG(AV_SCRATCH_1, 0x050403);
892 WRITE_VREG(AV_SCRATCH_2, 0x080706);
893 WRITE_VREG(AV_SCRATCH_3, 0x0b0a09);
894 WRITE_VREG(AV_SCRATCH_G, 0x090908);
895 WRITE_VREG(AV_SCRATCH_H, 0x0b0b0a);
896 WRITE_VREG(AV_SCRATCH_I, 0x0d0d0c);
897 WRITE_VREG(AV_SCRATCH_J, 0x0f0f0e);
898#endif
899
900 /* notify ucode the buffer offset */
901 WRITE_VREG(AV_SCRATCH_F, buf_offset);
902
903 /* disable PSCALE for hardware sharing */
904 WRITE_VREG(PSCALE_CTRL, 0);
905
906 WRITE_VREG(VC1_SOS_COUNT, 0);
907 WRITE_VREG(VC1_BUFFERIN, 0);
908 WRITE_VREG(VC1_BUFFEROUT, 0);
909
910 /* clear mailbox interrupt */
911 WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
912
913 /* enable mailbox interrupt */
914 WRITE_VREG(ASSIST_MBOX1_MASK, 1);
915
916#ifdef NV21
917 SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
918#endif
919 return r;
920}
921
922static void vvc1_local_init(bool is_reset)
923{
924 int i;
925
926 /* vvc1_ratio = vvc1_amstream_dec_info.ratio; */
927 vvc1_ratio = 0x100;
928
929 avi_flag = (unsigned long) vvc1_amstream_dec_info.param;
930
931 total_frame = 0;
932
933 next_pts = 0;
934
935 next_pts_us64 = 0;
936 saved_resolution = 0;
937 frame_width = frame_height = frame_dur = 0;
938#ifdef DEBUG_PTS
939 pts_hit = pts_missed = pts_i_hit = pts_i_missed = 0;
940#endif
941
942 memset(&frm, 0, sizeof(frm));
943
944 if (!is_reset) {
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 }
965
966 if (mm_blk_handle) {
967 decoder_bmmu_box_free(mm_blk_handle);
968 mm_blk_handle = NULL;
969 }
970
971 mm_blk_handle = decoder_bmmu_box_alloc_box(
972 DRIVER_NAME,
973 0,
974 MAX_BMMU_BUFFER_NUM,
975 4 + PAGE_SHIFT,
976 CODEC_MM_FLAGS_CMA_CLEAR |
977 CODEC_MM_FLAGS_FOR_VDECODER);
978}
979
980#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
981static void vvc1_ppmgr_reset(void)
982{
983 vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL);
984
985 vvc1_local_init(true);
986
987 /* vf_notify_receiver(PROVIDER_NAME,
988 * VFRAME_EVENT_PROVIDER_START,NULL);
989 */
990
991 pr_info("vvc1dec: vf_ppmgr_reset\n");
992}
993#endif
994
995static void vvc1_set_clk(struct work_struct *work)
996{
997 int fps = 96000 / frame_dur;
998
999 saved_resolution = frame_width * frame_height * fps;
1000 vdec_source_changed(VFORMAT_VC1,
1001 frame_width, frame_height, fps);
1002
1003}
1004
1005static void error_do_work(struct work_struct *work)
1006{
1007 amvdec_stop();
1008 msleep(20);
1009#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
1010 vvc1_ppmgr_reset();
1011#else
1012 vf_light_unreg_provider(&vvc1_vf_prov);
1013 vvc1_local_init(true);
1014 vf_reg_provider(&vvc1_vf_prov);
1015#endif
1016 vvc1_prot_init();
1017 amvdec_start();
1018}
1019
1020
1021static void vvc1_put_timer_func(unsigned long arg)
1022{
1023 struct timer_list *timer = (struct timer_list *)arg;
1024
1025 if (READ_VREG(VC1_SOS_COUNT) > 10)
1026 schedule_work(&error_wd_work);
1027
1028 while (!kfifo_is_empty(&recycle_q) && (READ_VREG(VC1_BUFFERIN) == 0)) {
1029 struct vframe_s *vf;
1030
1031 if (kfifo_get(&recycle_q, &vf)) {
1032 if ((vf->index < DECODE_BUFFER_NUM_MAX) &&
1033 (--vfbuf_use[vf->index] == 0)) {
1034 WRITE_VREG(VC1_BUFFERIN, ~(1 << vf->index));
1035 vf->index = DECODE_BUFFER_NUM_MAX;
1036 }
1037 if (pool_index(vf) == cur_pool_idx)
1038 kfifo_put(&newframe_q, (const struct vframe_s *)vf);
1039 }
1040 }
1041
1042 if (frame_dur > 0 && saved_resolution !=
1043 frame_width * frame_height * (96000 / frame_dur))
1044 schedule_work(&set_clk_work);
1045 timer->expires = jiffies + PUT_INTERVAL;
1046
1047 add_timer(timer);
1048}
1049
1050static s32 vvc1_init(void)
1051{
1052 int ret = -1;
1053 char *buf = vmalloc(0x1000 * 16);
1054 int fw_type = VIDEO_DEC_VC1;
1055
1056 if (IS_ERR_OR_NULL(buf))
1057 return -ENOMEM;
1058
1059 pr_info("vvc1_init, format %d\n", vvc1_amstream_dec_info.format);
1060 init_timer(&recycle_timer);
1061
1062 stat |= STAT_TIMER_INIT;
1063
1064 intra_output = 0;
1065 amvdec_enable();
1066
1067 vvc1_local_init(false);
1068
1069 if (vvc1_amstream_dec_info.format == VIDEO_DEC_FORMAT_WMV3) {
1070 pr_info("WMV3 dec format\n");
1071 vvc1_format = VIDEO_DEC_FORMAT_WMV3;
1072 WRITE_VREG(AV_SCRATCH_4, 0);
1073 } else if (vvc1_amstream_dec_info.format == VIDEO_DEC_FORMAT_WVC1) {
1074 pr_info("WVC1 dec format\n");
1075 vvc1_format = VIDEO_DEC_FORMAT_WVC1;
1076 WRITE_VREG(AV_SCRATCH_4, 1);
1077 } else
1078 pr_info("not supported VC1 format\n");
1079
1080 if (get_firmware_data(fw_type, buf) < 0) {
1081 amvdec_disable();
1082 pr_err("get firmware fail.");
1083 vfree(buf);
1084 return -1;
1085 }
1086
1087 ret = amvdec_loadmc_ex(VFORMAT_VC1, NULL, buf);
1088 if (ret < 0) {
1089 amvdec_disable();
1090 vfree(buf);
1091 pr_err("VC1: the %s fw loading failed, err: %x\n",
1092 tee_enabled() ? "TEE" : "local", ret);
1093 return -EBUSY;
1094 }
1095
1096 vfree(buf);
1097
1098 stat |= STAT_MC_LOAD;
1099
1100 /* enable AMRISC side protocol */
1101 ret = vvc1_prot_init();
1102 if (ret < 0)
1103 return ret;
1104
1105 if (vdec_request_irq(VDEC_IRQ_1, vvc1_isr,
1106 "vvc1-irq", (void *)vvc1_dec_id)) {
1107 amvdec_disable();
1108
1109 pr_info("vvc1 irq register error.\n");
1110 return -ENOENT;
1111 }
1112
1113 stat |= STAT_ISR_REG;
1114#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
1115 vf_provider_init(&vvc1_vf_prov,
1116 PROVIDER_NAME, &vvc1_vf_provider, NULL);
1117 vf_reg_provider(&vvc1_vf_prov);
1118 vf_notify_receiver(PROVIDER_NAME,
1119 VFRAME_EVENT_PROVIDER_START, NULL);
1120#else
1121 vf_provider_init(&vvc1_vf_prov,
1122 PROVIDER_NAME, &vvc1_vf_provider, NULL);
1123 vf_reg_provider(&vvc1_vf_prov);
1124#endif
1125
1126 if (!is_reset)
1127 vf_notify_receiver(PROVIDER_NAME,
1128 VFRAME_EVENT_PROVIDER_FR_HINT,
1129 (void *)
1130 ((unsigned long)vvc1_amstream_dec_info.rate));
1131
1132 stat |= STAT_VF_HOOK;
1133
1134 recycle_timer.data = (ulong)&recycle_timer;
1135 recycle_timer.function = vvc1_put_timer_func;
1136 recycle_timer.expires = jiffies + PUT_INTERVAL;
1137
1138 add_timer(&recycle_timer);
1139
1140 stat |= STAT_TIMER_ARM;
1141
1142 amvdec_start();
1143
1144 stat |= STAT_VDEC_RUN;
1145
1146 return 0;
1147}
1148
1149static int amvdec_vc1_probe(struct platform_device *pdev)
1150{
1151 struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
1152
1153 if (pdata == NULL) {
1154 pr_info("amvdec_vc1 memory resource undefined.\n");
1155 return -EFAULT;
1156 }
1157
1158 if (pdata->sys_info) {
1159 vvc1_amstream_dec_info = *pdata->sys_info;
1160
1161 if ((vvc1_amstream_dec_info.height != 0) &&
1162 (vvc1_amstream_dec_info.width >
1163 (VC1_MAX_SUPPORT_SIZE/vvc1_amstream_dec_info.height))) {
1164 pr_info("amvdec_vc1: over size, unsupport: %d * %d\n",
1165 vvc1_amstream_dec_info.width,
1166 vvc1_amstream_dec_info.height);
1167 return -EFAULT;
1168 }
1169 }
1170 pdata->dec_status = vvc1_dec_status;
1171 pdata->set_isreset = vvc1_set_isreset;
1172 is_reset = 0;
1173
1174 vvc1_vdec_info_init();
1175
1176 INIT_WORK(&error_wd_work, error_do_work);
1177 INIT_WORK(&set_clk_work, vvc1_set_clk);
1178 if (vvc1_init() < 0) {
1179 pr_info("amvdec_vc1 init failed.\n");
1180 kfree(gvs);
1181 gvs = NULL;
1182 pdata->dec_status = NULL;
1183 return -ENODEV;
1184 }
1185
1186 return 0;
1187}
1188
1189static int amvdec_vc1_remove(struct platform_device *pdev)
1190{
1191 cancel_work_sync(&error_wd_work);
1192 if (stat & STAT_VDEC_RUN) {
1193 amvdec_stop();
1194 stat &= ~STAT_VDEC_RUN;
1195 }
1196
1197 if (stat & STAT_ISR_REG) {
1198 vdec_free_irq(VDEC_IRQ_1, (void *)vvc1_dec_id);
1199 stat &= ~STAT_ISR_REG;
1200 }
1201
1202 if (stat & STAT_TIMER_ARM) {
1203 del_timer_sync(&recycle_timer);
1204 stat &= ~STAT_TIMER_ARM;
1205 }
1206
1207 cancel_work_sync(&set_clk_work);
1208 if (stat & STAT_VF_HOOK) {
1209 if (!is_reset)
1210 vf_notify_receiver(PROVIDER_NAME,
1211 VFRAME_EVENT_PROVIDER_FR_END_HINT,
1212 NULL);
1213
1214 vf_unreg_provider(&vvc1_vf_prov);
1215 stat &= ~STAT_VF_HOOK;
1216 }
1217
1218 amvdec_disable();
1219
1220 if (mm_blk_handle) {
1221 decoder_bmmu_box_free(mm_blk_handle);
1222 mm_blk_handle = NULL;
1223 }
1224
1225#ifdef DEBUG_PTS
1226 pr_debug("pts hit %d, pts missed %d, i hit %d, missed %d\n", pts_hit,
1227 pts_missed, pts_i_hit, pts_i_missed);
1228 pr_debug("total frame %d, avi_flag %d, rate %d\n",
1229 total_frame, avi_flag,
1230 vvc1_amstream_dec_info.rate);
1231#endif
1232 kfree(gvs);
1233 gvs = NULL;
1234
1235 return 0;
1236}
1237
1238/****************************************/
1239#ifdef CONFIG_PM
1240static int vc1_suspend(struct device *dev)
1241{
1242 amvdec_suspend(to_platform_device(dev), dev->power.power_state);
1243 return 0;
1244}
1245
1246static int vc1_resume(struct device *dev)
1247{
1248 amvdec_resume(to_platform_device(dev));
1249 return 0;
1250}
1251
1252static const struct dev_pm_ops vc1_pm_ops = {
1253 SET_SYSTEM_SLEEP_PM_OPS(vc1_suspend, vc1_resume)
1254};
1255#endif
1256
1257static struct platform_driver amvdec_vc1_driver = {
1258 .probe = amvdec_vc1_probe,
1259 .remove = amvdec_vc1_remove,
1260 .driver = {
1261 .name = DRIVER_NAME,
1262#ifdef CONFIG_PM
1263 .pm = &vc1_pm_ops,
1264#endif
1265 }
1266};
1267
1268#if defined(CONFIG_ARCH_MESON) /*meson1 only support progressive */
1269static struct codec_profile_t amvdec_vc1_profile = {
1270 .name = "vc1",
1271 .profile = "progressive, wmv3"
1272};
1273#else
1274static struct codec_profile_t amvdec_vc1_profile = {
1275 .name = "vc1",
1276 .profile = "progressive, interlace, wmv3"
1277};
1278#endif
1279
1280static int __init amvdec_vc1_driver_init_module(void)
1281{
1282 pr_debug("amvdec_vc1 module init\n");
1283
1284 if (platform_driver_register(&amvdec_vc1_driver)) {
1285 pr_err("failed to register amvdec_vc1 driver\n");
1286 return -ENODEV;
1287 }
1288 vcodec_profile_register(&amvdec_vc1_profile);
1289 return 0;
1290}
1291
1292static void __exit amvdec_vc1_driver_remove_module(void)
1293{
1294 pr_debug("amvdec_vc1 module remove.\n");
1295
1296 platform_driver_unregister(&amvdec_vc1_driver);
1297}
1298
1299/****************************************/
1300module_init(amvdec_vc1_driver_init_module);
1301module_exit(amvdec_vc1_driver_remove_module);
1302
1303MODULE_DESCRIPTION("AMLOGIC VC1 Video Decoder Driver");
1304MODULE_LICENSE("GPL");
1305MODULE_AUTHOR("Qi Wang <qi.wang@amlogic.com>");
1306