.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2016 MediaTek Inc. |
---|
3 | 4 | * Author: Daniel Hsiao <daniel.hsiao@mediatek.com> |
---|
4 | 5 | * Kai-Sean Yang <kai-sean.yang@mediatek.com> |
---|
5 | 6 | * Tiffany Lin <tiffany.lin@mediatek.com> |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or |
---|
8 | | - * modify it under the terms of the GNU General Public License |
---|
9 | | - * version 2 as published by the Free Software Foundation. |
---|
10 | | - * |
---|
11 | | - * This program is distributed in the hope that it will be useful, |
---|
12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | | - * GNU General Public License for more details. |
---|
15 | 7 | */ |
---|
16 | 8 | |
---|
17 | 9 | #include <linux/fs.h> |
---|
.. | .. |
---|
118 | 110 | * @buf_len_sz_c : size used to store cbcr plane ufo info (AP-R, VPU-W) |
---|
119 | 111 | |
---|
120 | 112 | * @profile : profile sparsed from vpu (AP-R, VPU-W) |
---|
121 | | - * @show_frame : display this frame or not (AP-R, VPU-W) |
---|
| 113 | + * @show_frame : [BIT(0)] display this frame or not (AP-R, VPU-W) |
---|
| 114 | + * [BIT(1)] reset segment data or not (AP-R, VPU-W) |
---|
| 115 | + * [BIT(2)] trig decoder hardware or not (AP-R, VPU-W) |
---|
| 116 | + * [BIT(3)] ask VPU to set bits(0~4) accordingly (AP-W, VPU-R) |
---|
| 117 | + * [BIT(4)] do not reset segment data before every frame (AP-R, VPU-W) |
---|
122 | 118 | * @show_existing_frame : inform this frame is show existing frame |
---|
123 | 119 | * (AP-R, VPU-W) |
---|
124 | 120 | * @frm_to_show_idx : index to show frame (AP-R, VPU-W) |
---|
.. | .. |
---|
481 | 477 | */ |
---|
482 | 478 | if ((frm_to_show->fb != NULL) && |
---|
483 | 479 | (inst->cur_fb->base_y.size >= |
---|
484 | | - frm_to_show->fb->base_y.size)) { |
---|
| 480 | + frm_to_show->fb->base_y.size) && |
---|
| 481 | + (inst->cur_fb->base_c.size >= |
---|
| 482 | + frm_to_show->fb->base_c.size)) { |
---|
485 | 483 | memcpy((void *)inst->cur_fb->base_y.va, |
---|
486 | 484 | (void *)frm_to_show->fb->base_y.va, |
---|
487 | | - vsi->buf_w * |
---|
488 | | - vsi->buf_h); |
---|
| 485 | + frm_to_show->fb->base_y.size); |
---|
489 | 486 | memcpy((void *)inst->cur_fb->base_c.va, |
---|
490 | 487 | (void *)frm_to_show->fb->base_c.va, |
---|
491 | | - vsi->buf_w * |
---|
492 | | - vsi->buf_h / 2); |
---|
| 488 | + frm_to_show->fb->base_c.size); |
---|
493 | 489 | } else { |
---|
494 | 490 | /* After resolution change case, current CAPTURE buffer |
---|
495 | 491 | * may have less buffer size than frm_to_show buffer |
---|
.. | .. |
---|
502 | 498 | frm_to_show->fb->base_y.size); |
---|
503 | 499 | } |
---|
504 | 500 | if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) { |
---|
505 | | - if (vsi->show_frame) |
---|
| 501 | + if (vsi->show_frame & BIT(0)) |
---|
506 | 502 | vp9_add_to_fb_disp_list(inst, inst->cur_fb); |
---|
507 | 503 | } |
---|
508 | 504 | } else { |
---|
509 | 505 | if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) { |
---|
510 | | - if (vsi->show_frame) |
---|
| 506 | + if (vsi->show_frame & BIT(0)) |
---|
511 | 507 | vp9_add_to_fb_disp_list(inst, frm_to_show->fb); |
---|
512 | 508 | } |
---|
513 | 509 | } |
---|
.. | .. |
---|
702 | 698 | |
---|
703 | 699 | static void get_pic_info(struct vdec_vp9_inst *inst, struct vdec_pic_info *pic) |
---|
704 | 700 | { |
---|
705 | | - pic->y_bs_sz = inst->vsi->buf_sz_y_bs; |
---|
706 | | - pic->c_bs_sz = inst->vsi->buf_sz_c_bs; |
---|
707 | | - pic->y_len_sz = inst->vsi->buf_len_sz_y; |
---|
708 | | - pic->c_len_sz = inst->vsi->buf_len_sz_c; |
---|
| 701 | + pic->fb_sz[0] = inst->vsi->buf_sz_y_bs + inst->vsi->buf_len_sz_y; |
---|
| 702 | + pic->fb_sz[1] = inst->vsi->buf_sz_c_bs + inst->vsi->buf_len_sz_c; |
---|
709 | 703 | |
---|
710 | 704 | pic->pic_w = inst->vsi->pic_w; |
---|
711 | 705 | pic->pic_h = inst->vsi->pic_h; |
---|
.. | .. |
---|
714 | 708 | |
---|
715 | 709 | mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", |
---|
716 | 710 | pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); |
---|
717 | | - mtk_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz, |
---|
718 | | - pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); |
---|
| 711 | + mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)", |
---|
| 712 | + pic->fb_sz[0], |
---|
| 713 | + pic->fb_sz[1]); |
---|
719 | 714 | } |
---|
720 | 715 | |
---|
721 | 716 | static void get_disp_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb) |
---|
.. | .. |
---|
766 | 761 | return 0; |
---|
767 | 762 | } |
---|
768 | 763 | |
---|
769 | | -static void vdec_vp9_deinit(unsigned long h_vdec) |
---|
| 764 | +static void vdec_vp9_deinit(void *h_vdec) |
---|
770 | 765 | { |
---|
771 | 766 | struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; |
---|
772 | 767 | struct mtk_vcodec_mem *mem; |
---|
.. | .. |
---|
788 | 783 | vp9_free_inst(inst); |
---|
789 | 784 | } |
---|
790 | 785 | |
---|
791 | | -static int vdec_vp9_init(struct mtk_vcodec_ctx *ctx, unsigned long *h_vdec) |
---|
| 786 | +static int vdec_vp9_init(struct mtk_vcodec_ctx *ctx) |
---|
792 | 787 | { |
---|
793 | 788 | struct vdec_vp9_inst *inst; |
---|
794 | 789 | |
---|
.. | .. |
---|
800 | 795 | inst->ctx = ctx; |
---|
801 | 796 | |
---|
802 | 797 | inst->vpu.id = IPI_VDEC_VP9; |
---|
803 | | - inst->vpu.dev = ctx->dev->vpu_plat_dev; |
---|
804 | 798 | inst->vpu.ctx = ctx; |
---|
805 | | - inst->vpu.handler = vpu_dec_ipi_handler; |
---|
806 | 799 | |
---|
807 | 800 | if (vpu_dec_init(&inst->vpu)) { |
---|
808 | 801 | mtk_vcodec_err(inst, "vp9_dec_vpu_init failed"); |
---|
.. | .. |
---|
810 | 803 | } |
---|
811 | 804 | |
---|
812 | 805 | inst->vsi = (struct vdec_vp9_vsi *)inst->vpu.vsi; |
---|
| 806 | + |
---|
| 807 | + inst->vsi->show_frame |= BIT(3); |
---|
| 808 | + |
---|
813 | 809 | init_all_fb_lists(inst); |
---|
814 | 810 | |
---|
815 | | - (*h_vdec) = (unsigned long)inst; |
---|
| 811 | + ctx->drv_handle = inst; |
---|
816 | 812 | return 0; |
---|
817 | 813 | |
---|
818 | 814 | err_deinit_inst: |
---|
.. | .. |
---|
821 | 817 | return -EINVAL; |
---|
822 | 818 | } |
---|
823 | 819 | |
---|
824 | | -static int vdec_vp9_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs, |
---|
825 | | - struct vdec_fb *fb, bool *res_chg) |
---|
| 820 | +static int vdec_vp9_decode(void *h_vdec, struct mtk_vcodec_mem *bs, |
---|
| 821 | + struct vdec_fb *fb, bool *res_chg) |
---|
826 | 822 | { |
---|
827 | 823 | int ret = 0; |
---|
828 | 824 | struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; |
---|
.. | .. |
---|
880 | 876 | vsi->sf_frm_sz[idx]); |
---|
881 | 877 | } |
---|
882 | 878 | } |
---|
883 | | - memset(inst->seg_id_buf.va, 0, inst->seg_id_buf.size); |
---|
| 879 | + |
---|
| 880 | + if (!(vsi->show_frame & BIT(4))) |
---|
| 881 | + memset(inst->seg_id_buf.va, 0, inst->seg_id_buf.size); |
---|
| 882 | + |
---|
884 | 883 | ret = vpu_dec_start(&inst->vpu, data, 3); |
---|
885 | 884 | if (ret) { |
---|
886 | 885 | mtk_vcodec_err(inst, "vpu_dec_start failed"); |
---|
887 | 886 | goto DECODE_ERROR; |
---|
| 887 | + } |
---|
| 888 | + |
---|
| 889 | + if (vsi->show_frame & BIT(1)) { |
---|
| 890 | + memset(inst->seg_id_buf.va, 0, inst->seg_id_buf.size); |
---|
| 891 | + |
---|
| 892 | + if (vsi->show_frame & BIT(2)) { |
---|
| 893 | + ret = vpu_dec_start(&inst->vpu, NULL, 0); |
---|
| 894 | + if (ret) { |
---|
| 895 | + mtk_vcodec_err(inst, "vpu trig decoder failed"); |
---|
| 896 | + goto DECODE_ERROR; |
---|
| 897 | + } |
---|
| 898 | + } |
---|
888 | 899 | } |
---|
889 | 900 | |
---|
890 | 901 | ret = validate_vsi_array_indexes(inst, vsi); |
---|
.. | .. |
---|
895 | 906 | |
---|
896 | 907 | if (vsi->resolution_changed) { |
---|
897 | 908 | if (!vp9_alloc_work_buf(inst)) { |
---|
898 | | - ret = -EINVAL; |
---|
| 909 | + ret = -EIO; |
---|
899 | 910 | goto DECODE_ERROR; |
---|
900 | 911 | } |
---|
901 | 912 | } |
---|
.. | .. |
---|
924 | 935 | |
---|
925 | 936 | if (vsi->show_existing_frame && (vsi->frm_to_show_idx < |
---|
926 | 937 | VP9_MAX_FRM_BUF_NUM)) { |
---|
927 | | - mtk_vcodec_err(inst, |
---|
| 938 | + mtk_vcodec_debug(inst, |
---|
928 | 939 | "Skip Decode drv->new_fb_idx=%d, drv->frm_to_show_idx=%d", |
---|
929 | 940 | vsi->new_fb_idx, vsi->frm_to_show_idx); |
---|
930 | 941 | |
---|
931 | 942 | vp9_ref_cnt_fb(inst, &vsi->new_fb_idx, |
---|
932 | 943 | vsi->frm_to_show_idx); |
---|
933 | | - ret = -EINVAL; |
---|
934 | | - goto DECODE_ERROR; |
---|
935 | 944 | } |
---|
936 | 945 | |
---|
937 | 946 | /* VPU assign the buffer pointer in its address space, |
---|
.. | .. |
---|
951 | 960 | goto DECODE_ERROR; |
---|
952 | 961 | } |
---|
953 | 962 | |
---|
954 | | - if (vp9_decode_end_proc(inst) != true) { |
---|
| 963 | + if (!vp9_decode_end_proc(inst)) { |
---|
955 | 964 | mtk_vcodec_err(inst, "vp9_decode_end_proc"); |
---|
956 | 965 | ret = -EINVAL; |
---|
957 | 966 | goto DECODE_ERROR; |
---|
.. | .. |
---|
980 | 989 | cr->left, cr->top, cr->width, cr->height); |
---|
981 | 990 | } |
---|
982 | 991 | |
---|
983 | | -static int vdec_vp9_get_param(unsigned long h_vdec, |
---|
984 | | - enum vdec_get_param_type type, void *out) |
---|
| 992 | +static int vdec_vp9_get_param(void *h_vdec, enum vdec_get_param_type type, |
---|
| 993 | + void *out) |
---|
985 | 994 | { |
---|
986 | 995 | struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; |
---|
987 | 996 | int ret = 0; |
---|
.. | .. |
---|
1011 | 1020 | return ret; |
---|
1012 | 1021 | } |
---|
1013 | 1022 | |
---|
1014 | | -static struct vdec_common_if vdec_vp9_if = { |
---|
| 1023 | +const struct vdec_common_if vdec_vp9_if = { |
---|
1015 | 1024 | .init = vdec_vp9_init, |
---|
1016 | 1025 | .decode = vdec_vp9_decode, |
---|
1017 | 1026 | .get_param = vdec_vp9_get_param, |
---|
1018 | 1027 | .deinit = vdec_vp9_deinit, |
---|
1019 | 1028 | }; |
---|
1020 | | - |
---|
1021 | | -struct vdec_common_if *get_vp9_dec_comm_if(void); |
---|
1022 | | - |
---|
1023 | | -struct vdec_common_if *get_vp9_dec_comm_if(void) |
---|
1024 | | -{ |
---|
1025 | | - return &vdec_vp9_if; |
---|
1026 | | -} |
---|