.. | .. |
---|
| 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) |
---|
.. | .. |
---|
230 | 226 | if (fb->base_y.va == addr) { |
---|
231 | 227 | list_move_tail(&node->list, |
---|
232 | 228 | &inst->available_fb_node_list); |
---|
233 | | - break; |
---|
| 229 | + return fb; |
---|
234 | 230 | } |
---|
235 | 231 | } |
---|
236 | | - return fb; |
---|
| 232 | + |
---|
| 233 | + return NULL; |
---|
237 | 234 | } |
---|
238 | 235 | |
---|
239 | 236 | static void vp9_add_to_fb_free_list(struct vdec_vp9_inst *inst, |
---|
.. | .. |
---|
481 | 478 | */ |
---|
482 | 479 | if ((frm_to_show->fb != NULL) && |
---|
483 | 480 | (inst->cur_fb->base_y.size >= |
---|
484 | | - frm_to_show->fb->base_y.size)) { |
---|
| 481 | + frm_to_show->fb->base_y.size) && |
---|
| 482 | + (inst->cur_fb->base_c.size >= |
---|
| 483 | + frm_to_show->fb->base_c.size)) { |
---|
485 | 484 | memcpy((void *)inst->cur_fb->base_y.va, |
---|
486 | 485 | (void *)frm_to_show->fb->base_y.va, |
---|
487 | | - vsi->buf_w * |
---|
488 | | - vsi->buf_h); |
---|
| 486 | + frm_to_show->fb->base_y.size); |
---|
489 | 487 | memcpy((void *)inst->cur_fb->base_c.va, |
---|
490 | 488 | (void *)frm_to_show->fb->base_c.va, |
---|
491 | | - vsi->buf_w * |
---|
492 | | - vsi->buf_h / 2); |
---|
| 489 | + frm_to_show->fb->base_c.size); |
---|
493 | 490 | } else { |
---|
494 | 491 | /* After resolution change case, current CAPTURE buffer |
---|
495 | 492 | * may have less buffer size than frm_to_show buffer |
---|
.. | .. |
---|
502 | 499 | frm_to_show->fb->base_y.size); |
---|
503 | 500 | } |
---|
504 | 501 | if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) { |
---|
505 | | - if (vsi->show_frame) |
---|
| 502 | + if (vsi->show_frame & BIT(0)) |
---|
506 | 503 | vp9_add_to_fb_disp_list(inst, inst->cur_fb); |
---|
507 | 504 | } |
---|
508 | 505 | } else { |
---|
509 | 506 | if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) { |
---|
510 | | - if (vsi->show_frame) |
---|
| 507 | + if (vsi->show_frame & BIT(0)) |
---|
511 | 508 | vp9_add_to_fb_disp_list(inst, frm_to_show->fb); |
---|
512 | 509 | } |
---|
513 | 510 | } |
---|
.. | .. |
---|
702 | 699 | |
---|
703 | 700 | static void get_pic_info(struct vdec_vp9_inst *inst, struct vdec_pic_info *pic) |
---|
704 | 701 | { |
---|
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; |
---|
| 702 | + pic->fb_sz[0] = inst->vsi->buf_sz_y_bs + inst->vsi->buf_len_sz_y; |
---|
| 703 | + pic->fb_sz[1] = inst->vsi->buf_sz_c_bs + inst->vsi->buf_len_sz_c; |
---|
709 | 704 | |
---|
710 | 705 | pic->pic_w = inst->vsi->pic_w; |
---|
711 | 706 | pic->pic_h = inst->vsi->pic_h; |
---|
.. | .. |
---|
714 | 709 | |
---|
715 | 710 | mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", |
---|
716 | 711 | 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); |
---|
| 712 | + mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)", |
---|
| 713 | + pic->fb_sz[0], |
---|
| 714 | + pic->fb_sz[1]); |
---|
719 | 715 | } |
---|
720 | 716 | |
---|
721 | 717 | static void get_disp_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb) |
---|
.. | .. |
---|
766 | 762 | return 0; |
---|
767 | 763 | } |
---|
768 | 764 | |
---|
769 | | -static void vdec_vp9_deinit(unsigned long h_vdec) |
---|
| 765 | +static void vdec_vp9_deinit(void *h_vdec) |
---|
770 | 766 | { |
---|
771 | 767 | struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; |
---|
772 | 768 | struct mtk_vcodec_mem *mem; |
---|
.. | .. |
---|
788 | 784 | vp9_free_inst(inst); |
---|
789 | 785 | } |
---|
790 | 786 | |
---|
791 | | -static int vdec_vp9_init(struct mtk_vcodec_ctx *ctx, unsigned long *h_vdec) |
---|
| 787 | +static int vdec_vp9_init(struct mtk_vcodec_ctx *ctx) |
---|
792 | 788 | { |
---|
793 | 789 | struct vdec_vp9_inst *inst; |
---|
794 | 790 | |
---|
.. | .. |
---|
800 | 796 | inst->ctx = ctx; |
---|
801 | 797 | |
---|
802 | 798 | inst->vpu.id = IPI_VDEC_VP9; |
---|
803 | | - inst->vpu.dev = ctx->dev->vpu_plat_dev; |
---|
804 | 799 | inst->vpu.ctx = ctx; |
---|
805 | | - inst->vpu.handler = vpu_dec_ipi_handler; |
---|
806 | 800 | |
---|
807 | 801 | if (vpu_dec_init(&inst->vpu)) { |
---|
808 | 802 | mtk_vcodec_err(inst, "vp9_dec_vpu_init failed"); |
---|
.. | .. |
---|
810 | 804 | } |
---|
811 | 805 | |
---|
812 | 806 | inst->vsi = (struct vdec_vp9_vsi *)inst->vpu.vsi; |
---|
| 807 | + |
---|
| 808 | + inst->vsi->show_frame |= BIT(3); |
---|
| 809 | + |
---|
813 | 810 | init_all_fb_lists(inst); |
---|
814 | 811 | |
---|
815 | | - (*h_vdec) = (unsigned long)inst; |
---|
| 812 | + ctx->drv_handle = inst; |
---|
816 | 813 | return 0; |
---|
817 | 814 | |
---|
818 | 815 | err_deinit_inst: |
---|
.. | .. |
---|
821 | 818 | return -EINVAL; |
---|
822 | 819 | } |
---|
823 | 820 | |
---|
824 | | -static int vdec_vp9_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs, |
---|
825 | | - struct vdec_fb *fb, bool *res_chg) |
---|
| 821 | +static int vdec_vp9_decode(void *h_vdec, struct mtk_vcodec_mem *bs, |
---|
| 822 | + struct vdec_fb *fb, bool *res_chg) |
---|
826 | 823 | { |
---|
827 | 824 | int ret = 0; |
---|
828 | 825 | struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; |
---|
.. | .. |
---|
880 | 877 | vsi->sf_frm_sz[idx]); |
---|
881 | 878 | } |
---|
882 | 879 | } |
---|
883 | | - memset(inst->seg_id_buf.va, 0, inst->seg_id_buf.size); |
---|
| 880 | + |
---|
| 881 | + if (!(vsi->show_frame & BIT(4))) |
---|
| 882 | + memset(inst->seg_id_buf.va, 0, inst->seg_id_buf.size); |
---|
| 883 | + |
---|
884 | 884 | ret = vpu_dec_start(&inst->vpu, data, 3); |
---|
885 | 885 | if (ret) { |
---|
886 | 886 | mtk_vcodec_err(inst, "vpu_dec_start failed"); |
---|
887 | 887 | goto DECODE_ERROR; |
---|
| 888 | + } |
---|
| 889 | + |
---|
| 890 | + if (vsi->show_frame & BIT(1)) { |
---|
| 891 | + memset(inst->seg_id_buf.va, 0, inst->seg_id_buf.size); |
---|
| 892 | + |
---|
| 893 | + if (vsi->show_frame & BIT(2)) { |
---|
| 894 | + ret = vpu_dec_start(&inst->vpu, NULL, 0); |
---|
| 895 | + if (ret) { |
---|
| 896 | + mtk_vcodec_err(inst, "vpu trig decoder failed"); |
---|
| 897 | + goto DECODE_ERROR; |
---|
| 898 | + } |
---|
| 899 | + } |
---|
888 | 900 | } |
---|
889 | 901 | |
---|
890 | 902 | ret = validate_vsi_array_indexes(inst, vsi); |
---|
.. | .. |
---|
895 | 907 | |
---|
896 | 908 | if (vsi->resolution_changed) { |
---|
897 | 909 | if (!vp9_alloc_work_buf(inst)) { |
---|
898 | | - ret = -EINVAL; |
---|
| 910 | + ret = -EIO; |
---|
899 | 911 | goto DECODE_ERROR; |
---|
900 | 912 | } |
---|
901 | 913 | } |
---|
.. | .. |
---|
924 | 936 | |
---|
925 | 937 | if (vsi->show_existing_frame && (vsi->frm_to_show_idx < |
---|
926 | 938 | VP9_MAX_FRM_BUF_NUM)) { |
---|
927 | | - mtk_vcodec_err(inst, |
---|
| 939 | + mtk_vcodec_debug(inst, |
---|
928 | 940 | "Skip Decode drv->new_fb_idx=%d, drv->frm_to_show_idx=%d", |
---|
929 | 941 | vsi->new_fb_idx, vsi->frm_to_show_idx); |
---|
930 | 942 | |
---|
931 | 943 | vp9_ref_cnt_fb(inst, &vsi->new_fb_idx, |
---|
932 | 944 | vsi->frm_to_show_idx); |
---|
933 | | - ret = -EINVAL; |
---|
934 | | - goto DECODE_ERROR; |
---|
935 | 945 | } |
---|
936 | 946 | |
---|
937 | 947 | /* VPU assign the buffer pointer in its address space, |
---|
.. | .. |
---|
951 | 961 | goto DECODE_ERROR; |
---|
952 | 962 | } |
---|
953 | 963 | |
---|
954 | | - if (vp9_decode_end_proc(inst) != true) { |
---|
| 964 | + if (!vp9_decode_end_proc(inst)) { |
---|
955 | 965 | mtk_vcodec_err(inst, "vp9_decode_end_proc"); |
---|
956 | 966 | ret = -EINVAL; |
---|
957 | 967 | goto DECODE_ERROR; |
---|
.. | .. |
---|
980 | 990 | cr->left, cr->top, cr->width, cr->height); |
---|
981 | 991 | } |
---|
982 | 992 | |
---|
983 | | -static int vdec_vp9_get_param(unsigned long h_vdec, |
---|
984 | | - enum vdec_get_param_type type, void *out) |
---|
| 993 | +static int vdec_vp9_get_param(void *h_vdec, enum vdec_get_param_type type, |
---|
| 994 | + void *out) |
---|
985 | 995 | { |
---|
986 | 996 | struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; |
---|
987 | 997 | int ret = 0; |
---|
.. | .. |
---|
1011 | 1021 | return ret; |
---|
1012 | 1022 | } |
---|
1013 | 1023 | |
---|
1014 | | -static struct vdec_common_if vdec_vp9_if = { |
---|
| 1024 | +const struct vdec_common_if vdec_vp9_if = { |
---|
1015 | 1025 | .init = vdec_vp9_init, |
---|
1016 | 1026 | .decode = vdec_vp9_decode, |
---|
1017 | 1027 | .get_param = vdec_vp9_get_param, |
---|
1018 | 1028 | .deinit = vdec_vp9_deinit, |
---|
1019 | 1029 | }; |
---|
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 | | -} |
---|