| // SPDX-License-Identifier: (GPL-2.0+ OR MIT) |
| /* |
| * drivers/amlogic/media/di_multi/deinterlace.c |
| * |
| * Copyright (C) 2017 Amlogic, Inc. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| * more details. |
| * |
| */ |
| |
| #include <linux/version.h> |
| #include <linux/module.h> |
| #include <linux/types.h> |
| #include <linux/kernel.h> |
| #include <linux/kthread.h> |
| #include <linux/semaphore.h> |
| #include <linux/workqueue.h> |
| #include <linux/spinlock.h> |
| #include <linux/delay.h> |
| #include <linux/interrupt.h> |
| #include <linux/fs.h> |
| #include <linux/init.h> |
| #include <linux/device.h> |
| #include <linux/mm.h> |
| #include <linux/slab.h> |
| #include <linux/major.h> |
| #include <linux/platform_device.h> |
| #include <linux/mutex.h> |
| #include <linux/cdev.h> |
| #include <linux/proc_fs.h> |
| #include <linux/list.h> |
| #include <linux/of_reserved_mem.h> |
| #include <linux/of_irq.h> |
| #include <linux/uaccess.h> |
| #include <linux/of_fdt.h> |
| #include <linux/cma.h> |
| #include <linux/dma-contiguous.h> |
| #include <linux/ctype.h> |
| #include <linux/string.h> |
| #include <linux/amlogic/iomap.h> |
| #include <linux/amlogic/media/codec_mm/codec_mm.h> |
| #include <linux/amlogic/cpu_version.h> |
| #include <linux/amlogic/media/vfm/vframe.h> |
| #include <linux/amlogic/media/vfm/vframe_provider.h> |
| #include <linux/amlogic/media/vfm/vframe_receiver.h> |
| #include <linux/amlogic/media/canvas/canvas.h> |
| #include <linux/amlogic/media/canvas/canvas_mgr.h> |
| #include <linux/amlogic/media/frame_provider/tvin/tvin_v4l2.h> |
| #include <linux/amlogic/media/vout/vinfo.h> |
| #include <linux/amlogic/media/vout/vout_notify.h> |
| #include <linux/amlogic/media/vpu/vpu.h> |
| #ifdef CONFIG_AMLOGIC_MEDIA_RDMA |
| #include <linux/amlogic/media/rdma/rdma_mgr.h> |
| #endif |
| #include <linux/amlogic/media/video_sink/video.h> |
| |
| #include "../common/vfm/vfm.h" |
| |
| #include "register.h" |
| #include "deinterlace.h" |
| #include "deinterlace_dbg.h" |
| #include "nr_downscale.h" |
| #include "di_reg_v2.h" |
| |
| #include "di_data_l.h" |
| #include "deinterlace_hw.h" |
| #include "sc2/di_hw_v3.h" |
| #include "sc2/di_afbc_v3.h" |
| |
| #include "di_dbg.h" |
| #include "di_pps.h" |
| #include "di_pre.h" |
| #include "di_prc.h" |
| #include "di_task.h" |
| #include "di_vframe.h" |
| #include "di_que.h" |
| #include "di_api.h" |
| #include "di_sys.h" |
| #include "di_reg_v3.h" |
| #include "dolby_sys.h" |
| /*2018-07-18 add debugfs*/ |
| #include <linux/seq_file.h> |
| #include <linux/debugfs.h> |
| /*2018-07-18 -----------*/ |
| |
| #ifdef DET3D |
| #include "detect3d.h" |
| #endif |
| //#define ENABLE_SPIN_LOCK_ALWAYS |
| |
| static DEFINE_SPINLOCK(di_lock2); |
| |
| #define di_lock_irqfiq_save(irq_flag) \ |
| spin_lock_irqsave(&di_lock2, irq_flag) |
| |
| #define di_unlock_irqfiq_restore(irq_flag) \ |
| spin_unlock_irqrestore(&di_lock2, irq_flag) |
| void di_lock_irq(void) |
| { |
| spin_lock(&di_lock2); |
| } |
| |
| void di_unlock_irq(void) |
| { |
| spin_unlock(&di_lock2); |
| } |
| |
| #ifdef SUPPORT_MPEG_TO_VDIN |
| static int mpeg2vdin_flag; |
| static int mpeg2vdin_en; |
| #endif |
| |
| static int di_reg_unreg_cnt = 40; |
| static bool overturn; |
| |
| int dim_get_reg_unreg_cnt(void) |
| { |
| return di_reg_unreg_cnt; |
| } |
| |
| static bool mc_mem_alloc; |
| |
| bool dim_get_mcmem_alloc(void) |
| { |
| return mc_mem_alloc; |
| } |
| |
| static unsigned int di_pre_rdma_enable; |
| |
| static int kpi_frame_num;// default print first coming n frames |
| |
| int di_get_kpi_frame_num(void) |
| { |
| return kpi_frame_num; |
| } |
| /************************************** |
| * |
| * |
| *************************************/ |
| //move to di_prc.c |
| #ifdef MARK_HIS |
| unsigned int di_dbg = DBG_M_EVENT; |
| module_param(di_dbg, uint, 0664); |
| MODULE_PARM_DESC(di_dbg, "debug print"); |
| #endif |
| |
| /* destroy unnecessary frames before display */ |
| static unsigned int hold_video; |
| |
| DEFINE_SPINLOCK(plist_lock); |
| |
| static const char version_s[] = "2019-04-25ma"; |
| |
| /*1:enable bypass pre,ei only; |
| * 2:debug force bypass pre,ei for post |
| */ |
| static int bypass_pre; |
| |
| static int invert_top_bot; |
| |
| /* add avoid vframe put/get error */ |
| static int di_blocking; |
| /* |
| * bit[2]: enable bypass all when skip |
| * bit[1:0]: enable bypass post when skip |
| */ |
| /*static int di_vscale_skip_enable;*/ |
| |
| /* 0: not support nr10bit, 1: support nr10bit */ |
| /*static unsigned int nr10bit_support;*/ |
| |
| #ifdef RUN_DI_PROCESS_IN_IRQ |
| /* |
| * di_process() run in irq, |
| * dim_reg_process(), dim_unreg_process() run in kernel thread |
| * dim_reg_process_irq(), di_unreg_process_irq() run in irq |
| * di_vf_put(), di_vf_peek(), di_vf_get() run in irq |
| * di_receiver_event_fun() run in task or irq |
| */ |
| /* |
| * important: |
| * to set input2pre, VFRAME_EVENT_PROVIDER_VFRAME_READY of |
| * vdin should be sent in irq |
| */ |
| |
| static int input2pre; |
| /*false:process progress by field; |
| * true: process progress by frame with 2 interlace buffer |
| */ |
| static int input2pre_buf_miss_count; |
| static int input2pre_proc_miss_count; |
| static int input2pre_throw_count; |
| static int input2pre_miss_policy; |
| /* 0, do not force pre_de_busy to 0, use di_wr_buf after dim_irq happen; |
| * 1, force pre_de_busy to 0 and call |
| * dim_pre_de_done_buf_clear to clear di_wr_buf |
| */ |
| #endif |
| /*false:process progress by field; |
| * bit0: process progress by frame with 2 interlace buffer |
| * bit1: temp add debug for 3d process FA,1:bit0 force to 1; |
| */ |
| /*static int use_2_interlace_buff;*/ |
| /* prog_proc_config, |
| * bit[2:1]: when two field buffers are used, |
| * 0 use vpp for blending , |
| * 1 use post_di module for blending |
| * 2 debug mode, bob with top field |
| * 3 debug mode, bot with bot field |
| * bit[0]: |
| * 0 "prog vdin" use two field buffers, |
| * 1 "prog vdin" use single frame buffer |
| * bit[4]: |
| * 0 "prog frame from decoder/vdin" use two field buffers, |
| * 1 use single frame buffer |
| * bit[5]: |
| * when two field buffers are used for decoder (bit[4] is 0): |
| * 1,handle prog frame as two interlace frames |
| * bit[6]:(bit[4] is 0,bit[5] is 0,use_2_interlace_buff is 0): 0, |
| * process progress frame as field,blend by post; |
| * 1, process progress frame as field,process by normal di |
| */ |
| /*static int prog_proc_config = (1 << 5) | (1 << 1) | 1;*/ |
| /* |
| * for source include both progressive and interlace pictures, |
| * always use post_di module for blending |
| */ |
| #define is_handle_prog_frame_as_interlace(vframe) \ |
| (((dimp_get(edi_mp_prog_proc_config) & 0x30) == 0x20) && \ |
| (((vframe)->type & VIDTYPE_VIU_422) == 0)) |
| |
| static int frame_count; |
| static int disp_frame_count; |
| int di_get_disp_cnt(void) |
| { |
| return disp_frame_count; |
| } |
| |
| static unsigned long reg_unreg_timeout_cnt; |
| #ifdef DET3D |
| static unsigned int det3d_mode; |
| static void set3d_view(enum tvin_trans_fmt trans_fmt, struct vframe_s *vf); |
| #endif |
| |
| static void di_pq_parm_destroy(struct di_pq_parm_s *pq_ptr); |
| static struct di_pq_parm_s *di_pq_parm_create(struct am_pq_parm_s *); |
| |
| //static unsigned int unreg_cnt;/*cnt for vframe unreg*/ |
| //static unsigned int reg_cnt;/*cnt for vframe reg*/ |
| |
| static unsigned char recovery_flag; |
| |
| static unsigned int recovery_log_reason; |
| static unsigned int recovery_log_queue_idx; |
| static struct di_buf_s *recovery_log_di_buf; |
| |
| unsigned char dim_vcry_get_flg(void) |
| { |
| return recovery_flag; |
| } |
| |
| void dim_vcry_flg_inc(void) |
| { |
| recovery_flag++; |
| } |
| |
| void dim_vcry_set_flg(unsigned char val) |
| { |
| recovery_flag = val; |
| } |
| |
| void dim_reg_timeout_inc(void) |
| { |
| reg_unreg_timeout_cnt++; |
| } |
| |
| /********************************/ |
| unsigned int dim_vcry_get_log_reason(void) |
| { |
| return recovery_log_reason; |
| } |
| |
| void dim_vcry_set_log_reason(unsigned int val) |
| { |
| recovery_log_reason = val; |
| } |
| |
| /********************************/ |
| unsigned char dim_vcry_get_log_q_idx(void) |
| { |
| return recovery_log_queue_idx; |
| } |
| |
| void dim_vcry_set_log_q_idx(unsigned int val) |
| { |
| recovery_log_queue_idx = val; |
| } |
| |
| /********************************/ |
| struct di_buf_s **dim_vcry_get_log_di_buf(void) |
| { |
| return &recovery_log_di_buf; |
| } |
| |
| void dim_vcry_set_log_di_buf(struct di_buf_s *di_bufp) |
| { |
| recovery_log_di_buf = di_bufp; |
| } |
| |
| void dim_vcry_set(unsigned int reason, unsigned int idx, |
| struct di_buf_s *di_bufp) |
| { |
| recovery_log_reason = reason; |
| recovery_log_queue_idx = idx; |
| recovery_log_di_buf = di_bufp; |
| } |
| |
| static long same_field_top_count; |
| static long same_field_bot_count; |
| /* bit 0: |
| * 0, keep 3 buffers in pre_ready_list for checking; |
| * 1, keep 4 buffers in pre_ready_list for checking; |
| */ |
| |
| static struct queue_s *get_queue_by_idx(unsigned int channel, int idx); |
| //static void dump_state(unsigned int channel); |
| //static void recycle_keep_buffer(unsigned int channel); |
| |
| #define DI_PRE_INTERVAL (HZ / 100) |
| |
| /* |
| * progressive frame process type config: |
| * 0, process by field; |
| * 1, process by frame (only valid for vdin source whose |
| * width/height does not change) |
| */ |
| |
| //static struct di_buf_s *cur_post_ready_di_buf; |
| |
| /************For Write register**********************/ |
| |
| static unsigned int num_di_stop_reg_addr = 4; |
| static unsigned int di_stop_reg_addr[4] = {0}; |
| |
| static unsigned int is_need_stop_reg(unsigned int addr) |
| { |
| int idx = 0; |
| |
| if (dimp_get(edi_mp_di_stop_reg_flag)) { |
| for (idx = 0; idx < num_di_stop_reg_addr; idx++) { |
| if (addr == di_stop_reg_addr[idx]) { |
| pr_dbg("stop write addr: %x\n", addr); |
| return 1; |
| } |
| } |
| } |
| |
| return 0; |
| } |
| |
| void DIM_DI_WR(unsigned int addr, unsigned int val) |
| { |
| if (is_need_stop_reg(addr)) |
| return; |
| ddbg_reg_save(addr, val, 0, 32); |
| WR(addr, val); |
| } |
| |
| void wr_reg_bits(unsigned int adr, unsigned int val, |
| unsigned int start, unsigned int len) |
| { |
| if (len >= 32) { |
| DIM_DI_WR(adr, val); |
| return; |
| } |
| aml_vcbus_update_bits(adr, ((1 << (len)) - 1) << (start), |
| (val) << (start)); |
| } |
| |
| void DIM_DI_WR_REG_BITS(unsigned int adr, unsigned int val, |
| unsigned int start, unsigned int len) |
| { |
| if (is_need_stop_reg(adr)) |
| return; |
| ddbg_reg_save(adr, val, start, len); /*ary add for debug*/ |
| wr_reg_bits(adr, val, start, len); |
| } |
| |
| void DIM_VSYNC_WR_MPEG_REG(unsigned int addr, unsigned int val) |
| { |
| if (is_need_stop_reg(addr)) |
| return; |
| if (dimp_get(edi_mp_post_wr_en) && dimp_get(edi_mp_post_wr_support)) |
| DIM_DI_WR(addr, val); |
| else |
| VSYNC_WR_MPEG_REG(addr, val); |
| } |
| |
| /* dim_VSYNC_WR_MPEG_REG_BITS */ |
| |
| unsigned int DIM_VSC_WR_MPG_BT(unsigned int addr, unsigned int val, |
| unsigned int start, unsigned int len) |
| { |
| if (is_need_stop_reg(addr)) |
| return 0; |
| if (dimp_get(edi_mp_post_wr_en) && dimp_get(edi_mp_post_wr_support)) |
| DIM_DI_WR_REG_BITS(addr, val, start, len); |
| else |
| VSYNC_WR_MPEG_REG_BITS(addr, val, start, len); |
| |
| return 0; |
| } |
| |
| #ifdef DI_V2 |
| unsigned int DI_POST_REG_RD(unsigned int addr) |
| { |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| |
| if (IS_ERR_OR_NULL(de_devp)) |
| return 0; |
| if (de_devp->flags & DI_SUSPEND_FLAG) { |
| PR_ERR("REG 0x%x access prohibited.\n", addr); |
| return 0; |
| } |
| return VSYNC_RD_MPEG_REG(addr); |
| } |
| EXPORT_SYMBOL(DI_POST_REG_RD); |
| |
| int DI_POST_WR_REG_BITS(u32 adr, u32 val, u32 start, u32 len) |
| { |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| |
| if (IS_ERR_OR_NULL(de_devp)) |
| return 0; |
| if (de_devp->flags & DI_SUSPEND_FLAG) { |
| PR_ERR("REG 0x%x access prohibited.\n", adr); |
| return -1; |
| } |
| return VSYNC_WR_MPEG_REG_BITS(adr, val, start, len); |
| } |
| EXPORT_SYMBOL(DI_POST_WR_REG_BITS); |
| #else |
| unsigned int l_DI_POST_REG_RD(unsigned int addr) |
| { |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| |
| if (IS_ERR_OR_NULL(de_devp)) |
| return 0; |
| if (de_devp->flags & DI_SUSPEND_FLAG) { |
| PR_ERR("REG 0x%x access prohibited.\n", addr); |
| return 0; |
| } |
| return VSYNC_RD_MPEG_REG(addr); |
| } |
| |
| int l_DI_POST_WR_REG_BITS(u32 adr, u32 val, u32 start, u32 len) |
| { |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| |
| if (IS_ERR_OR_NULL(de_devp)) |
| return 0; |
| if (de_devp->flags & DI_SUSPEND_FLAG) { |
| PR_ERR("REG 0x%x access prohibited.\n", adr); |
| return -1; |
| } |
| return VSYNC_WR_MPEG_REG_BITS(adr, val, start, len); |
| } |
| |
| #endif |
| /**********************************/ |
| |
| /***************************** |
| * di attr management : |
| * enable |
| * mode |
| * reg |
| ******************************/ |
| /*config attr*/ |
| |
| int pre_run_flag = DI_RUN_FLAG_RUN; |
| static int dump_state_flag; |
| |
| int dump_state_flag_get(void) |
| { |
| return dump_state_flag; |
| } |
| const struct afd_ops_s *dim_afds(void) |
| { |
| return get_datal()->afds; |
| } |
| |
| struct afbcd_ctr_s *di_get_afd_ctr(void) |
| { |
| return &get_datal()->di_afd.ctr; |
| } |
| |
| const char *dim_get_version_s(void) |
| { |
| return version_s; |
| } |
| |
| int dim_get_blocking(void) |
| { |
| return di_blocking; |
| } |
| |
| unsigned long dim_get_reg_unreg_timeout_cnt(void) |
| { |
| return reg_unreg_timeout_cnt; |
| } |
| |
| struct di_buf_s *dim_get_recovery_log_di_buf(void) |
| { |
| return recovery_log_di_buf; |
| } |
| |
| struct vframe_s **dim_get_vframe_in(unsigned int ch) |
| { |
| return get_vframe_in(ch); |
| } |
| |
| int dim_get_dump_state_flag(void) |
| { |
| return dump_state_flag; |
| } |
| |
| /*--------------------------*/ |
| |
| ssize_t |
| store_dbg(struct device *dev, |
| struct device_attribute *attr, |
| const char *buf, size_t count) |
| { |
| unsigned int channel = get_current_channel(); /* debug only*/ |
| struct di_buf_s *pbuf_local = get_buf_local(channel); |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| struct di_post_stru_s *ppost = get_post_stru(channel); |
| |
| if (strncmp(buf, "buf", 3) == 0) { |
| struct di_buf_s *di_buf_tmp = 0; |
| |
| if (kstrtoul(buf + 3, 16, (unsigned long *)&di_buf_tmp)) |
| return count; |
| dim_dump_di_buf(di_buf_tmp); |
| } else if (strncmp(buf, "vframe", 6) == 0) { |
| vframe_t *vf = 0; |
| |
| if (kstrtoul(buf + 6, 16, (unsigned long *)&vf)) |
| return count; |
| dim_dump_vframe(vf); |
| } else if (strncmp(buf, "pool", 4) == 0) { |
| unsigned long idx = 0; |
| |
| if (kstrtoul(buf + 4, 10, &idx)) |
| return count; |
| dim_dump_pool(get_queue_by_idx(channel, idx)); |
| } else if (strncmp(buf, "state", 4) == 0) { |
| //dump_state(channel); |
| pr_info("add new debugfs: cat /sys/kernel/debug/di/state\n"); |
| } else if (strncmp(buf, "prog_proc_config", 16) == 0) { |
| if (buf[16] == '1') |
| dimp_set(edi_mp_prog_proc_config, 1); |
| else |
| dimp_set(edi_mp_prog_proc_config, 0); |
| } else if (strncmp(buf, "init_flag", 9) == 0) { |
| if (buf[9] == '1') |
| set_init_flag(0, true);/*init_flag = 1;*/ |
| else |
| set_init_flag(0, false);/*init_flag = 0;*/ |
| } else if (strncmp(buf, "prun", 4) == 0) { |
| pre_run_flag = DI_RUN_FLAG_RUN; |
| } else if (strncmp(buf, "ppause", 6) == 0) { |
| pre_run_flag = DI_RUN_FLAG_PAUSE; |
| } else if (strncmp(buf, "pstep", 5) == 0) { |
| pre_run_flag = DI_RUN_FLAG_STEP; |
| } else if (strncmp(buf, "dumpreg", 7) == 0) { |
| pr_info("add new debugfs: cat /sys/kernel/debug/di/dumpreg\n"); |
| } else if (strncmp(buf, "dumpmif", 7) == 0) { |
| dim_dump_mif_size_state(ppre, ppost); |
| } else if (strncmp(buf, "recycle_buf", 11) == 0) { |
| // recycle_keep_buffer(channel); |
| } else if (strncmp(buf, "recycle_post", 12) == 0) { |
| if (di_vf_l_peek(channel)) |
| di_vf_l_put(di_vf_l_get(channel), channel); |
| } else if (strncmp(buf, "mem_map", 7) == 0) { |
| dim_dump_buf_addr(pbuf_local, MAX_LOCAL_BUF_NUM * 2); |
| } else if (strncmp(buf, "setdv", 5) == 0) { |
| pr_info("setdv\n"); |
| di_dolby_do_setting(); |
| } else if (strncmp(buf, "endv", 4) == 0) { |
| pr_info("endv\n"); |
| di_dolby_enable(1); |
| } else if (strncmp(buf, "initdv", 6) == 0) { |
| pr_info("initdv\n"); |
| di_dolby_sw_init(); |
| } else if (strncmp(buf, "crcdump", 7) == 0) { |
| dim_dump_crc_state(); |
| } else if (strncmp(buf, "pulldown", 8) == 0) { |
| dim_dump_pulldown_state(); |
| } else { |
| pr_info("DI no support cmd %s!!!\n", buf); |
| } |
| |
| return count; |
| } |
| |
| #ifdef ARY_TEMP |
| static int __init di_read_canvas_reverse(char *str) |
| { |
| unsigned char *ptr = str; |
| |
| pr_dbg("%s: bootargs is %s.\n", __func__, str); |
| if (strstr(ptr, "1")) { |
| invert_top_bot |= 0x1; |
| overturn = true; |
| } else { |
| invert_top_bot &= (~0x1); |
| overturn = false; |
| } |
| |
| return 0; |
| } |
| |
| __setup("video_reverse=", di_read_canvas_reverse); |
| #endif |
| |
| static unsigned char *di_log_buf; |
| static unsigned int di_log_wr_pos; |
| static unsigned int di_log_rd_pos; |
| static unsigned int di_log_buf_size; |
| |
| //static unsigned int buf_state_log_start; |
| /* set to 1 by condition of "post_ready count < buf_state_log_threshold", |
| * reset to 0 by set buf_state_log_threshold as 0 |
| */ |
| |
| static DEFINE_SPINLOCK(di_print_lock); |
| |
| #define PRINT_TEMP_BUF_SIZE 128 |
| |
| static int di_print_buf(char *buf, int len) |
| { |
| unsigned long flags; |
| int pos; |
| int di_log_rd_pos_; |
| |
| if (di_log_buf_size == 0) |
| return 0; |
| |
| spin_lock_irqsave(&di_print_lock, flags); |
| di_log_rd_pos_ = di_log_rd_pos; |
| if (di_log_wr_pos >= di_log_rd_pos) |
| di_log_rd_pos_ += di_log_buf_size; |
| |
| for (pos = 0; pos < len && di_log_wr_pos < (di_log_rd_pos_ - 1); |
| pos++, di_log_wr_pos++) { |
| if (di_log_wr_pos >= di_log_buf_size) |
| di_log_buf[di_log_wr_pos - di_log_buf_size] = buf[pos]; |
| else |
| di_log_buf[di_log_wr_pos] = buf[pos]; |
| } |
| if (di_log_wr_pos >= di_log_buf_size) |
| di_log_wr_pos -= di_log_buf_size; |
| spin_unlock_irqrestore(&di_print_lock, flags); |
| return pos; |
| } |
| |
| /* static int log_seq = 0; */ |
| int dim_print(const char *fmt, ...) |
| { |
| va_list args; |
| int avail = PRINT_TEMP_BUF_SIZE; |
| char buf[PRINT_TEMP_BUF_SIZE]; |
| int pos, len = 0; |
| |
| if (dimp_get(edi_mp_di_printk_flag) & 1) { |
| if (dimp_get(edi_mp_di_log_flag) & DI_LOG_PRECISE_TIMESTAMP) |
| pr_dbg("%llums:", cur_to_msecs()); |
| va_start(args, fmt); |
| vprintk(fmt, args); |
| va_end(args); |
| return 0; |
| } |
| |
| if (di_log_buf_size == 0) |
| return 0; |
| |
| /* len += snprintf(buf+len, avail-len, "%d:",log_seq++); */ |
| if (dimp_get(edi_mp_di_log_flag) & DI_LOG_TIMESTAMP) |
| len += snprintf(buf + len, avail - len, "%u:", |
| jiffies_to_msecs(jiffies_64)); |
| |
| va_start(args, fmt); |
| len += vsnprintf(buf + len, avail - len, fmt, args); |
| va_end(args); |
| |
| if ((avail - len) <= 0) |
| buf[PRINT_TEMP_BUF_SIZE - 1] = '\0'; |
| |
| pos = di_print_buf(buf, len); |
| /* pr_dbg("dim_print:%d %d\n", di_log_wr_pos, di_log_rd_pos); */ |
| return pos; |
| } |
| |
| ssize_t dim_read_log(char *buf) |
| { |
| unsigned long flags; |
| ssize_t read_size = 0; |
| |
| if (di_log_buf_size == 0) |
| return 0; |
| /* pr_dbg("show_log:%d %d\n", di_log_wr_pos, di_log_rd_pos); */ |
| spin_lock_irqsave(&di_print_lock, flags); |
| if (di_log_rd_pos < di_log_wr_pos) |
| read_size = di_log_wr_pos - di_log_rd_pos; |
| |
| else if (di_log_rd_pos > di_log_wr_pos) |
| read_size = di_log_buf_size - di_log_rd_pos; |
| |
| if (read_size > PAGE_SIZE) |
| read_size = PAGE_SIZE; |
| if (read_size > 0) |
| memcpy(buf, di_log_buf + di_log_rd_pos, read_size); |
| |
| di_log_rd_pos += read_size; |
| if (di_log_rd_pos >= di_log_buf_size) |
| di_log_rd_pos = 0; |
| spin_unlock_irqrestore(&di_print_lock, flags); |
| return read_size; |
| } |
| |
| ssize_t |
| store_log(struct device *dev, |
| struct device_attribute *attr, |
| const char *buf, size_t count) |
| { |
| unsigned long flags, tmp; |
| |
| if (strncmp(buf, "bufsize", 7) == 0) { |
| if (kstrtoul(buf + 7, 10, &tmp)) |
| return count; |
| spin_lock_irqsave(&di_print_lock, flags); |
| kfree(di_log_buf); |
| di_log_buf = NULL; |
| di_log_buf_size = 0; |
| di_log_rd_pos = 0; |
| di_log_wr_pos = 0; |
| if (tmp >= 1024) { |
| di_log_buf_size = 0; |
| di_log_rd_pos = 0; |
| di_log_wr_pos = 0; |
| di_log_buf = kmalloc(tmp, GFP_KERNEL); |
| if (di_log_buf) |
| di_log_buf_size = tmp; |
| } |
| spin_unlock_irqrestore(&di_print_lock, flags); |
| pr_dbg("di_store:set bufsize tmp %lu %u\n", |
| tmp, di_log_buf_size); |
| } else if (strncmp(buf, "printk", 6) == 0) { |
| if (kstrtoul(buf + 6, 10, &tmp)) |
| return count; |
| |
| dimp_set(edi_mp_di_printk_flag, tmp); |
| } else { |
| dim_print("%s", buf); |
| } |
| return 16; |
| } |
| |
| ssize_t |
| show_vframe_status(struct device *dev, |
| struct device_attribute *attr, |
| char *buf) |
| { |
| int ret = 0; |
| int get_ret = 0; |
| |
| struct vframe_states states; |
| int ch; |
| struct di_mng_s *pbm = get_bufmng(); |
| |
| for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { |
| if (!pbm->sub_act_flg[ch]) |
| continue; |
| else |
| ret += sprintf(buf + ret, "ch[%d]\n", ch); |
| |
| get_ret = vf_get_states_by_name(di_rev_name[ch], &states); |
| |
| if (get_ret == 0) { |
| ret += sprintf(buf + ret, "vframe_pool_size=%d\n", |
| states.vf_pool_size); |
| ret += sprintf(buf + ret, "vframe buf_free_num=%d\n", |
| states.buf_free_num); |
| ret += sprintf(buf + ret, "vframe buf_recycle_num=%d\n", |
| states.buf_recycle_num); |
| ret += sprintf(buf + ret, "vframe buf_avail_num=%d\n", |
| states.buf_avail_num); |
| } else { |
| ret += sprintf(buf + ret, "vframe no states\n"); |
| } |
| } |
| return ret; |
| } |
| |
| ssize_t |
| show_kpi_frame_num(struct device *dev, |
| struct device_attribute *attr, |
| char *buf) |
| { |
| return sprintf(buf, "kpi_frame_num:%d\n", kpi_frame_num); |
| } |
| |
| ssize_t |
| store_kpi_frame_num(struct device *dev, struct device_attribute *attr, |
| const char *buf, size_t len) |
| { |
| unsigned long num; |
| int ret = kstrtoul(buf, 0, (unsigned long *)&num); |
| |
| if (ret < 0) |
| return -EINVAL; |
| kpi_frame_num = (int)num; |
| return len; |
| } |
| |
| /*************************** |
| * di buffer management |
| ***************************/ |
| |
| static const char * const vframe_type_name[] = { |
| "", "di_buf_in", "di_buf_loc", "di_buf_post" |
| }; |
| |
| const char *dim_get_vfm_type_name(unsigned int nub) |
| { |
| if (nub < 4) |
| return vframe_type_name[nub]; |
| |
| return ""; |
| } |
| |
| static unsigned int default_width = 1920; |
| static unsigned int default_height = 1080; |
| |
| void dim_get_default(unsigned int *h, unsigned int *w) |
| { |
| *h = default_height; |
| *w = default_width; |
| } |
| |
| void di_set_default(unsigned int ch) |
| { |
| struct div2_mm_s *mm; |
| // enum EDI_SGN sgn; |
| // struct di_pre_stru_s *ppre = get_pre_stru(ch); |
| |
| mm = dim_mm_get(ch); |
| if (dim_afds() && |
| dip_is_support_4k(ch)) { |
| default_width = 3840; |
| default_height = 2160; |
| } else { |
| default_width = 1920; |
| default_height = 1080; |
| } |
| } |
| |
| void dbg_h_w(unsigned int ch, unsigned int nub) |
| { |
| struct div2_mm_s *mm; |
| |
| mm = dim_mm_get(ch); |
| dbg_reg("%s:ch[%d][%d]:h[%d],w[%d]\n", __func__, |
| ch, nub, mm->cfg.di_h, mm->cfg.di_w); |
| } |
| /* |
| * all buffers are in |
| * 1) list of local_free_list,in_free_list,pre_ready_list,recycle_list |
| * 2) di_pre_stru.di_inp_buf |
| * 3) di_pre_stru.di_wr_buf |
| * 4) cur_post_ready_di_buf |
| * 5) (struct di_buf_s*)(vframe->private_data)->di_buf[] |
| * |
| * 6) post_free_list_head |
| * 8) (struct di_buf_s*)(vframe->private_data) |
| */ |
| |
| /*move to deinterlace .h #define queue_t struct queue_s*/ |
| |
| static struct queue_s *get_queue_by_idx(unsigned int channel, int idx) |
| { |
| struct queue_s *pqueue = get_queue(channel); |
| |
| if (idx < QUEUE_NUM) |
| return &pqueue[idx]; |
| else |
| return NULL; |
| } |
| |
| struct di_buf_s *dim_get_buf(unsigned int channel, int queue_idx, |
| int *start_pos) |
| { |
| struct queue_s *pqueue = get_queue(channel); |
| queue_t *q = &pqueue[queue_idx]; |
| int idx = 0; |
| unsigned int pool_idx, num; |
| struct di_buf_s *di_buf = NULL; |
| int start_pos_init = *start_pos; |
| struct di_buf_pool_s *pbuf_pool = get_buf_pool(channel); |
| |
| if (dimp_get(edi_mp_di_log_flag) & DI_LOG_QUEUE) |
| dim_print("%s:<%d:%d,%d,%d> %d\n", __func__, queue_idx, |
| q->num, q->in_idx, q->out_idx, *start_pos); |
| |
| if (q->type == 0) { |
| if ((*start_pos) < q->num) { |
| idx = q->out_idx + (*start_pos); |
| if (idx >= MAX_QUEUE_POOL_SIZE) |
| idx -= MAX_QUEUE_POOL_SIZE; |
| |
| (*start_pos)++; |
| } else { |
| idx = MAX_QUEUE_POOL_SIZE; |
| } |
| } else if ((q->type == 1) || (q->type == 2)) { |
| for (idx = (*start_pos); idx < MAX_QUEUE_POOL_SIZE; idx++) { |
| if (q->pool[idx] != 0) { |
| *start_pos = idx + 1; |
| break; |
| } |
| } |
| } |
| if (idx < MAX_QUEUE_POOL_SIZE) { |
| pool_idx = ((q->pool[idx] >> 8) & 0xff) - 1; |
| num = q->pool[idx] & 0xff; |
| if (pool_idx < VFRAME_TYPE_NUM) { |
| if (num < pbuf_pool[pool_idx].size) |
| di_buf = |
| &pbuf_pool[pool_idx].di_buf_ptr[num]; |
| } |
| } |
| |
| if ((di_buf) && ((((pool_idx + 1) << 8) | num) |
| != ((di_buf->type << 8) | di_buf->index))) { |
| PR_ERR("%s:(%x,%x)\n", __func__, |
| (((pool_idx + 1) << 8) | num), |
| ((di_buf->type << 8) | (di_buf->index))); |
| if (recovery_flag == 0) { |
| recovery_log_reason = 1; |
| recovery_log_queue_idx = |
| (start_pos_init << 8) | queue_idx; |
| recovery_log_di_buf = di_buf; |
| } |
| recovery_flag++; |
| di_buf = NULL; |
| } |
| |
| if (dimp_get(edi_mp_di_log_flag) & DI_LOG_QUEUE) { |
| if (di_buf) |
| dim_print("%s: 0x%p(%d,%d)\n", __func__, di_buf, |
| pool_idx, num); |
| else |
| dim_print("%s: 0x%p\n", __func__, di_buf); |
| } |
| |
| return di_buf; |
| } |
| |
| /*--------------------------*/ |
| /*--------------------------*/ |
| ssize_t |
| store_dump_mem(struct device *dev, struct device_attribute *attr, |
| const char *buf, size_t len) |
| { |
| unsigned int n = 0, canvas_w = 0, canvas_h = 0; |
| unsigned long nr_size = 0, dump_adr = 0; |
| struct di_buf_s *di_buf = NULL; |
| struct vframe_s *post_vf = NULL; |
| char *buf_orig, *ps, *token; |
| char *parm[5] = { NULL }; |
| char delim1[3] = " "; |
| char delim2[2] = "\n"; |
| struct file *filp = NULL; |
| loff_t pos = 0; |
| void *buff = NULL; |
| mm_segment_t old_fs; |
| bool bflg_vmap = false; |
| unsigned int channel = get_current_channel();/* debug only*/ |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| // struct di_dev_s *de_devp = get_dim_de_devp(); |
| /*ary add 2019-07-2 being*/ |
| unsigned int indx; |
| struct di_buf_s *pbuf_post; |
| struct di_buf_s *pbuf_local; |
| struct di_post_stru_s *ppost; |
| struct div2_mm_s *mm; |
| struct di_ch_s *pch; |
| unsigned int sh, sv; |
| /*************************/ |
| pch = get_chdata(channel); |
| |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| ps = buf_orig; |
| strcat(delim1, delim2); |
| while (1) { |
| token = strsep(&ps, delim1); |
| if (!token) |
| break; |
| if (*token == '\0') |
| continue; |
| parm[n++] = token; |
| } |
| if (strcmp(parm[0], "capture") == 0) { |
| di_buf = ppre->di_mem_buf_dup_p; |
| } else if (strcmp(parm[0], "c_post") == 0) { |
| /*ary add 2019-07-2*/ |
| if (kstrtouint(parm[2], 0, &channel)) { |
| PR_ERR("c_post:ch is not number\n"); |
| kfree(buf_orig); |
| return 0; |
| } |
| if (kstrtouint(parm[3], 0, &indx)) { |
| PR_ERR("c_post:ch is not number\n"); |
| kfree(buf_orig); |
| return 0; |
| } |
| di_pr_info("c_post:ch[%d],index[%d]\n", channel, indx); |
| mm = dim_mm_get(channel); |
| |
| ppre = get_pre_stru(channel); |
| ppost = get_post_stru(channel); |
| #ifdef MARK_SC2 |
| /*mm-0705 if (indx >= ppost->di_post_num) {*/ |
| if (indx >= mm->sts.num_post) { |
| PR_ERR("c_post:index is overflow:%d[%d]\n", indx, |
| mm->sts.num_post); |
| kfree(buf_orig); |
| return 0; |
| } |
| #endif |
| pbuf_post = get_buf_post(channel); |
| di_buf = &pbuf_post[indx]; |
| } else if (strcmp(parm[0], "c_local") == 0) { |
| /*ary add 2019-07-2*/ |
| if (kstrtouint(parm[2], 0, &channel)) { |
| PR_ERR("c_local:ch is not number\n"); |
| kfree(buf_orig); |
| return 0; |
| } |
| if (kstrtouint(parm[3], 0, &indx)) { |
| PR_ERR("c_local:ch is not number\n"); |
| kfree(buf_orig); |
| return 0; |
| } |
| di_pr_info("c_local:ch[%d],index[%d]\n", channel, indx); |
| |
| ppre = get_pre_stru(channel); |
| ppost = get_post_stru(channel); |
| #ifdef MARK_HIS |
| if (indx >= ppost->di_post_num) { |
| PR_ERR("c_local:index is overflow:%d[%d]\n", |
| indx, ppost->di_post_num); |
| kfree(buf_orig); |
| return 0; |
| } |
| #endif |
| pbuf_local = get_buf_local(channel); |
| di_buf = &pbuf_local[indx]; |
| } else if (strcmp(parm[0], "capture_pready") == 0) { /*ary add*/ |
| #ifdef MARK_HIS |
| if (!di_que_is_empty(channel, QUE_POST_READY)) { |
| di_buf = di_que_peek(channel, QUE_POST_READY); |
| pr_info("get post ready di_buf:%d:0x%p\n", |
| di_buf->index, di_buf); |
| } else { |
| pr_info("war:no post ready buf\n"); |
| } |
| #else |
| di_buf = ndrd_qpeekbuf(pch); |
| if (di_buf) |
| pr_info("get post ready di_buf:%d:0x%p\n", |
| di_buf->index, di_buf); |
| else |
| pr_info("war:no post ready buf\n"); |
| |
| #endif |
| } else if (strcmp(parm[0], "capture_post") == 0) { |
| if (di_vf_l_peek(channel)) { |
| post_vf = di_vf_l_get(channel); |
| if (!IS_ERR_OR_NULL(post_vf)) { |
| di_buf = post_vf->private_data; |
| di_vf_l_put(post_vf, channel); |
| pr_info("get post di_buf:%d:0x%p\n", |
| di_buf->index, di_buf); |
| } else { |
| pr_info("war:peek no post buf, vfm[0x%p]\n", |
| post_vf); |
| } |
| |
| post_vf = NULL; |
| } else { |
| pr_info("war:can't peek post buf\n"); |
| } |
| } else if (strcmp(parm[0], "capture_nrds") == 0) { |
| dim_get_nr_ds_buf(&dump_adr, &nr_size); |
| } else { |
| PR_ERR("wrong dump cmd\n"); |
| kfree(buf_orig); |
| return len; |
| } |
| if (nr_size == 0) { |
| if (unlikely(!di_buf)) { |
| pr_info("war:di_buf is null\n"); |
| kfree(buf_orig); |
| return len; |
| } |
| canvas_w = di_buf->canvas_width[NR_CANVAS]; |
| canvas_h = di_buf->canvas_height; |
| //nr_size = canvas_w * canvas_h * 2; |
| dump_adr = di_buf->nr_adr; |
| sh = di_buf->vframe->canvas0_config[0].width; |
| sv = di_buf->vframe->canvas0_config[0].height; |
| nr_size = sh * sv; |
| |
| if (di_buf->vframe->plane_num == 2) |
| nr_size = nr_size * 2; |
| |
| pr_info("w=%d,h=%d,size=%ld,addr=%lx\n", |
| canvas_w, canvas_h, nr_size, dump_adr); |
| } |
| old_fs = get_fs(); |
| set_fs(KERNEL_DS); |
| /* pr_dbg("dump path =%s\n",dump_path); */ |
| filp = filp_open(parm[1], O_RDWR | O_CREAT, 0666); |
| if (IS_ERR(filp)) { |
| PR_ERR("create %s error.\n", parm[1]); |
| kfree(buf_orig); |
| return len; |
| } |
| dump_state_flag = 1; |
| if (/*de_devp->flags & DI_MAP_FLAG*/ 1) { |
| /*buff = (void *)phys_to_virt(dump_adr);*/ |
| buff = dim_vmap(dump_adr, nr_size, &bflg_vmap); |
| if (!buff) { |
| if (nr_size <= 5222400) { |
| pr_info("di_vap err\n"); |
| filp_close(filp, NULL); |
| kfree(buf_orig); |
| return len; |
| } |
| /*try again:*/ |
| PR_INF("vap err,size to 5222400, try again\n"); |
| nr_size = 5222400; |
| buff = dim_vmap(dump_adr, nr_size, &bflg_vmap); |
| if (!buff) { |
| filp_close(filp, NULL); |
| kfree(buf_orig); |
| return len; |
| } |
| } |
| pr_info("wr buffer 0x%lx to %s.\n", dump_adr, parm[1]); |
| pr_info("size:0x%lx, bflg_vmap[%d]\n", nr_size, bflg_vmap); |
| } else { |
| buff = ioremap(dump_adr, nr_size); |
| } |
| if (IS_ERR_OR_NULL(buff)) |
| PR_ERR("%s: ioremap error.\n", __func__); |
| vfs_write(filp, buff, nr_size, &pos); |
| /* pr_dbg("di_chan2_buf_dup_p:\n nr:%u,mtn:%u,cnt:%u\n", |
| * di_pre_stru.di_chan2_buf_dup_p->nr_adr, |
| * di_pre_stru.di_chan2_buf_dup_p->mtn_adr, |
| * di_pre_stru.di_chan2_buf_dup_p->cnt_adr); |
| * pr_dbg("di_inp_buf:\n nr:%u,mtn:%u,cnt:%u\n", |
| * di_pre_stru.di_inp_buf->nr_adr, |
| * di_pre_stru.di_inp_buf->mtn_adr, |
| * di_pre_stru.di_inp_buf->cnt_adr); |
| * pr_dbg("di_wr_buf:\n nr:%u,mtn:%u,cnt:%u\n", |
| * di_pre_stru.di_wr_buf->nr_adr, |
| * di_pre_stru.di_wr_buf->mtn_adr, |
| * di_pre_stru.di_wr_buf->cnt_adr); |
| * pr_dbg("di_mem_buf_dup_p:\n nr:%u,mtn:%u,cnt:%u\n", |
| * di_pre_stru.di_mem_buf_dup_p->nr_adr, |
| * di_pre_stru.di_mem_buf_dup_p->mtn_adr, |
| * di_pre_stru.di_mem_buf_dup_p->cnt_adr); |
| * pr_dbg("di_mem_start=%u\n",di_mem_start); |
| */ |
| vfs_fsync(filp, 0); |
| pr_info("write buffer 0x%lx to %s.\n", dump_adr, parm[1]); |
| if (bflg_vmap) |
| dim_unmap_phyaddr(buff); |
| #ifdef MARK_HIS |
| if (!(de_devp->flags & DI_MAP_FLAG)) |
| iounmap(buff); |
| #endif |
| dump_state_flag = 0; |
| filp_close(filp, NULL); |
| set_fs(old_fs); |
| kfree(buf_orig); |
| return len; |
| } |
| |
| static void recycle_vframe_type_pre(struct di_buf_s *di_buf, |
| unsigned int channel); |
| static void recycle_vframe_type_post(struct di_buf_s *di_buf, |
| unsigned int channel); |
| static void add_dummy_vframe_type_pre(struct di_buf_s *src_buf, |
| unsigned int channel); |
| #ifdef DI_BUFFER_DEBUG |
| static void |
| recycle_vframe_type_post_print(struct di_buf_s *di_buf, |
| const char *func, |
| const int line); |
| #endif |
| |
| static void dis2_di(void) |
| { |
| //ary 2020-12-09 ulong flags = 0, irq_flag2 = 0; |
| unsigned int channel = get_current_channel();/* debug only*/ |
| struct vframe_s **pvframe_in = get_vframe_in(channel); |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| |
| set_init_flag(channel, false);/*init_flag = 0;*/ |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); |
| /* vf_unreg_provider(&di_vf_prov); */ |
| pw_vf_light_unreg_provider(channel); |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| set_reg_flag(channel, false); |
| //ary 2020-12-09 spin_lock_irqsave(&plist_lock, flags); |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); |
| if (ppre->di_inp_buf) { |
| if (pvframe_in[ppre->di_inp_buf->index]) { |
| pw_vf_put(pvframe_in[ppre->di_inp_buf->index], |
| channel); |
| pvframe_in[ppre->di_inp_buf->index] = NULL; |
| pw_vf_notify_provider(channel, |
| VFRAME_EVENT_RECEIVER_PUT, NULL); |
| } |
| ppre->di_inp_buf->invert_top_bot_flag = 0; |
| |
| di_que_in(channel, QUE_IN_FREE, ppre->di_inp_buf); |
| ppre->di_inp_buf = NULL; |
| } |
| dim_uninit_buf(0, channel); |
| if (0/*get_blackout_policy()*/) { |
| DIM_DI_WR(DI_CLKG_CTRL, 0x2); |
| if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) { |
| dimh_enable_di_post_mif(GATE_OFF); |
| dim_post_gate_control(false); |
| dim_top_gate_control(false, false); |
| } |
| } |
| |
| if (dimp_get(edi_mp_post_wr_en) && dimp_get(edi_mp_post_wr_support)) |
| dim_set_power_control(0); |
| |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| //ary 2020-12-09 spin_unlock_irqrestore(&plist_lock, flags); |
| } |
| |
| ssize_t |
| store_config(struct device *dev, |
| struct device_attribute *attr, |
| const char *buf, size_t count) |
| { |
| int rc = 0; |
| char *parm[2] = { NULL }, *buf_orig; |
| unsigned int channel = get_current_channel();/* debug only*/ |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| dim_parse_cmd_params(buf_orig, (char **)(&parm)); |
| |
| if (strncmp(buf, "disable", 7) == 0) { |
| dim_print("%s: disable\n", __func__); |
| |
| if (get_init_flag(channel)) {/*if (init_flag) {*/ |
| ppre->disable_req_flag = 1; |
| |
| while (ppre->disable_req_flag) |
| usleep_range(1000, 1001); |
| } |
| } else if (strncmp(buf, "dis2", 4) == 0) { |
| dis2_di(); |
| } else if (strcmp(parm[0], "hold_video") == 0) { |
| pr_info("%s(%s %s)\n", __func__, parm[0], parm[1]); |
| rc = kstrtouint(parm[1], 10, &hold_video); |
| } |
| kfree(buf_orig); |
| return count; |
| } |
| |
| static unsigned char is_progressive(vframe_t *vframe) |
| { |
| unsigned char ret = 0; |
| |
| ret = ((vframe->type & VIDTYPE_TYPEMASK) == VIDTYPE_PROGRESSIVE); |
| return ret; |
| } |
| |
| static unsigned char is_source_change(vframe_t *vframe, unsigned int channel) |
| { |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| unsigned int x, y; |
| |
| dim_vf_x_y(vframe, &x, &y); |
| #define VFRAME_FORMAT_MASK \ |
| (VIDTYPE_VIU_422 | VIDTYPE_VIU_SINGLE_PLANE | VIDTYPE_VIU_444 | \ |
| VIDTYPE_MVC) |
| if (ppre->cur_width != x || |
| ppre->cur_height != y || |
| (((ppre->cur_inp_type & VFRAME_FORMAT_MASK) != |
| (vframe->type & VFRAME_FORMAT_MASK)) && |
| (!is_handle_prog_frame_as_interlace(vframe))) || |
| (ppre->cur_source_type != vframe->source_type) || |
| ((ppre->cur_inp_type & VIDTYPE_INTERLACE_TOP) != |
| (vframe->type & VIDTYPE_INTERLACE_TOP))) { |
| /* video format changed */ |
| return 1; |
| } else if (((ppre->cur_prog_flag != is_progressive(vframe)) && |
| (!is_handle_prog_frame_as_interlace(vframe))) || |
| ((ppre->cur_inp_type & VIDTYPE_VIU_FIELD) != |
| (vframe->type & VIDTYPE_VIU_FIELD)) |
| ) { |
| /* just scan mode changed */ |
| if (!ppre->force_interlace) |
| pr_dbg("DI I<->P.\n"); |
| return 2; |
| } |
| return 0; |
| } |
| |
| /* |
| * static unsigned char is_vframe_type_change(vframe_t* vframe) |
| * { |
| * if( |
| * (di_pre_stru.cur_prog_flag!=is_progressive(vframe))|| |
| * ((di_pre_stru.cur_inp_type&VFRAME_FORMAT_MASK)!= |
| * (vframe->type&VFRAME_FORMAT_MASK)) |
| * ) |
| * return 1; |
| * |
| * return 0; |
| * } |
| */ |
| static int trick_mode; |
| |
| static unsigned int dim_bypass_check(struct vframe_s *vf); |
| |
| unsigned char dim_is_bypass(vframe_t *vf_in, unsigned int ch) |
| { |
| // unsigned int vtype = 0; |
| struct di_pre_stru_s *ppre = get_pre_stru(ch); |
| unsigned int reason = 0; |
| struct di_ch_s *pch; |
| |
| /*need bypass*/ |
| reason = dim_bypass_check(vf_in); |
| |
| if (reason) |
| return reason; |
| |
| if (di_cfgx_get(ch, EDI_CFGX_BYPASS_ALL)) { |
| reason = 0x81; |
| } else if (ppre->cur_prog_flag && |
| ((ppre->cur_width > default_width) || |
| (ppre->cur_height > default_height) || |
| (ppre->cur_inp_type & VIDTYPE_VIU_444))) { |
| reason = 0x82; |
| } else if ((ppre->cur_width < 128) || (ppre->cur_height < 16)) { |
| reason = 0x83; |
| } else if (ppre->cur_inp_type & VIDTYPE_MVC) { |
| reason = 0x84; |
| } else if (ppre->cur_source_type == VFRAME_SOURCE_TYPE_PPMGR) { |
| reason = 0x85; |
| } else if (dimp_get(edi_mp_bypass_3d) && |
| (ppre->source_trans_fmt != 0)) { |
| reason = 0x86; |
| /*prot is conflict with di post*/ |
| } else if (vf_in && vf_in->video_angle) { |
| reason = 0x87; |
| } |
| |
| if (reason) |
| return reason; |
| |
| pch = get_chdata(ch); |
| if (dimp_get(edi_mp_bypass_trick_mode)) { |
| int trick_mode_fffb = 0; |
| int trick_mode_i = 0; |
| |
| if (dimp_get(edi_mp_bypass_trick_mode) & 0x1) |
| query_video_status(0, &trick_mode_fffb); |
| if (dimp_get(edi_mp_bypass_trick_mode) & 0x2) |
| query_video_status(1, &trick_mode_i); |
| trick_mode = trick_mode_fffb | (trick_mode_i << 1); |
| if (trick_mode) |
| reason = 0x88; |
| } |
| |
| if (!reason && pch->rsc_bypass.d32) |
| reason = 0x89; |
| |
| if (!reason && |
| vf_in && |
| pch->ponly && |
| IS_I_SRC(vf_in->type)) { |
| reason = 0x8a; |
| //PR_INF("%s:bypass for p only\n", __func__); |
| } |
| return reason; |
| } |
| |
| //bool dim_need_bypass(struct vframe_s *vf); |
| |
| /********************************** |
| *diff with dim_is_bypass |
| * delet di_vscale_skip_enable |
| * use vf_in replace ppre |
| **********************************/ |
| bool is_bypass2(struct vframe_s *vf_in, unsigned int ch) |
| { |
| /*check debug info*/ |
| if (dimp_get(edi_mp_di_debug_flag) & 0x10000) /* for debugging */ |
| return true; |
| |
| if (di_cfgx_get(ch, EDI_CFGX_BYPASS_ALL)) /*bypass_all*/ |
| return true; |
| |
| if (dimp_get(edi_mp_bypass_trick_mode)) { |
| int trick_mode_fffb = 0; |
| int trick_mode_i = 0; |
| |
| if (dimp_get(edi_mp_bypass_trick_mode) & 0x1) |
| query_video_status(0, &trick_mode_fffb); |
| if (dimp_get(edi_mp_bypass_trick_mode) & 0x2) |
| query_video_status(1, &trick_mode_i); |
| trick_mode = trick_mode_fffb | (trick_mode_i << 1); |
| if (trick_mode) |
| return true; |
| } |
| /* check vframe */ |
| if (!vf_in) |
| return false; |
| |
| if (/*dim_need_bypass(ch, vf_in)*/dim_bypass_check(vf_in)) |
| return true; |
| |
| if (vf_in->width < 16 || vf_in->height < 16) |
| return true; |
| |
| if (dimp_get(edi_mp_bypass_3d) && |
| vf_in->trans_fmt != 0) |
| return true; |
| |
| /*prot is conflict with di post*/ |
| if (vf_in->video_angle) |
| return true; |
| |
| return false; |
| } |
| |
| static unsigned char is_bypass_post(unsigned int channel) |
| { |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| |
| if (dimp_get(edi_mp_di_debug_flag) & 0x40000) /* for debugging */ |
| return (dimp_get(edi_mp_di_debug_flag) >> 19) & 0x1; |
| |
| /*prot is conflict with di post*/ |
| if (ppre->orientation) |
| return 1; |
| if (dimp_get(edi_mp_bypass_post)) |
| return 1; |
| |
| #ifdef DET3D |
| if (ppre->vframe_interleave_flag != 0) |
| return 1; |
| |
| #endif |
| return 0; |
| } |
| |
| |
| #ifdef MARK_SC2 |
| static int di_post_idx[2][6]; |
| static int di_pre_idx[2][10]; |
| #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC |
| static unsigned int di_inp_idx[3]; |
| #else |
| static int di_wr_idx; |
| #endif |
| #endif |
| |
| int dim_get_canvas(void) |
| { |
| unsigned int pre_num = 7, post_num = 6; |
| // struct di_dev_s *de_devp = get_dim_de_devp(); |
| struct di_cvs_s *cvss = &get_datal()->cvs; |
| |
| if (dimp_get(edi_mp_mcpre_en)) { |
| /* mem/chan2/nr/mtn/contrd/contrd2/ |
| * contw/mcinfrd/mcinfow/mcvecw |
| */ |
| pre_num = 10; |
| /* buf0/buf1/buf2/mtnp/mcvec */ |
| post_num = 6; |
| } |
| cvss->pre_num = pre_num; |
| cvss->post_num = post_num; |
| |
| if (ops_ext()->cvs_alloc_table("di_pre", |
| &cvss->pre_idx[0][0], |
| pre_num, |
| CANVAS_MAP_TYPE_1)) { |
| cvss->err_cnt++; |
| PR_ERR("%s:pre\n", __func__); |
| return 1; |
| } |
| cvss->en |= DI_CVS_EN_PRE; |
| |
| if (di_pre_rdma_enable) { |
| if (ops_ext()->cvs_alloc_table("di_pre", |
| &cvss->pre_idx[1][0], |
| pre_num, |
| CANVAS_MAP_TYPE_1)) { |
| PR_ERR("%s di pre 2.\n", __func__); |
| cvss->err_cnt++; |
| return 1; |
| } |
| cvss->en |= DI_CVS_EN_PRE2; |
| } else { |
| memcpy(&cvss->pre_idx[1][0], |
| &cvss->pre_idx[0][0], sizeof(int) * pre_num); |
| } |
| if (ops_ext()->cvs_alloc_table("di_post", |
| &cvss->post_idx[0][0], |
| post_num, |
| CANVAS_MAP_TYPE_1)) { |
| PR_ERR("%s:post\n", __func__); |
| return 1; |
| } |
| cvss->en |= DI_CVS_EN_PST; |
| if (ops_ext()->cvs_alloc_table("di_post", |
| &cvss->post_idx[1][0], |
| post_num, |
| CANVAS_MAP_TYPE_1)) { |
| PR_ERR("%s post 2\n", __func__); |
| return 1; |
| } |
| cvss->en |= DI_CVS_EN_PST2; |
| |
| if (ops_ext()->cvs_alloc_table("di_inp", |
| &cvss->inp_idx[0], |
| 3, |
| CANVAS_MAP_TYPE_1)) { |
| PR_ERR("%s inp\n", __func__); |
| return 1; |
| } |
| cvss->en |= DI_CVS_EN_INP; |
| pr_info("DI: support multi decoding 0x%x~0x%x~0x%x.\n", |
| cvss->inp_idx[0], cvss->inp_idx[1], cvss->inp_idx[2]); |
| |
| return 0; |
| } |
| |
| void dim_release_canvas(void) |
| { |
| struct di_cvs_s *cvss = &get_datal()->cvs; |
| |
| if (cvss->en & DI_CVS_EN_PRE) |
| ops_ext()->cvs_free_table(&cvss->pre_idx[0][0], cvss->pre_num); |
| |
| if (cvss->en & DI_CVS_EN_PRE2) |
| ops_ext()->cvs_free_table(&cvss->pre_idx[1][0], cvss->pre_num); |
| |
| if (cvss->en & DI_CVS_EN_PST) |
| ops_ext()->cvs_free_table(&cvss->post_idx[0][0], |
| cvss->post_num); |
| |
| if (cvss->en & DI_CVS_EN_PST2) |
| ops_ext()->cvs_free_table(&cvss->post_idx[1][0], |
| cvss->post_num); |
| |
| if (cvss->en & DI_CVS_EN_INP) |
| ops_ext()->cvs_free_table(&cvss->inp_idx[0], 3); |
| |
| if (cvss->en & DI_CVS_EN_DS) |
| ops_ext()->cvs_free_table(&cvss->nr_ds_idx, 1); |
| cvss->en = 0; |
| PR_INF("%s:finish\n", __func__); |
| } |
| |
| static void config_canvas_idx(struct di_buf_s *di_buf, int nr_canvas_idx, |
| int mtn_canvas_idx) |
| { |
| unsigned int height = 0; |
| |
| if (!di_buf) |
| return; |
| if (di_buf->canvas_config_flag == 1) { |
| if (nr_canvas_idx >= 0) { |
| /* linked two interlace buffer should double height*/ |
| if (di_buf->di_wr_linked_buf) |
| height = (di_buf->canvas_height << 1); |
| else |
| height = di_buf->canvas_height; |
| di_buf->nr_canvas_idx = nr_canvas_idx; |
| canvas_config(nr_canvas_idx, di_buf->nr_adr, |
| di_buf->canvas_width[NR_CANVAS], |
| height, 0, 0); |
| } |
| } else if (di_buf->canvas_config_flag == 2) { |
| if (nr_canvas_idx >= 0) { |
| di_buf->nr_canvas_idx = nr_canvas_idx; |
| canvas_config(nr_canvas_idx, di_buf->nr_adr, |
| di_buf->canvas_width[NR_CANVAS], |
| di_buf->canvas_height, 0, 0); |
| } |
| if (mtn_canvas_idx >= 0) { |
| di_buf->mtn_canvas_idx = mtn_canvas_idx; |
| canvas_config(mtn_canvas_idx, di_buf->mtn_adr, |
| di_buf->canvas_width[MTN_CANVAS], |
| di_buf->canvas_height, 0, 0); |
| } |
| } |
| if (nr_canvas_idx >= 0) { |
| di_buf->vframe->canvas0Addr = di_buf->nr_canvas_idx; |
| di_buf->vframe->canvas1Addr = di_buf->nr_canvas_idx; |
| } |
| } |
| |
| static void config_canvas_idx_mtn(struct di_buf_s *di_buf, |
| int mtn_canvas_idx) |
| { |
| if (!di_buf) |
| return; |
| |
| if (di_buf->canvas_config_flag == 2) { |
| if (mtn_canvas_idx >= 0) { |
| di_buf->mtn_canvas_idx = mtn_canvas_idx; |
| canvas_config(mtn_canvas_idx, di_buf->mtn_adr, |
| di_buf->canvas_width[MTN_CANVAS], |
| di_buf->canvas_height, 0, 0); |
| } |
| } |
| } |
| |
| static void config_cnt_canvas_idx(struct di_buf_s *di_buf, |
| unsigned int cnt_canvas_idx) |
| { |
| if (!di_buf) |
| return; |
| |
| di_buf->cnt_canvas_idx = cnt_canvas_idx; |
| canvas_config(cnt_canvas_idx, di_buf->cnt_adr, |
| di_buf->canvas_width[MTN_CANVAS], |
| di_buf->canvas_height, 0, 0); |
| } |
| |
| static void config_mcinfo_canvas_idx(struct di_buf_s *di_buf, |
| int mcinfo_canvas_idx) |
| { |
| if (!di_buf) |
| return; |
| |
| di_buf->mcinfo_canvas_idx = mcinfo_canvas_idx; |
| canvas_config(mcinfo_canvas_idx, |
| di_buf->mcinfo_adr, |
| di_buf->canvas_height_mc, 2, 0, 0); |
| } |
| |
| static void config_mcvec_canvas_idx(struct di_buf_s *di_buf, |
| int mcvec_canvas_idx) |
| { |
| if (!di_buf) |
| return; |
| |
| di_buf->mcvec_canvas_idx = mcvec_canvas_idx; |
| canvas_config(mcvec_canvas_idx, |
| di_buf->mcvec_adr, |
| di_buf->canvas_width[MV_CANVAS], |
| di_buf->canvas_height, 0, 0); |
| } |
| |
| |
| //----begin |
| #ifdef DIM_HIS /*no use*/ |
| /******************************************* |
| * |
| * |
| ******************************************/ |
| #define DI_KEEP_BUF_SIZE 3 |
| static struct di_buf_s *di_keep_buf[DI_KEEP_BUF_SIZE]; |
| static int di_keep_point; |
| |
| void keep_buf_clear(void) |
| { |
| int i; |
| |
| for (i = 0; i < DI_KEEP_BUF_SIZE; i++) |
| di_keep_buf[i] = NULL; |
| |
| di_keep_point = -1; |
| } |
| |
| void keep_buf_in(struct di_buf_s *ready_buf) |
| { |
| di_keep_point++; |
| if (di_keep_point >= DI_KEEP_BUF_SIZE) |
| di_keep_point = 0; |
| di_keep_buf[di_keep_point] = ready_buf; |
| } |
| |
| void keep_buf_in_full(struct di_buf_s *ready_buf) |
| { |
| int i; |
| |
| keep_buf_in(ready_buf); |
| for (i = 0; i < DI_KEEP_BUF_SIZE; i++) { |
| if (!di_keep_buf[i]) |
| di_keep_buf[i] = ready_buf; |
| } |
| } |
| #endif |
| |
| int di_cnt_buf(int width, int height, int prog_flag, int mc_mm, |
| int bit10_support, int pack422) |
| { |
| int canvas_height = height + 8; |
| unsigned int di_buf_size = 0, di_post_buf_size = 0, mtn_size = 0; |
| unsigned int nr_size = 0, count_size = 0, mv_size = 0, mc_size = 0; |
| unsigned int nr_width = width, mtn_width = width, mv_width = width; |
| unsigned int nr_canvas_width = width, mtn_canvas_width = width; |
| unsigned int mv_canvas_width = width, canvas_align_width = 32; |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| canvas_align_width = 64; |
| |
| if (dimp_get(edi_mp_nr10bit_support)) { |
| if (dimp_get(edi_mp_full_422_pack)) |
| nr_width = (width * 5) / 4; |
| else |
| nr_width = (width * 3) / 2; |
| } else { |
| nr_width = width; |
| } |
| /* make sure canvas width must be divided by 256bit|32byte align */ |
| nr_canvas_width = nr_width << 1; |
| mtn_canvas_width = mtn_width >> 1; |
| mv_canvas_width = (mv_width << 1) / 5; |
| nr_canvas_width = roundup(nr_canvas_width, canvas_align_width); |
| mtn_canvas_width = roundup(mtn_canvas_width, canvas_align_width); |
| mv_canvas_width = roundup(mv_canvas_width, canvas_align_width); |
| nr_width = nr_canvas_width >> 1; |
| mtn_width = mtn_canvas_width << 1; |
| mv_width = (mv_canvas_width * 5) >> 1; |
| |
| if (prog_flag) { |
| di_buf_size = nr_width * canvas_height * 2; |
| di_buf_size = roundup(di_buf_size, PAGE_SIZE); |
| |
| } else { |
| /*pr_info("canvas_height=%d\n", canvas_height);*/ |
| |
| /*nr_size(bits)=w*active_h*8*2(yuv422) |
| * mtn(bits)=w*active_h*4 |
| * cont(bits)=w*active_h*4 mv(bits)=w*active_h/5*16 |
| * mcinfo(bits)=active_h*16 |
| */ |
| nr_size = (nr_width * canvas_height) * 8 * 2 / 16; |
| mtn_size = (mtn_width * canvas_height) * 4 / 16; |
| count_size = (mtn_width * canvas_height) * 4 / 16; |
| mv_size = (mv_width * canvas_height) / 5; |
| /*mc_size = canvas_height;*/ |
| mc_size = roundup(canvas_height >> 1, canvas_align_width) << 1; |
| if (mc_mm) { |
| di_buf_size = nr_size + mtn_size + count_size + |
| mv_size + mc_size; |
| } else { |
| di_buf_size = nr_size + mtn_size + count_size; |
| } |
| di_buf_size = roundup(di_buf_size, PAGE_SIZE); |
| } |
| |
| PR_INF("size:0x%x\n", di_buf_size); |
| PR_INF("\t%-15s:0x%x\n", "nr_size", nr_size); |
| PR_INF("\t%-15s:0x%x\n", "count", count_size); |
| PR_INF("\t%-15s:0x%x\n", "mtn", mtn_size); |
| PR_INF("\t%-15s:0x%x\n", "mv", mv_size); |
| PR_INF("\t%-15s:0x%x\n", "mcinfo", mc_size); |
| |
| di_post_buf_size = nr_width * canvas_height * 2; |
| /*PR_INF("size:post:0x%x\n", di_post_buf_size);*/ |
| di_post_buf_size = roundup(di_post_buf_size, PAGE_SIZE); |
| PR_INF("size:post:0x%x\n", di_post_buf_size); |
| |
| return 0; |
| } |
| |
| unsigned int insert_line; //= 0x100; |
| module_param(insert_line, uint, 0664); |
| MODULE_PARM_DESC(insert_line, "debug insert_line"); |
| |
| static unsigned int di_cnt_pre_afbct(struct di_ch_s *pch) |
| { |
| unsigned int afbc_info_size = 0, afbc_tab_size = 0; |
| unsigned int afbc_buffer_size = 0, blk_total = 0; |
| unsigned int width, height; |
| |
| width = 1920; |
| height = 1088; |
| |
| if (dim_afds() && dim_afds()->cnt_info_size && |
| (cfggch(pch, DAT) & DI_BIT1)) { |
| afbc_info_size = dim_afds()->cnt_info_size(width, |
| height / 2, |
| &blk_total); |
| afbc_buffer_size = dim_afds()->cnt_buf_size(0x21, |
| blk_total); |
| |
| afbc_tab_size = dim_afds()->cnt_tab_size(afbc_buffer_size); |
| } else { |
| afbc_tab_size = 0; |
| } |
| |
| return afbc_tab_size; |
| } |
| |
| static int di_cnt_i_buf(struct di_ch_s *pch, int width, int height) |
| { |
| unsigned int canvas_height = height; |
| enum EDPST_MODE mode; |
| |
| unsigned int di_buf_size = 0, mtn_size = 0; |
| unsigned int nr_size = 0, count_size = 0, mv_size = 0, mc_size = 0; |
| unsigned int nr_width = width, mtn_width = width, mv_width = width; |
| unsigned int nr_canvas_width = width, mtn_canvas_width = width; |
| unsigned int mv_canvas_width = width, canvas_align_width = 32; |
| unsigned int afbc_buffer_size = 0, blk_total = 0; |
| struct div2_mm_s *mm; |
| unsigned int ch; |
| unsigned int afbc_info_size = 0, afbc_tab_size = 0, old_size; |
| //unsigned int insert_line = 544; |
| unsigned int insert_size; |
| |
| unsigned int one_idat_size = 0; |
| /**********************************************/ |
| /* count buf info */ |
| /**********************************************/ |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| canvas_align_width = 64; |
| |
| ch = pch->ch_id; |
| mode = pch->mode; |
| mm = dim_mm_get(ch); |
| |
| if (mode == EDPST_MODE_422_10BIT_PACK) |
| nr_width = (width * 5) / 4; |
| else if (mode == EDPST_MODE_422_10BIT) |
| nr_width = (width * 3) / 2; |
| else |
| nr_width = width; |
| //dbg_reg("%s:begin\n", __func__); |
| |
| /* make sure canvas width must be divided by 256bit|32byte align */ |
| nr_canvas_width = nr_width << 1; |
| mtn_canvas_width = mtn_width >> 1; |
| mv_canvas_width = (mv_width << 1) / 5; |
| nr_canvas_width = roundup(nr_canvas_width, canvas_align_width); |
| mtn_canvas_width = roundup(mtn_canvas_width, canvas_align_width); |
| mv_canvas_width = roundup(mv_canvas_width, canvas_align_width); |
| nr_width = nr_canvas_width >> 1; |
| mtn_width = mtn_canvas_width << 1; |
| mv_width = (mv_canvas_width * 5) >> 1; |
| // rot_width = roundup((rot_width << 1), canvas_align_width); |
| |
| /* tvp flg */ |
| if (get_flag_tvp(ch) == 2) { |
| mm->sts.flg_tvp = 1; |
| mm->cfg.ibuf_flg.b.tvp = 1; |
| mm->cfg.pbuf_flg.b.tvp = 1; |
| } else { |
| mm->sts.flg_tvp = 0; |
| mm->cfg.ibuf_flg.b.tvp = 0; |
| mm->cfg.pbuf_flg.b.tvp = 0; |
| } |
| |
| dbg_ev("%s1:tvp:%d\n", __func__, mm->cfg.pbuf_flg.b.tvp); |
| if (dim_afds() && dim_afds()->cnt_info_size && |
| (dim_afds()->is_sts(EAFBC_MEMI_NEED) || cfgg(FIX_BUF))) { |
| afbc_info_size = dim_afds()->cnt_info_size(width, |
| height / 2, |
| &blk_total); |
| afbc_buffer_size = dim_afds()->cnt_buf_size(0x21, |
| blk_total); |
| } |
| |
| mm->cfg.buf_alloc_mode = 0; |
| /*nr_size(bits) = w * active_h * 8 * 2(yuv422) |
| * mtn(bits) = w * active_h * 4 |
| * cont(bits) = w * active_h * 4 mv(bits) = w * active_h / 5*16 |
| * mcinfo(bits) = active_h * 16 |
| */ |
| nr_size = (nr_width * canvas_height) * 8 * 2 / 16; |
| if (afbc_buffer_size > nr_size) { |
| PR_INF("%s:0x%x, 0x%x\n", "bufi large:", |
| nr_size, afbc_buffer_size); |
| nr_size = afbc_buffer_size; |
| } |
| |
| if (dim_afds() && dim_afds()->cnt_tab_size && |
| (dim_afds()->is_sts(EAFBC_MEMI_NEED) || cfgg(FIX_BUF))) |
| afbc_tab_size = dim_afds()->cnt_tab_size(nr_size); |
| |
| mtn_size = (mtn_width * canvas_height) * 4 / 16; |
| count_size = (mtn_width * canvas_height) * 4 / 16; |
| mv_size = (mv_width * canvas_height) / 5; |
| /*mc_size = canvas_height;*/ |
| mc_size = roundup(canvas_height >> 1, canvas_align_width) << 1; |
| |
| #ifdef CFG_BUF_ALLOC_SP |
| insert_size = insert_line * nr_canvas_width; |
| |
| di_buf_size = nr_size; |
| if (mc_mem_alloc) { |
| di_buf_size += mtn_size + |
| count_size + |
| mv_size + |
| mc_size; |
| //one_idat_size = mc_size; |
| } else { |
| di_buf_size += mtn_size + |
| count_size; |
| //one_idat_size = 0; |
| } |
| mm->cfg.afbct_local_max_size = di_cnt_pre_afbct(pch); |
| mm->cfg.ibuf_hsize = width; |
| one_idat_size += mm->cfg.afbct_local_max_size; |
| |
| old_size = nr_size; |
| di_buf_size = roundup(di_buf_size, PAGE_SIZE); |
| di_buf_size += afbc_info_size; |
| |
| if (is_mask(SC2_DW_EN)) |
| di_buf_size += dim_getdw()->size_info.p.size_buf; |
| |
| di_buf_size = roundup(di_buf_size, PAGE_SIZE); |
| #else |
| if (mc_mem_alloc) { |
| di_buf_size = nr_size + mtn_size + count_size + |
| mv_size + mc_size; |
| } else { |
| di_buf_size = nr_size + mtn_size + count_size; |
| } |
| |
| insert_size = insert_line * nr_canvas_width; |
| di_buf_size += insert_size; |
| di_buf_size = roundup(di_buf_size, PAGE_SIZE); |
| old_size = di_buf_size; |
| di_buf_size += afbc_info_size; |
| di_buf_size += afbc_tab_size; |
| if (is_mask(SC2_DW_EN)) |
| di_buf_size += dim_getdw()->size_info.p.size_buf; |
| #endif |
| dbg_init("nr_width=%d,cvs_h=%d,w[%d],h[%d],al_w[%d]\n", |
| nr_width, canvas_height, |
| width, height, |
| canvas_align_width); |
| /*de_devp->buffer_size = di_buf_size;*/ |
| mm->cfg.size_local = di_buf_size; |
| mm->cfg.size_local_page = mm->cfg.size_local >> PAGE_SHIFT; |
| mm->cfg.nr_size = nr_size; |
| mm->cfg.count_size = count_size; |
| mm->cfg.mtn_size = mtn_size; |
| mm->cfg.mv_size = mv_size; |
| mm->cfg.mcinfo_size = mc_size; |
| mm->cfg.di_size = old_size; |
| mm->cfg.afbci_size = afbc_info_size; |
| mm->cfg.afbct_size = afbc_tab_size; |
| mm->cfg.pre_inser_size = insert_size; |
| if (is_mask(SC2_DW_EN)) |
| mm->cfg.dw_size = dim_getdw()->size_info.p.size_buf; |
| else |
| mm->cfg.dw_size = 0; |
| #ifdef CFG_BUF_ALLOC_SP |
| mm->cfg.size_idat_one = one_idat_size; |
| mm->cfg.nub_idat = DIM_IAT_NUB; |
| mm->cfg.size_idat_all = mm->cfg.size_idat_one * mm->cfg.nub_idat; |
| mm->cfg.size_idat_all += mm->cfg.pre_inser_size; |
| mm->cfg.size_idat_all = roundup(mm->cfg.size_idat_all, PAGE_SIZE); |
| /* cfg i dat buf flg */ |
| mm->cfg.dat_idat_flg.b.page = mm->cfg.size_idat_all >> PAGE_SHIFT; |
| mm->cfg.dat_idat_flg.b.is_i = 1; |
| mm->cfg.dat_idat_flg.b.afbc = 1; |
| mm->cfg.dat_idat_flg.b.dw = 0; |
| mm->cfg.dat_idat_flg.b.tvp = 0; |
| mm->cfg.dat_idat_flg.b.typ = EDIM_BLK_TYP_DATI; |
| #endif |
| dimp_set(edi_mp_same_field_top_count, 0); |
| same_field_bot_count = 0; |
| #ifdef PRINT_BASIC |
| dbg_mem2("%s:size:\n", __func__); |
| dbg_mem2("\t%-15s:0x%x\n", "nr_size", mm->cfg.nr_size); |
| dbg_mem2("\t%-15s:0x%x\n", "count", mm->cfg.count_size); |
| dbg_mem2("\t%-15s:0x%x\n", "mtn", mm->cfg.mtn_size); |
| dbg_mem2("\t%-15s:0x%x\n", "mv", mm->cfg.mv_size); |
| dbg_mem2("\t%-15s:0x%x\n", "mcinfo", mm->cfg.mcinfo_size); |
| dbg_mem2("\t%-15s:0x%x\n", "insert_size", mm->cfg.pre_inser_size); |
| dbg_mem2("\t%-15s:0x%x\n", "afbci_size", mm->cfg.afbci_size); |
| dbg_mem2("\t%-15s:0x%x\n", "afbct_size", mm->cfg.afbct_size); |
| dbg_mem2("\t%-15s:0x%x\n", "dw_size", mm->cfg.dw_size); |
| dbg_mem2("\t%-15s:0x%x\n", "size_local", mm->cfg.size_local); |
| dbg_mem2("\t%-15s:0x%x\n", "size_page", mm->cfg.size_local_page); |
| dbg_mem2("\t%-15s:0x%x\n", "afbct_local_max_size", |
| mm->cfg.afbct_local_max_size); |
| dbg_mem2("\t%-15s:0x%x\n", "size_idat_one", mm->cfg.size_idat_one); |
| dbg_mem2("\t%-15s:0x%x\n", "nub_idat", mm->cfg.nub_idat); |
| dbg_mem2("\t%-15s:0x%x\n", "size_idat_all", mm->cfg.size_idat_all); |
| dbg_mem2("\t%-15s:0x%x\n", "idat_pate", mm->cfg.dat_idat_flg.b.page); |
| #endif |
| mm->cfg.canvas_width[NR_CANVAS] = nr_canvas_width; |
| mm->cfg.canvas_width[MTN_CANVAS] = mtn_canvas_width; |
| mm->cfg.canvas_width[MV_CANVAS] = mv_canvas_width; |
| mm->cfg.canvas_height = (canvas_height >> 1); |
| mm->cfg.canvas_height_mc = roundup(mm->cfg.canvas_height, |
| canvas_align_width); |
| dbg_mem2("\t%-15s:0x%x\n", "canvas_height_mc", |
| mm->cfg.canvas_height_mc); |
| |
| /* cfg i/p buf flg */ |
| mm->cfg.ibuf_flg.b.page = mm->cfg.size_local_page; |
| mm->cfg.ibuf_flg.b.is_i = 1; |
| if (mm->cfg.afbci_size) |
| mm->cfg.ibuf_flg.b.afbc = 1; |
| else |
| mm->cfg.ibuf_flg.b.afbc = 0; |
| if (mm->cfg.dw_size) |
| mm->cfg.ibuf_flg.b.dw = 1; |
| else |
| mm->cfg.ibuf_flg.b.dw = 0; |
| |
| mm->cfg.ibuf_flg.b.typ = EDIM_BLK_TYP_OLDI; |
| return 0; |
| } |
| |
| static void di_cnt_pst_afbct(struct di_ch_s *pch) |
| { |
| #ifdef CFG_BUF_ALLOC_SP |
| |
| /* cnt the largest size to avoid rebuild */ |
| unsigned int height, width, ch; |
| bool is_4k = false; |
| const struct di_mm_cfg_s *pcfg; |
| unsigned int afbc_buffer_size = 0, afbc_tab_size = 0; |
| unsigned int afbc_info_size = 0, blk_total = 0, tsize; |
| bool flg_afbc = false; |
| struct div2_mm_s *mm; |
| |
| if (!pch) |
| return; |
| ch = pch->ch_id; |
| mm = dim_mm_get(ch); |
| |
| if (dim_afds() && |
| dim_afds()->cnt_info_size && |
| (cfgg(DAT) & DI_BIT0)) |
| flg_afbc = true; |
| |
| if (!flg_afbc) { |
| mm->cfg.size_pafbct_all = 0; |
| mm->cfg.size_pafbct_one = 0; |
| mm->cfg.nub_pafbct = 0; |
| mm->cfg.dat_pafbct_flg.d32 = 0; |
| return; |
| } |
| |
| //if (cfgg(4K)) |
| is_4k = true; |
| |
| pcfg = di_get_mm_tab(is_4k, pch); |
| width = pcfg->di_w; |
| height = pcfg->di_h; |
| |
| afbc_info_size = dim_afds()->cnt_info_size(width, |
| height, |
| &blk_total); |
| afbc_buffer_size = |
| dim_afds()->cnt_buf_size(0x21, blk_total); |
| afbc_buffer_size = roundup(afbc_buffer_size, PAGE_SIZE); |
| tsize = afbc_buffer_size + afbc_info_size; |
| afbc_tab_size = |
| dim_afds()->cnt_tab_size(tsize); |
| |
| mm->cfg.nub_pafbct = DIM_PAT_NUB - 1;/*pcfg->num_post*/ |
| mm->cfg.size_pafbct_all = afbc_tab_size * mm->cfg.nub_pafbct; |
| mm->cfg.size_pafbct_one = afbc_tab_size; |
| |
| mm->cfg.dat_pafbct_flg.d32 = 0; |
| //mm->cfg.dat_pafbct_flg.b.afbc = 1; |
| mm->cfg.dat_pafbct_flg.b.typ = EDIM_BLK_TYP_PAFBCT; |
| mm->cfg.dat_pafbct_flg.b.page = mm->cfg.size_pafbct_all >> PAGE_SHIFT; |
| mm->cfg.dat_pafbci_flg.b.tvp = 0; |
| dbg_mem2("%s:size_pafbct_all:0x%x, 0x%x, nub[%d]\n", |
| __func__, |
| mm->cfg.size_pafbct_all, |
| mm->cfg.size_pafbct_one, |
| mm->cfg.nub_pafbct); |
| #endif |
| } |
| |
| /* width, height from mm*/ |
| static int di_cnt_post_buf(struct di_ch_s *pch /*,enum EDPST_OUT_MODE mode*/) |
| { |
| unsigned int ch; |
| struct div2_mm_s *mm; |
| unsigned int nr_width, nr_canvas_width, canvas_align_width = 32; |
| unsigned int height, width; |
| unsigned int tmpa, tmpb; |
| unsigned int canvas_height; |
| unsigned int afbc_info_size = 0, afbc_tab_size = 0; |
| unsigned int afbc_buffer_size = 0, blk_total = 0; |
| enum EDPST_MODE mode; |
| bool is_4k = false; |
| bool is_yuv420_10 = false; |
| |
| ch = pch->ch_id; |
| mm = dim_mm_get(ch); |
| |
| height = mm->cfg.di_h; |
| canvas_height = roundup(height, 32); |
| width = mm->cfg.di_w; |
| if (mm->cfg.di_w > 1920) |
| is_4k = true; |
| mm->cfg.pbuf_hsize = width; |
| nr_width = width; |
| dbg_mem2("%s w[%d]h[%d]\n", __func__, width, height); |
| nr_canvas_width = width; |
| /**********************************************/ |
| /* count buf info */ |
| /**********************************************/ |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| canvas_align_width = 64; |
| |
| /***********************/ |
| #ifdef MARK_SC2 |
| if (dim_cfg_nv21()) { |
| mode = EDPST_MODE_NV21_8BIT; |
| } else { |
| if (dimp_get(edi_mp_nr10bit_support)) { |
| if (dimp_get(edi_mp_full_422_pack)) |
| mode = EDPST_MODE_422_10BIT_PACK; |
| else |
| mode = EDPST_MODE_422_10BIT; |
| } else { |
| mode = EDPST_MODE_422_8BIT; |
| } |
| } |
| #else |
| mode = pch->mode; |
| if (is_4k && |
| ((cfggch(pch, POUT_FMT) == 1) || |
| (cfggch(pch, POUT_FMT) == 2) || |
| (cfggch(pch, POUT_FMT) == 5))) |
| mode = EDPST_MODE_NV21_8BIT; |
| dbg_mem2("%s:mode:%d\n", __func__, mode); |
| #endif |
| /***********************/ |
| if (mode == EDPST_MODE_422_10BIT_PACK) |
| nr_width = (width * 5) / 4; |
| else if (mode == EDPST_MODE_422_10BIT) |
| nr_width = (width * 3) / 2; |
| else |
| nr_width = width; |
| |
| /* p */ |
| //tmp nr_width = roundup(nr_width, canvas_align_width); |
| mm->cfg.pst_mode = mode; |
| if (mode == EDPST_MODE_NV21_8BIT) { |
| nr_width = roundup(nr_width, canvas_align_width); |
| tmpa = (nr_width * canvas_height) >> 1;/*uv*/ |
| tmpb = tmpa; |
| tmpa = nr_width * canvas_height; |
| |
| mm->cfg.pst_buf_uv_size = roundup(tmpb, PAGE_SIZE); |
| mm->cfg.pst_buf_y_size = roundup(tmpa, PAGE_SIZE); |
| mm->cfg.pst_buf_size = mm->cfg.pst_buf_y_size + |
| mm->cfg.pst_buf_uv_size;//tmpa + tmpb; |
| mm->cfg.size_post = mm->cfg.pst_buf_size; |
| mm->cfg.pst_cvs_w = nr_width; |
| mm->cfg.pst_cvs_h = canvas_height; |
| mm->cfg.pst_afbci_size = 0; |
| mm->cfg.pst_afbct_size = 0; |
| } else { |
| /* 422 */ |
| tmpa = roundup(nr_width * canvas_height * 2, PAGE_SIZE); |
| mm->cfg.pst_buf_size = tmpa; |
| mm->cfg.pst_buf_uv_size = tmpa >> 1; |
| mm->cfg.pst_buf_y_size = mm->cfg.pst_buf_uv_size; |
| |
| if (dim_afds() && dim_afds()->cnt_info_size && |
| ((dim_afds()->is_sts(EAFBC_MEM_NEED) && |
| (!mm->cfg.dis_afbce)) || |
| cfgg(FIX_BUF))) { |
| afbc_info_size = |
| dim_afds()->cnt_info_size(width, |
| height, |
| &blk_total); |
| if (is_4k && dip_is_support_nv2110(ch)) |
| is_yuv420_10 = true; |
| |
| if (is_yuv420_10) |
| afbc_buffer_size = |
| dim_afds()->cnt_buf_size(0x20, blk_total); |
| else |
| afbc_buffer_size = |
| dim_afds()->cnt_buf_size(0x21, |
| blk_total); |
| afbc_buffer_size = roundup(afbc_buffer_size, PAGE_SIZE); |
| if (afbc_buffer_size > mm->cfg.pst_buf_size) { |
| PR_INF("%s:0x%x, 0x%x\n", "buf large:", |
| mm->cfg.pst_buf_size, |
| afbc_buffer_size); |
| mm->cfg.pst_buf_size = afbc_buffer_size; |
| } |
| |
| if (is_yuv420_10) |
| mm->cfg.pst_buf_size = afbc_buffer_size; |
| |
| afbc_tab_size = |
| dim_afds()->cnt_tab_size(mm->cfg.pst_buf_size); |
| } |
| mm->cfg.pst_afbci_size = afbc_info_size; |
| mm->cfg.pst_afbct_size = afbc_tab_size; |
| |
| #ifdef CFG_BUF_ALLOC_SP |
| if (is_4k && dip_is_4k_sct_mem(pch)) { |
| mm->cfg.size_post = mm->cfg.pst_afbci_size; |
| } else if (pch->ponly && dip_is_ponly_sct_mem(pch)) { |
| mm->cfg.size_post = mm->cfg.pst_afbci_size; |
| } else if (dip_itf_is_ins_exbuf(pch)) { |
| mm->cfg.size_post = mm->cfg.pst_afbci_size; |
| } else { |
| mm->cfg.size_post = mm->cfg.pst_buf_size + |
| mm->cfg.pst_afbci_size; |
| } |
| #else |
| mm->cfg.size_post = mm->cfg.pst_buf_size + |
| mm->cfg.pst_afbci_size + mm->cfg.pst_afbct_size; |
| |
| #endif |
| mm->cfg.pst_cvs_w = nr_width << 1; |
| mm->cfg.pst_cvs_w = roundup(mm->cfg.pst_cvs_w, |
| canvas_align_width); |
| mm->cfg.pst_cvs_h = canvas_height; |
| } |
| mm->cfg.size_post = roundup(mm->cfg.size_post, PAGE_SIZE); |
| mm->cfg.size_post_page = mm->cfg.size_post >> PAGE_SHIFT; |
| |
| /* p */ |
| mm->cfg.pbuf_flg.b.page = mm->cfg.size_post_page; |
| mm->cfg.pbuf_flg.b.is_i = 0; |
| if (mm->cfg.pst_afbct_size) |
| mm->cfg.pbuf_flg.b.afbc = 1; |
| else |
| mm->cfg.pbuf_flg.b.afbc = 0; |
| if (mm->cfg.dw_size) |
| mm->cfg.pbuf_flg.b.dw = 1; |
| else |
| mm->cfg.pbuf_flg.b.dw = 0; |
| |
| if (is_4k && dip_is_4k_sct_mem(pch)) |
| mm->cfg.pbuf_flg.b.typ = EDIM_BLK_TYP_PSCT; |
| else if (pch->ponly && dip_is_ponly_sct_mem(pch)) |
| mm->cfg.pbuf_flg.b.typ = EDIM_BLK_TYP_PSCT; |
| else |
| mm->cfg.pbuf_flg.b.typ = EDIM_BLK_TYP_OLDP; |
| |
| if (dip_itf_is_ins_exbuf(pch)) |
| mm->cfg.pbuf_flg.b.typ |= EDIM_BLK_TYP_POUT; |
| |
| dbg_mem2("%s:3 pst_cvs_w[%d]\n", __func__, mm->cfg.pst_cvs_w); |
| #ifdef PRINT_BASIC |
| dbg_mem2("%s:size:\n", __func__); |
| dbg_mem2("\t%-15s:0x%x\n", "total_size", mm->cfg.size_post); |
| dbg_mem2("\t%-15s:0x%x\n", "total_page", mm->cfg.size_post_page); |
| dbg_mem2("\t%-15s:0x%x\n", "buf_size", mm->cfg.pst_buf_size); |
| dbg_mem2("\t%-15s:0x%x\n", "y_size", mm->cfg.pst_buf_y_size); |
| dbg_mem2("\t%-15s:0x%x\n", "uv_size", mm->cfg.pst_buf_uv_size); |
| dbg_mem2("\t%-15s:0x%x\n", "afbci_size", mm->cfg.pst_afbci_size); |
| dbg_mem2("\t%-15s:0x%x\n", "afbct_size", mm->cfg.pst_afbct_size); |
| dbg_mem2("\t%-15s:0x%x\n", "flg", mm->cfg.pbuf_flg.d32); |
| #endif |
| return 0; |
| } |
| |
| static int di_init_buf_simple(struct di_ch_s *pch) |
| { |
| int i, j; |
| |
| struct vframe_s **pvframe_in; |
| struct vframe_s *pvframe_in_dup; |
| struct vframe_s *pvframe_local; |
| struct vframe_s *pvframe_post; |
| struct di_buf_s *pbuf_local; |
| struct di_buf_s *pbuf_in; |
| struct di_buf_s *pbuf_post; |
| struct di_buf_s *di_buf; |
| |
| struct div2_mm_s *mm; /*mm-0705*/ |
| unsigned int cnt; |
| |
| unsigned int ch; |
| unsigned int length; |
| |
| /**********************************************/ |
| /* count buf info */ |
| /**********************************************/ |
| //if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| // canvas_align_width = 64; |
| |
| ch = pch->ch_id; |
| pvframe_in = get_vframe_in(ch); |
| pvframe_in_dup = get_vframe_in_dup(ch); |
| pvframe_local = get_vframe_local(ch); |
| pvframe_post = get_vframe_post(ch); |
| pbuf_local = get_buf_local(ch); |
| pbuf_in = get_buf_in(ch); |
| pbuf_post = get_buf_post(ch); |
| mm = dim_mm_get(ch); |
| |
| //dbg_reg("%s:begin\n", __func__); |
| |
| /* decoder'buffer had been releae no need put */ |
| for (i = 0; i < MAX_IN_BUF_NUM; i++) |
| pvframe_in[i] = NULL; |
| |
| /**********************************************/ |
| /* que init */ |
| /**********************************************/ |
| |
| queue_init(ch, MAX_LOCAL_BUF_NUM * 2); |
| di_que_init(ch); /*new que*/ |
| |
| //mem_st_local = di_get_mem_start(ch); |
| |
| /**********************************************/ |
| /* local buf init */ |
| /**********************************************/ |
| |
| //for (i = 0; i < mm->cfg.num_local; i++) { |
| for (i = 0; i < (MAX_LOCAL_BUF_NUM * 2); i++) { |
| di_buf = &pbuf_local[i]; |
| |
| /* backup cma pages */ |
| //tmp_page = di_buf->pages; |
| memset(di_buf, 0, sizeof(struct di_buf_s)); |
| //di_buf->pages = tmp_page; |
| di_buf->type = VFRAME_TYPE_LOCAL; |
| di_buf->pre_ref_count = 0; |
| di_buf->post_ref_count = 0; |
| for (j = 0; j < 3; j++) |
| di_buf->canvas_width[j] = mm->cfg.canvas_width[j]; |
| |
| di_buf->index = i; |
| di_buf->flg_null = 1; |
| di_buf->vframe = &pvframe_local[i]; |
| di_buf->vframe->private_data = di_buf; |
| di_buf->vframe->canvas0Addr = di_buf->nr_canvas_idx; |
| di_buf->vframe->canvas1Addr = di_buf->nr_canvas_idx; |
| di_buf->queue_index = -1; |
| di_buf->invert_top_bot_flag = 0; |
| di_buf->channel = ch; |
| di_buf->canvas_config_flag = 2; |
| //queue_in(channel, di_buf, QUEUE_LOCAL_FREE); |
| di_que_in(ch, QUE_PRE_NO_BUF, di_buf); |
| dbg_init("buf[%d], addr=0x%lx\n", di_buf->index, |
| di_buf->nr_adr); |
| } |
| |
| /**********************************************/ |
| /* input buf init */ |
| /**********************************************/ |
| |
| for (i = 0; i < MAX_IN_BUF_NUM; i++) { |
| di_buf = &pbuf_in[i]; |
| |
| if (di_buf) { |
| memset(di_buf, 0, sizeof(struct di_buf_s)); |
| di_buf->type = VFRAME_TYPE_IN; |
| di_buf->pre_ref_count = 0; |
| di_buf->post_ref_count = 0; |
| di_buf->vframe = &pvframe_in_dup[i]; |
| di_buf->vframe->private_data = di_buf; |
| di_buf->index = i; |
| di_buf->queue_index = -1; |
| di_buf->invert_top_bot_flag = 0; |
| di_buf->channel = ch; |
| di_que_in(ch, QUE_IN_FREE, di_buf); |
| } |
| } |
| /**********************************************/ |
| /* post buf init */ |
| /**********************************************/ |
| cnt = 0; |
| for (i = 0; i < MAX_POST_BUF_NUM; i++) { |
| di_buf = &pbuf_post[i]; |
| |
| if (di_buf) { |
| #ifdef MARK_HIS |
| if (dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) { |
| if (di_que_is_in_que(ch, QUE_POST_KEEP, |
| di_buf)) { |
| dbg_reg("%s:post keep buf %d\n", |
| __func__, |
| di_buf->index); |
| dbg_wq("k:b[%d]\n", di_buf->index); |
| continue; |
| } |
| } |
| #endif |
| memset(di_buf, 0, sizeof(struct di_buf_s)); |
| |
| di_buf->type = VFRAME_TYPE_POST; |
| di_buf->index = i; |
| di_buf->vframe = &pvframe_post[i]; |
| di_buf->vframe->private_data = di_buf; |
| di_buf->queue_index = -1; |
| di_buf->invert_top_bot_flag = 0; |
| di_buf->channel = ch; |
| di_buf->flg_null = 1; |
| if (dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) { |
| di_buf->canvas_width[NR_CANVAS] = |
| mm->cfg.pst_cvs_w; |
| //di_buf->canvas_rot_w = rot_width; |
| di_buf->canvas_height = mm->cfg.pst_cvs_h; |
| di_buf->canvas_config_flag = 1; |
| |
| dbg_init("[%d]post buf:%d: addr=0x%lx\n", i, |
| di_buf->index, di_buf->nr_adr); |
| } |
| cnt++; |
| //di_que_in(channel, QUE_POST_FREE, di_buf); |
| di_que_in(ch, QUE_PST_NO_BUF, di_buf); |
| |
| } else { |
| PR_ERR("%s:%d:post buf is null\n", __func__, i); |
| } |
| } |
| /* check */ |
| length = di_que_list_count(ch, QUE_PST_NO_BUF); |
| |
| di_buf = di_que_out_to_di_buf(ch, QUE_PST_NO_BUF); |
| dbg_mem2("%s:ch[%d]:pst_no_buf:%d, indx[%d]\n", __func__, |
| ch, length, di_buf->index); |
| return 0; |
| } |
| |
| static void check_tvp_state(struct di_ch_s *pch) |
| { |
| #ifdef TMP_TEST /* for ko only */ |
| set_flag_tvp(pch->ch_id, 1); |
| #else |
| unsigned int ch; |
| struct provider_state_req_s req; |
| char *provider_name;// = vf_get_provider_name(pch->vfm.name); |
| |
| ch = pch->ch_id; |
| if (!dip_itf_is_vfm(pch)) { |
| set_flag_secure_pre(ch, 0); |
| set_flag_secure_pst(ch, 0); |
| if (pch->itf.u.dinst.parm.output_format & DI_OUTPUT_TVP) |
| set_flag_tvp(pch->ch_id, 2); |
| else |
| set_flag_tvp(pch->ch_id, 1); |
| return; |
| } |
| |
| set_flag_tvp(ch, 0); |
| set_flag_secure_pre(ch, 0); |
| set_flag_secure_pst(ch, 0); |
| provider_name = vf_get_provider_name(pch->itf.dvfm.name); |
| |
| while (provider_name) { |
| if (!vf_get_provider_name(provider_name)) |
| break; |
| provider_name = |
| vf_get_provider_name(provider_name); |
| } |
| if (provider_name) { |
| req.vf = NULL; |
| req.req_type = REQ_STATE_SECURE; |
| req.req_result[0] = 0xffffffff; |
| vf_notify_provider_by_name |
| (provider_name, |
| VFRAME_EVENT_RECEIVER_REQ_STATE, |
| (void *)&req); |
| if (req.req_result[0] == 0) |
| set_flag_tvp(ch, 1); |
| else if (req.req_result[0] != 0xffffffff) |
| set_flag_tvp(ch, 2); |
| } |
| dbg_mem2("%s:tvp1:%d\n", __func__, get_flag_tvp(ch)); |
| if (get_flag_tvp(ch) == 0) { |
| if (codec_mm_video_tvp_enabled()) |
| set_flag_tvp(ch, 2); |
| else |
| set_flag_tvp(ch, 1); |
| } |
| dbg_mem2("%s:tvp2:%d\n", __func__, get_flag_tvp(ch)); |
| #endif |
| } |
| |
| static int di_init_buf_new(struct di_ch_s *pch) |
| { |
| struct mtsk_cmd_s blk_cmd; |
| //struct di_dev_s *de_devp = get_dim_de_devp(); |
| struct div2_mm_s *mm; |
| unsigned int ch; |
| unsigned int length_keep; |
| // struct di_dat_s *pdat; |
| |
| ch = pch->ch_id; |
| mm = dim_mm_get(ch); |
| |
| check_tvp_state(pch); |
| di_cnt_i_buf(pch, 1920, 1088); |
| //di_cnt_i_buf(pch, 1920, 2160); |
| di_cnt_pst_afbct(pch); |
| di_cnt_post_buf(pch); |
| di_init_buf_simple(pch); |
| |
| length_keep = ndis_cnt(pch, QBF_NDIS_Q_KEEP); |
| //di_que_list_count(ch, QUE_POST_KEEP); |
| |
| if (cfgeq(MEM_FLAG, EDI_MEM_M_CMA) || |
| cfgeq(MEM_FLAG, EDI_MEM_M_CODEC_A) || |
| cfgeq(MEM_FLAG, EDI_MEM_M_CODEC_B)) { /*trig cma alloc*/ |
| blk_cmd.cmd = ECMD_BLK_ALLOC; |
| #ifdef MARK_HIS |
| /*pre idat*/ |
| if (!pch->rse_ori.dat_i.blk_buf) { |
| blk_cmd.nub = 1; |
| blk_cmd.flg.d32 = mm->cfg.dat_idat_flg.d32; |
| mtask_send_cmd(ch, &blk_cmd); |
| PR_INF("%s:alloc idat\n", __func__); |
| } else { |
| PR_INF("%s:no alloc idat\n", __func__); |
| } |
| #endif |
| if (mm->cfg.num_local) { |
| /* pre */ |
| //blk_cmd.cmd = ECMD_BLK_ALLOC; |
| blk_cmd.nub = mm->cfg.num_local; |
| blk_cmd.flg.d32 = mm->cfg.ibuf_flg.d32; |
| |
| mtask_send_cmd(ch, &blk_cmd); |
| } |
| |
| /* post */ |
| if (length_keep > 8) |
| PR_ERR("%s:keep nub:%d\n", __func__, length_keep); |
| |
| #ifdef CFG_BUF_ALLOC_SP |
| #ifdef MARK_HIS |
| pdat = get_pst_afbct(pch); |
| if ((!pdat->flg_alloc) && mm->cfg.dat_pafbct_flg.d32) { |
| blk_cmd.nub = 1; |
| blk_cmd.flg.d32 = mm->cfg.dat_pafbct_flg.d32; |
| mtask_send_cmd(ch, &blk_cmd); |
| dbg_mem2("%s:send alloc afbct cmd\n", __func__); |
| } else { |
| dbg_mem2("%s:not afbct %d,%d\n", __func__, |
| (!pdat->flg_alloc), |
| mm->cfg.dat_pafbct_flg.d32); |
| } |
| #endif |
| #endif |
| blk_cmd.nub = mm->cfg.num_post - length_keep; |
| blk_cmd.flg.d32 = mm->cfg.pbuf_flg.d32; |
| |
| if (mm->cfg.pbuf_flg.b.page) {//@ary_note: ?? |
| mtask_send_cmd(ch, &blk_cmd); |
| } else if ((mm->cfg.pbuf_flg.b.typ & 0x8) == |
| EDIM_BLK_TYP_POUT) { |
| //move all to wait: |
| di_buf_no2wait(pch); |
| } |
| } |
| return 0; |
| } |
| |
| #ifdef MARK_SC2 |
| static int di_init_buf(int width, int height, unsigned char prog_flag, |
| unsigned int channel) |
| { |
| int i; |
| int canvas_height = height + 8; |
| struct page *tmp_page = NULL; |
| unsigned long tmp_addr; |
| unsigned int di_buf_size = 0, di_post_buf_size = 0, mtn_size = 0; |
| unsigned int nr_size = 0, count_size = 0, mv_size = 0, mc_size = 0; |
| unsigned int nr_width = width, mtn_width = width, mv_width = width; |
| unsigned int nr_canvas_width = width, mtn_canvas_width = width; |
| unsigned int mv_canvas_width = width, canvas_align_width = 32; |
| unsigned long di_post_mem = 0, nrds_mem = 0; |
| struct vframe_s **pvframe_in = get_vframe_in(channel); |
| struct vframe_s *pvframe_in_dup = get_vframe_in_dup(channel); |
| struct vframe_s *pvframe_local = get_vframe_local(channel); |
| struct vframe_s *pvframe_post = get_vframe_post(channel); |
| struct di_buf_s *pbuf_local = get_buf_local(channel); |
| struct di_buf_s *pbuf_in = get_buf_in(channel); |
| struct di_buf_s *pbuf_post = get_buf_post(channel); |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| struct di_post_stru_s *ppost = get_post_stru(channel); |
| struct di_buf_s *keep_buf = ppost->keep_buf; |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| /* struct di_buf_s *keep_buf_post = ppost->keep_buf_post;*/ |
| struct div2_mm_s *mm = dim_mm_get(channel); /*mm-0705*/ |
| |
| unsigned int mem_st_local; |
| unsigned int afbc_info_size = 0, afbc_tab_size = 0, old_size; |
| unsigned int afbc_buffer_size = 0, blk_total = 0; |
| unsigned int afbc_info_size_p = 0, afbc_tab_size_p = 0; |
| |
| /**********************************************/ |
| /* count buf info */ |
| /**********************************************/ |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| canvas_align_width = 64; |
| |
| dbg_reg("%s:begin\n", __func__); |
| frame_count = 0; |
| disp_frame_count = 0; |
| cur_post_ready_di_buf = NULL; |
| /* decoder'buffer had been releae no need put */ |
| for (i = 0; i < MAX_IN_BUF_NUM; i++) |
| pvframe_in[i] = NULL; |
| /*pre init*/ |
| memset(ppre, 0, sizeof(struct di_pre_stru_s)); |
| |
| if (dimp_get(edi_mp_nr10bit_support)) { |
| if (dimp_get(edi_mp_full_422_pack)) |
| nr_width = (width * 5) / 4; |
| else |
| nr_width = (width * 3) / 2; |
| } else { |
| nr_width = width; |
| } |
| /* make sure canvas width must be divided by 256bit|32byte align */ |
| nr_canvas_width = nr_width << 1; |
| mtn_canvas_width = mtn_width >> 1; |
| mv_canvas_width = (mv_width << 1) / 5; |
| nr_canvas_width = roundup(nr_canvas_width, canvas_align_width); |
| mtn_canvas_width = roundup(mtn_canvas_width, canvas_align_width); |
| mv_canvas_width = roundup(mv_canvas_width, canvas_align_width); |
| nr_width = nr_canvas_width >> 1; |
| mtn_width = mtn_canvas_width << 1; |
| mv_width = (mv_canvas_width * 5) >> 1; |
| /* tvp flg */ |
| if (codec_mm_video_tvp_enabled()) |
| mm->sts.flg_tvp = 1; |
| else |
| mm->sts.flg_tvp = 0; |
| |
| if (dim_afds() && dim_afds()->cnt_info_size && |
| (dim_afds()->is_sts(EAFBC_MEM_NEED) || cfgg(FIX_BUF))) { |
| afbc_info_size = dim_afds()->cnt_info_size(width, height, |
| &blk_total); |
| afbc_buffer_size = dim_afds()->cnt_buf_size(0x21, |
| blk_total); |
| } |
| if (prog_flag) { |
| ppre->prog_proc_type = 1; |
| mm->cfg.buf_alloc_mode = 1; |
| di_buf_size = nr_width * canvas_height * 2; |
| di_buf_size = roundup(di_buf_size, PAGE_SIZE); |
| old_size = di_buf_size; |
| nr_size = di_buf_size; |
| |
| if (dim_afds() && dim_afds()->cnt_tab_size && |
| dim_afds()->is_sts(EAFBC_MEM_NEED)) { |
| afbc_info_size = |
| dim_afds()->cnt_info_size(width, height); |
| afbc_tab_size = dim_afds()->cnt_tab_size(nr_size); |
| |
| di_buf_size += afbc_info_size; |
| di_buf_size += afbc_tab_size; |
| } |
| #ifdef MARK_SC2 |
| if (is_mask(SC2_DW_EN)) |
| di_buf_size += dim_getdw()->size_info.p.size_buf; |
| #endif |
| |
| } else { |
| /*pr_info("canvas_height=%d\n", canvas_height);*/ |
| ppre->prog_proc_type = 0; |
| mm->cfg.buf_alloc_mode = 0; |
| /*nr_size(bits) = w * active_h * 8 * 2(yuv422) |
| * mtn(bits) = w * active_h * 4 |
| * cont(bits) = w * active_h * 4 mv(bits) = w * active_h / 5*16 |
| * mcinfo(bits) = active_h * 16 |
| */ |
| nr_size = (nr_width * canvas_height) * 8 * 2 / 16; |
| mtn_size = (mtn_width * canvas_height) * 4 / 16; |
| count_size = (mtn_width * canvas_height) * 4 / 16; |
| mv_size = (mv_width * canvas_height) / 5; |
| /*mc_size = canvas_height;*/ |
| mc_size = roundup(canvas_height >> 1, canvas_align_width) << 1; |
| if (mc_mem_alloc) { |
| di_buf_size = nr_size + mtn_size + count_size + |
| mv_size + mc_size; |
| } else { |
| di_buf_size = nr_size + mtn_size + count_size; |
| } |
| di_buf_size = roundup(di_buf_size, PAGE_SIZE); |
| old_size = di_buf_size; |
| if (dim_afds() && dim_afds()->cnt_tab_size && |
| dim_afds()->is_sts(EAFBC_MEM_NEED)) { |
| afbc_info_size = |
| dim_afds()->cnt_info_size(width, |
| height);/*ary ?*/ |
| afbc_tab_size = dim_afds()->cnt_tab_size(nr_size); |
| } |
| di_buf_size += afbc_info_size; |
| di_buf_size += afbc_tab_size; |
| } |
| /*de_devp->buffer_size = di_buf_size;*/ |
| mm->cfg.size_local = di_buf_size; |
| |
| mm->cfg.nr_size = nr_size; |
| mm->cfg.count_size = count_size; |
| mm->cfg.mtn_size = mtn_size; |
| mm->cfg.mv_size = mv_size; |
| mm->cfg.mcinfo_size = mc_size; |
| mm->cfg.ll_afbci_size = afbc_info_size; |
| mm->cfg.ll_afbct_size = afbc_tab_size; |
| |
| dimp_set(edi_mp_same_field_top_count, 0); |
| same_field_bot_count = 0; |
| dbg_init("size:\n"); |
| dbg_init("\t%-15s:0x%x\n", "nr_size", mm->cfg.nr_size); |
| dbg_init("\t%-15s:0x%x\n", "count", mm->cfg.count_size); |
| dbg_init("\t%-15s:0x%x\n", "mtn", mm->cfg.mtn_size); |
| dbg_init("\t%-15s:0x%x\n", "mv", mm->cfg.mv_size); |
| dbg_init("\t%-15s:0x%x\n", "mcinfo", mm->cfg.mcinfo_size); |
| dbg_init("\t%-15s:0x%x\n", "ll_afbci_size", mm->cfg.ll_afbci_size); |
| dbg_init("\t%-15s:0x%x\n", "ll_afbct_size", mm->cfg.ll_afbct_size); |
| |
| /**********************************************/ |
| /* que init */ |
| /**********************************************/ |
| |
| queue_init(channel, mm->cfg.num_local); |
| di_que_init(channel); /*new que*/ |
| |
| mem_st_local = di_get_mem_start(channel); |
| |
| /**********************************************/ |
| /* local buf init */ |
| /**********************************************/ |
| |
| for (i = 0; i < mm->cfg.num_local; i++) { |
| struct di_buf_s *di_buf = &pbuf_local[i]; |
| int ii = USED_LOCAL_BUF_MAX; |
| |
| if (!IS_ERR_OR_NULL(keep_buf)) { |
| for (ii = 0; ii < USED_LOCAL_BUF_MAX; ii++) { |
| if (di_buf == keep_buf->di_buf_dup_p[ii]) { |
| dim_print("%s skip %d\n", __func__, i); |
| break; |
| } |
| } |
| } |
| |
| if (ii >= USED_LOCAL_BUF_MAX) { |
| /* backup cma pages */ |
| tmp_page = di_buf->pages; |
| tmp_addr = di_buf->nr_adr; |
| memset(di_buf, 0, sizeof(struct di_buf_s)); |
| di_buf->pages = tmp_page; |
| di_buf->nr_adr = tmp_addr; |
| di_buf->type = VFRAME_TYPE_LOCAL; |
| di_buf->pre_ref_count = 0; |
| di_buf->post_ref_count = 0; |
| di_buf->canvas_width[NR_CANVAS] = nr_canvas_width; |
| di_buf->canvas_width[MTN_CANVAS] = mtn_canvas_width; |
| di_buf->canvas_width[MV_CANVAS] = mv_canvas_width; |
| if (prog_flag) { |
| di_buf->canvas_height = canvas_height; |
| di_buf->canvas_height_mc = canvas_height; |
| if (cfgeq(MEM_FLAG, EDI_MEM_M_REV) || |
| cfgeq(MEM_FLAG, EDI_MEM_M_CMA_ALL)) { |
| di_buf->nr_adr = mem_st_local + |
| di_buf_size * i; |
| } |
| di_buf->canvas_config_flag = 1; |
| } else { |
| di_buf->canvas_height = (canvas_height >> 1); |
| di_buf->canvas_height_mc = |
| roundup(di_buf->canvas_height, |
| canvas_align_width); |
| if (cfgeq(MEM_FLAG, EDI_MEM_M_REV) || |
| cfgeq(MEM_FLAG, EDI_MEM_M_CMA_ALL)) { |
| di_buf->nr_adr = mem_st_local + |
| di_buf_size * i; |
| } |
| di_buf->mtn_adr = di_buf->nr_adr + |
| nr_size; |
| di_buf->cnt_adr = di_buf->nr_adr + |
| nr_size + mtn_size; |
| |
| if (mc_mem_alloc) { |
| di_buf->mcvec_adr = di_buf->nr_adr + |
| nr_size + mtn_size |
| + count_size; |
| di_buf->mcinfo_adr = |
| di_buf->nr_adr + nr_size + |
| mtn_size + count_size |
| + mv_size; |
| if (cfgeq(MEM_FLAG, EDI_MEM_M_REV) || |
| cfgeq(MEM_FLAG, EDI_MEM_M_CMA_ALL)) |
| dim_mcinfo_v_alloc(di_buf, |
| mm->cfg.mcinfo_size); |
| } |
| di_buf->canvas_config_flag = 2; |
| } |
| di_buf->index = i; |
| di_buf->vframe = &pvframe_local[i]; |
| di_buf->vframe->private_data = di_buf; |
| di_buf->vframe->canvas0Addr = di_buf->nr_canvas_idx; |
| di_buf->vframe->canvas1Addr = di_buf->nr_canvas_idx; |
| di_buf->queue_index = -1; |
| di_buf->invert_top_bot_flag = 0; |
| di_buf->channel = channel; |
| queue_in(channel, di_buf, QUEUE_LOCAL_FREE); |
| dbg_init("buf[%d], addr=0x%lx\n", di_buf->index, |
| di_buf->nr_adr); |
| } |
| } |
| |
| dbg_init("one local buf size:0x%x\n", di_buf_size); |
| /*mm-0705 di_post_mem = mem_st_local +*/ |
| /*mm-0705 di_buf_size*de_devp->buf_num_avail;*/ |
| di_post_mem = mem_st_local + di_buf_size * mm->cfg.num_local; |
| if (dimp_get(edi_mp_post_wr_en) && dimp_get(edi_mp_post_wr_support)) { |
| di_post_buf_size = nr_width * canvas_height * 2; |
| mm->cfg.p_nr_size = di_post_buf_size; |
| if (dim_afds() && dim_afds()->cnt_tab_size && |
| dim_afds()->is_sts(EAFBC_MEM_NEED)) { |
| afbc_info_size_p = |
| dim_afds()->cnt_info_size(width, height); |
| afbc_tab_size_p = |
| dim_afds()->cnt_tab_size(di_post_buf_size); |
| // mm->cfg.pst_buf_size = di_buf_size; |
| di_post_buf_size += afbc_info_size_p; |
| di_post_buf_size += afbc_tab_size_p; |
| mm->cfg.p_afbci_size = afbc_info_size_p; |
| mm->cfg.p_afbct_size = afbc_tab_size_p; |
| } |
| mm->cfg.dw_size = 0; |
| if (is_mask(SC2_DW_EN)) { |
| di_post_buf_size += dim_getdw()->size_info.p.size_buf; |
| mm->cfg.dw_size = dim_getdw()->size_info.p.size_buf; |
| } |
| #ifdef MARK_SC2 |
| dbg_init("\t%-15s:0x%x\n", |
| "p_afbci_size", mm->cfg.p_afbci_size); |
| dbg_init("\t%-15s:0x%x\n", |
| "p_afbct_size", mm->cfg.p_afbct_size); |
| dbg_init("\t%-15s:0x%x\n", |
| "dw_size", mm->cfg.dw_size); |
| dbg_init("DI: di post buffer size 0x%x byte.\n", |
| di_post_buf_size); |
| #endif |
| } else { |
| /*mm-0705 ppost->di_post_num = MAX_POST_BUF_NUM;*/ |
| di_post_buf_size = 0; |
| mm->cfg.p_nr_size = 0; |
| } |
| /*de_devp->post_buffer_size = di_post_buf_size;*/ |
| mm->cfg.size_post = di_post_buf_size; |
| |
| /**********************************************/ |
| /* input buf init */ |
| /**********************************************/ |
| |
| for (i = 0; i < MAX_IN_BUF_NUM; i++) { |
| struct di_buf_s *di_buf = &pbuf_in[i]; |
| |
| if (di_buf) { |
| memset(di_buf, 0, sizeof(struct di_buf_s)); |
| di_buf->type = VFRAME_TYPE_IN; |
| di_buf->pre_ref_count = 0; |
| di_buf->post_ref_count = 0; |
| di_buf->vframe = &pvframe_in_dup[i]; |
| di_buf->vframe->private_data = di_buf; |
| di_buf->index = i; |
| di_buf->queue_index = -1; |
| di_buf->invert_top_bot_flag = 0; |
| di_buf->channel = channel; |
| di_que_in(channel, QUE_IN_FREE, di_buf); |
| } |
| } |
| /**********************************************/ |
| /* post buf init */ |
| /**********************************************/ |
| /*mm-0705 for (i = 0; i < ppost->di_post_num; i++) {*/ |
| for (i = 0; i < mm->cfg.num_post; i++) { |
| struct di_buf_s *di_buf = &pbuf_post[i]; |
| |
| if (di_buf) { |
| if (dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) { |
| if (di_que_is_in_que(channel, QUE_POST_KEEP, |
| di_buf)) { |
| dbg_reg("%s:post keep buf %d\n", |
| __func__, |
| di_buf->index); |
| dbg_wq("k:b[%d]\n", di_buf->index); |
| continue; |
| } |
| } |
| tmp_page = di_buf->pages; |
| tmp_addr = di_buf->nr_adr; |
| memset(di_buf, 0, sizeof(struct di_buf_s)); |
| di_buf->pages = tmp_page; |
| di_buf->nr_adr = tmp_addr; |
| di_buf->type = VFRAME_TYPE_POST; |
| di_buf->index = i; |
| di_buf->vframe = &pvframe_post[i]; |
| di_buf->vframe->private_data = di_buf; |
| di_buf->queue_index = -1; |
| di_buf->invert_top_bot_flag = 0; |
| di_buf->channel = channel; |
| if (dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) { |
| di_buf->canvas_width[NR_CANVAS] = |
| (nr_width << 1); |
| di_buf->canvas_height = canvas_height; |
| di_buf->canvas_config_flag = 1; |
| if (cfgeq(MEM_FLAG, EDI_MEM_M_REV) || |
| cfgeq(MEM_FLAG, EDI_MEM_M_CMA_ALL)) { |
| di_buf->nr_adr = di_post_mem |
| + di_post_buf_size * i; |
| } |
| dbg_init("[%d]post buf:%d: addr=0x%lx\n", i, |
| di_buf->index, di_buf->nr_adr); |
| } |
| |
| di_que_in(channel, QUE_POST_FREE, di_buf); |
| |
| } else { |
| PR_ERR("%s:%d:post buf is null\n", __func__, i); |
| } |
| } |
| if (cfgeq(MEM_FLAG, EDI_MEM_M_CMA) || |
| cfgeq(MEM_FLAG, EDI_MEM_M_CODEC_A) || |
| cfgeq(MEM_FLAG, EDI_MEM_M_CODEC_B)) { /*trig cma alloc*/ |
| dip_wq_cma_run(channel, ECMA_CMD_ALLOC); |
| } |
| if (cfgeq(MEM_FLAG, EDI_MEM_M_REV) && de_devp->nrds_enable) { |
| nrds_mem = di_post_mem + mm->cfg.num_post * di_post_buf_size; |
| /*mm-0705 ppost->di_post_num * di_post_buf_size;*/ |
| dim_nr_ds_buf_init(cfgg(MEM_FLAG), nrds_mem, |
| &de_devp->pdev->dev, 0); |
| } |
| return 0; |
| } |
| #endif |
| |
| #ifdef MARK_HIS/* @ary_note: no used */ |
| void dim_post_keep_mirror_buffer(unsigned int channel) |
| { |
| struct di_buf_s *p = NULL; |
| int itmp; |
| bool flg = false; |
| struct di_post_stru_s *ppost = get_post_stru(channel); |
| |
| queue_for_each_entry(p, channel, QUEUE_DISPLAY, list) { |
| if (p->type != VFRAME_TYPE_POST || |
| !p->process_fun_index) { |
| dbg_reg("%s:not post buf:%d\n", |
| __func__, p->type); |
| continue; |
| } |
| |
| ppost->keep_buf_post = p; /*only keep one*/ |
| flg = true; |
| dbg_reg("%s %d\n", __func__, p->index); |
| } |
| |
| if (flg && ppost->keep_buf_post) { |
| ppost->keep_buf_post->queue_index = -1; |
| ppost->keep_buf_post->invert_top_bot_flag = 0; |
| } |
| } |
| #endif |
| |
| #ifdef MARK_HIS |
| void dim_post_keep_mirror_buffer2(unsigned int ch) |
| { |
| struct di_buf_s *p = NULL; |
| int itmp; |
| struct vframe_s **pvframe_in = get_vframe_in(ch); |
| |
| queue_for_each_entry(p, ch, QUEUE_DISPLAY, list) { |
| if (p->type != VFRAME_TYPE_POST) { |
| dbg_keep("%s:not post buf:%d\n", __func__, p->type); |
| continue; |
| } |
| if (di_que_is_in_que(ch, QUE_POST_BACK, p)) { |
| dbg_keep("%s:is in back[%d]\n", __func__, p->index); |
| continue; |
| } |
| |
| if (!p->blk_buf) { |
| //dbg_keep("%s:no blk:%d\n", __func__, p->index); |
| continue; |
| } |
| /* dec vf keep */ |
| if (p->in_buf) { |
| pvframe_in[p->in_buf->index] = NULL; |
| queue_in(ch, p->in_buf, QUEUE_RECYCLE); |
| p->in_buf = NULL; |
| } |
| |
| p->queue_index = -1; |
| di_que_in(ch, QUE_POST_KEEP, p); |
| |
| dbg_wq("k:k[%d]:blk[%d][%d]\n", |
| p->index, |
| p->blk_buf->header.index, |
| p->blk_buf->reg_cnt); |
| p->invert_top_bot_flag = 0; |
| |
| dbg_keep("%s %d\n", __func__, p->index); |
| } |
| } |
| #endif |
| #ifdef MARK_HIS |
| |
| bool dim_post_keep_is_in(unsigned int ch, struct di_buf_s *di_buf) |
| { |
| if (di_que_is_in_que(ch, QUE_POST_KEEP, di_buf)) |
| return true; |
| return false; |
| } |
| |
| static bool dim_post_keep_release_one(unsigned int ch, |
| unsigned int di_buf_index) |
| { |
| struct di_buf_s *pbuf_post; |
| struct di_buf_s *di_buf; |
| struct div2_mm_s *mm; |
| struct di_ch_s *pch = get_chdata(ch); |
| bool release_flg = false; |
| |
| /*must post or err*/ |
| pbuf_post = get_buf_post(ch); |
| di_buf = &pbuf_post[di_buf_index]; |
| |
| if (!di_que_is_in_que(ch, QUE_POST_KEEP, di_buf)) { |
| if (is_in_queue(ch, di_buf, QUEUE_DISPLAY)) { |
| di_buf->queue_index = -1; |
| di_que_in(ch, QUE_POST_BACK, di_buf); |
| dbg_keep("%s:to back[%d]\n", __func__, di_buf_index); |
| } else { |
| PR_ERR("%s:buf[%d] is not in keep or display\n", |
| __func__, di_buf_index); |
| } |
| return false; |
| } |
| di_que_out_not_fifo(ch, QUE_POST_KEEP, di_buf); |
| di_buf->flg_nr = 0; |
| |
| di_buf->flg_nv21 = 0; |
| //dim_print("nv21 clear %s:%px:\n", __func__, di_buf); |
| |
| mm = dim_mm_get(ch); |
| if (di_buf->blk_buf) { |
| if (di_buf->blk_buf->flg.d32 != mm->cfg.pbuf_flg.d32) { |
| mem_release_one_inused(pch, di_buf->blk_buf); |
| dbg_mem2("keep_buf:1:flg trig realloc,0x%x->0x%x\n", |
| di_buf->blk_buf->flg.d32, |
| mm->cfg.pbuf_flg.d32); |
| di_buf->blk_buf = NULL; |
| |
| di_que_in(ch, QUE_PST_NO_BUF, di_buf); |
| release_flg = true; |
| mm->sts.flg_realloc++; |
| } |
| } |
| if (!release_flg) |
| di_que_in(ch, QUE_POST_FREE, di_buf); |
| |
| dbg_keep("%s:buf[%d]\n", __func__, di_buf_index); |
| return true; |
| } |
| #endif |
| /* @ary_note: only for ready */ |
| /* @ary_note: when ready, process non-keep buffer and keep buffer */ |
| #ifdef MARK_HIS |
| bool dim_post_keep_release_one_check(unsigned int ch, unsigned int di_buf_index) |
| { |
| struct di_buf_s *pbuf_post; |
| struct di_buf_s *di_buf; |
| struct div2_mm_s *mm = dim_mm_get(ch); |
| bool flg_alloc = false; |
| struct di_ch_s *pch; |
| |
| pbuf_post = get_buf_post(ch); |
| di_buf = &pbuf_post[di_buf_index]; |
| |
| if (!di_que_is_in_que(ch, QUE_POST_KEEP, di_buf)) { |
| if (is_in_queue(ch, di_buf, QUEUE_DISPLAY)) { |
| di_buf->queue_index = -1; |
| di_que_in(ch, QUE_POST_BACK, di_buf); |
| dbg_keep("%s:to back[%d]\n", __func__, di_buf_index); |
| } else { |
| PR_ERR("%s:buf[%d] q[%d]is not in keep or display\n", |
| __func__, di_buf_index, di_buf->queue_index); |
| if (di_buf->blk_buf) { |
| PR_ERR("\tblk[%d],[%d]\n", |
| di_buf->blk_buf->header.index, |
| di_buf->blk_buf->reg_cnt); |
| } |
| } |
| return false; |
| } |
| |
| #if 1 |
| if (mm->sts.flg_tvp) { |
| if ((di_buf->blk_buf) && (!di_buf->blk_buf->flg.b.tvp)) { |
| flg_alloc = true; |
| PR_ERR("%d is not tvp\n", di_buf->index); |
| } |
| } |
| |
| if (di_buf->blk_buf) { |
| if ((di_buf->blk_buf->flg.d32 != mm->cfg.pbuf_flg.d32) || |
| (di_buf->blk_buf->sct_keep != 0xff)) { |
| flg_alloc = true; |
| dbg_mem2("keep_buf:2:flg trig realloc,0x%x->0x%x\n", |
| di_buf->blk_buf->flg.d32, |
| mm->cfg.pbuf_flg.d32); |
| } |
| } else { |
| PR_ERR("%s:err:no blk?\n", __func__); |
| } |
| #else /*use for test flow*/ |
| flg_alloc = true; |
| #endif |
| #if 1 |
| if (flg_alloc) { |
| mm->sts.flg_realloc++; |
| /* IN_USED -> OUT */ |
| pch = get_chdata(ch); |
| di_que_out_not_fifo(ch, QUE_POST_KEEP, di_buf); |
| mem_release_one_inused(pch, di_buf->blk_buf); |
| di_que_in(ch, QUE_PST_NO_BUF, di_buf); |
| |
| } else { |
| di_que_out_not_fifo(ch, QUE_POST_KEEP, di_buf); |
| di_buf->flg_nr = 0; |
| di_buf->flg_nv21 = 0; |
| //dim_print("nv21 clear %s:%px:\n", __func__, di_buf); |
| di_que_in(ch, QUE_POST_FREE, di_buf); |
| dbg_keep("%s:buf[%d]\n", __func__, di_buf_index); |
| } |
| #else |
| di_que_out_not_fifo(ch, QUE_POST_KEEP, di_buf); |
| di_que_in(ch, QUE_POST_FREE, di_buf); |
| dbg_keep("%s:buf[%d]\n", __func__, di_buf_index); |
| #endif |
| return true; |
| } |
| #else |
| bool dim_post_keep_release_one_check(unsigned int ch, unsigned int di_buf_index) |
| { |
| // struct di_buf_s *pbuf_post; |
| struct di_buf_s *di_buf; |
| struct div2_mm_s *mm = dim_mm_get(ch); |
| // bool flg_alloc = false; |
| struct di_ch_s *pch; |
| struct dim_ndis_s *ndis; |
| |
| pch = get_chdata(ch); |
| |
| ndis = ndis_get_fromid(pch, di_buf_index); |
| if (!ndis) { |
| PR_ERR("%s:no ndis\n", __func__); |
| return false; |
| } |
| |
| if (!ndis_is_in_keep(pch, ndis)) { |
| /* @ary_note: from put */ |
| if (ndis_is_in_display(pch, ndis)) { |
| di_buf = ndis->c.di_buf; |
| if (!di_buf) { |
| PR_ERR("%s:no di_buf\n", __func__); |
| return false; |
| } |
| di_buf->queue_index = -1; |
| di_que_in(ch, QUE_POST_BACK, di_buf); |
| ndis_move_display2idle(pch, ndis); |
| if (dimp_get(edi_mp_bypass_post_state)) |
| PR_INF("%s:buf[%d,%d]\n", __func__, |
| di_buf->type, di_buf->index); |
| |
| dbg_keep("%s:to back[%d]\n", __func__, di_buf_index); |
| } else { |
| PR_ERR("%s:ndis[%d] is not in keep or display\n", |
| __func__, ndis->header.index); |
| } |
| return true; |
| } |
| |
| mm->sts.flg_realloc++; |
| dbg_mem2("%s:stsflg_realloc[%d]\n", __func__, mm->sts.flg_realloc); |
| mem_release_one_inused(pch, ndis->c.blk); |
| ndis_move_keep2idle(pch, ndis); |
| return true; |
| } |
| #endif |
| /* after dim_post_keep_release_one_check */ |
| void dim_post_re_alloc(unsigned int ch) |
| { |
| struct div2_mm_s *mm = dim_mm_get(ch); |
| // struct di_mng_s *pbm = get_bufmng(); |
| struct di_ch_s *pch; |
| unsigned int length; |
| struct mtsk_cmd_s cmd; |
| |
| pch = get_chdata(ch); |
| if (mm->sts.flg_release) { |
| /* KEEP_BACK -> release */ |
| mem_release_keep_back(pch); |
| //mtsk_release(ch, ECMD_BLK_RELEASE); |
| mm->sts.flg_release = 0; |
| } |
| |
| /* trig recycle */ |
| length = qbufp_count(&pch->mem_qb, QBF_MEM_Q_RECYCLE); |
| if (length) { |
| mem_2_blk(pch); |
| cmd.cmd = ECMD_BLK_RELEASE; |
| mtask_send_cmd(ch, &cmd); |
| //mtsk_release(ch, ECMD_BLK_RELEASE); |
| } |
| |
| if (mm->sts.flg_realloc) { |
| cmd.cmd = ECMD_BLK_ALLOC; |
| cmd.nub = mm->sts.flg_realloc; |
| cmd.flg.d32 = mm->cfg.pbuf_flg.d32; |
| mtask_send_cmd(ch, &cmd); |
| //mtsk_alloc(ch, mm->sts.flg_realloc, mm->cfg.size_post_page); |
| mm->sts.flg_realloc = 0; |
| } |
| } |
| |
| #ifdef MARK_HIS |
| bool dim_post_keep_release_all_2free(unsigned int ch) |
| { |
| struct di_buf_s *di_buf; |
| struct di_buf_s *pbuf_post; |
| unsigned int i = 0; |
| |
| if (di_que_is_empty(ch, QUE_POST_KEEP)) |
| return true; |
| |
| pbuf_post = get_buf_post(ch); |
| dbg_keep("%s:ch[%d]\n", __func__, ch); |
| |
| while (i <= MAX_POST_BUF_NUM) { |
| i++; |
| di_buf = di_que_peek(ch, QUE_POST_KEEP); |
| if (!di_buf) |
| break; |
| |
| if (!di_que_out(ch, QUE_POST_KEEP, di_buf)) { |
| PR_ERR("%s:out err\n", __func__); |
| break; |
| } |
| di_buf->flg_nr = 0; |
| di_buf->flg_nv21 = 0; |
| //dim_print("nv21 clear %s:%px:\n", __func__, di_buf); |
| di_que_in(ch, QUE_POST_FREE, di_buf); |
| |
| dbg_keep("\ttype[%d],index[%d]\n", di_buf->type, di_buf->index); |
| } |
| |
| return true; |
| } |
| #endif |
| |
| #ifdef MARK_HIS |
| /* @ary_note debug release cmd */ |
| void dim_post_keep_cmd_release(unsigned int ch, struct vframe_s *vframe) |
| { |
| struct di_buf_s *di_buf; |
| |
| if (!vframe) |
| return; |
| |
| di_buf = (struct di_buf_s *)vframe->private_data; |
| |
| if (!di_buf) { |
| PR_WARN("%s:ch[%d]:no di_buf\n", __func__, ch); |
| return; |
| } |
| |
| if (di_buf->type != VFRAME_TYPE_POST) { |
| PR_WARN("%s:ch[%d]:not post\n", __func__, ch); |
| return; |
| } |
| dbg_keep("release keep ch[%d],index[%d]\n", |
| di_buf->channel, |
| di_buf->index); |
| task_send_cmd2(ch, LCMD2(ECMD_RL_KEEP, di_buf->channel, di_buf->index)); |
| } |
| |
| void dim_post_keep_cmd_release2_local(struct vframe_s *vframe) |
| { |
| struct di_buf_s *di_buf; |
| |
| if (!dil_get_diffver_flag()) |
| return; |
| |
| if (!vframe) |
| return; |
| |
| di_buf = (struct di_buf_s *)vframe->private_data; |
| |
| if (!di_buf) { |
| PR_WARN("%s:no di_buf\n", __func__); |
| return; |
| } |
| |
| if (di_buf->type != VFRAME_TYPE_POST) { |
| PR_WARN("%s:ch[%d]:not post\n", __func__, di_buf->channel); |
| return; |
| } |
| |
| dbg_keep("release keep ch[%d],index[%d]\n", |
| di_buf->channel, |
| di_buf->index); |
| dbg_wq("k:c[%d]\n", di_buf->index); |
| task_send_cmd2(di_buf->channel, |
| LCMD2(ECMD_RL_KEEP, |
| di_buf->channel, |
| di_buf->index)); |
| } |
| #endif |
| |
| //EXPORT_SYMBOL(dim_post_keep_cmd_release2); |
| #ifdef MARK_HIS |
| void dim_dbg_release_keep_all(unsigned int ch) |
| { |
| unsigned int tmpa[MAX_FIFO_SIZE]; |
| unsigned int psize, itmp; |
| struct di_buf_s *p; |
| |
| di_que_list(ch, QUE_POST_KEEP, &tmpa[0], &psize); |
| dbg_keep("post_keep: curr(%d)\n", psize); |
| |
| for (itmp = 0; itmp < psize; itmp++) { |
| p = pw_qindex_2_buf(ch, tmpa[itmp]); |
| dbg_keep("\ttype[%d],index[%d]\n", p->type, p->index); |
| dim_post_keep_cmd_release(ch, p->vframe); |
| } |
| dbg_keep("%s:end\n", __func__); |
| } |
| |
| void dim_post_keep_back_recycle(unsigned int ch) |
| { |
| unsigned int tmpa[MAX_FIFO_SIZE]; |
| unsigned int psize, itmp; |
| struct di_buf_s *p; |
| |
| if (di_que_is_empty(ch, QUE_POST_KEEP_BACK)) |
| return; |
| di_que_list(ch, QUE_POST_KEEP_BACK, &tmpa[0], &psize); |
| dbg_keep("post_keep_back: curr(%d)\n", psize); |
| for (itmp = 0; itmp < psize; itmp++) { |
| p = pw_qindex_2_buf(ch, tmpa[itmp]); |
| dbg_keep("keep back recycle %d\n", p->index); |
| dim_post_keep_release_one(ch, p->index); |
| } |
| pw_queue_clear(ch, QUE_POST_KEEP_BACK); |
| } |
| #endif |
| #ifdef MARK_HIS |
| void dim_post_keep_cmd_proc(unsigned int ch, unsigned int index) |
| { |
| struct di_dev_s *di_dev; |
| enum EDI_TOP_STATE chst; |
| unsigned int len_keep, len_back; |
| struct di_buf_s *pbuf_post; |
| struct di_buf_s *di_buf; |
| ulong flags = 0; |
| struct div2_mm_s *mm = dim_mm_get(ch); |
| struct di_ch_s *pch; |
| |
| /*must post or err*/ |
| di_dev = get_dim_de_devp(); |
| |
| if (!di_dev || !di_dev->data_l) { |
| PR_WARN("%s: no di_dev\n", __func__); |
| return; |
| } |
| pch = get_chdata(ch); |
| |
| spin_lock_irqsave(&plist_lock, flags); |
| |
| chst = dip_chst_get(ch); |
| dbg_wq("k:p[%d]%d\n", chst, index); |
| switch (chst) { |
| case EDI_TOP_STATE_READY: /* need check tvp*/ |
| case EDI_TOP_STATE_UNREG_STEP2: |
| /*dim_post_keep_release_one(ch, index);*/ |
| dim_post_keep_release_one_check(ch, index); |
| break; |
| case EDI_TOP_STATE_IDLE: |
| case EDI_TOP_STATE_BYPASS: |
| pbuf_post = get_buf_post(ch); |
| if (!pbuf_post) { |
| PR_ERR("%s:no pbuf_post\n", __func__); |
| break; |
| } |
| |
| di_buf = &pbuf_post[index]; |
| di_buf->queue_index = -1; |
| di_que_in(ch, QUE_POST_KEEP_BACK, di_buf); |
| len_keep = di_que_list_count(ch, QUE_POST_KEEP); |
| len_back = di_que_list_count(ch, QUE_POST_KEEP_BACK); |
| mm->sts.flg_release++; |
| #ifdef HIS_CODE |
| if (len_back >= len_keep) { |
| /*release all*/ |
| pw_queue_clear(ch, QUE_POST_KEEP); |
| pw_queue_clear(ch, QUE_POST_KEEP_BACK); |
| mm->sts.flg_release = 0; |
| qpat_in_ready_msk(pch, 0); |
| mem_release_all_inused(pch); |
| //mtsk_release(ch, ECMD_BLK_RELEASE); |
| } |
| #endif |
| break; |
| case EDI_TOP_STATE_REG_STEP1: |
| case EDI_TOP_STATE_REG_STEP1_P1: |
| case EDI_TOP_STATE_REG_STEP2: |
| pbuf_post = get_buf_post(ch); |
| if (!pbuf_post) { |
| PR_ERR("%s:no pbuf_post\n", __func__); |
| break; |
| } |
| |
| di_buf = &pbuf_post[index]; |
| di_buf->queue_index = -1; |
| di_que_in(ch, QUE_POST_KEEP_BACK, di_buf); |
| |
| break; |
| case EDI_TOP_STATE_UNREG_STEP1: |
| pbuf_post = get_buf_post(ch); |
| if (!pbuf_post) { |
| PR_ERR("%s:no pbuf_post\n", __func__); |
| break; |
| } |
| |
| di_buf = &pbuf_post[index]; |
| if (is_in_queue(ch, di_buf, QUEUE_DISPLAY)) { |
| di_buf->queue_index = -1; |
| di_que_in(ch, QUE_POST_BACK, di_buf); |
| dbg_keep("%s:to back[%d]\n", __func__, index); |
| } else { |
| PR_ERR("%s:buf[%d] is not in display\n", |
| __func__, index); |
| } |
| break; |
| default: |
| PR_ERR("%s:do nothing? %s:%d\n", |
| __func__, |
| dip_chst_get_name(chst), |
| index); |
| break; |
| } |
| spin_unlock_irqrestore(&plist_lock, flags); |
| } |
| #else |
| void dim_post_keep_cmd_proc(unsigned int ch, unsigned int index) |
| { |
| struct di_dev_s *di_dev; |
| enum EDI_TOP_STATE chst; |
| // unsigned int len_keep, len_back; |
| // struct di_buf_s *pbuf_post; |
| // struct di_buf_s *di_buf; |
| //ulong flags = 0; |
| struct div2_mm_s *mm = dim_mm_get(ch); |
| struct di_ch_s *pch; |
| |
| /*must post or err*/ |
| di_dev = get_dim_de_devp(); |
| |
| if (!di_dev || !di_dev->data_l) { |
| PR_WARN("%s: no di_dev\n", __func__); |
| return; |
| } |
| pch = get_chdata(ch); |
| |
| //ary 2020-12-07 spin_lock_irqsave(&plist_lock, flags); |
| |
| chst = dip_chst_get(ch); |
| dbg_wq("k:p[%d]%d\n", chst, index); |
| switch (chst) { |
| case EDI_TOP_STATE_READY: /* need check tvp*/ |
| case EDI_TOP_STATE_UNREG_STEP1: |
| case EDI_TOP_STATE_UNREG_STEP2: |
| /*dim_post_keep_release_one(ch, index);*/ |
| dim_post_keep_release_one_check(ch, index); |
| break; |
| case EDI_TOP_STATE_IDLE: |
| case EDI_TOP_STATE_BYPASS: |
| ndkb_qin_byidx(pch, index); |
| mm->sts.flg_release++; |
| break; |
| case EDI_TOP_STATE_REG_STEP1: |
| case EDI_TOP_STATE_REG_STEP1_P1: |
| case EDI_TOP_STATE_REG_STEP2: |
| ndkb_qin_byidx(pch, index); |
| break; |
| default: |
| PR_ERR("%s:do nothing? %s:%d\n", |
| __func__, |
| dip_chst_get_name(chst), |
| index); |
| break; |
| } |
| //ary 2020-12-07 spin_unlock_irqrestore(&plist_lock, flags); |
| } |
| #endif |
| |
| #ifdef MARK_HIS |
| void dim_uninit_buf(unsigned int disable_mirror, unsigned int channel) |
| { |
| /*int i = 0;*/ |
| struct vframe_s **pvframe_in = get_vframe_in(channel); |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| struct di_post_stru_s *ppost = get_post_stru(channel); |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| struct di_ch_s *pch; |
| |
| //if (!queue_empty(channel, QUEUE_DISPLAY) || disable_mirror) |
| // ppost->keep_buf = NULL; |
| |
| if (!disable_mirror) |
| dim_post_keep_mirror_buffer2(channel); |
| |
| pch = get_chdata(channel); |
| mem_release(pch); |
| mem_2_blk(pch); |
| |
| queue_init(channel, 0); |
| di_que_init(channel); /*new que*/ |
| qiat_all_back2_ready(pch); |
| |
| /* decoder'buffer had been releae no need put */ |
| |
| memset(pvframe_in, 0, sizeof(*pvframe_in) * MAX_IN_BUF_NUM); |
| ppre->pre_de_process_flag = 0; |
| if (dimp_get(edi_mp_post_wr_en) && dimp_get(edi_mp_post_wr_support)) { |
| ppost->cur_post_buf = NULL; |
| ppost->post_de_busy = 0; |
| ppost->de_post_process_done = 0; |
| ppost->post_wr_cnt = 0; |
| } |
| if (cfgeq(MEM_FLAG, EDI_MEM_M_REV) && de_devp->nrds_enable) { |
| dim_nr_ds_buf_uninit(cfgg(MEM_FLAG), |
| &de_devp->pdev->dev); |
| } |
| } |
| #else |
| void dim_uninit_buf(unsigned int disable_mirror, unsigned int channel) |
| { |
| /*int i = 0;*/ |
| #ifdef VFM_ORI |
| struct vframe_s **pvframe_in = get_vframe_in(channel); |
| #endif |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| struct di_post_stru_s *ppost = get_post_stru(channel); |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| struct di_ch_s *pch; |
| struct dim_mm_blk_s *blks[POST_BUF_NUM]; |
| unsigned int blk_nub = 0; |
| int i; |
| |
| pch = get_chdata(channel); |
| |
| for (i = 0; i < POST_BUF_NUM; i++) |
| blks[i] = NULL; |
| |
| //if (!disable_mirror) |
| blk_nub = ndis_2keep(pch, &blks[0], POST_BUF_NUM, disable_mirror); |
| //dim_post_keep_mirror_buffer2(channel); |
| |
| mem_release(pch, &blks[0], blk_nub); |
| mem_2_blk(pch); |
| |
| queue_init(channel, 0); |
| di_que_init(channel); /*new que*/ |
| //bufq_iat_rest(pch); |
| qiat_all_back2_ready(pch); |
| bufq_ndis_unreg(pch); |
| |
| /* decoder'buffer had been releae no need put */ |
| #ifdef VFM_ORI |
| memset(pvframe_in, 0, sizeof(*pvframe_in) * MAX_IN_BUF_NUM); |
| #else |
| /* clear all ?*/ |
| #endif |
| ppre->pre_de_process_flag = 0; |
| if (dimp_get(edi_mp_post_wr_en) && dimp_get(edi_mp_post_wr_support)) { |
| ppost->cur_post_buf = NULL; |
| ppost->post_de_busy = 0; |
| ppost->de_post_process_done = 0; |
| ppost->post_wr_cnt = 0; |
| } |
| if (cfgeq(MEM_FLAG, EDI_MEM_M_REV) && de_devp->nrds_enable) { |
| dim_nr_ds_buf_uninit(cfgg(MEM_FLAG), |
| &de_devp->pdev->dev); |
| } |
| } |
| #endif |
| #ifdef MARK_HIS |
| void dim_log_buffer_state(unsigned char *tag, unsigned int channel) |
| { |
| struct di_pre_stru_s *ppre; |
| unsigned int tmpa[MAX_FIFO_SIZE]; /*new que*/ |
| unsigned int psize; /*new que*/ |
| |
| if (dimp_get(edi_mp_di_log_flag) & DI_LOG_BUFFER_STATE) { |
| struct di_buf_s *p = NULL;/* , *ptmp; */ |
| int itmp; |
| int in_free = 0; |
| int local_free = 0; |
| int pre_ready = 0; |
| int post_free = 0; |
| int post_ready = 0; |
| int post_ready_ext = 0; |
| int display = 0; |
| int display_ext = 0; |
| int recycle = 0; |
| int di_inp = 0; |
| int di_wr = 0; |
| ulong irq_flag2 = 0; |
| |
| ppre = get_pre_stru(channel); |
| |
| di_lock_irqfiq_save(irq_flag2); |
| in_free = di_que_list_count(channel, QUE_IN_FREE); |
| local_free = list_count(channel, QUEUE_LOCAL_FREE); |
| pre_ready = di_que_list_count(channel, QUE_PRE_READY); |
| post_free = di_que_list_count(channel, QUE_POST_FREE); |
| post_ready = di_que_list_count(channel, QUE_POST_READY); |
| |
| di_que_list(channel, QUE_POST_READY, &tmpa[0], &psize); |
| /*di_que_for_each(channel, p, psize, &tmpa[0]) {*/ |
| for (itmp = 0; itmp < psize; itmp++) { |
| p = pw_qindex_2_buf(channel, tmpa[itmp]); |
| if (p->di_buf[0]) |
| post_ready_ext++; |
| |
| if (p->di_buf[1]) |
| post_ready_ext++; |
| } |
| queue_for_each_entry(p, channel, QUEUE_DISPLAY, list) { |
| display++; |
| if (p->di_buf[0]) |
| display_ext++; |
| |
| if (p->di_buf[1]) |
| display_ext++; |
| } |
| recycle = list_count(channel, QUEUE_RECYCLE); |
| |
| if (ppre->di_inp_buf) |
| di_inp++; |
| if (ppre->di_wr_buf) |
| di_wr++; |
| |
| if (dimp_get(edi_mp_buf_state_log_threshold) == 0) |
| buf_state_log_start = 0; |
| else if (post_ready < dimp_get(edi_mp_buf_state_log_threshold)) |
| buf_state_log_start = 1; |
| |
| if (buf_state_log_start) { |
| dim_print("[%s]i i_f %d/%d, l_f %d", |
| tag, |
| in_free, MAX_IN_BUF_NUM, |
| local_free); |
| dim_print("pre_r %d, post_f %d/%d", |
| pre_ready, |
| post_free, MAX_POST_BUF_NUM); |
| dim_print("post_r (%d:%d), disp (%d:%d),rec %d\n", |
| post_ready, post_ready_ext, |
| display, display_ext, recycle); |
| dim_print("di_i %d, di_w %d\n", di_inp, di_wr); |
| } |
| di_unlock_irqfiq_restore(irq_flag2); |
| } |
| } |
| #endif |
| |
| #ifdef MARK_HIS |
| static void dump_state(unsigned int channel) |
| { |
| struct di_buf_s *p = NULL/*, *keep_buf*/; |
| int itmp, i; |
| struct vframe_s **pvframe_in = get_vframe_in(channel); |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| struct di_post_stru_s *ppost = get_post_stru(channel); |
| /*struct di_dev_s *de_devp = get_dim_de_devp();*/ |
| unsigned int tmpa[MAX_FIFO_SIZE]; /*new que*/ |
| unsigned int psize; /*new que*/ |
| struct div2_mm_s *mm = dim_mm_get(channel); /*mm-0705*/ |
| |
| dump_state_flag = 1; |
| pr_info("version %s, init_flag %d, is_bypass %d\n", |
| version_s, get_init_flag(channel), |
| dim_is_bypass(NULL, channel)); |
| pr_info("recovery_flag = %d, recovery_log_reason=%d, di_blocking=%d", |
| recovery_flag, recovery_log_reason, di_blocking); |
| pr_info("recovery_log_queue_idx=%d, recovery_log_di_buf=0x%p\n", |
| recovery_log_queue_idx, recovery_log_di_buf); |
| pr_info("buffer_size=%d, mem_flag=%s, cma_flag=%d\n", |
| /*atomic_read(&de_devp->mem_flag)*/ |
| mm->cfg.size_local, di_cma_dbg_get_st_name(channel), |
| cfgg(MEM_FLAG)); |
| |
| pr_info("\nin_free_list (max %d):\n", MAX_IN_BUF_NUM); |
| |
| di_que_list(channel, QUE_IN_FREE, &tmpa[0], &psize); |
| |
| for (itmp = 0; itmp < psize; itmp++) { |
| p = pw_qindex_2_buf(channel, tmpa[itmp]); |
| pr_info("index %2d, 0x%p, type %d\n", |
| p->index, p, p->type); |
| } |
| pr_info("local_free_list (max %d):\n", mm->cfg.num_local); |
| queue_for_each_entry(p, channel, QUEUE_LOCAL_FREE, list) { |
| pr_info("index %2d, 0x%p, type %d\n", p->index, p, p->type); |
| } |
| |
| pr_info("post_doing_list:\n"); |
| //queue_for_each_entry(p, channel, QUEUE_POST_DOING, list) { |
| di_que_list(channel, QUE_POST_DOING, &tmpa[0], &psize); |
| for (itmp = 0; itmp < psize; itmp++) { |
| p = pw_qindex_2_buf(channel, tmpa[itmp]); |
| dim_print_di_buf(p, 2); |
| } |
| pr_info("pre_ready_list:\n"); |
| |
| di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize); |
| |
| for (itmp = 0; itmp < psize; itmp++) { |
| p = pw_qindex_2_buf(channel, tmpa[itmp]); |
| dim_print_di_buf(p, 2); |
| } |
| pr_info("post_free_list (max %d):\n", mm->cfg.num_post); |
| |
| di_que_list(channel, QUE_POST_FREE, &tmpa[0], &psize); |
| |
| for (itmp = 0; itmp < psize; itmp++) { |
| p = pw_qindex_2_buf(channel, tmpa[itmp]); |
| |
| pr_info("index %2d, 0x%p, type %d, vframetype 0x%x\n", |
| p->index, p, p->type, p->vframe->type); |
| } |
| pr_info("post_ready_list:\n"); |
| |
| di_que_list(channel, QUE_POST_READY, &tmpa[0], &psize); |
| |
| for (itmp = 0; itmp < psize; itmp++) { |
| p = pw_qindex_2_buf(channel, tmpa[itmp]); |
| |
| dim_print_di_buf(p, 2); |
| dim_print_di_buf(p->di_buf[0], 1); |
| dim_print_di_buf(p->di_buf[1], 1); |
| } |
| pr_info("display_list:\n"); |
| queue_for_each_entry(p, channel, QUEUE_DISPLAY, list) { |
| dim_print_di_buf(p, 2); |
| dim_print_di_buf(p->di_buf[0], 1); |
| dim_print_di_buf(p->di_buf[1], 1); |
| } |
| pr_info("recycle_list:\n"); |
| queue_for_each_entry(p, channel, QUEUE_RECYCLE, list) { |
| pr_info("index %d, 0x%p, type %d, vframetype 0x%x\n", |
| p->index, p, p->type, |
| p->vframe->type); |
| pr_info("pre_ref_count %d post_ref_count %d\n", |
| p->pre_ref_count, |
| p->post_ref_count); |
| if (p->di_wr_linked_buf) { |
| pr_info("linked index %2d, 0x%p, type %d\n", |
| p->di_wr_linked_buf->index, |
| p->di_wr_linked_buf, |
| p->di_wr_linked_buf->type); |
| pr_info("linked pre_ref_count %d post_ref_count %d\n", |
| p->di_wr_linked_buf->pre_ref_count, |
| p->di_wr_linked_buf->post_ref_count); |
| } |
| } |
| if (ppre->di_inp_buf) { |
| pr_info("di_inp_buf:index %d, 0x%p, type %d\n", |
| ppre->di_inp_buf->index, |
| ppre->di_inp_buf, |
| ppre->di_inp_buf->type); |
| } else { |
| pr_info("di_inp_buf: NULL\n"); |
| } |
| if (ppre->di_wr_buf) { |
| pr_info("di_wr_buf:index %d, 0x%p, type %d\n", |
| ppre->di_wr_buf->index, |
| ppre->di_wr_buf, |
| ppre->di_wr_buf->type); |
| } else { |
| pr_info("di_wr_buf: NULL\n"); |
| } |
| dim_dump_pre_stru(ppre); |
| dim_dump_post_stru(ppost); |
| pr_info("vframe_in[]:"); |
| |
| for (i = 0; i < MAX_IN_BUF_NUM; i++) |
| pr_info("0x%p ", pvframe_in[i]); |
| |
| pr_info("\n"); |
| pr_info("vf_peek()=>0x%p, video_peek_cnt = %d\n", |
| pw_vf_peek(channel), di_sum_get(channel, EDI_SUM_O_PEEK_CNT)); |
| pr_info("reg_unreg_timerout = %lu\n", reg_unreg_timeout_cnt); |
| dump_state_flag = 0; |
| } |
| #endif |
| |
| unsigned char dim_check_di_buf(struct di_buf_s *di_buf, int reason, |
| unsigned int channel) |
| { |
| int error = 0; |
| struct vframe_s *pvframe_in_dup = get_vframe_in_dup(channel); |
| struct vframe_s *pvframe_local = get_vframe_local(channel); |
| struct vframe_s *pvframe_post = get_vframe_post(channel); |
| |
| if (!di_buf) { |
| PR_ERR("%s: %d, di_buf is NULL\n", __func__, reason); |
| return 1; |
| } |
| |
| if (di_buf->type == VFRAME_TYPE_IN) { |
| if (di_buf->vframe != &pvframe_in_dup[di_buf->index]) |
| error = 1; |
| } else if (di_buf->type == VFRAME_TYPE_LOCAL) { |
| if (di_buf->vframe != &pvframe_local[di_buf->index]) |
| error = 1; |
| } else if (di_buf->type == VFRAME_TYPE_POST) { |
| if (di_buf->vframe != &pvframe_post[di_buf->index]) |
| error = 1; |
| } else { |
| error = 1; |
| } |
| |
| if (error) { |
| PR_ERR("%s: %d, di_buf wrong\n", __func__, reason); |
| if (recovery_flag == 0) |
| recovery_log_reason = reason; |
| recovery_flag++; |
| dim_dump_di_buf(di_buf); |
| return 1; |
| } |
| |
| return 0; |
| } |
| |
| /* |
| * di pre process |
| */ |
| static void |
| config_di_mcinford_mif(struct DI_MC_MIF_s *di_mcinford_mif, |
| struct di_buf_s *di_buf) |
| { |
| if (di_buf) { |
| di_mcinford_mif->size_x = (di_buf->vframe->height + 2) / 4 - 1; |
| di_mcinford_mif->size_y = 1; |
| di_mcinford_mif->canvas_num = di_buf->mcinfo_canvas_idx; |
| di_mcinford_mif->addr = di_buf->mcinfo_adr; |
| } |
| } |
| |
| static void |
| config_di_pre_mc_mif(struct DI_MC_MIF_s *di_mcinfo_mif, |
| struct DI_MC_MIF_s *di_mcvec_mif, |
| struct di_buf_s *di_buf) |
| { |
| unsigned int pre_size_w = 0, pre_size_h = 0; |
| |
| if (di_buf) { |
| pre_size_w = di_buf->vframe->width; |
| pre_size_h = di_buf->vframe->height / 2; |
| di_mcinfo_mif->size_x = pre_size_h / 2 - 1; |
| di_mcinfo_mif->size_y = 1; |
| di_mcinfo_mif->canvas_num = di_buf->mcinfo_canvas_idx; |
| di_mcinfo_mif->addr = di_buf->mcinfo_adr; |
| |
| di_mcvec_mif->size_x = (pre_size_w + 4) / 5 - 1; |
| di_mcvec_mif->size_y = pre_size_h - 1; |
| di_mcvec_mif->canvas_num = di_buf->mcvec_canvas_idx; |
| di_mcvec_mif->addr = di_buf->mcvec_adr; |
| } |
| } |
| |
| static void config_di_cnt_mif(struct DI_SIM_MIF_s *di_cnt_mif, |
| struct di_buf_s *di_buf) |
| { |
| if (di_buf) { |
| di_cnt_mif->start_x = 0; |
| di_cnt_mif->end_x = di_buf->vframe->width - 1; |
| di_cnt_mif->start_y = 0; |
| di_cnt_mif->end_y = di_buf->vframe->height / 2 - 1; |
| di_cnt_mif->canvas_num = di_buf->cnt_canvas_idx; |
| di_cnt_mif->addr = di_buf->cnt_adr; |
| } |
| } |
| |
| static void |
| config_di_wr_mif(struct DI_SIM_MIF_s *di_nrwr_mif, |
| struct DI_SIM_MIF_s *di_mtnwr_mif, |
| struct di_buf_s *di_buf, unsigned int channel) |
| { |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| vframe_t *vf = di_buf->vframe; |
| |
| di_nrwr_mif->canvas_num = di_buf->nr_canvas_idx; |
| di_nrwr_mif->start_x = 0; |
| di_nrwr_mif->end_x = vf->width - 1; |
| di_nrwr_mif->start_y = 0; |
| if (di_buf->vframe->bitdepth & BITDEPTH_Y10) |
| di_nrwr_mif->bit_mode = |
| (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? |
| 3 : 1; |
| else |
| di_nrwr_mif->bit_mode = 0; |
| if (ppre->prog_proc_type == 0) |
| di_nrwr_mif->end_y = vf->height / 2 - 1; |
| else |
| di_nrwr_mif->end_y = vf->height - 1; |
| /* separate */ |
| if (vf->type & VIDTYPE_VIU_422) |
| di_nrwr_mif->set_separate_en = 0; |
| else |
| di_nrwr_mif->set_separate_en = 2; /*nv12 ? nv 21?*/ |
| if (ppre->prog_proc_type == 0) { |
| di_mtnwr_mif->start_x = 0; |
| di_mtnwr_mif->end_x = vf->width - 1; |
| di_mtnwr_mif->start_y = 0; |
| di_mtnwr_mif->end_y = vf->height / 2 - 1; |
| di_mtnwr_mif->canvas_num = di_buf->mtn_canvas_idx; |
| } |
| } |
| |
| #ifdef MARK_SC2 /* move di_hw_v2.c */ |
| static void config_di_nrwr_mif(struct DI_SIM_MIF_s *di_nrwr_mif, |
| struct di_buf_s *di_buf) |
| { |
| vframe_t *vf = di_buf->vframe; |
| |
| di_nrwr_mif->canvas_num = di_buf->nr_canvas_idx; |
| di_nrwr_mif->start_x = 0; |
| di_nrwr_mif->end_x = vf->width - 1; |
| di_nrwr_mif->start_y = 0; |
| if (di_buf->vframe->bitdepth & BITDEPTH_Y10) |
| di_nrwr_mif->bit_mode = |
| (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? |
| 3 : 1; |
| else |
| di_nrwr_mif->bit_mode = 0; |
| if (di_nrwr_mif->src_i) |
| di_nrwr_mif->end_y = vf->height / 2 - 1; |
| else |
| di_nrwr_mif->end_y = vf->height - 1; |
| } |
| #endif |
| |
| /* move di_hw_v2.c */ |
| static void config_di_mtnwr_mif(struct DI_SIM_MIF_s *di_mtnwr_mif, |
| struct di_buf_s *di_buf) |
| { |
| // struct di_pre_stru_s *ppre = get_pre_stru(ch); |
| vframe_t *vf = di_buf->vframe; |
| |
| if (di_mtnwr_mif->src_i) { |
| di_mtnwr_mif->start_x = 0; |
| di_mtnwr_mif->end_x = vf->width - 1; |
| di_mtnwr_mif->start_y = 0; |
| di_mtnwr_mif->end_y = vf->height / 2 - 1; |
| di_mtnwr_mif->canvas_num = di_buf->mtn_canvas_idx; |
| di_mtnwr_mif->addr = di_buf->mtn_adr; |
| } |
| } |
| |
| /*ary move to di_hw_v2.c */ |
| static void config_di_mif(struct DI_MIF_S *di_mif, struct di_buf_s *di_buf, |
| unsigned int channel) |
| { |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| |
| if (!di_buf) |
| return; |
| di_mif->canvas0_addr0 = |
| di_buf->vframe->canvas0Addr & 0xff; |
| di_mif->canvas0_addr1 = |
| (di_buf->vframe->canvas0Addr >> 8) & 0xff; |
| di_mif->canvas0_addr2 = |
| (di_buf->vframe->canvas0Addr >> 16) & 0xff; |
| |
| di_mif->nocompress = (di_buf->vframe->type & VIDTYPE_COMPRESS) ? 0 : 1; |
| |
| if (di_buf->vframe->bitdepth & BITDEPTH_Y10) { |
| if (di_buf->vframe->type & VIDTYPE_VIU_444) |
| di_mif->bit_mode = |
| (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? |
| 3 : 2; |
| else if (di_buf->vframe->type & VIDTYPE_VIU_422) |
| di_mif->bit_mode = |
| (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? |
| 3 : 1; |
| } else { |
| di_mif->bit_mode = 0; |
| } |
| if (di_buf->vframe->type & VIDTYPE_VIU_422) { |
| /* from vdin or local vframe */ |
| if ((!is_progressive(di_buf->vframe)) || |
| ppre->prog_proc_type) { |
| di_mif->video_mode = 0; |
| di_mif->set_separate_en = 0; |
| di_mif->src_field_mode = 0; |
| di_mif->output_field_num = 0; |
| di_mif->luma_x_start0 = 0; |
| di_mif->luma_x_end0 = |
| di_buf->vframe->width - 1; |
| di_mif->luma_y_start0 = 0; |
| if (ppre->prog_proc_type) |
| di_mif->luma_y_end0 = |
| di_buf->vframe->height - 1; |
| else |
| di_mif->luma_y_end0 = |
| di_buf->vframe->height / 2 - 1; |
| di_mif->chroma_x_start0 = 0; |
| di_mif->chroma_x_end0 = 0; |
| di_mif->chroma_y_start0 = 0; |
| di_mif->chroma_y_end0 = 0; |
| di_mif->canvas0_addr0 = |
| di_buf->vframe->canvas0Addr & 0xff; |
| di_mif->canvas0_addr1 = |
| (di_buf->vframe->canvas0Addr >> 8) & 0xff; |
| di_mif->canvas0_addr2 = |
| (di_buf->vframe->canvas0Addr >> 16) & 0xff; |
| } |
| di_mif->reg_swap = 1; |
| di_mif->l_endian = 0; |
| di_mif->cbcr_swap = 0; |
| } else { |
| if (di_buf->vframe->type & VIDTYPE_VIU_444) |
| di_mif->video_mode = 1; |
| else |
| di_mif->video_mode = 0; |
| if ((di_buf->vframe->type & VIDTYPE_VIU_NV21) || |
| (di_buf->vframe->type & VIDTYPE_VIU_NV12)) |
| di_mif->set_separate_en = 2; |
| else |
| di_mif->set_separate_en = 1; |
| |
| if (is_progressive(di_buf->vframe) && ppre->prog_proc_type) { |
| di_mif->src_field_mode = 0; |
| di_mif->output_field_num = 0; /* top */ |
| di_mif->luma_x_start0 = 0; |
| di_mif->luma_x_end0 = |
| di_buf->vframe->width - 1; |
| di_mif->luma_y_start0 = 0; |
| di_mif->luma_y_end0 = |
| di_buf->vframe->height - 1; |
| di_mif->chroma_x_start0 = 0; |
| di_mif->chroma_x_end0 = |
| di_buf->vframe->width / 2 - 1; |
| di_mif->chroma_y_start0 = 0; |
| di_mif->chroma_y_end0 = |
| (di_buf->vframe->height + 1) / 2 - 1; |
| } else if ((ppre->cur_inp_type & VIDTYPE_INTERLACE) && |
| (ppre->cur_inp_type & VIDTYPE_VIU_FIELD)) { |
| di_mif->src_prog = 0; |
| di_mif->src_field_mode = 0; |
| di_mif->output_field_num = 0; /* top */ |
| di_mif->luma_x_start0 = 0; |
| di_mif->luma_x_end0 = |
| di_buf->vframe->width - 1; |
| di_mif->luma_y_start0 = 0; |
| di_mif->luma_y_end0 = |
| di_buf->vframe->height / 2 - 1; |
| di_mif->chroma_x_start0 = 0; |
| di_mif->chroma_x_end0 = |
| di_buf->vframe->width / 2 - 1; |
| di_mif->chroma_y_start0 = 0; |
| di_mif->chroma_y_end0 = |
| di_buf->vframe->height / 4 - 1; |
| } else { |
| /*move to mp di_mif->src_prog = force_prog?1:0;*/ |
| if (ppre->cur_inp_type & VIDTYPE_INTERLACE) |
| di_mif->src_prog = 0; |
| else |
| di_mif->src_prog = |
| dimp_get(edi_mp_force_prog) ? 1 : 0; |
| di_mif->src_field_mode = 1; |
| if ((di_buf->vframe->type & VIDTYPE_TYPEMASK) == |
| VIDTYPE_INTERLACE_TOP) { |
| di_mif->output_field_num = 0; /* top */ |
| di_mif->luma_x_start0 = 0; |
| di_mif->luma_x_end0 = |
| di_buf->vframe->width - 1; |
| di_mif->luma_y_start0 = 0; |
| di_mif->luma_y_end0 = |
| di_buf->vframe->height - 1; |
| di_mif->chroma_x_start0 = 0; |
| di_mif->chroma_x_end0 = |
| di_buf->vframe->width / 2 - 1; |
| di_mif->chroma_y_start0 = 0; |
| di_mif->chroma_y_end0 = |
| (di_buf->vframe->height + 1) / 2 - 1; |
| } else { |
| di_mif->output_field_num = 1; |
| /* bottom */ |
| di_mif->luma_x_start0 = 0; |
| di_mif->luma_x_end0 = |
| di_buf->vframe->width - 1; |
| di_mif->luma_y_start0 = 1; |
| di_mif->luma_y_end0 = |
| di_buf->vframe->height - 1; |
| di_mif->chroma_x_start0 = 0; |
| di_mif->chroma_x_end0 = |
| di_buf->vframe->width / 2 - 1; |
| di_mif->chroma_y_start0 = |
| (di_mif->src_prog ? 0 : 1); |
| di_mif->chroma_y_end0 = |
| (di_buf->vframe->height + 1) / 2 - 1; |
| } |
| } |
| } |
| } |
| |
| static void di_pre_size_change(unsigned short width, |
| unsigned short height, |
| unsigned short vf_type, |
| unsigned int channel); |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC |
| static void pre_inp_canvas_config(struct vframe_s *vf); |
| #endif |
| |
| //static void pre_inp_mif_w(struct DI_MIF_S *di_mif, struct vframe_s *vf); |
| static void dim_canvas_set2(struct vframe_s *vf, u32 *index); |
| |
| void dim_pre_de_process(unsigned int channel) |
| { |
| ulong irq_flag2 = 0; |
| unsigned short pre_width = 0, pre_height = 0; |
| unsigned char chan2_field_num = 1; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| int canvases_idex = ppre->field_count_for_cont % 2; |
| unsigned short cur_inp_field_type = VIDTYPE_TYPEMASK; |
| unsigned short int_mask = 0x7f; |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| struct di_cvs_s *cvss; |
| struct vframe_s *vf_i, *vf_mem, *vf_chan2; |
| union hw_sc2_ctr_pre_s *sc2_pre_cfg; |
| struct di_ch_s *pch; |
| u32 cvs_nv21[2]; |
| |
| vf_i = NULL; |
| vf_mem = NULL; |
| vf_chan2 = NULL; |
| |
| pch = get_chdata(channel); |
| ppre->pre_de_process_flag = 1; |
| dim_ddbg_mod_save(EDI_DBG_MOD_PRE_SETB, channel, ppre->in_seq);/*dbg*/ |
| cvss = &get_datal()->cvs; |
| |
| if (IS_ERR_OR_NULL(ppre->di_inp_buf)) |
| return; |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC |
| pre_inp_canvas_config(ppre->di_inp_buf->vframe); |
| #endif |
| |
| pre_inp_mif_w(&ppre->di_inp_mif, ppre->di_inp_buf->vframe); |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pre_cfg_mif(&ppre->di_inp_mif, |
| DI_MIF0_ID_INP, |
| ppre->di_inp_buf, |
| channel); |
| else |
| config_di_mif(&ppre->di_inp_mif, ppre->di_inp_buf, channel); |
| /* pr_dbg("set_separate_en=%d vframe->type %d\n", |
| * di_pre_stru.di_inp_mif.set_separate_en, |
| * di_pre_stru.di_inp_buf->vframe->type); |
| */ |
| |
| if (IS_ERR_OR_NULL(ppre->di_mem_buf_dup_p)) |
| return; |
| |
| dim_secure_sw_pre(channel); |
| |
| if (ppre->di_mem_buf_dup_p && |
| ppre->di_mem_buf_dup_p != ppre->di_inp_buf) { |
| if (ppre->di_mem_buf_dup_p->flg_nv21) { |
| cvs_nv21[0] = cvss->post_idx[1][3]; |
| cvs_nv21[1] = cvss->post_idx[1][4]; |
| ppre->di_mem_buf_dup_p->vframe->canvas0Addr = ((u32)-1); |
| dim_canvas_set2(ppre->di_mem_buf_dup_p->vframe, |
| &cvs_nv21[0]); |
| dim_print("mem:vfm:pnub[%d],w[%d]\n", |
| ppre->di_mem_buf_dup_p->vframe->plane_num, |
| ppre->di_mem_buf_dup_p->vframe-> |
| canvas0_config[0].width); |
| |
| //ppre->di_mem_mif.canvas_num = |
| //re->di_mem_buf_dup_p->vframe->canvas0Addr; |
| } else { |
| config_canvas_idx(ppre->di_mem_buf_dup_p, |
| cvss->pre_idx[canvases_idex][0], -1); |
| } |
| dim_print("mem:flg_nv21[%d]:flg_[%d] %px\n", |
| ppre->di_mem_buf_dup_p->flg_nv21, |
| ppre->di_mem_buf_dup_p->flg_nr, |
| ppre->di_mem_buf_dup_p); |
| config_cnt_canvas_idx(ppre->di_mem_buf_dup_p, |
| cvss->pre_idx[canvases_idex][1]); |
| } else { |
| config_cnt_canvas_idx(ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][1]); |
| config_di_cnt_mif(&ppre->di_contp2rd_mif, |
| ppre->di_wr_buf); |
| } |
| if (ppre->di_chan2_buf_dup_p) { |
| config_canvas_idx(ppre->di_chan2_buf_dup_p, |
| cvss->pre_idx[canvases_idex][2], -1); |
| config_cnt_canvas_idx(ppre->di_chan2_buf_dup_p, |
| cvss->pre_idx[canvases_idex][3]); |
| } else { |
| config_cnt_canvas_idx(ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][3]); |
| } |
| if (ppre->di_wr_buf->flg_nv21) { |
| //cvss = &get_datal()->cvs; |
| //0925 cvs_nv21[0] = cvss->post_idx[1][1]; |
| cvs_nv21[0] = cvss->pre_idx[canvases_idex][4];//0925 |
| cvs_nv21[1] = cvss->post_idx[1][2]; |
| dim_canvas_set2(ppre->di_wr_buf->vframe, &cvs_nv21[0]); |
| config_canvas_idx_mtn(ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][5]); |
| //ppost->di_diwr_mif.canvas_num = pst->vf_post.canvas0Addr; |
| ppre->di_nrwr_mif.canvas_num = |
| ppre->di_wr_buf->vframe->canvas0Addr; |
| ppre->di_wr_buf->nr_canvas_idx = |
| ppre->di_wr_buf->vframe->canvas0Addr; |
| if (ppre->di_wr_buf->flg_nv21 == 1) |
| ppre->di_nrwr_mif.cbcr_swap = 0; |
| else |
| ppre->di_nrwr_mif.cbcr_swap = 1; |
| if (dip_itf_is_o_linear(pch)) { |
| ppre->di_nrwr_mif.reg_swap = 0; |
| ppre->di_nrwr_mif.l_endian = 1; |
| |
| } else { |
| ppre->di_nrwr_mif.reg_swap = 1; |
| ppre->di_nrwr_mif.l_endian = 0; |
| } |
| if (cfgg(LINEAR)) { |
| ppre->di_nrwr_mif.linear = 1; |
| ppre->di_nrwr_mif.addr = |
| ppre->di_wr_buf->vframe->canvas0_config[0].phy_addr; |
| ppre->di_nrwr_mif.addr1 = |
| ppre->di_wr_buf->vframe->canvas0_config[1].phy_addr; |
| } |
| |
| //dim_print("wr:%px\n", ppre->di_wr_buf); |
| } else { |
| ppre->di_nrwr_mif.reg_swap = 1; |
| ppre->di_nrwr_mif.cbcr_swap = 0; |
| ppre->di_nrwr_mif.l_endian = 0; |
| if (cfgg(LINEAR)) { |
| ppre->di_nrwr_mif.linear = 1; |
| ppre->di_nrwr_mif.addr = ppre->di_wr_buf->nr_adr; |
| } |
| config_canvas_idx(ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][4], |
| cvss->pre_idx[canvases_idex][5]); |
| } |
| config_cnt_canvas_idx(ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][6]); |
| if (dimp_get(edi_mp_mcpre_en)) { |
| if (ppre->di_chan2_buf_dup_p) |
| config_mcinfo_canvas_idx |
| (ppre->di_chan2_buf_dup_p, |
| cvss->pre_idx[canvases_idex][7]); |
| else |
| config_mcinfo_canvas_idx |
| (ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][7]); |
| |
| config_mcinfo_canvas_idx(ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][8]); |
| config_mcvec_canvas_idx(ppre->di_wr_buf, |
| cvss->pre_idx[canvases_idex][9]); |
| } |
| |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pre_cfg_mif(&ppre->di_mem_mif, |
| DI_MIF0_ID_MEM, |
| ppre->di_mem_buf_dup_p, |
| channel); |
| else |
| config_di_mif(&ppre->di_mem_mif, |
| ppre->di_mem_buf_dup_p, channel); |
| /* patch */ |
| if (ppre->di_wr_buf->flg_nv21 && |
| ppre->di_mem_buf_dup_p && |
| ppre->di_mem_buf_dup_p != ppre->di_inp_buf) { |
| ppre->di_mem_mif.l_endian = ppre->di_nrwr_mif.l_endian; |
| ppre->di_mem_mif.cbcr_swap = ppre->di_nrwr_mif.cbcr_swap; |
| ppre->di_mem_mif.reg_swap = ppre->di_nrwr_mif.reg_swap; |
| } |
| if (!ppre->di_chan2_buf_dup_p) { |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pre_cfg_mif(&ppre->di_chan2_mif, |
| DI_MIF0_ID_CHAN2, |
| ppre->di_inp_buf, |
| channel); |
| else |
| config_di_mif(&ppre->di_chan2_mif, |
| ppre->di_inp_buf, channel); |
| |
| } else { |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pre_cfg_mif(&ppre->di_chan2_mif, |
| DI_MIF0_ID_CHAN2, |
| ppre->di_chan2_buf_dup_p, |
| channel); |
| else |
| config_di_mif(&ppre->di_chan2_mif, |
| ppre->di_chan2_buf_dup_p, channel); |
| } |
| if (ppre->prog_proc_type == 0) { |
| ppre->di_nrwr_mif.src_i = 1; |
| ppre->di_mtnwr_mif.src_i = 1; |
| } else { |
| ppre->di_nrwr_mif.src_i = 0; |
| ppre->di_mtnwr_mif.src_i = 0; |
| } |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->wr_cfg_mif(&ppre->di_nrwr_mif, |
| EDI_MIFSM_NR, |
| ppre->di_wr_buf, NULL); |
| else |
| config_di_wr_mif(&ppre->di_nrwr_mif, &ppre->di_mtnwr_mif, |
| ppre->di_wr_buf, channel); |
| |
| if (DIM_IS_IC_EF(SC2)) |
| config_di_mtnwr_mif(&ppre->di_mtnwr_mif, ppre->di_wr_buf); |
| |
| if (ppre->di_chan2_buf_dup_p) |
| config_di_cnt_mif(&ppre->di_contprd_mif, |
| ppre->di_chan2_buf_dup_p); |
| else |
| config_di_cnt_mif(&ppre->di_contprd_mif, |
| ppre->di_wr_buf); |
| |
| config_di_cnt_mif(&ppre->di_contwr_mif, ppre->di_wr_buf); |
| if (dimp_get(edi_mp_mcpre_en)) { |
| if (ppre->di_chan2_buf_dup_p) |
| config_di_mcinford_mif(&ppre->di_mcinford_mif, |
| ppre->di_chan2_buf_dup_p); |
| else |
| config_di_mcinford_mif(&ppre->di_mcinford_mif, |
| ppre->di_wr_buf); |
| |
| config_di_pre_mc_mif(&ppre->di_mcinfowr_mif, |
| &ppre->di_mcvecwr_mif, ppre->di_wr_buf); |
| } |
| |
| if (ppre->di_chan2_buf_dup_p && |
| ((ppre->di_chan2_buf_dup_p->vframe->type & VIDTYPE_TYPEMASK) |
| == VIDTYPE_INTERLACE_TOP)) |
| chan2_field_num = 0; |
| |
| pre_width = ppre->di_nrwr_mif.end_x + 1; |
| pre_height = ppre->di_nrwr_mif.end_y + 1; |
| |
| if (IS_ERR_OR_NULL(ppre->di_inp_buf)) |
| return; |
| |
| if (/*ppre->di_inp_buf && */ppre->di_inp_buf->vframe) |
| vf_i = ppre->di_inp_buf->vframe; |
| |
| if (dim_afds() && dim_afds()->pre_check) |
| dim_afds()->pre_check(ppre->di_wr_buf->vframe, pch); |
| if (ppre->di_wr_buf->is_4k) { |
| ppre->pre_top_cfg.b.is_inp_4k = 1; |
| ppre->pre_top_cfg.b.is_mem_4k = 1; |
| } |
| if (ppre->input_size_change_flag) { |
| if (dim_afds() && dim_afds()->rest_val) |
| dim_afds()->rest_val(); |
| cur_inp_field_type = |
| (ppre->di_inp_buf->vframe->type & VIDTYPE_TYPEMASK); |
| cur_inp_field_type = |
| ppre->cur_prog_flag ? VIDTYPE_PROGRESSIVE : cur_inp_field_type; |
| /*di_async_reset2();*/ |
| di_pre_size_change(pre_width, pre_height, |
| cur_inp_field_type, channel); |
| ppre->input_size_change_flag = false; |
| } |
| |
| if (DIM_IS_IC_EF(SC2)) { |
| sc2_pre_cfg = &get_hw_pre()->pre_top_cfg; |
| if (sc2_pre_cfg->d32 != ppre->pre_top_cfg.d32) { |
| sc2_pre_cfg->d32 = ppre->pre_top_cfg.d32; |
| dim_sc2_contr_pre(sc2_pre_cfg); |
| dim_sc2_4k_set(sc2_pre_cfg->b.mode_4k); |
| } |
| } |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { |
| if (de_devp->nrds_enable) { |
| dim_nr_ds_mif_config(); |
| dim_nr_ds_hw_ctrl(true); |
| int_mask = 0x3f; |
| } else { |
| dim_nr_ds_hw_ctrl(false); |
| } |
| } |
| #ifndef TMP_MASK_FOR_T7 |
| /*patch for SECAM signal format from vlsi-feijun for all IC*/ |
| get_ops_nr()->secam_cfr_adjust(ppre->di_inp_buf->vframe->sig_fmt, |
| ppre->di_inp_buf->vframe->type); |
| #endif |
| /* set interrupt mask for pre module. |
| * we need to only leave one mask open |
| * to prevent multiple entry for dim_irq |
| */ |
| |
| /*dim_dbg_pre_cnt(channel, "s2");*/ |
| |
| dimh_enable_di_pre_aml(&ppre->di_inp_mif, |
| &ppre->di_mem_mif, |
| &ppre->di_chan2_mif, |
| &ppre->di_nrwr_mif, |
| &ppre->di_mtnwr_mif, |
| &ppre->di_contp2rd_mif, |
| &ppre->di_contprd_mif, |
| &ppre->di_contwr_mif, |
| ppre->madi_enable, |
| chan2_field_num, |
| ppre->vdin2nr | |
| (ppre->is_bypass_mem << 4), |
| ppre); |
| |
| //dimh_enable_afbc_input(ppre->di_inp_buf->vframe); |
| if (IS_ERR_OR_NULL(ppre->di_wr_buf)) |
| return; |
| dcntr_set(); |
| |
| if (dim_afds()) { |
| if (ppre->di_mem_buf_dup_p && ppre->di_mem_buf_dup_p->vframe) |
| vf_mem = ppre->di_mem_buf_dup_p->vframe; |
| if (ppre->di_chan2_buf_dup_p && |
| ppre->di_chan2_buf_dup_p->vframe) |
| vf_chan2 = ppre->di_chan2_buf_dup_p->vframe; |
| |
| if (/*ppre->di_wr_buf && */ppre->di_wr_buf->vframe) |
| dim_afds()->en_pre_set(vf_i, |
| vf_mem, |
| vf_chan2, |
| ppre->di_wr_buf->vframe); |
| } |
| |
| if (dimp_get(edi_mp_mcpre_en)) { |
| if (DIM_IS_IC_EF(T7) && opl1()->pre_enable_mc) |
| opl1()->pre_enable_mc(&ppre->di_mcinford_mif, |
| &ppre->di_mcinfowr_mif, |
| &ppre->di_mcvecwr_mif, |
| ppre->mcdi_enable); |
| else if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| dimh_enable_mc_di_pre_g12(&ppre->di_mcinford_mif, |
| &ppre->di_mcinfowr_mif, |
| &ppre->di_mcvecwr_mif, |
| ppre->mcdi_enable); |
| else |
| dimh_enable_mc_di_pre(&ppre->di_mcinford_mif, |
| &ppre->di_mcinfowr_mif, |
| &ppre->di_mcvecwr_mif, |
| ppre->mcdi_enable); |
| } |
| |
| ppre->field_count_for_cont++; |
| |
| if (ppre->field_count_for_cont >= 5) |
| DIM_DI_WR_REG_BITS(DI_MTN_CTRL, 0, 30, 1); |
| |
| dimh_txl_patch_prog(ppre->cur_prog_flag, |
| ppre->field_count_for_cont, |
| dimp_get(edi_mp_mcpre_en)); |
| |
| /* must make sure follow part issue without interrupts, |
| * otherwise may cause watch dog reboot |
| */ |
| di_lock_irqfiq_save(irq_flag2); |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { |
| /* enable mc pre mif*/ |
| dimh_enable_di_pre_mif(true, dimp_get(edi_mp_mcpre_en)); |
| dim_pre_frame_reset_g12(ppre->madi_enable, |
| ppre->mcdi_enable); |
| } else { |
| dim_pre_frame_reset(); |
| /* enable mc pre mif*/ |
| dimh_enable_di_pre_mif(true, dimp_get(edi_mp_mcpre_en)); |
| } |
| /*dbg_set_DI_PRE_CTRL();*/ |
| atomic_set(&get_hw_pre()->flg_wait_int, 1); |
| di_unlock_irqfiq_restore(irq_flag2); |
| /*reinit pre busy flag*/ |
| ppre->pre_de_busy = 1; |
| pch->sum_pre++; |
| dim_dbg_pre_cnt(channel, "s3"); |
| ppre->irq_time[0] = cur_to_msecs(); |
| ppre->irq_time[1] = cur_to_msecs(); |
| dim_ddbg_mod_save(EDI_DBG_MOD_PRE_SETE, channel, ppre->in_seq);/*dbg*/ |
| dim_tr_ops.pre_set(ppre->di_wr_buf->vframe->index_disp); |
| #ifdef CONFIG_AMLOGIC_MEDIA_RDMA |
| if (di_pre_rdma_enable & 0x2) |
| rdma_config(de_devp->rdma_handle, RDMA_TRIGGER_MANUAL); |
| else if (di_pre_rdma_enable & 1) |
| rdma_config(de_devp->rdma_handle, RDMA_DEINT_IRQ); |
| #endif |
| ppre->pre_de_process_flag = 0; |
| } |
| |
| void dim_pre_de_done_buf_clear(unsigned int channel) |
| { |
| struct di_buf_s *wr_buf = NULL; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| |
| if (ppre->di_wr_buf) { |
| wr_buf = ppre->di_wr_buf; |
| if (ppre->prog_proc_type == 2 && |
| wr_buf->di_wr_linked_buf) { |
| wr_buf->di_wr_linked_buf->pre_ref_count = 0; |
| wr_buf->di_wr_linked_buf->post_ref_count = 0; |
| queue_in(channel, wr_buf->di_wr_linked_buf, |
| QUEUE_RECYCLE); |
| wr_buf->di_wr_linked_buf = NULL; |
| } |
| wr_buf->pre_ref_count = 0; |
| wr_buf->post_ref_count = 0; |
| queue_in(channel, wr_buf, QUEUE_RECYCLE); |
| ppre->di_wr_buf = NULL; |
| } |
| if (ppre->di_inp_buf) { |
| if (ppre->di_mem_buf_dup_p == ppre->di_inp_buf) |
| ppre->di_mem_buf_dup_p = NULL; |
| |
| queue_in(channel, ppre->di_inp_buf, QUEUE_RECYCLE); |
| ppre->di_inp_buf = NULL; |
| } |
| } |
| |
| static void top_bot_config(struct di_buf_s *di_buf) |
| { |
| vframe_t *vframe = di_buf->vframe; |
| |
| if (((invert_top_bot & 0x1) != 0) && (!is_progressive(vframe))) { |
| if (di_buf->invert_top_bot_flag == 0) { |
| if ((vframe->type & VIDTYPE_TYPEMASK) == |
| VIDTYPE_INTERLACE_TOP) { |
| vframe->type &= (~VIDTYPE_TYPEMASK); |
| vframe->type |= VIDTYPE_INTERLACE_BOTTOM; |
| } else { |
| vframe->type &= (~VIDTYPE_TYPEMASK); |
| vframe->type |= VIDTYPE_INTERLACE_TOP; |
| } |
| di_buf->invert_top_bot_flag = 1; |
| } |
| } |
| } |
| |
| void dim_pre_de_done_buf_config(unsigned int channel, bool flg_timeout) |
| { |
| //ary 2020-12-09 ulong irq_flag2 = 0; |
| int tmp_cur_lev; |
| struct di_buf_s *post_wr_buf = NULL; |
| unsigned int frame_motnum = 0; |
| unsigned int field_motnum = 0; |
| unsigned int pd_info = 0; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| struct di_ch_s *pch; |
| //struct di_buf_s *bufn; |
| //bool crc_right; |
| unsigned int afbce_used; |
| |
| dim_dbg_pre_cnt(channel, "d1"); |
| dim_ddbg_mod_save(EDI_DBG_MOD_PRE_DONEB, channel, ppre->in_seq);/*dbg*/ |
| if (ppre->di_wr_buf) { |
| if (flg_timeout) { |
| hpre_timeout_read(); |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pre_gl_sw(false); |
| else |
| hpre_gl_sw(false); |
| } |
| |
| dim_pqrpt_init(&ppre->di_wr_buf->pq_rpt); |
| if (!flg_timeout) |
| dcntr_pq_tune(&ppre->di_wr_buf->pq_rpt); |
| dim_tr_ops.pre_ready(ppre->di_wr_buf->vframe->index_disp); |
| ppre->di_wr_buf->flg_nr = 1; |
| if (ppre->pre_throw_flag > 0) { |
| ppre->di_wr_buf->throw_flag = 1; |
| ppre->pre_throw_flag--; |
| } else { |
| ppre->di_wr_buf->throw_flag = 0; |
| } |
| if (/*ppre->di_wr_buf->flg_afbce_set*/ppre->prog_proc_type != |
| 0x10) { /*afbce check cec*/ |
| //ppre->di_wr_buf->flg_afbce_set = 0; |
| //afbce_sw(EAFBC_ENC0, 0); |
| #ifdef DBG_CRC |
| bufn = next_buf(ppre->di_wr_buf); |
| if (bufn) { |
| crc_right = dbg_checkcrc(bufn); |
| if (!crc_right) |
| PR_ERR("pre crc next err:b[%d]nb[%d]\n", |
| ppre->di_wr_buf->index, |
| bufn->index); |
| } |
| #endif |
| } else { |
| //dbg_checkcrc(ppre->di_wr_buf); |
| } |
| if (ppre->di_wr_buf->flg_afbce_set) { |
| ppre->di_wr_buf->flg_afbce_set = 0; |
| //tmp |
| //if (ppre->di_wr_buf->blk_buf->flg.b.typ == |
| //EDIM_BLK_TYP_PSCT) { |
| if (ppre->di_wr_buf->blk_buf && |
| dim_blk_tvp_is_sct(ppre->di_wr_buf->blk_buf)) { |
| afbce_used = afbce_read_used(EAFBC_ENC0); |
| pch = get_chdata(channel); |
| sct_free_tail_l(pch, |
| afbce_used, |
| (struct dim_sct_s *)ppre->di_wr_buf->blk_buf->sct); |
| // tst_resize(pch, afbce_used); |
| } |
| /*************************/ |
| //afbce_sw(EAFBC_ENC0, 0); |
| } |
| #ifdef DET3D |
| if (ppre->di_wr_buf->vframe->trans_fmt == 0 && |
| ppre->det3d_trans_fmt != 0 && |
| dimp_get(edi_mp_det3d_en)) { |
| ppre->di_wr_buf->vframe->trans_fmt = |
| ppre->det3d_trans_fmt; |
| set3d_view(ppre->det3d_trans_fmt, |
| ppre->di_wr_buf->vframe); |
| } |
| #endif |
| /*dec vf keep*/ |
| if (ppre->di_inp_buf && |
| ppre->di_inp_buf->dec_vf_state & DI_BIT0) { |
| ppre->di_wr_buf->in_buf = ppre->di_inp_buf; |
| dim_print("dim:dec vf:l[%d]\n", |
| ppre->di_wr_buf->in_buf->vframe->index_disp); |
| } |
| |
| if (!di_pre_rdma_enable) |
| ppre->di_post_wr_buf = ppre->di_wr_buf; |
| post_wr_buf = ppre->di_post_wr_buf; |
| |
| if (post_wr_buf) { |
| post_wr_buf->vframe->di_pulldown = 0; |
| post_wr_buf->vframe->di_gmv = 0; |
| post_wr_buf->vframe->di_cm_cnt = 0; |
| } |
| |
| if (post_wr_buf && !ppre->cur_prog_flag && |
| !flg_timeout && ppre->di_inp_buf) { |
| dim_read_pulldown_info(&frame_motnum, |
| &field_motnum); |
| if (dimp_get(edi_mp_pulldown_enable)) { |
| /*pulldown_detection*/ |
| pd_info = get_ops_pd()->detection |
| (&post_wr_buf->pd_config, |
| ppre->mtn_status, |
| overturn, |
| ppre->di_inp_buf->vframe); |
| post_wr_buf->vframe->di_pulldown = pd_info; |
| } |
| post_wr_buf->vframe->di_pulldown |= 0x08; |
| |
| post_wr_buf->vframe->di_gmv = frame_motnum; |
| post_wr_buf->vframe->di_cm_cnt = dim_rd_mcdi_fldcnt(); |
| |
| /*if (combing_fix_en)*/ |
| /*if (dimp_get(eDI_MP_combing_fix_en)) {*/ |
| if (ppre->combing_fix_en) { |
| tmp_cur_lev = /*cur_lev*/ |
| get_ops_mtn()->adaptive_combing_fixing |
| (ppre->mtn_status, |
| field_motnum, |
| frame_motnum, |
| dimp_get(edi_mp_di_force_bit_mode)); |
| dimp_set(edi_mp_cur_lev, tmp_cur_lev); |
| } |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) |
| get_ops_nr()->adaptive_cue_adjust(frame_motnum, |
| field_motnum); |
| if (!(di_dbg & DBG_M_RESET_PRE)) |
| dim_pulldown_info_clear_g12a(); |
| } |
| if (ppre->prog_proc_type == 0x10) { |
| ppre->di_mem_buf_dup_p->pre_ref_count = 0; |
| /*recycle the progress throw buffer*/ |
| |
| if (ppre->di_wr_buf->throw_flag) { |
| ppre->di_wr_buf->pre_ref_count = 0; |
| ppre->di_mem_buf_dup_p = NULL; |
| |
| } else { |
| if (ppre->di_mem_buf_dup_p->flg_nr) { |
| di_que_in(channel, QUE_PRE_READY, |
| ppre->di_mem_buf_dup_p); |
| } |
| ppre->di_mem_buf_dup_p = ppre->di_wr_buf; |
| } |
| |
| ppre->di_wr_buf->seq = ppre->pre_ready_seq++; |
| ppre->di_wr_buf->post_ref_count = 0; |
| ppre->di_wr_buf->left_right = ppre->left_right; |
| /******************************************/ |
| /* need check */ |
| if (ppre->source_change_flag) { |
| //ppre->di_wr_buf->new_format_flag = 1; |
| ppre->source_change_flag = 0; |
| } else { |
| //ppre->di_wr_buf->new_format_flag = 0; |
| } |
| if (di_bypass_state_get(channel) == 1) { |
| //ppre->di_wr_buf->new_format_flag = 1; |
| /*bypass_state = 0;*/ |
| di_bypass_state_set(channel, false); |
| } |
| if (ppre->di_wr_buf) { |
| if (di_pre_rdma_enable) |
| ppre->di_post_wr_buf = |
| ppre->di_wr_buf; |
| else |
| ppre->di_post_wr_buf = NULL; |
| ppre->di_wr_buf = NULL; |
| } |
| |
| } else if (ppre->cur_prog_flag) { |
| if (ppre->prog_proc_type == 0) { |
| /* di_mem_buf_dup->vfrme |
| * is either local vframe, |
| * or bot field of vframe from in_list |
| */ |
| ppre->di_mem_buf_dup_p->pre_ref_count = 0; |
| ppre->di_mem_buf_dup_p = |
| ppre->di_chan2_buf_dup_p; |
| ppre->di_chan2_buf_dup_p = ppre->di_wr_buf; |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s:set di_mem to di_chan2,", __func__); |
| dim_print("%s:set di_chan2 to di_wr_buf\n", __func__); |
| #endif |
| } else { |
| ppre->di_mem_buf_dup_p->pre_ref_count = 0; |
| /*recycle the progress throw buffer*/ |
| if (ppre->di_wr_buf->throw_flag) { |
| ppre->di_wr_buf->pre_ref_count = 0; |
| ppre->di_mem_buf_dup_p = NULL; |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s st throw %s[%d] pre_ref_cont 0\n", |
| __func__, |
| vframe_type_name[ppre->di_wr_buf->type], |
| ppre->di_wr_buf->index); |
| #endif |
| } else { |
| ppre->di_mem_buf_dup_p = |
| ppre->di_wr_buf; |
| } |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s: set di_mem_buf_dup_p to di_wr_buf\n", |
| __func__); |
| #endif |
| } |
| |
| ppre->di_wr_buf->seq = ppre->pre_ready_seq++; |
| ppre->di_wr_buf->post_ref_count = 0; |
| ppre->di_wr_buf->left_right = ppre->left_right; |
| if (ppre->source_change_flag) { |
| ppre->di_wr_buf->new_format_flag = 1; |
| ppre->source_change_flag = 0; |
| } else { |
| ppre->di_wr_buf->new_format_flag = 0; |
| } |
| if (di_bypass_state_get(channel) == 1) { |
| ppre->di_wr_buf->new_format_flag = 1; |
| /*bypass_state = 0;*/ |
| di_bypass_state_set(channel, false); |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s:bypass_state->0, is_bypass() %d\n", |
| __func__, dim_is_bypass(NULL, channel)); |
| dim_print("trick_mode %d bypass_all %d\n", |
| trick_mode, |
| di_cfgx_get(channel, EDI_CFGX_BYPASS_ALL)); |
| #endif |
| } |
| if (ppre->di_post_wr_buf) |
| di_que_in(channel, QUE_PRE_READY, |
| ppre->di_post_wr_buf); |
| |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s: %s[%d] => pre_ready_list\n", __func__, |
| vframe_type_name[ppre->di_wr_buf->type], |
| ppre->di_wr_buf->index); |
| #endif |
| if (ppre->di_wr_buf) { |
| if (di_pre_rdma_enable) |
| ppre->di_post_wr_buf = |
| ppre->di_wr_buf; |
| else |
| ppre->di_post_wr_buf = NULL; |
| ppre->di_wr_buf = NULL; |
| } |
| } else { |
| ppre->di_mem_buf_dup_p->pre_ref_count = 0; |
| ppre->di_mem_buf_dup_p = NULL; |
| if (ppre->di_chan2_buf_dup_p) { |
| ppre->di_mem_buf_dup_p = |
| ppre->di_chan2_buf_dup_p; |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s:mem_buf=chan2_buf_dup_p\n", |
| __func__); |
| #endif |
| } |
| ppre->di_chan2_buf_dup_p = ppre->di_wr_buf; |
| |
| if (ppre->source_change_flag) { |
| /* add dummy buf, will not be displayed */ |
| add_dummy_vframe_type_pre(post_wr_buf, |
| channel); |
| } |
| ppre->di_wr_buf->seq = ppre->pre_ready_seq++; |
| ppre->di_wr_buf->left_right = ppre->left_right; |
| ppre->di_wr_buf->post_ref_count = 0; |
| |
| if (ppre->source_change_flag) { |
| ppre->di_wr_buf->new_format_flag = 1; |
| ppre->source_change_flag = 0; |
| } else { |
| ppre->di_wr_buf->new_format_flag = 0; |
| } |
| if (di_bypass_state_get(channel) == 1) { |
| ppre->di_wr_buf->new_format_flag = 1; |
| /*bypass_state = 0;*/ |
| di_bypass_state_set(channel, false); |
| |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s:bypass_state->0, is_bypass() %d\n", |
| __func__, dim_is_bypass(NULL, channel)); |
| dim_print("trick_mode %d bypass_all %d\n", |
| trick_mode, |
| di_cfgx_get(channel, EDI_CFGX_BYPASS_ALL)); |
| #endif |
| } |
| |
| if (ppre->di_post_wr_buf) |
| di_que_in(channel, QUE_PRE_READY, |
| ppre->di_post_wr_buf); |
| |
| dim_print("%s: %s[%d] => pre_ready_list\n", __func__, |
| vframe_type_name[ppre->di_wr_buf->type], |
| ppre->di_wr_buf->index); |
| |
| if (ppre->di_wr_buf) { |
| if (di_pre_rdma_enable) |
| ppre->di_post_wr_buf = ppre->di_wr_buf; |
| else |
| ppre->di_post_wr_buf = NULL; |
| |
| ppre->di_wr_buf = NULL; |
| } |
| } |
| } |
| if (ppre->di_post_inp_buf && di_pre_rdma_enable) { |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s: %s[%d] => recycle_list\n", __func__, |
| vframe_type_name[ppre->di_post_inp_buf->type], |
| ppre->di_post_inp_buf->index); |
| #endif |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); |
| queue_in(channel, ppre->di_post_inp_buf, QUEUE_RECYCLE); |
| ppre->di_post_inp_buf = NULL; |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| } |
| if (ppre->di_inp_buf) { |
| if (!di_pre_rdma_enable) { |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s: %s[%d] => recycle_list\n", __func__, |
| vframe_type_name[ppre->di_inp_buf->type], |
| ppre->di_inp_buf->index); |
| #endif |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); |
| if (!(ppre->di_inp_buf->dec_vf_state & DI_BIT0)) { |
| /*dec vf keep*/ |
| queue_in(channel, ppre->di_inp_buf, |
| QUEUE_RECYCLE); |
| ppre->di_inp_buf = NULL; |
| } |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| } else { |
| ppre->di_post_inp_buf = ppre->di_inp_buf; |
| ppre->di_inp_buf = NULL; |
| } |
| } |
| dim_ddbg_mod_save(EDI_DBG_MOD_PRE_DONEE, channel, ppre->in_seq);/*dbg*/ |
| |
| dim_dbg_pre_cnt(channel, "d2"); |
| } |
| |
| static void recycle_vframe_type_pre(struct di_buf_s *di_buf, |
| unsigned int channel) |
| { |
| //ary 2020-12-09 ulong irq_flag2 = 0; |
| |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); |
| |
| queue_in(channel, di_buf, QUEUE_RECYCLE); |
| |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| } |
| |
| /* |
| * add dummy buffer to pre ready queue |
| */ |
| static void add_dummy_vframe_type_pre(struct di_buf_s *src_buf, |
| unsigned int channel) |
| { |
| struct di_buf_s *di_buf_tmp = NULL; |
| |
| if (!queue_empty(channel, QUEUE_LOCAL_FREE)) { |
| di_buf_tmp = get_di_buf_head(channel, QUEUE_LOCAL_FREE); |
| if (di_buf_tmp) { |
| queue_out(channel, di_buf_tmp); |
| di_buf_tmp->pre_ref_count = 0; |
| di_buf_tmp->post_ref_count = 0; |
| di_buf_tmp->post_proc_flag = 3; |
| di_buf_tmp->new_format_flag = 0; |
| if (!IS_ERR_OR_NULL(src_buf)) |
| memcpy(di_buf_tmp->vframe, src_buf->vframe, |
| sizeof(vframe_t)); |
| |
| di_que_in(channel, QUE_PRE_READY, di_buf_tmp); |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s: dummy %s[%d] => pre_ready_list\n", |
| __func__, |
| vframe_type_name[di_buf_tmp->type], |
| di_buf_tmp->index); |
| #endif |
| } |
| } |
| } |
| |
| #ifdef HIS_CODE |
| static void add_eos_pre(unsigned int ch, struct dim_nins_s *nin) |
| { |
| struct di_buf_s *di_buf; |
| |
| if (di_que_is_empty(ch, QUE_PRE_NO_BUF)) { |
| PR_ERR("%s:no no_buf\n", __func__); |
| return; |
| } |
| //PR_INF("%s:ch[%d]\n", __func__, ch); |
| di_buf = di_que_out_to_di_buf(ch, QUE_PRE_NO_BUF); |
| di_buf->is_eos = 1; |
| if (nin) |
| di_buf->c.in = nin; |
| di_que_in(ch, QUE_PRE_READY, di_buf); |
| } |
| #endif |
| /* 2021-01-26 for eos out*/ |
| static void add_eos_in(unsigned int ch, struct dim_nins_s *nin) |
| { |
| struct di_buf_s *di_buf; |
| |
| if (di_que_is_empty(ch, QUE_IN_FREE)) { |
| PR_ERR("%s:no in buf\n", __func__); |
| return; |
| } |
| //PR_INF("%s:ch[%d]\n", __func__, ch); |
| di_buf = di_que_out_to_di_buf(ch, QUE_IN_FREE); |
| di_buf->is_eos = 1; |
| if (nin) { |
| di_buf->c.in = nin; |
| di_buf->is_nbypass = 1; |
| } else { |
| di_buf->c.in = NULL; |
| } |
| |
| di_que_in(ch, QUE_PRE_READY, di_buf); |
| dbg_bypass("%s:\n", __func__); |
| } |
| |
| /* |
| * it depend on local buffer queue type is 2 |
| */ |
| static int peek_free_linked_buf(unsigned int channel) |
| { |
| struct di_buf_s *p = NULL; |
| int itmp, p_index = -2; |
| |
| if (list_count(channel, QUEUE_LOCAL_FREE) < 2) |
| return -1; |
| |
| queue_for_each_entry(p, channel, QUEUE_LOCAL_FREE, list) { |
| if (abs(p->index - p_index) == 1) |
| return min(p->index, p_index); |
| p_index = p->index; |
| } |
| return -1; |
| } |
| |
| /* |
| * it depend on local buffer queue type is 2 |
| */ |
| static struct di_buf_s *get_free_linked_buf(int idx, unsigned int channel) |
| { |
| struct di_buf_s *di_buf = NULL, *linkp = NULL; |
| int pool_idx = 0, di_buf_idx = 0; |
| struct queue_s *pqueue = get_queue(channel); |
| struct di_buf_pool_s *ppo = get_buf_pool(channel); |
| |
| queue_t *q = &pqueue[QUEUE_LOCAL_FREE]; |
| |
| if (list_count(channel, QUEUE_LOCAL_FREE) < 2) |
| return NULL; |
| if (q->pool[idx] != 0 && q->pool[idx + 1] != 0) { |
| pool_idx = ((q->pool[idx] >> 8) & 0xff) - 1; |
| di_buf_idx = q->pool[idx] & 0xff; |
| if (pool_idx < VFRAME_TYPE_NUM) { |
| if (di_buf_idx < ppo[pool_idx].size) { |
| di_buf = &ppo[pool_idx].di_buf_ptr[di_buf_idx]; |
| queue_out(channel, di_buf); |
| } |
| } |
| pool_idx = ((q->pool[idx + 1] >> 8) & 0xff) - 1; |
| di_buf_idx = q->pool[idx + 1] & 0xff; |
| if (pool_idx < VFRAME_TYPE_NUM) { |
| if (di_buf_idx < ppo[pool_idx].size) { |
| linkp = &ppo[pool_idx].di_buf_ptr[di_buf_idx]; |
| queue_out(channel, linkp); |
| } |
| } |
| if (IS_ERR_OR_NULL(di_buf)) |
| return NULL; |
| di_buf->di_wr_linked_buf = linkp; |
| } |
| return di_buf; |
| } |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC |
| static void pre_inp_canvas_config(struct vframe_s *vf) |
| { |
| struct di_cvs_s *cvss; |
| |
| cvss = &get_datal()->cvs; |
| |
| if (vf->canvas0Addr == (u32)-1) { |
| canvas_config_config(cvss->inp_idx[0], |
| &vf->canvas0_config[0]); |
| canvas_config_config(cvss->inp_idx[1], |
| &vf->canvas0_config[1]); |
| vf->canvas0Addr = (cvss->inp_idx[1] << 8) | (cvss->inp_idx[0]); |
| if (vf->plane_num == 2) { |
| vf->canvas0Addr |= (cvss->inp_idx[1] << 16); |
| } else if (vf->plane_num == 3) { |
| canvas_config_config(cvss->inp_idx[2], |
| &vf->canvas0_config[2]); |
| vf->canvas0Addr |= (cvss->inp_idx[2] << 16); |
| } |
| vf->canvas1Addr = vf->canvas0Addr; |
| dim_print("%s:w:%d\n", __func__, vf->canvas0_config[0].width); |
| } |
| } |
| #endif |
| |
| void pre_cfg_cvs(struct vframe_s *vf) |
| { |
| #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC |
| pre_inp_canvas_config(vf); |
| #endif |
| } |
| |
| //static |
| void pre_inp_mif_w(struct DI_MIF_S *di_mif, struct vframe_s *vf) |
| { |
| unsigned int dbga = dim_get_dbg_dec21(); |
| int i; |
| unsigned long addr[3]; |
| |
| if (vf->canvas0Addr != (u32)-1) |
| di_mif->canvas_w = |
| canvas_get_width(vf->canvas0Addr & 0xff); |
| else |
| di_mif->canvas_w = vf->canvas0_config[0].width; |
| |
| if (cfgg(LINEAR)) { |
| for (i = 0; i < vf->plane_num; i++) { |
| addr[i] = vf->canvas0_config[i].phy_addr; |
| dbg_ic("%s:[%d]addr[0x%lx]\n", __func__, i, addr[i]); |
| } |
| di_mif->addr0 = addr[0]; |
| di_mif->cvs0_w = vf->canvas0_config[0].width; |
| di_mif->cvs1_w = 0; |
| di_mif->cvs2_w = 0; |
| if (vf->plane_num >= 2) { |
| di_mif->addr1 = addr[1]; |
| di_mif->cvs1_w = vf->canvas0_config[1].width; |
| } |
| if (vf->plane_num >= 3) { |
| di_mif->addr2 = addr[2]; |
| di_mif->cvs2_w = vf->canvas0_config[2].width; |
| } |
| di_mif->linear = 1; |
| if (vf->plane_num == 2) { |
| di_mif->buf_crop_en = 1; |
| di_mif->buf_hsize = vf->canvas0_config[0].width; |
| dbg_ic("\t:buf_h[%d]\n", di_mif->buf_hsize); |
| } else { |
| di_mif->buf_crop_en = 0; |
| dbg_ic("\t:not nv21?\n"); |
| } |
| |
| if (vf->canvas0_config[0].block_mode) |
| di_mif->block_mode = 1; |
| else |
| di_mif->block_mode = 0; |
| } |
| |
| if (vf->type & VIDTYPE_VIU_NV12) |
| di_mif->cbcr_swap = 1; |
| else |
| di_mif->cbcr_swap = 0; |
| if ((vf->flag & VFRAME_FLAG_VIDEO_LINEAR) || |
| dim_in_linear()) { |
| di_mif->reg_swap = 0; |
| di_mif->l_endian = 1; |
| |
| } else { |
| di_mif->reg_swap = 1; |
| di_mif->l_endian = 0; |
| //di_mif->cbcr_swap = 0; |
| } |
| if (dbga & 0xf) { |
| di_mif->reg_swap = bget(&dbga, 0); |
| di_mif->l_endian = bget(&dbga, 1); |
| di_mif->cbcr_swap = bget(&dbga, 2); |
| } |
| } |
| |
| #ifdef MARK_HIS |
| bool di_get_pre_hsc_down_en(void) |
| { |
| return pre_hsc_down_en; |
| } |
| #endif |
| bool dbg_first_frame; /*debug */ |
| unsigned int dbg_first_cnt_pre; |
| unsigned int dbg_first_cnt_post; |
| #define DI_DBG_CNT (2) |
| void dim_dbg_pre_cnt(unsigned int channel, char *item) |
| { |
| bool flgs = false; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| |
| if (ppre->field_count_for_cont < DI_DBG_CNT) { |
| dbg_first_frame("%d:%s:%d\n", channel, item, |
| ppre->field_count_for_cont); |
| dbg_first_frame = true; |
| flgs = true; |
| dbg_first_cnt_pre = DI_DBG_CNT * 5; |
| dbg_first_cnt_post = DI_DBG_CNT * 4 + 1; |
| } else if (ppre->field_count_for_cont == DI_DBG_CNT) {/*don't use >=*/ |
| dbg_first_frame = false; |
| dbg_first_cnt_pre = 0; |
| dbg_first_cnt_post = 0; |
| } |
| |
| if ((dbg_first_frame) && !flgs && dbg_first_cnt_pre) { |
| dbg_first_frame("%d:n%s:%d\n", channel, item, |
| ppre->field_count_for_cont); |
| dbg_first_cnt_pre--; |
| } |
| } |
| |
| static void dbg_post_cnt(unsigned int ch, char *item) |
| { |
| struct di_post_stru_s *ppost = get_post_stru(ch); |
| |
| if (dbg_first_cnt_post) { |
| dbg_first_frame("%d:%s:%d\n", ch, item, |
| ppost->frame_cnt); |
| dbg_first_cnt_post--; |
| } |
| } |
| |
| #ifdef MARK_HIS |
| /*must been called when dim_pre_de_buf_config return true*/ |
| void pre_p_asi_set_next(unsigned int ch) |
| { |
| struct di_pre_stru_s *ppre = get_pre_stru(ch); |
| |
| ppre->p_asi_next = ppre->di_inp_buf; |
| } |
| #endif |
| |
| unsigned char pre_p_asi_de_buf_config(unsigned int ch) |
| { |
| struct di_pre_stru_s *ppre = get_pre_stru(ch); |
| |
| #ifdef MARK_HIS |
| if (di_blocking || !dip_cma_st_is_ready(ch)) |
| return 0; |
| |
| if (di_que_list_count(ch, QUE_IN_FREE) < 1) |
| return 0; |
| |
| if (queue_empty(ch, QUEUE_LOCAL_FREE)) |
| return 0; |
| #endif |
| ppre->di_inp_buf = ppre->di_inp_buf_next; |
| ppre->di_inp_buf_next = NULL; |
| |
| if (!ppre->di_mem_buf_dup_p) {/* use n */ |
| ppre->di_mem_buf_dup_p = ppre->di_inp_buf; |
| } |
| |
| return 1; |
| } |
| |
| #ifdef MARK_HIS |
| /*for first frame no need to ready buf*/ |
| bool dim_bypass_first_frame(unsigned int ch) |
| { |
| struct di_buf_s *di_buf = NULL; |
| struct di_buf_s *di_buf_post = NULL; |
| struct vframe_s *vframe; |
| struct di_pre_stru_s *ppre = get_pre_stru(ch); |
| struct vframe_s **pvframe_in = get_vframe_in(ch); |
| ulong irq_flag2 = 0; |
| |
| vframe = pw_vf_peek(ch); |
| |
| if (!vframe) |
| return false; |
| if (di_que_is_empty(ch, QUE_POST_FREE)) |
| return false; |
| |
| vframe = pw_vf_get(ch); |
| |
| di_buf = di_que_out_to_di_buf(ch, QUE_IN_FREE); |
| |
| if (dim_check_di_buf(di_buf, 10, ch)) |
| return 0; |
| |
| memcpy(di_buf->vframe, vframe, sizeof(struct vframe_s)); |
| di_buf->vframe->private_data = di_buf; |
| pvframe_in[di_buf->index] = vframe; |
| di_buf->seq = ppre->in_seq; |
| ppre->in_seq++; |
| |
| #ifdef MARK_HIS |
| |
| if (vframe->type & VIDTYPE_COMPRESS) { /*?*/ |
| vframe->width = vframe->compWidth; |
| vframe->height = vframe->compHeight; |
| } |
| |
| di_que_in(ch, QUE_PRE_READY, di_buf); |
| #endif |
| |
| di_buf_post = di_que_out_to_di_buf(ch, QUE_POST_FREE); |
| memcpy(di_buf_post->vframe, vframe, sizeof(struct vframe_s)); |
| di_buf_post->vframe->private_data = di_buf_post; |
| di_lock_irqfiq_save(irq_flag2); |
| |
| di_que_in(ch, QUE_POST_READY, di_buf_post); |
| |
| di_unlock_irqfiq_restore(irq_flag2); |
| pw_vf_notify_receiver(ch, |
| VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); |
| |
| PR_INF("%s:ok\n", __func__); |
| return true; |
| } |
| #endif |
| static bool pp_check_buf_cfg(struct di_ch_s *pch) |
| { |
| unsigned int ch; |
| |
| ch = pch->ch_id; |
| |
| if (di_que_is_empty(ch, QUE_PRE_NO_BUF)) |
| return false; |
| if (di_que_is_empty(ch, QUE_POST_FREE)) |
| return false; |
| |
| return true; |
| } |
| |
| static bool pp_check_buf_post(struct di_ch_s *pch) |
| { |
| unsigned int ch; |
| |
| ch = pch->ch_id; |
| |
| if (di_que_is_empty(ch, QUE_PST_NO_BUF)) |
| return false; |
| |
| return true; |
| } |
| |
| static void pp_buf_cp(struct di_buf_s *buft, struct di_buf_s *buff) |
| { |
| buft->blk_buf = buff->blk_buf; |
| buft->nr_adr = buff->nr_adr; |
| buft->afbc_adr = buff->afbc_adr; |
| buft->afbct_adr = buff->afbct_adr; |
| buft->dw_adr = buff->dw_adr; |
| buft->afbc_crc = buff->afbc_crc; |
| buft->adr_start = buff->adr_start; |
| // buft->pat_buf = buff->pat_buf; |
| buft->nr_size = buff->nr_size; |
| buft->tab_size = buff->tab_size; |
| buft->canvas_height = buff->canvas_height; |
| buft->canvas_width[NR_CANVAS] = buff->canvas_width[NR_CANVAS]; |
| buft->buf_is_i = buff->buf_is_i; |
| buft->flg_null = buff->flg_null; |
| buft->in_buf = buff->in_buf; |
| buft->afbce_out_yuv420_10 = buff->afbce_out_yuv420_10; |
| buft->c.buffer = buff->c.buffer; |
| buft->c.src_is_i = buff->c.src_is_i; |
| buft->buf_hsize = buff->buf_hsize; |
| |
| /* clear */ |
| buff->blk_buf = NULL; |
| buff->flg_null = 1; |
| buff->buf_is_i = 0; |
| buff->afbc_crc = 0; |
| // buff->pat_buf = 0; |
| buff->adr_start = 0; |
| buff->nr_adr = 0; |
| buff->afbc_adr = 0; |
| buff->afbct_adr = 0; |
| buff->dw_adr = 0; |
| buff->canvas_height = 0; |
| buff->canvas_width[NR_CANVAS] = 0; |
| buff->nr_size = 0; |
| buff->tab_size = 0; |
| buff->in_buf = NULL; |
| buff->afbce_out_yuv420_10 = 0; |
| buff->c.buffer = NULL; |
| buff->c.src_is_i = false; |
| buff->buf_hsize = 0; |
| } |
| |
| static struct di_buf_s *pp_pst_2_local(struct di_ch_s *pch) |
| { |
| struct di_buf_s *di_buf = NULL; |
| struct di_buf_s *buf_pst = NULL; |
| unsigned int ch; |
| //ary 2020-12-09 ulong irq_flag2 = 0; |
| |
| if (!pp_check_buf_cfg(pch)) |
| return di_buf; |
| |
| ch = pch->ch_id; |
| |
| di_buf = di_que_out_to_di_buf(ch, QUE_PRE_NO_BUF); |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); |
| buf_pst = di_que_out_to_di_buf(ch, QUE_POST_FREE); |
| |
| pp_buf_cp(di_buf, buf_pst); |
| di_que_in(ch, QUE_PST_NO_BUF, buf_pst); |
| /* debug */ |
| //dbg_buf_log_save(pch, di_buf, 1); |
| //dbg_buf_log_save(pch, buf_pst, 2); |
| |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| |
| return di_buf; |
| } |
| |
| static struct di_buf_s *pp_local_2_post(struct di_ch_s *pch, |
| struct di_buf_s *di_buf) |
| { |
| struct di_buf_s *buf_pst = NULL; |
| unsigned int ch; |
| //ulong irq_flag2 = 0; |
| |
| if (!pp_check_buf_post(pch)) |
| return NULL; |
| |
| ch = pch->ch_id; |
| //di_lock_irqfiq_save(irq_flag2); |
| buf_pst = di_que_out_to_di_buf(ch, QUE_PST_NO_BUF); |
| //di_unlock_irqfiq_restore(irq_flag2); |
| if (!buf_pst) |
| return NULL; |
| pp_buf_cp(buf_pst, di_buf); |
| |
| //di_que_in(ch, QUE_PRE_NO_BUF, di_buf); |
| |
| return buf_pst; |
| } |
| |
| static void pp_drop_frame(struct di_buf_s *di_buf, |
| unsigned int channel) |
| { |
| //ary 2020-12-09 ulong irq_flag2 = 0; |
| |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); |
| |
| if (dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) { |
| //queue_in(channel, di_buf, QUEUE_POST_DOING); |
| di_que_in(channel, QUE_POST_DOING, di_buf); |
| } else { |
| //no use di_que_in(channel, QUE_POST_READY, di_buf); |
| } |
| dim_tr_ops.post_do(di_buf->vframe->index_disp); |
| dim_print("di:ch[%d]:%dth %s[%d] => post ready %u ms.\n", |
| channel, |
| frame_count, |
| vframe_type_name[di_buf->type], di_buf->index, |
| jiffies_to_msecs(jiffies_64 - |
| di_buf->vframe->ready_jiffies64)); |
| |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| } |
| |
| static void dimpst_fill_outvf(struct vframe_s *vfm, |
| struct di_buf_s *di_buf, |
| enum EDPST_OUT_MODE mode); |
| //static void dimpst_fill_outvf_ext(struct vframe_s *vfm, |
| // struct di_buf_s *di_buf, |
| // enum EDPST_OUT_MODE mode); |
| |
| static void re_build_buf(struct di_ch_s *pch, enum EDI_SGN sgn) |
| { |
| bool is_4k = false; |
| struct div2_mm_s *mm; |
| const struct di_mm_cfg_s *ptab; |
| struct mtsk_cmd_s blk_cmd; |
| unsigned int ch; |
| unsigned int release_post; |
| unsigned int post_nub; |
| |
| if (sgn == EDI_SGN_4K) |
| is_4k = true; |
| |
| ch = pch->ch_id; |
| /* free buf -> release */ |
| release_post = mem_release_free(pch); |
| mem_2_blk(pch); |
| mtsk_release(ch, ECMD_BLK_RELEASE); |
| |
| /* mm change*/ |
| ptab = di_get_mm_tab(is_4k, pch); |
| mm = dim_mm_get(ch); |
| |
| mm->cfg.di_h = ptab->di_h; |
| mm->cfg.di_w = ptab->di_w; |
| mm->cfg.num_local = ptab->num_local; |
| mm->cfg.num_post = ptab->num_post; |
| mm->cfg.num_step1_post = ptab->num_step1_post; |
| |
| post_nub = cfgg(POST_NUB); |
| if ((post_nub) && (post_nub < POST_BUF_NUM)) |
| mm->cfg.num_post = post_nub; |
| |
| if (pch->ponly && dip_is_ponly_sct_mem(pch)) |
| mm->cfg.dis_afbce = 0; |
| else if ((!is_4k && |
| ((cfggch(pch, POUT_FMT) == 4) || (cfggch(pch, POUT_FMT) == 6)))) |
| mm->cfg.dis_afbce = 1; |
| else |
| mm->cfg.dis_afbce = 0; |
| |
| di_cnt_post_buf(pch); |
| if (cfgeq(MEM_FLAG, EDI_MEM_M_CMA) || |
| cfgeq(MEM_FLAG, EDI_MEM_M_CODEC_A) || |
| cfgeq(MEM_FLAG, EDI_MEM_M_CODEC_B)) { /*trig cma alloc*/ |
| |
| blk_cmd.cmd = ECMD_BLK_ALLOC; |
| if (mm->cfg.num_local) { |
| #ifdef MARK_HIS |
| /*pre idat*/ |
| if (!pch->rse_ori.dat_i.blk_buf) { |
| blk_cmd.nub = 1; |
| blk_cmd.flg.d32 = mm->cfg.dat_idat_flg.d32; |
| mtask_send_cmd(ch, &blk_cmd); |
| } else { |
| PR_INF("%s:need idat\n", __func__); |
| } |
| #else |
| /*pre idat*/ |
| pre_sec_alloc(pch, mm->cfg.dat_idat_flg.d32); |
| #endif |
| /* pre */ |
| blk_cmd.nub = mm->cfg.num_local; |
| blk_cmd.flg.d32 = mm->cfg.ibuf_flg.d32; |
| |
| mtask_send_cmd(ch, &blk_cmd); |
| } |
| |
| /* post */ |
| if (mm->cfg.pbuf_flg.b.typ == EDIM_BLK_TYP_PSCT) |
| sct_sw_on(pch, |
| mm->cfg.num_post, |
| mm->cfg.pbuf_flg.b.tvp, |
| mm->cfg.pst_buf_size); |
| else |
| sct_sw_off_rebuild(pch); |
| release_post += mem_release_sct_wait(pch); |
| |
| blk_cmd.nub = release_post;//mm->cfg.num_post; |
| blk_cmd.flg.d32 = mm->cfg.pbuf_flg.d32; |
| |
| mtask_send_cmd(ch, &blk_cmd); |
| } |
| } |
| |
| /* @ary_note: change return val for check block reason */ |
| /* 0: ok |
| * other: reason |
| **/ |
| unsigned char dim_pre_de_buf_config(unsigned int channel) |
| { |
| struct di_buf_s *di_buf = NULL; |
| struct vframe_s *vframe; |
| int /*i,*/ di_linked_buf_idx = -1; |
| unsigned char change_type = 0; |
| unsigned char change_type2 = 0; |
| bool bit10_pack_patch = false; |
| unsigned int width_roundup = 2; |
| #ifdef VFM_ORI |
| struct vframe_s **pvframe_in = get_vframe_in(channel); |
| #endif |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| // struct di_post_stru_s *ppost = get_post_stru(channel); |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| int cfg_prog_proc = dimp_get(edi_mp_prog_proc_config); |
| bool flg_1080i = false; |
| bool flg_480i = false; |
| unsigned int bypassr; |
| struct di_ch_s *pch; |
| unsigned int nv21_flg = 0; |
| enum EDI_SGN sgn; |
| struct div2_mm_s *mm; |
| u32 cur_dw_width = 0xffff; |
| u32 cur_dw_height = 0xffff; |
| struct dim_nins_s *nins = NULL; |
| enum EDPST_OUT_MODE tmpmode; |
| |
| pch = get_chdata(channel); |
| |
| if (di_blocking /*|| !dip_cma_st_is_ready(channel)*/) |
| return 1; |
| |
| if (di_que_list_count(channel, QUE_IN_FREE) < 1) |
| return 2; |
| |
| if ((di_que_list_count(channel, QUE_IN_FREE) < 2 && |
| !ppre->di_inp_buf_next) || |
| (((ppre->sgn_lv != EDI_SGN_4K) && (!pch->ponly)) && |
| (queue_empty(channel, QUEUE_LOCAL_FREE)))) |
| return 3; |
| |
| if (di_que_list_count(channel, QUE_PRE_READY) >= DI_PRE_READY_LIMIT) |
| return 4; |
| |
| if (di_que_is_empty(channel, QUE_POST_FREE)) |
| return 5; |
| di_buf = di_que_peek(channel, QUE_POST_FREE); |
| mm = dim_mm_get(channel); |
| if (!dip_itf_is_ins_exbuf(pch) && |
| (!di_buf->blk_buf || |
| di_buf->blk_buf->flg.d32 != mm->cfg.pbuf_flg.d32)) { |
| if (!di_buf->blk_buf) |
| PR_ERR("%s:pst no blk:idx[%d]\n", |
| __func__, |
| di_buf->index); |
| else |
| PR_ERR("%s:pst flgis err:buf:idx[%d] 0x%x->0x%x\n", |
| __func__, |
| di_buf->index, |
| mm->cfg.pbuf_flg.d32, |
| di_buf->blk_buf->flg.d32); |
| |
| return 6; |
| } |
| |
| if (di_que_is_empty(channel, QUE_PRE_NO_BUF)) |
| return 7; |
| |
| if (dim_is_bypass(NULL, channel)) { |
| /* some provider has problem if receiver |
| * get all buffers of provider |
| */ |
| int in_buf_num = 0; |
| /*cur_lev = 0;*/ |
| dimp_set(edi_mp_cur_lev, 0); |
| #ifdef VFM_ORI |
| for (i = 0; i < MAX_IN_BUF_NUM; i++) |
| if (pvframe_in[i]) |
| in_buf_num++; |
| #else |
| in_buf_num = nins_cnt_used_all(pch); |
| #endif |
| if (in_buf_num > BYPASS_GET_MAX_BUF_NUM) { |
| #ifdef DET3D |
| if (ppre->vframe_interleave_flag == 0) |
| #endif |
| return 30; |
| } |
| |
| dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER, false); |
| } else if (ppre->prog_proc_type == 2) { |
| di_linked_buf_idx = peek_free_linked_buf(channel); |
| if (di_linked_buf_idx == -1) |
| return 8; |
| } else if (ppre->prog_proc_type == 0x10) { //ary add for pp |
| if (!pp_check_buf_cfg(pch)) |
| return 9; |
| } |
| if (ppre->di_inp_buf_next) { |
| ppre->di_inp_buf = ppre->di_inp_buf_next; |
| ppre->di_inp_buf_next = NULL; |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s: di_inp_buf_next %s[%d] => di_inp_buf\n", |
| __func__, |
| vframe_type_name[ppre->di_inp_buf->type], |
| ppre->di_inp_buf->index); |
| #endif |
| if (!ppre->di_mem_buf_dup_p) {/* use n */ |
| ppre->di_mem_buf_dup_p = ppre->di_inp_buf; |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s: set di_mem_buf_dup_p to di_inp_buf\n", |
| __func__); |
| #endif |
| } |
| } else { |
| |
| nins = nins_peek(pch); |
| if (!nins) |
| return 10; |
| vframe = &nins->c.vfm_cp; |
| |
| /*eos check*/ |
| if ((vframe->type & VIDTYPE_V4L_EOS) || |
| dbg_is_trig_eos(channel)) { |
| nins = nins_get(pch); |
| if (!nins) |
| return 11; |
| //vframe = &nins->c.vfm_cp; |
| |
| PR_INF("eos\n"); |
| if ((ppre->cur_prog_flag == 0) && |
| (ppre->field_count_for_cont > 0)) { |
| if (dip_itf_is_ins(pch) && (vframe->type & |
| VIDTYPE_V4L_EOS)) |
| add_eos_in(channel, nins); |
| else |
| add_eos_in(channel, NULL); |
| } else if (ppre->prog_proc_type == 0x10 && |
| ppre->di_mem_buf_dup_p && |
| ppre->di_mem_buf_dup_p->flg_nr) { |
| /*clear last p buf eos */ |
| ppre->di_mem_buf_dup_p->pre_ref_count = 0; |
| ppre->di_mem_buf_dup_p->is_lastp = 1; |
| di_que_in(channel, QUE_PRE_READY, |
| ppre->di_mem_buf_dup_p); |
| ppre->di_mem_buf_dup_p = NULL; |
| if (dip_itf_is_ins(pch) && |
| (vframe->type & VIDTYPE_V4L_EOS)) |
| add_eos_in(channel, nins); |
| else |
| add_eos_in(channel, NULL); |
| } else { |
| if (dip_itf_is_ins(pch) && |
| (vframe->type & VIDTYPE_V4L_EOS)) |
| add_eos_in(channel, nins); |
| else |
| add_eos_in(channel, NULL); |
| } |
| ppre->cur_width = 0; |
| ppre->di_mem_buf_dup_p = NULL; |
| ppre->di_chan2_buf_dup_p = NULL; |
| ppre->field_count_for_cont = 0; |
| #ifdef VFM_ORI |
| pw_vf_put(vframe, channel); |
| pw_vf_notify_provider(channel, |
| VFRAME_EVENT_RECEIVER_PUT, NULL); |
| #else |
| if (dip_itf_is_vfm(pch)) |
| nins_used_some_to_recycle(pch, nins); |
| #endif |
| /*debug only*/ |
| //pre_run_flag = DI_RUN_FLAG_PAUSE; |
| return 12; |
| } |
| /**************************************************/ |
| /*mem check*/ |
| memcpy(&ppre->vfm_cpy, vframe, sizeof(ppre->vfm_cpy)); |
| #ifdef HIS_CODE |
| if (vframe->type & VIDTYPE_COMPRESS) { |
| /* backup the orignal vf->width/height for bypass case */ |
| cur_dw_width = vframe->width; |
| cur_dw_height = vframe->height; |
| vframe->width = vframe->compWidth; |
| vframe->height = vframe->compHeight; |
| } |
| #endif |
| bypassr = dim_is_bypass(vframe, channel); |
| /*2020-12-02: here use di_buf->vframe is err*/ |
| change_type = is_source_change(vframe, channel); |
| if ((!bypassr) && change_type) { |
| sgn = di_vframe_2_sgn(vframe); |
| if (pch->ponly && dip_is_ponly_sct_mem(pch)) { |
| if (sgn != ppre->sgn_lv) |
| PR_INF("%s:p:%d->%d\n", __func__, |
| ppre->sgn_lv, sgn); |
| ppre->sgn_lv = sgn; |
| } else if ((sgn != ppre->sgn_lv) && |
| dim_afds() && |
| dip_is_support_4k(channel) && |
| (((sgn == EDI_SGN_4K) && |
| (ppre->sgn_lv <= EDI_SGN_HD)) || |
| ((sgn <= EDI_SGN_HD) && |
| (ppre->sgn_lv == EDI_SGN_4K)))) { |
| ppre->sgn_lv = sgn; |
| if (!mm->cfg.fix_buf) { |
| re_build_buf(pch, sgn); |
| /*debug*/ |
| //pre_run_flag = DI_RUN_FLAG_PAUSE; |
| //dimp_set(edi_mp_di_printk_flag, 1); |
| //cnt_rebuild = 0; |
| PR_INF("%s:rebuild:%d,sgn[%d]\n", |
| __func__, |
| mm->cfg.fix_buf, ppre->sgn_lv); |
| return 13; |
| } |
| } else if (sgn != ppre->sgn_lv) { |
| PR_INF("%s:%d->%d\n", __func__, |
| ppre->sgn_lv, sgn); |
| ppre->sgn_lv = sgn; |
| } |
| } |
| /**************************************************/ |
| |
| nins = nins_get(pch); |
| if (!nins) |
| return 14; |
| vframe = &nins->c.vfm_cp; |
| |
| if (vframe->type & VIDTYPE_COMPRESS) { |
| /*backup the orignal vf->width/height for bypass case */ |
| cur_dw_width = vframe->width; |
| cur_dw_height = vframe->height; |
| vframe->width = vframe->compWidth; |
| vframe->height = vframe->compHeight; |
| } |
| |
| /*dbg_vfm(vframe, 1);*/ |
| if (ppre->in_seq < kpi_frame_num) { |
| pr_dbg("[di_kpi] DI:ch[%d] get %dth vf[0x%p] from frontend %u ms.\n", |
| channel, |
| ppre->in_seq, vframe, |
| jiffies_to_msecs(jiffies_64 - |
| vframe->ready_jiffies64)); |
| } |
| dim_tr_ops.pre_get(vframe->index_disp); |
| if (dip_itf_is_vfm(pch)) |
| didbg_vframe_in_copy(channel, nins->c.ori); |
| else |
| didbg_vframe_in_copy(channel, vframe); |
| #ifdef MARK_SC2 |
| if (vframe->type & VIDTYPE_COMPRESS) { |
| vframe->width = vframe->compWidth; |
| vframe->height = vframe->compHeight; |
| } |
| #endif |
| dim_print("DI:ch[%d]get %dth vf[0x%p][%d] from front %u ms\n", |
| channel, |
| ppre->in_seq, vframe, |
| vframe->index_disp, |
| jiffies_to_msecs(jiffies_64 - |
| vframe->ready_jiffies64)); |
| vframe->prog_proc_config = (cfg_prog_proc & 0x20) >> 5; |
| |
| #ifdef VFM_ORI /* 2020-12-02: di no need throw bad_frame */ |
| if (vframe->width > 10000 || vframe->height > 10000 || |
| hold_video || ppre->bad_frame_throw_count > 0) { |
| if (vframe->width > 10000 || vframe->height > 10000) |
| ppre->bad_frame_throw_count = 10; |
| ppre->bad_frame_throw_count--; |
| pw_vf_put(vframe, channel); |
| pw_vf_notify_provider(channel, |
| VFRAME_EVENT_RECEIVER_PUT, NULL); |
| return 15; |
| } |
| #endif //end of VFM_ORI |
| bit10_pack_patch = (is_meson_gxtvbb_cpu() || |
| is_meson_gxl_cpu() || |
| is_meson_gxm_cpu()); |
| width_roundup = bit10_pack_patch ? 16 : width_roundup; |
| #ifdef MARK_SC2 //tmp |
| if (dimp_get(edi_mp_di_force_bit_mode) == 10) |
| dimp_set(edi_mp_force_width, |
| roundup(vframe->width, width_roundup)); |
| else |
| dimp_set(edi_mp_force_width, 0); |
| #endif |
| ppre->source_trans_fmt = vframe->trans_fmt; |
| ppre->left_right = ppre->left_right ? 0 : 1; |
| ppre->invert_flag = |
| (vframe->type & TB_DETECT_MASK) ? true : false; |
| vframe->type &= ~TB_DETECT_MASK; |
| |
| if ((((invert_top_bot & 0x2) != 0) || |
| ppre->invert_flag) && |
| (!is_progressive(vframe))) { |
| if ((vframe->type & VIDTYPE_TYPEMASK) == |
| VIDTYPE_INTERLACE_TOP) { |
| vframe->type &= (~VIDTYPE_TYPEMASK); |
| vframe->type |= VIDTYPE_INTERLACE_BOTTOM; |
| } else { |
| vframe->type &= (~VIDTYPE_TYPEMASK); |
| vframe->type |= VIDTYPE_INTERLACE_TOP; |
| } |
| } |
| ppre->width_bk = vframe->width; |
| if (dimp_get(edi_mp_force_width)) |
| vframe->width = dimp_get(edi_mp_force_width); |
| if (dimp_get(edi_mp_force_height)) |
| vframe->height = dimp_get(edi_mp_force_height); |
| |
| /* backup frame motion info */ |
| vframe->combing_cur_lev = dimp_get(edi_mp_cur_lev);/*cur_lev;*/ |
| |
| dim_print("%s: vf_get => 0x%p\n", __func__, nins->c.ori); |
| |
| di_buf = di_que_out_to_di_buf(channel, QUE_IN_FREE); |
| di_buf->dec_vf_state = 0; /*dec vf keep*/ |
| if (dim_check_di_buf(di_buf, 10, channel)) |
| return 16; |
| |
| if (dimp_get(edi_mp_di_log_flag) & DI_LOG_VFRAME) |
| dim_dump_vframe(vframe); |
| |
| #ifdef SUPPORT_MPEG_TO_VDIN |
| if ((!is_from_vdin(vframe)) && |
| vframe->sig_fmt == TVIN_SIG_FMT_NULL && |
| mpeg2vdin_flag) { |
| struct vdin_arg_s vdin_arg; |
| struct vdin_v4l2_ops_s *vdin_ops = get_vdin_v4l2_ops(); |
| |
| vdin_arg.cmd = VDIN_CMD_GET_HISTGRAM; |
| vdin_arg.private = (unsigned int)vframe; |
| if (vdin_ops->tvin_vdin_func) |
| vdin_ops->tvin_vdin_func(0, &vdin_arg); |
| } |
| #endif |
| memcpy(di_buf->vframe, vframe, sizeof(vframe_t)); |
| dim_dbg_pre_cnt(channel, "cf1"); |
| di_buf->width_bk = ppre->width_bk; /*ary.sui 2019-04-23*/ |
| di_buf->dw_width_bk = cur_dw_width; |
| di_buf->dw_height_bk = cur_dw_height; |
| di_buf->vframe->private_data = di_buf; |
| //10-09 di_buf->vframe->vf_ext = NULL; /*09-25*/ |
| #ifdef VFM_ORI |
| pvframe_in[di_buf->index] = vframe; |
| #else |
| di_buf->c.in = nins; |
| //dbg_nins_log_buf(di_buf, 1); |
| #endif |
| di_buf->seq = ppre->in_seq; |
| ppre->in_seq++; |
| |
| pre_vinfo_set(channel, vframe); |
| change_type = is_source_change(vframe, channel); |
| if ((di_bypass_state_get(channel) == 0) && |
| change_type && |
| (ppre->cur_prog_flag == 0) && |
| /*(ppre->in_seq > 1)*/(ppre->field_count_for_cont > 0)) { |
| /* last is i */ |
| add_eos_in(channel, NULL); |
| } |
| /* source change, when i mix p,force p as i*/ |
| //if (change_type == 1 || (change_type == 2 && |
| // ppre->cur_prog_flag == 1)) { |
| if (change_type) { |
| if (ppre->prog_proc_type == 0x10 && |
| ppre->di_mem_buf_dup_p && |
| ppre->di_mem_buf_dup_p->flg_nr) { |
| #if 1 |
| /*clear last p buf eos */ |
| ppre->di_mem_buf_dup_p->pre_ref_count = 0; |
| ppre->di_mem_buf_dup_p->is_lastp = 1; |
| di_que_in(channel, QUE_PRE_READY, |
| ppre->di_mem_buf_dup_p); |
| ppre->di_mem_buf_dup_p = NULL; |
| #else |
| |
| #endif |
| } else if (ppre->di_mem_buf_dup_p) { |
| /*avoid only 2 i field then p field*/ |
| if (ppre->cur_prog_flag == 0 && |
| dimp_get(edi_mp_use_2_interlace_buff)) |
| ppre->di_mem_buf_dup_p->post_proc_flag = |
| -1; |
| ppre->di_mem_buf_dup_p->pre_ref_count = 0; |
| ppre->di_mem_buf_dup_p = NULL; |
| } |
| if (ppre->di_chan2_buf_dup_p) { |
| /*avoid only 1 i field then p field*/ |
| if (ppre->cur_prog_flag == 0 && |
| dimp_get(edi_mp_use_2_interlace_buff)) |
| ppre->di_chan2_buf_dup_p-> |
| post_proc_flag = -1; |
| ppre->di_chan2_buf_dup_p->pre_ref_count = |
| 0; |
| ppre->di_chan2_buf_dup_p = NULL; |
| } |
| #ifdef MARK_HIS |
| /* channel change will occur between atv and dtv, |
| * that need mirror |
| */ |
| if (!IS_ERR_OR_NULL(di_post_stru.keep_buf)) { |
| if (di_post_stru.keep_buf->vframe |
| ->source_type != |
| di_buf->vframe->source_type) { |
| recycle_keep_buffer(); |
| pr_info("%s:source_tp chg recycle bf\n", |
| __func__); |
| } |
| } |
| #endif |
| pr_info("%s:ch[%d]:%ums %dth source change:\n", |
| __func__, |
| channel, |
| jiffies_to_msecs(jiffies_64), |
| ppre->in_seq); |
| pr_info("source change:0x%x/%d/%d/%d=>0x%x/%d/%d/%d\n", |
| ppre->cur_inp_type, |
| ppre->cur_width, |
| ppre->cur_height, |
| ppre->cur_source_type, |
| di_buf->vframe->type, |
| di_buf->vframe->width, |
| di_buf->vframe->height, |
| di_buf->vframe->source_type); |
| if (di_buf->vframe->type & VIDTYPE_COMPRESS) { |
| ppre->cur_width = |
| di_buf->vframe->compWidth; |
| ppre->cur_height = |
| di_buf->vframe->compHeight; |
| } else { |
| ppre->cur_width = di_buf->vframe->width; |
| ppre->cur_height = di_buf->vframe->height; |
| } |
| ppre->cur_prog_flag = |
| is_progressive(di_buf->vframe); |
| if (ppre->cur_prog_flag) { |
| #ifndef TEST_4K_NR |
| if ((dimp_get(edi_mp_use_2_interlace_buff)) && |
| !(cfg_prog_proc & 0x10)) |
| ppre->prog_proc_type = 2; |
| else |
| ppre->prog_proc_type = |
| cfg_prog_proc & 0x10; |
| #else |
| ppre->prog_proc_type = 0x10; |
| #endif |
| } else { |
| ppre->prog_proc_type = 0; |
| } |
| ppre->cur_inp_type = di_buf->vframe->type; |
| ppre->cur_source_type = |
| di_buf->vframe->source_type; |
| ppre->cur_sig_fmt = di_buf->vframe->sig_fmt; |
| ppre->orientation = di_buf->vframe->video_angle; |
| ppre->source_change_flag = 1; |
| ppre->input_size_change_flag = true; |
| ppre->is_bypass_mem = 0; |
| #ifdef SUPPORT_MPEG_TO_VDIN |
| if ((!is_from_vdin(vframe)) && |
| vframe->sig_fmt == TVIN_SIG_FMT_NULL && |
| (mpeg2vdin_en)) { |
| struct vdin_arg_s vdin_arg; |
| struct vdin_v4l2_ops_s *vdin_ops = |
| get_vdin_v4l2_ops(); |
| vdin_arg.cmd = VDIN_CMD_MPEGIN_START; |
| vdin_arg.h_active = ppre->cur_width; |
| vdin_arg.v_active = ppre->cur_height; |
| if (vdin_ops->tvin_vdin_func) |
| vdin_ops->tvin_vdin_func(0, &vdin_arg); |
| mpeg2vdin_flag = 1; |
| } |
| #endif |
| ppre->field_count_for_cont = 0; |
| } else if (ppre->cur_prog_flag == 0) { |
| #ifdef MARK_SC2 |
| /* check if top/bot interleaved */ |
| if (change_type == 2) |
| /* source is i interleaves p fields */ |
| ppre->force_interlace = true; |
| #endif |
| if ((ppre->cur_inp_type & |
| VIDTYPE_TYPEMASK) == (di_buf->vframe->type & |
| VIDTYPE_TYPEMASK)) { |
| if ((di_buf->vframe->type & |
| VIDTYPE_TYPEMASK) == |
| VIDTYPE_INTERLACE_TOP) |
| same_field_top_count++; |
| else |
| same_field_bot_count++; |
| } |
| ppre->cur_inp_type = di_buf->vframe->type; |
| } else { |
| ppre->cur_inp_type = di_buf->vframe->type; |
| } |
| /*--------------------------*/ |
| if (!change_type) { |
| change_type2 = is_vinfo_change(channel); |
| if (change_type2) { |
| /*ppre->source_change_flag = 1;*/ |
| ppre->input_size_change_flag = true; |
| } |
| } |
| |
| /*--------------------------*/ |
| bypassr = dim_is_bypass(di_buf->vframe, channel); |
| if (bypassr) { |
| dim_bypass_set(pch, 1, bypassr); |
| } else { |
| bypassr = dim_polic_is_bypass(pch, di_buf->vframe); |
| dim_bypass_set(pch, 1, bypassr); |
| } |
| if (bypassr |
| /*|| is_bypass_i_p()*/ |
| /*|| ((ppre->pre_ready_seq % 5)== 0)*/ |
| /*|| (ppre->pre_ready_seq == 10)*/ |
| ) { |
| if ((di_buf->vframe->type & VIDTYPE_COMPRESS) && |
| (cur_dw_width != 0xffff) && |
| (cur_dw_height != 0xffff)) { |
| di_buf->vframe->width = cur_dw_width; |
| di_buf->vframe->height = cur_dw_height; |
| } |
| /* bypass progressive */ |
| di_buf->seq = ppre->pre_ready_seq++; |
| di_buf->post_ref_count = 0; |
| /*cur_lev = 0;*/ |
| dimp_set(edi_mp_cur_lev, 0); |
| if (ppre->source_change_flag) { |
| di_buf->new_format_flag = 1; |
| ppre->source_change_flag = 0; |
| } else { |
| di_buf->new_format_flag = 0; |
| } |
| |
| if (di_bypass_state_get(channel) == 0) { |
| //cnt_rebuild = 0; /*from no bypass to bypass*/ |
| ppre->is_bypass_all = true; |
| bset(&pch->self_trig_mask, 29); |
| /*********************************/ |
| if ((ppre->cur_prog_flag == 0) && |
| (ppre->in_seq > 1)) { |
| /* last is i */ |
| add_eos_in(channel, NULL); |
| PR_INF("i to bypass, inset eos\n"); |
| } |
| |
| if (ppre->prog_proc_type == 0x10 && |
| ppre->di_mem_buf_dup_p && |
| ppre->di_mem_buf_dup_p->flg_nr) { |
| /*clear last p buf eos */ |
| ppre->di_mem_buf_dup_p->pre_ref_count = 0; |
| ppre->di_mem_buf_dup_p->is_lastp = 1; |
| di_que_in(channel, QUE_PRE_READY, |
| ppre->di_mem_buf_dup_p); |
| ppre->di_mem_buf_dup_p = NULL; |
| PR_INF("p to bypass, push mem\n"); |
| /*********************************/ |
| } else if (ppre->di_mem_buf_dup_p) { |
| ppre->di_mem_buf_dup_p->pre_ref_count = 0; |
| ppre->di_mem_buf_dup_p = NULL; |
| } |
| if (ppre->di_chan2_buf_dup_p) { |
| ppre->di_chan2_buf_dup_p->pre_ref_count = 0; |
| ppre->di_chan2_buf_dup_p = NULL; |
| } |
| |
| if (ppre->di_wr_buf) { |
| ppre->di_wr_buf->pre_ref_count = 0; |
| ppre->di_wr_buf->post_ref_count = 0; |
| recycle_vframe_type_pre(ppre->di_wr_buf, |
| channel); |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s: %s[%d] => recycle_list\n", |
| __func__, |
| vframe_type_name[ppre->di_wr_buf->type], |
| ppre->di_wr_buf->index); |
| #endif |
| ppre->di_wr_buf = NULL; |
| } |
| |
| di_buf->new_format_flag = 1; |
| di_bypass_state_set(channel, true);/*bypass_state:1;*/ |
| |
| dim_print("%s:bypass_state = 1, is_bypass(0x%x)\n", |
| __func__, dim_is_bypass(NULL, channel)); |
| #ifdef DI_BUFFER_DEBUG |
| |
| dim_print("trick_mode %d bypass_all %d\n", |
| trick_mode, |
| di_cfgx_get(channel, EDI_CFGX_BYPASS_ALL)); |
| #endif |
| } |
| |
| top_bot_config(di_buf); |
| |
| di_que_in(channel, QUE_PRE_READY, di_buf); |
| /*if previous isn't bypass post_wr_buf not recycled */ |
| if (ppre->di_post_wr_buf && di_pre_rdma_enable) { |
| queue_in(channel, ppre->di_post_inp_buf, |
| QUEUE_RECYCLE); |
| ppre->di_post_inp_buf = NULL; |
| } |
| |
| if ((bypass_pre & 0x2) && !ppre->cur_prog_flag) |
| di_buf->post_proc_flag = -2; |
| else |
| di_buf->post_proc_flag = 0; |
| |
| dim_print("di:cfg:post_proc_flag=%d\n", |
| di_buf->post_proc_flag); |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s: %s[%d] => pre_ready_list\n", |
| __func__, |
| vframe_type_name[di_buf->type], |
| di_buf->index); |
| #endif |
| di_buf->is_nbypass = 1; /* 2020-12-07*/ |
| if (pch->rsc_bypass.b.ponly_fst_cnt) { |
| pch->rsc_bypass.b.ponly_fst_cnt--; |
| //PR_INF("%s:%d\n", __func__, |
| //pch->rsc_bypass.b.ponly_fst_cnt); |
| } |
| return 17; |
| } else if (is_progressive(di_buf->vframe)) { |
| if (ppre->is_bypass_all) { |
| ppre->input_size_change_flag = true; |
| ppre->source_change_flag = 1; |
| bclr(&pch->self_trig_mask, 29); |
| //ppre->field_count_for_cont = 0; |
| } |
| ppre->is_bypass_all = false; |
| if (ppre->prog_proc_type != 0x10 && |
| is_handle_prog_frame_as_interlace(vframe) && |
| is_progressive(vframe)) { |
| struct di_buf_s *di_buf_tmp = NULL; |
| #ifdef VFM_ORI |
| pvframe_in[di_buf->index] = NULL; |
| #else |
| di_buf->c.in = NULL; |
| #endif |
| di_buf->vframe->type &= |
| (~VIDTYPE_TYPEMASK); |
| di_buf->vframe->type |= |
| VIDTYPE_INTERLACE_TOP; |
| di_buf->post_proc_flag = 0; |
| |
| di_buf_tmp = di_que_out_to_di_buf(channel, QUE_IN_FREE); |
| if (dim_check_di_buf(di_buf_tmp, 10, channel)) { |
| recycle_vframe_type_pre(di_buf, channel); |
| PR_ERR("DI:no free in_buffer for progressive skip.\n"); |
| return 18; |
| } |
| |
| di_buf_tmp->vframe->private_data = di_buf_tmp; |
| di_buf_tmp->seq = ppre->in_seq; |
| ppre->in_seq++; |
| #ifdef VFM_ORI |
| pvframe_in[di_buf_tmp->index] = vframe; |
| #else |
| di_buf_tmp->c.in = nins; |
| #endif |
| memcpy(di_buf_tmp->vframe, vframe, |
| sizeof(vframe_t)); |
| ppre->di_inp_buf_next = di_buf_tmp; |
| di_buf_tmp->vframe->type &= |
| (~VIDTYPE_TYPEMASK); |
| di_buf_tmp->vframe->type |= |
| VIDTYPE_INTERLACE_BOTTOM; |
| di_buf_tmp->post_proc_flag = 0; |
| /*keep dec vf*/ |
| if (pch->ponly && dip_is_ponly_sct_mem(pch)) |
| di_buf_tmp->dec_vf_state = DI_BIT0; |
| else if (cfggch(pch, KEEP_DEC_VF) == 1) |
| di_buf_tmp->dec_vf_state = DI_BIT0; |
| else if ((cfggch(pch, KEEP_DEC_VF) == 2) && |
| (ppre->sgn_lv == EDI_SGN_4K)) |
| di_buf_tmp->dec_vf_state = DI_BIT0; |
| ppre->di_inp_buf = di_buf; |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s:%s[%d]>in_bf;%s[%d]>in_bf_next\n", |
| __func__, |
| vframe_type_name[di_buf->type], |
| di_buf->index, |
| vframe_type_name[di_buf_tmp->type], |
| di_buf_tmp->index); |
| #endif |
| if (!ppre->di_mem_buf_dup_p) { |
| ppre->di_mem_buf_dup_p = di_buf; |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s:set mem_buf to inp_buf\n", |
| __func__); |
| #endif |
| } |
| } else { |
| di_buf->post_proc_flag = 0; |
| if ((cfg_prog_proc & 0x40) || |
| ppre->force_interlace) |
| di_buf->post_proc_flag = 1; |
| |
| ppre->di_inp_buf = di_buf; |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s: %s[%d] => di_inp_buf\n", |
| __func__, |
| vframe_type_name[di_buf->type], |
| di_buf->index); |
| #endif |
| if (!ppre->di_mem_buf_dup_p) { |
| /* use n */ |
| ppre->di_mem_buf_dup_p = di_buf; |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s:set mem_buf to inp_buf\n", |
| __func__); |
| #endif |
| } |
| } |
| } else { |
| if (ppre->is_bypass_all) { |
| ppre->input_size_change_flag = true; |
| ppre->source_change_flag = 1; |
| //ppre->field_count_for_cont = 0; |
| } |
| ppre->is_bypass_all = false; |
| /*********************************/ |
| if (di_buf->vframe->width >= 1920 && |
| di_buf->vframe->height >= 1080) |
| flg_1080i = true; |
| else if ((di_buf->vframe->width == 720) && |
| (di_buf->vframe->height == 480)) |
| flg_480i = true; |
| /*********************************/ |
| |
| if (!ppre->di_chan2_buf_dup_p) { |
| ppre->field_count_for_cont = 0; |
| /* ignore contp2rd and contprd */ |
| } |
| di_buf->post_proc_flag = 1; |
| ppre->di_inp_buf = di_buf; |
| dim_print("%s: %s[%d] => di_inp_buf\n", __func__, |
| vframe_type_name[di_buf->type], |
| di_buf->index); |
| |
| if (!ppre->di_mem_buf_dup_p) {/* use n */ |
| ppre->di_mem_buf_dup_p = di_buf; |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s: set di_mem_buf to di_inp_buf\n", |
| __func__); |
| #endif |
| } |
| } |
| //dcntr_check(vframe); |
| dcntr_check(&ppre->vfm_cpy); |
| } |
| /*dim_dbg_pre_cnt(channel, "cfg");*/ |
| /* di_wr_buf */ |
| if (ppre->prog_proc_type == 0 && (VFMT_IS_I(ppre->cur_inp_type))) { |
| /* i */ |
| di_buf = get_di_buf_head(channel, QUEUE_LOCAL_FREE); |
| if (dim_check_di_buf(di_buf, 11, channel)) { |
| /* recycle_keep_buffer(); |
| * pr_dbg("%s:recycle keep buffer\n", __func__); |
| */ |
| recycle_vframe_type_pre(ppre->di_inp_buf, channel); |
| return 19; |
| } |
| queue_out(channel, di_buf);/*QUEUE_LOCAL_FREE*/ |
| if (ppre->prog_proc_type & 0x10) |
| di_buf->canvas_config_flag = 1; |
| else |
| di_buf->canvas_config_flag = 2; |
| di_buf->di_wr_linked_buf = NULL; |
| |
| if (dimp_get(edi_mp_bypass_post_state)) { |
| PR_INF("%s:no post buffer\n", __func__); |
| } else { |
| di_buf->di_buf_post = |
| di_que_out_to_di_buf(channel, QUE_POST_FREE); |
| if (!di_buf->di_buf_post) { |
| PR_ERR("%s:no post buf\n", __func__); |
| return 20; |
| } |
| if (ppre->input_size_change_flag) |
| di_buf->di_buf_post->trig_post_update = 1; |
| else |
| di_buf->di_buf_post->trig_post_update = 0; |
| di_buf->di_buf_post->c.src_is_i = true; |
| mem_resize_buf(pch, di_buf->di_buf_post); |
| dim_pqrpt_init(&di_buf->di_buf_post->pq_rpt); |
| if (dip_itf_is_ins(pch) && dim_dbg_new_int(2)) |
| dim_dbg_buffer2(di_buf->di_buf_post->c.buffer, |
| 3); |
| //dim_pqrpt_init(&di_buf->di_buf_post->pq_rpt); |
| } |
| |
| } else if (ppre->prog_proc_type == 2) { |
| /* p use 2 i buf */ |
| di_linked_buf_idx = peek_free_linked_buf(channel); |
| if (di_linked_buf_idx != -1) |
| di_buf = get_free_linked_buf(di_linked_buf_idx, |
| channel); |
| else |
| di_buf = NULL; |
| if (!di_buf) { |
| /* recycle_vframe_type_pre(di_pre_stru.di_inp_buf); |
| *save for next process |
| */ |
| //recycle_keep_buffer(channel); |
| ppre->di_inp_buf_next = ppre->di_inp_buf; |
| return 21; |
| } |
| di_buf->post_proc_flag = 0; |
| di_buf->di_wr_linked_buf->pre_ref_count = 0; |
| di_buf->di_wr_linked_buf->post_ref_count = 0; |
| di_buf->canvas_config_flag = 1; |
| di_buf->c.src_is_i = false; |
| #ifdef TEST_4K_NR |
| } else if (ppre->prog_proc_type == 0x10) { |
| /********************************************************/ |
| /* di_buf is local buf */ |
| //di_que_out_to_di_buf(channel, QUE_POST_FREE); |
| di_buf = pp_pst_2_local(pch); |
| if (dim_check_di_buf(di_buf, 17, channel)) { |
| //di_unlock_irqfiq_restore(irq_flag2); |
| return 22; |
| } |
| mem_resize_buf(pch, di_buf); |
| di_buf->post_proc_flag = 0; |
| di_buf->canvas_config_flag = 1; |
| di_buf->di_wr_linked_buf = NULL; |
| di_buf->c.src_is_i = false; |
| //if (dim_cfg_pre_nv21(0)) { |
| if (pch->ponly && dip_is_ponly_sct_mem(pch)) { |
| nv21_flg = 0; |
| di_buf->flg_nv21 = 0; |
| } else if ((cfggch(pch, POUT_FMT) == 1) || |
| (cfggch(pch, POUT_FMT) == 2)) { |
| nv21_flg = 1; /*nv21*/ |
| di_buf->flg_nv21 = cfggch(pch, POUT_FMT); |
| } else if ((cfggch(pch, POUT_FMT) == 5) && |
| (ppre->sgn_lv == EDI_SGN_4K)) { |
| nv21_flg = 1; /*nv21*/ |
| di_buf->flg_nv21 = 1; |
| } |
| /*keep dec vf*/ |
| //di_buf->dec_vf_state = DI_BIT0; |
| if (pch->ponly && dip_is_ponly_sct_mem(pch)) |
| ppre->di_inp_buf->dec_vf_state = DI_BIT0; |
| else if (cfggch(pch, KEEP_DEC_VF) == 1) |
| ppre->di_inp_buf->dec_vf_state = DI_BIT0; |
| else if ((cfggch(pch, KEEP_DEC_VF) == 2) && |
| (ppre->sgn_lv == EDI_SGN_4K)) |
| ppre->di_inp_buf->dec_vf_state = DI_BIT0; |
| |
| if ((dip_is_support_nv2110(channel)) && |
| (ppre->sgn_lv == EDI_SGN_4K)) |
| di_buf->afbce_out_yuv420_10 = 1; |
| else |
| di_buf->afbce_out_yuv420_10 = 0; |
| |
| if (ppre->input_size_change_flag) |
| di_buf->trig_post_update = 1; |
| else |
| di_buf->trig_post_update = 0; |
| #endif |
| } else { |
| di_buf = get_di_buf_head(channel, QUEUE_LOCAL_FREE); |
| if (dim_check_di_buf(di_buf, 11, channel)) { |
| /* recycle_keep_buffer(); |
| * pr_dbg("%s:recycle keep buffer\n", __func__); |
| */ |
| recycle_vframe_type_pre(ppre->di_inp_buf, channel); |
| return 23; |
| } |
| queue_out(channel, di_buf);/*QUEUE_LOCAL_FREE*/ |
| if (ppre->prog_proc_type & 0x10) |
| di_buf->canvas_config_flag = 1; |
| else |
| di_buf->canvas_config_flag = 2; |
| di_buf->di_wr_linked_buf = NULL; |
| } |
| |
| di_buf->afbc_sgn_cfg = 0; |
| di_buf->sgn_lv = ppre->sgn_lv; |
| ppre->di_wr_buf = di_buf; |
| ppre->di_wr_buf->pre_ref_count = 1; |
| #ifdef DBG_TEST_CRC_P |
| //if (ppre->di_wr_buf->blk_buf->flg.b.typ != EDIM_BLK_TYP_PSCT) |
| if (ppre->di_wr_buf->blk_buf && |
| ((ppre->di_wr_buf->blk_buf->flg.b.typ == EDIM_BLK_TYP_OLDI) || |
| (ppre->di_wr_buf->blk_buf->flg.b.typ == EDIM_BLK_TYP_OLDP))) |
| dbg_checkcrc(ppre->di_wr_buf, 2); //debug |
| #endif |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s: %s[%d] => di_wr_buf\n", __func__, |
| vframe_type_name[di_buf->type], di_buf->index); |
| if (di_buf->di_wr_linked_buf) |
| dim_print("%s: linked %s[%d] => di_wr_buf\n", __func__, |
| vframe_type_name[di_buf->di_wr_linked_buf->type], |
| di_buf->di_wr_linked_buf->index); |
| #endif |
| if (ppre->cur_inp_type & VIDTYPE_COMPRESS) { |
| ppre->di_inp_buf->vframe->width = |
| ppre->di_inp_buf->vframe->compWidth; |
| ppre->di_inp_buf->vframe->height = |
| ppre->di_inp_buf->vframe->compHeight; |
| } |
| |
| memcpy(di_buf->vframe, |
| ppre->di_inp_buf->vframe, sizeof(vframe_t)); |
| di_buf->dw_width_bk = cur_dw_width; |
| di_buf->dw_height_bk = cur_dw_height; |
| di_buf->vframe->private_data = di_buf; |
| di_buf->vframe->canvas0Addr = di_buf->nr_canvas_idx; |
| di_buf->vframe->canvas1Addr = di_buf->nr_canvas_idx; |
| //if (di_buf->vframe->width == 3840 && di_buf->vframe->height == 2160) |
| if (ppre->sgn_lv == EDI_SGN_4K) { |
| di_buf->is_4k = 1; |
| if (cfgg(BYPASS_MEM) == 2) { |
| ppre->is_bypass_mem = 1; |
| } else if (cfgg(BYPASS_MEM) == 3) { |
| if (IS_VDIN_SRC(pch->src_type)) |
| ppre->is_bypass_mem = 0; |
| else |
| ppre->is_bypass_mem = 1; |
| } else { |
| ppre->is_bypass_mem = 0; |
| } |
| } else { |
| di_buf->is_4k = 0; |
| } |
| |
| /* set vframe bit info */ |
| di_buf->vframe->bitdepth &= ~(BITDEPTH_YMASK); |
| di_buf->vframe->bitdepth &= ~(FULL_PACK_422_MODE); |
| /* pps auto */ |
| if (de_devp->pps_enable & DI_BIT1) { |
| if (VFMT_IS_I(ppre->cur_inp_type)) |
| dimp_set(edi_mp_pps_position, 0); |
| else |
| dimp_set(edi_mp_pps_position, 1); |
| } |
| if (de_devp->pps_enable && dimp_get(edi_mp_pps_position)) { |
| if (dimp_get(edi_mp_pps_dstw) != di_buf->vframe->width) { |
| di_buf->vframe->width = dimp_get(edi_mp_pps_dstw); |
| ppre->width_bk = dimp_get(edi_mp_pps_dstw); |
| } |
| if (dimp_get(edi_mp_pps_dsth) != di_buf->vframe->height) |
| di_buf->vframe->height = dimp_get(edi_mp_pps_dsth); |
| } else if (de_devp->h_sc_down_en) { |
| if (di_mp_uit_get(edi_mp_pre_hsc_down_width) |
| != di_buf->vframe->width) { |
| pr_info("di: hscd %d to %d\n", di_buf->vframe->width, |
| di_mp_uit_get(edi_mp_pre_hsc_down_width)); |
| di_buf->vframe->width = |
| di_mp_uit_get(edi_mp_pre_hsc_down_width); |
| /*di_pre_stru.width_bk = pre_hsc_down_width;*/ |
| ppre->width_bk = |
| di_mp_uit_get(edi_mp_pre_hsc_down_width); |
| } |
| } |
| if (dimp_get(edi_mp_di_force_bit_mode) == 10) { |
| di_buf->vframe->bitdepth |= (BITDEPTH_Y10); |
| if (dimp_get(edi_mp_full_422_pack)) |
| di_buf->vframe->bitdepth |= (FULL_PACK_422_MODE); |
| } else { |
| di_buf->vframe->bitdepth |= (BITDEPTH_Y8); |
| } |
| di_buf->width_bk = ppre->width_bk; /*ary:2019-04-23*/ |
| di_buf->field_count = ppre->field_count_for_cont; |
| if (ppre->prog_proc_type) { |
| if ((ppre->prog_proc_type != 0x10) || |
| ((ppre->prog_proc_type == 0x10) && (!nv21_flg))) |
| di_buf->vframe->type = VIDTYPE_PROGRESSIVE | |
| VIDTYPE_VIU_422 | |
| VIDTYPE_VIU_SINGLE_PLANE | |
| VIDTYPE_VIU_FIELD; |
| if (ppre->cur_inp_type & VIDTYPE_PRE_INTERLACE) |
| di_buf->vframe->type |= VIDTYPE_PRE_INTERLACE; |
| |
| if (pch->ponly && dip_is_ponly_sct_mem(pch)) { |
| if (dim_afds() && dim_afds()->cnt_sgn_mode) { |
| if (IS_COMP_MODE |
| (ppre->di_inp_buf->vframe->type)) { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode |
| (AFBC_SGN_P_H265); |
| } else { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode(AFBC_SGN_P); |
| } |
| } |
| } else if (ppre->prog_proc_type == 0x10 && |
| (nv21_flg || |
| (cfggch(pch, POUT_FMT) == 0) || |
| (((cfggch(pch, POUT_FMT) == 4) || |
| (cfggch(pch, POUT_FMT) == 5) || |
| (cfggch(pch, POUT_FMT) == 6)) && |
| (ppre->sgn_lv <= EDI_SGN_HD)))) { |
| if (dim_afds() && dim_afds()->cnt_sgn_mode) { |
| if (IS_COMP_MODE |
| (ppre->di_inp_buf->vframe->type)) { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode |
| (AFBC_SGN_P_H265_AS_P); |
| if (ppre->di_inp_buf == |
| ppre->di_mem_buf_dup_p) { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode |
| (AFBC_SGN_H265_SINP); |
| } |
| } else { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode |
| (AFBC_SGN_BYPSS); |
| } |
| } |
| } else { |
| if (dim_afds() && dim_afds()->cnt_sgn_mode) { |
| if (IS_COMP_MODE |
| (ppre->di_inp_buf->vframe->type)) { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode |
| (AFBC_SGN_P_H265); |
| } else { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode(AFBC_SGN_P); |
| } |
| } |
| } |
| if (nv21_flg && ppre->prog_proc_type == 0x10) { |
| dim_print("cfg wr buf as nv21\n"); |
| //if (dip_itf_is_ins_exbuf(pch)) { |
| if (cfggch(pch, POUT_FMT) == 1) |
| tmpmode = EDPST_OUT_MODE_NV21; |
| else |
| tmpmode = EDPST_OUT_MODE_NV12; |
| dimpst_fill_outvf(di_buf->vframe, |
| di_buf, tmpmode); |
| //} else { |
| // dimpst_fill_outvf(di_buf->vframe, |
| // di_buf, EDPST_OUT_MODE_NV21); |
| //} |
| } |
| } else { |
| if (((ppre->di_inp_buf->vframe->type & |
| VIDTYPE_TYPEMASK) == |
| VIDTYPE_INTERLACE_TOP)) |
| di_buf->vframe->type = VIDTYPE_INTERLACE_TOP | |
| VIDTYPE_VIU_422 | |
| VIDTYPE_VIU_SINGLE_PLANE | |
| VIDTYPE_VIU_FIELD; |
| else |
| di_buf->vframe->type = VIDTYPE_INTERLACE_BOTTOM | |
| VIDTYPE_VIU_422 | |
| VIDTYPE_VIU_SINGLE_PLANE | |
| VIDTYPE_VIU_FIELD; |
| /*add for vpp skip line ref*/ |
| if (di_bypass_state_get(channel) == 0) |
| di_buf->vframe->type |= VIDTYPE_PRE_INTERLACE; |
| |
| if (VFMT_IS_I(ppre->cur_inp_type)) |
| di_buf->afbc_info |= DI_BIT1;/*flg is real i */ |
| #ifdef HIS_CODE |
| if (DIM_IS_IC_EF(SC2) && dim_afds() && |
| dim_afds()->cnt_sgn_mode) { |
| if (IS_COMP_MODE(ppre->di_inp_buf->vframe->type)) { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode(AFBC_SGN_I_H265); |
| } else { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode(AFBC_SGN_I); |
| } |
| } else if (dim_afds() && dim_afds()->cnt_sgn_mode) { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode(AFBC_SGN_BYPSS); |
| } |
| #else |
| if (dim_afds()) { |
| if (dim_afds()->is_sts(EAFBC_EN_6CH)) { |
| if (IS_COMP_MODE(ppre->di_inp_buf->vframe->type)) { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode(AFBC_SGN_I_H265); |
| } else { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode(AFBC_SGN_I); |
| } |
| if (cfggch(pch, IOUT_FMT) != 3) //afbce |
| dim_afds()->sgn_mode_set(&di_buf->afbc_sgn_cfg, |
| EAFBC_SNG_CLR_WR); |
| } else { |
| di_buf->afbc_sgn_cfg = |
| dim_afds()->cnt_sgn_mode(AFBC_SGN_BYPSS); |
| if (cfggch(pch, IOUT_FMT) == 3) |
| dim_afds()->sgn_mode_set(&di_buf->afbc_sgn_cfg, |
| EAFBC_SNG_SET_WR); |
| } |
| } |
| #endif |
| } |
| |
| if (is_bypass_post(channel)) { |
| if (dimp_get(edi_mp_bypass_post_state) == 0) |
| ppre->source_change_flag = 1; |
| |
| dimp_set(edi_mp_bypass_post_state, 1); |
| } else { |
| if (dimp_get(edi_mp_bypass_post_state)) |
| ppre->source_change_flag = 1; |
| |
| dimp_set(edi_mp_bypass_post_state, 0); |
| } |
| |
| if (ppre->di_inp_buf->post_proc_flag == 0) { |
| ppre->madi_enable = 0; |
| ppre->mcdi_enable = 0; |
| di_buf->post_proc_flag = 0; |
| dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER, false); |
| } else if (dimp_get(edi_mp_bypass_post_state)) { |
| ppre->madi_enable = 0; |
| ppre->mcdi_enable = 0; |
| di_buf->post_proc_flag = 0; |
| dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER, false); |
| } else { |
| ppre->madi_enable = (dimp_get(edi_mp_pre_enable_mask) & 1); |
| ppre->mcdi_enable = |
| ((dimp_get(edi_mp_pre_enable_mask) >> 1) & 1); |
| di_buf->post_proc_flag = 1; |
| dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER, |
| dimp_get(edi_mp_mcpre_en));/*en*/ |
| } |
| if (ppre->di_mem_buf_dup_p == ppre->di_wr_buf || |
| ppre->di_chan2_buf_dup_p == ppre->di_wr_buf) { |
| pr_dbg("+++++++++++++++++++++++\n"); |
| if (recovery_flag == 0) |
| recovery_log_reason = 12; |
| |
| recovery_flag++; |
| |
| return 24; |
| } |
| if (is_meson_tl1_cpu() && |
| ppre->comb_mode && |
| flg_1080i) { |
| ppre->combing_fix_en = false; |
| get_ops_mtn()->fix_tl1_1080i_patch_sel(ppre->comb_mode); |
| } else { |
| ppre->combing_fix_en = di_mpr(combing_fix_en); |
| } |
| |
| if (ppre->combing_fix_en) { |
| if (flg_1080i) |
| get_ops_mtn()->com_patch_pre_sw_set(1); |
| else if (flg_480i) |
| get_ops_mtn()->com_patch_pre_sw_set(2); |
| else |
| get_ops_mtn()->com_patch_pre_sw_set(0); |
| } |
| return 0; /*ok*/ |
| } |
| |
| int dim_check_recycle_buf(unsigned int channel) |
| { |
| struct di_buf_s *di_buf = NULL;/* , *ptmp; */ |
| struct di_buf_s *tmp; |
| int itmp; |
| int ret = 0; |
| struct div2_mm_s *mm; |
| struct di_ch_s *pch = get_chdata(channel); |
| #ifdef DI_BUFFER_DEBUG |
| int type; |
| int index; |
| #endif |
| #ifdef VFM_ORI |
| struct vframe_s **pvframe_in = get_vframe_in(channel); |
| #else |
| struct dim_nins_s *ins = NULL; |
| #endif |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| |
| mm = dim_mm_get(channel); |
| if (di_blocking) |
| return ret; |
| queue_for_each_entry(di_buf, channel, QUEUE_RECYCLE, list) { |
| if (di_buf->pre_ref_count == 0 && |
| di_buf->post_ref_count <= 0) { /*ary maybe <=*/ |
| if (di_buf->type == VFRAME_TYPE_IN) { |
| queue_out(channel, di_buf); |
| #ifdef VFM_ORI |
| if (pvframe_in[di_buf->index]) { |
| pw_vf_put(pvframe_in[di_buf->index], |
| channel); |
| pw_vf_notify_provider |
| (channel, |
| VFRAME_EVENT_RECEIVER_PUT, |
| NULL); |
| dim_print("%s:ch[%d]:idx[%d]\n", |
| __func__, channel, |
| di_buf->index); |
| dim_print("vfpt(%d)0x%p,%ums\n", |
| ppre->recycle_seq, |
| pvframe_in[di_buf->index], |
| jiffies_to_msecs(jiffies_64 - |
| pvframe_in[di_buf->index]-> |
| ready_jiffies64)); |
| pvframe_in[di_buf->index] = NULL; |
| } |
| #else |
| if (di_buf->c.in) { |
| ins = (struct dim_nins_s *)di_buf->c.in; |
| nins_used_some_to_recycle(pch, ins); |
| di_buf->c.in = NULL; |
| } |
| #endif |
| di_buf->invert_top_bot_flag = 0; |
| di_buf->dec_vf_state = 0; |
| di_que_in(channel, QUE_IN_FREE, di_buf); |
| ppre->recycle_seq++; |
| ret |= 1; |
| } else { |
| queue_out(channel, di_buf); |
| di_buf->invert_top_bot_flag = 0; |
| di_buf->afbc_sgn_cfg = 0; |
| di_buf->flg_nr = 0; |
| di_buf->flg_nv21 = 0; |
| di_buf->afbce_out_yuv420_10 = 0; |
| di_buf->post_ref_count = 0;/*ary maybe*/ |
| if (mm->cfg.num_local == 0) { |
| if (di_buf->iat_buf) { |
| qiat_in_ready(pch, |
| (struct dim_iat_s *)di_buf->iat_buf); |
| di_buf->iat_buf = NULL; |
| } |
| mem_release_one_inused(pch, |
| di_buf->blk_buf); |
| di_buf->blk_buf = NULL; |
| di_que_in(channel, |
| QUE_PRE_NO_BUF, di_buf); |
| } else { |
| if (di_buf->di_wr_linked_buf) { |
| tmp = di_buf->di_wr_linked_buf; |
| queue_in(channel, |
| tmp, |
| QUEUE_LOCAL_FREE); |
| |
| di_buf->di_wr_linked_buf = NULL; |
| } |
| queue_in(channel, |
| di_buf, QUEUE_LOCAL_FREE); |
| } |
| ret |= 2; |
| } |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s: recycle %s[%d]\n", __func__, |
| vframe_type_name[di_buf->type], |
| di_buf->index); |
| #endif |
| } |
| } |
| return ret; |
| } |
| |
| #ifdef DET3D |
| static void set3d_view(enum tvin_trans_fmt trans_fmt, struct vframe_s *vf) |
| { |
| struct vframe_view_s *left_eye, *right_eye; |
| |
| left_eye = &vf->left_eye; |
| right_eye = &vf->right_eye; |
| |
| switch (trans_fmt) { |
| case TVIN_TFMT_3D_DET_LR: |
| case TVIN_TFMT_3D_LRH_OLOR: |
| left_eye->start_x = 0; |
| left_eye->start_y = 0; |
| left_eye->width = vf->width >> 1; |
| left_eye->height = vf->height; |
| right_eye->start_x = vf->width >> 1; |
| right_eye->start_y = 0; |
| right_eye->width = vf->width >> 1; |
| right_eye->height = vf->height; |
| break; |
| case TVIN_TFMT_3D_DET_TB: |
| case TVIN_TFMT_3D_TB: |
| left_eye->start_x = 0; |
| left_eye->start_y = 0; |
| left_eye->width = vf->width; |
| left_eye->height = vf->height >> 1; |
| right_eye->start_x = 0; |
| right_eye->start_y = vf->height >> 1; |
| right_eye->width = vf->width; |
| right_eye->height = vf->height >> 1; |
| break; |
| case TVIN_TFMT_3D_DET_INTERLACE: |
| left_eye->start_x = 0; |
| left_eye->start_y = 0; |
| left_eye->width = vf->width; |
| left_eye->height = vf->height >> 1; |
| right_eye->start_x = 0; |
| right_eye->start_y = 0; |
| right_eye->width = vf->width; |
| right_eye->height = vf->height >> 1; |
| break; |
| case TVIN_TFMT_3D_DET_CHESSBOARD: |
| /*** |
| * LRLRLR LRLRLR |
| * LRLRLR or RLRLRL |
| * LRLRLR LRLRLR |
| * LRLRLR RLRLRL |
| */ |
| break; |
| default: /* 2D */ |
| left_eye->start_x = 0; |
| left_eye->start_y = 0; |
| left_eye->width = 0; |
| left_eye->height = 0; |
| right_eye->start_x = 0; |
| right_eye->start_y = 0; |
| right_eye->width = 0; |
| right_eye->height = 0; |
| break; |
| } |
| } |
| |
| /* |
| * static int get_3d_info(struct vframe_s *vf) |
| * { |
| * int ret = 0; |
| * |
| * vf->trans_fmt = det3d_fmt_detect(); |
| * pr_dbg("[det3d..]new 3d fmt: %d\n", vf->trans_fmt); |
| * |
| * vdin_set_view(vf->trans_fmt, vf); |
| * |
| * return ret; |
| * } |
| */ |
| static unsigned int det3d_frame_cnt = 50; |
| module_param_named(det3d_frame_cnt, det3d_frame_cnt, uint, 0644); |
| static void det3d_irq(unsigned int channel) |
| { |
| unsigned int data32 = 0, likely_val = 0; |
| unsigned long frame_sum = 0; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| |
| if (!dimp_get(edi_mp_det3d_en)) |
| return; |
| |
| data32 = get_ops_3d()->det3d_fmt_detect();/*det3d_fmt_detect();*/ |
| switch (data32) { |
| case TVIN_TFMT_3D_DET_LR: |
| case TVIN_TFMT_3D_LRH_OLOR: |
| ppre->det_lr++; |
| break; |
| case TVIN_TFMT_3D_DET_TB: |
| case TVIN_TFMT_3D_TB: |
| ppre->det_tp++; |
| break; |
| case TVIN_TFMT_3D_DET_INTERLACE: |
| ppre->det_la++; |
| break; |
| default: |
| ppre->det_null++; |
| break; |
| } |
| |
| if (det3d_mode != data32) { |
| det3d_mode = data32; |
| dim_print("[det3d..]new 3d fmt: %d\n", det3d_mode); |
| } |
| if (frame_count > 20) { |
| frame_sum = ppre->det_lr + ppre->det_tp |
| + ppre->det_la |
| + ppre->det_null; |
| if ((frame_count % det3d_frame_cnt) || frame_sum > UINT_MAX) |
| return; |
| likely_val = max3(ppre->det_lr, |
| ppre->det_tp, |
| ppre->det_la); |
| if (ppre->det_null >= likely_val) |
| det3d_mode = 0; |
| else if (likely_val == ppre->det_lr) |
| det3d_mode = TVIN_TFMT_3D_LRH_OLOR; |
| else if (likely_val == ppre->det_tp) |
| det3d_mode = TVIN_TFMT_3D_TB; |
| else |
| det3d_mode = TVIN_TFMT_3D_DET_INTERLACE; |
| ppre->det3d_trans_fmt = det3d_mode; |
| } else { |
| ppre->det3d_trans_fmt = 0; |
| } |
| } |
| #endif |
| |
| static unsigned int ro_mcdi_col_cfd[26]; |
| static void get_mcinfo_from_reg_in_irq(unsigned int channel) |
| { |
| unsigned int i = 0, ncolcrefsum = 0, blkcount = 0, *reg = NULL; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| struct di_buf_s *wr_buf; |
| |
| wr_buf = ppre->di_wr_buf; |
| |
| if (!wr_buf) { |
| PR_ERR("%s:no di_wr_buf\n", __func__); |
| return; |
| } |
| |
| /*get info for current field process by post*/ |
| wr_buf->curr_field_mcinfo.highvertfrqflg = |
| (RD(MCDI_RO_HIGH_VERT_FRQ_FLG) & 0x1); |
| /* post:MCDI_MC_REL_GAIN_OFFST_0 */ |
| wr_buf->curr_field_mcinfo.motionparadoxflg = |
| (RD(MCDI_RO_MOTION_PARADOX_FLG) & 0x1); |
| /* post:MCDI_MC_REL_GAIN_OFFST_0 */ |
| reg = wr_buf->curr_field_mcinfo.regs; |
| for (i = 0; i < 26; i++) { |
| ro_mcdi_col_cfd[i] = RD(0x2fb0 + i); |
| wr_buf->curr_field_mcinfo.regs[i] = 0; |
| if (!dimp_get(edi_mp_calc_mcinfo_en)) |
| *(reg + i) = ro_mcdi_col_cfd[i]; |
| } |
| if (dimp_get(edi_mp_calc_mcinfo_en)) { |
| blkcount = (ppre->cur_width + 4) / 5; |
| for (i = 0; i < blkcount; i++) { |
| ncolcrefsum += |
| ((ro_mcdi_col_cfd[i / 32] >> (i % 32)) & 0x1); |
| if (((ncolcrefsum + (blkcount >> 1)) << 8) / |
| blkcount > dimp_get(edi_mp_colcfd_thr)) |
| for (i = 0; i < blkcount; i++) |
| *(reg + i / 32) += (1 << (i % 32)); |
| } |
| } |
| } |
| |
| static unsigned int bit_reverse(unsigned int val) |
| { |
| unsigned int i = 0, res = 0; |
| |
| for (i = 0; i < 16; i++) { |
| res |= (((val & (1 << i)) >> i) << (31 - i)); |
| res |= (((val & (1 << (31 - i))) << i) >> (31 - i)); |
| } |
| return res; |
| } |
| |
| static void set_post_mcinfo(struct mcinfo_pre_s *curr_field_mcinfo) |
| { |
| unsigned int i = 0, value = 0; |
| |
| DIM_VSC_WR_MPG_BT(MCDI_MC_REL_GAIN_OFFST_0, |
| curr_field_mcinfo->highvertfrqflg, 24, 1); |
| DIM_VSC_WR_MPG_BT(MCDI_MC_REL_GAIN_OFFST_0, |
| curr_field_mcinfo->motionparadoxflg, 25, 1); |
| for (i = 0; i < 26; i++) { |
| if (overturn) |
| value = bit_reverse(curr_field_mcinfo->regs[i]); |
| else |
| value = curr_field_mcinfo->regs[i]; |
| DIM_VSYNC_WR_MPEG_REG(0x2f78 + i, value); |
| } |
| } |
| |
| static unsigned char intr_mode; |
| |
| irqreturn_t dim_irq(int irq, void *dev_instance) |
| { |
| unsigned int channel; |
| struct di_pre_stru_s *ppre; |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| struct di_hpre_s *pre = get_hw_pre(); |
| |
| #ifndef CHECK_DI_DONE |
| unsigned int data32 = RD(DI_INTR_CTRL); |
| unsigned int mask32 = (data32 >> 16) & 0x3ff; |
| unsigned int flag = 0; |
| |
| if (!sc2_dbg_is_en_pre_irq()) { |
| sc2_dbg_pre_info(data32); |
| return IRQ_HANDLED; |
| } |
| di_lock_irq(); //2020-12-10 |
| channel = pre->curr_ch; |
| ppre = pre->pres; |
| |
| data32 &= 0x3fffffff; |
| if ((data32 & 1) == 0 && dimp_get(edi_mp_di_dbg_mask) & 8) |
| pr_info("irq[%d]pre|post=0 write done.\n", irq); |
| if (ppre->pre_de_busy) { |
| /* only one inetrrupr mask should be enable */ |
| if ((data32 & 2) && !(mask32 & 2)) { |
| dim_print("irq pre MTNWR ==ch[%d]\n", channel); |
| flag = 1; |
| } else if ((data32 & 1) && !(mask32 & 1)) { |
| dim_print("irq pre NRWR ==ch[%d]\n", channel); |
| flag = 1; |
| } else { |
| dim_print("irq pre DI IRQ 0x%x ==\n", data32); |
| flag = 0; |
| } |
| } |
| |
| #else |
| di_lock_irq(); //2020-12-10 |
| channel = pre->curr_ch; |
| ppre = pre->pres; |
| #endif |
| |
| if (flag) { |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pre_gl_sw(false); |
| else |
| hpre_gl_sw(false); |
| DIM_DI_WR(DI_INTR_CTRL, |
| (data32 & 0xfffffffb) | (intr_mode << 30)); |
| } |
| |
| /*if (ppre->pre_de_busy == 0) {*/ |
| /*if (!di_pre_wait_irq_get()) {*/ |
| if (flag && (!atomic_dec_and_test(&get_hw_pre()->flg_wait_int))) { |
| PR_ERR("%s:ch[%d]:enter:reg[0x%x]= 0x%x,dtab[%d]\n", __func__, |
| channel, |
| DI_INTR_CTRL, |
| RD(DI_INTR_CTRL), |
| pre->sdt_mode.op_crr); |
| di_unlock_irq(); //2020-12-10 |
| return IRQ_HANDLED; |
| } |
| |
| if (flag) { |
| ppre->irq_time[0] = |
| (cur_to_msecs() - ppre->irq_time[0]); |
| |
| dim_tr_ops.pre(ppre->field_count_for_cont, ppre->irq_time[0]); |
| |
| /*add from valsi wang.feng*/ |
| if (!dim_dbg_cfg_disable_arb()) { |
| dim_arb_sw(false); |
| dim_arb_sw(true); |
| dbg_ic("arb reset\n"); |
| } else { |
| dbg_ic("arb not reset\n"); |
| } |
| if (dimp_get(edi_mp_mcpre_en)) { |
| get_mcinfo_from_reg_in_irq(channel); |
| if ((is_meson_gxlx_cpu() && |
| ppre->field_count_for_cont >= 4) || |
| is_meson_txhd_cpu()) |
| dimh_mc_pre_mv_irq(); |
| dimh_calc_lmv_base_mcinfo((ppre->cur_height >> 1), |
| ppre->di_wr_buf->mcinfo_adr_v, |
| /*ppre->mcinfo_size*/0); |
| } |
| get_ops_nr()->nr_process_in_irq(); |
| if ((data32 & 0x200) && de_devp->nrds_enable) |
| dim_nr_ds_irq(); |
| /* disable mif */ |
| dimh_enable_di_pre_mif(false, dimp_get(edi_mp_mcpre_en)); |
| dcntr_dis(); |
| |
| ppre->pre_de_busy = 0; |
| |
| if (get_init_flag(channel)) |
| /* pr_dbg("%s:up di sema\n", __func__); */ |
| task_send_ready(); |
| |
| pre->flg_int_done = 1; |
| } |
| di_unlock_irq(); //2020-12-10 |
| return IRQ_HANDLED; |
| } |
| |
| irqreturn_t dim_post_irq(int irq, void *dev_instance) |
| { |
| unsigned int data32 = RD(DI_INTR_CTRL); |
| unsigned int channel; |
| struct di_post_stru_s *ppost; |
| struct di_hpst_s *pst = get_hw_pst(); |
| bool flg_right = false; |
| |
| if (!sc2_dbg_is_en_pst_irq()) { |
| sc2_dbg_pst_info(data32); |
| return IRQ_HANDLED; |
| } |
| |
| channel = pst->curr_ch; |
| ppost = pst->psts; |
| |
| data32 &= 0x3fffffff; |
| if ((data32 & 4) == 0) { |
| if (dimp_get(edi_mp_di_dbg_mask) & 8) |
| pr_info("irq[%d]post write undone.\n", irq); |
| return IRQ_HANDLED; |
| } |
| if ((pst->state == EDI_PST_ST_SET) && pst->flg_have_set) |
| flg_right = true; |
| |
| if ((pst->state != EDI_PST_ST_WAIT_INT) && |
| (!pst->pst_tst_use) && |
| (!flg_right)) { |
| PR_ERR("%s:ch[%d]:s[%d]\n", __func__, channel, pst->state); |
| ddbg_sw(EDI_LOG_TYPE_MOD, false); |
| return IRQ_HANDLED; |
| } |
| dim_ddbg_mod_save(EDI_DBG_MOD_POST_IRQB, pst->curr_ch, |
| ppost->frame_cnt); |
| dim_tr_ops.post_ir(0); |
| |
| if ((dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) && |
| (data32 & 0x4)) { |
| ppost->de_post_process_done = 1; |
| ppost->post_de_busy = 0; |
| ppost->irq_time = |
| (cur_to_msecs() - ppost->irq_time); |
| |
| dim_tr_ops.post(ppost->post_wr_cnt, ppost->irq_time); |
| |
| DIM_DI_WR(DI_INTR_CTRL, |
| (data32 & 0xffff0004) | (intr_mode << 30)); |
| |
| /* disable wr back avoid pps sreay in g12a */ |
| /* dim_DI_Wr_reg_bits(DI_POST_CTRL, 0, 7, 1); */ |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pst_set_flow(1, EDI_POST_FLOW_STEP3_IRQ); |
| else |
| di_post_set_flow(1, EDI_POST_FLOW_STEP3_IRQ); |
| dim_print("irq p ch[%d]done\n", channel); |
| pst->flg_int_done = true; |
| pst->flg_have_set = false; |
| } |
| dim_ddbg_mod_save(EDI_DBG_MOD_POST_IRQE, pst->curr_ch, |
| ppost->frame_cnt); |
| |
| if (get_init_flag(channel)) |
| task_send_ready(); |
| |
| return IRQ_HANDLED; |
| } |
| |
| /* |
| * di post process |
| */ |
| static void inc_post_ref_count(struct di_buf_s *di_buf) |
| { |
| int i; /*debug only:*/ |
| |
| /* int post_blend_mode; */ |
| if (IS_ERR_OR_NULL(di_buf)) { |
| PR_ERR("%s:\n", __func__); |
| if (recovery_flag == 0) |
| recovery_log_reason = 13; |
| |
| recovery_flag++; |
| return; |
| } |
| |
| if (di_buf->di_buf_dup_p[1]) |
| di_buf->di_buf_dup_p[1]->post_ref_count++; |
| |
| if (di_buf->di_buf_dup_p[0]) |
| di_buf->di_buf_dup_p[0]->post_ref_count++; |
| |
| if (di_buf->di_buf_dup_p[2]) |
| di_buf->di_buf_dup_p[2]->post_ref_count++; |
| |
| /*debug only:*/ |
| for (i = 0; i < 3; i++) { |
| if (di_buf->di_buf_dup_p[i]) |
| dbg_post_ref("%s:pst_buf[%d],dup_p[%d],pref[%d]\n", |
| __func__, |
| di_buf->index, |
| i, |
| di_buf->di_buf_dup_p[i]->post_ref_count); |
| } |
| } |
| |
| static void dec_post_ref_count(struct di_buf_s *di_buf) |
| { |
| int i; /*debug only:*/ |
| |
| if (IS_ERR_OR_NULL(di_buf)) { |
| PR_ERR("%s:\n", __func__); |
| if (recovery_flag == 0) |
| recovery_log_reason = 14; |
| |
| recovery_flag++; |
| return; |
| } |
| if (di_buf->pd_config.global_mode == PULL_DOWN_BUF1) |
| return; |
| if (di_buf->di_buf_dup_p[1]) |
| di_buf->di_buf_dup_p[1]->post_ref_count--; |
| |
| if (di_buf->di_buf_dup_p[0] && |
| di_buf->di_buf_dup_p[0]->post_proc_flag != -2) |
| di_buf->di_buf_dup_p[0]->post_ref_count--; |
| |
| if (di_buf->di_buf_dup_p[2]) |
| di_buf->di_buf_dup_p[2]->post_ref_count--; |
| |
| /*debug only:*/ |
| for (i = 0; i < 3; i++) { |
| if (di_buf->di_buf_dup_p[i]) |
| dbg_post_ref("%s:pst_buf[%d],dup_p[%d],pref[%d]\n", |
| __func__, |
| di_buf->index, |
| i, |
| di_buf->di_buf_dup_p[i]->post_ref_count); |
| } |
| } |
| |
| /*early_process_fun*/ |
| static int early_NONE(void) |
| { |
| return 0; |
| } |
| |
| int dim_do_post_wr_fun(void *arg, vframe_t *disp_vf) |
| { |
| |
| return early_NONE(); |
| } |
| |
| static int de_post_disable_fun(void *arg, vframe_t *disp_vf) |
| { |
| |
| return early_NONE(); |
| } |
| |
| static int do_nothing_fun(void *arg, vframe_t *disp_vf) |
| { |
| return early_NONE(); |
| } |
| |
| static int do_pre_only_fun(void *arg, vframe_t *disp_vf) |
| { |
| |
| return early_NONE(); |
| } |
| |
| static void get_vscale_skip_count(unsigned int par) |
| { |
| /*di_vscale_skip_count_real = (par >> 24) & 0xff;*/ |
| dimp_set(edi_mp_di_vscale_skip_real, |
| (par >> 24) & 0xff); |
| } |
| |
| #define get_vpp_reg_update_flag(par) (((par) >> 16) & 0x1) |
| |
| static unsigned int pldn_dly = 1; |
| |
| /****************************************** |
| * |
| ******************************************/ |
| |
| #ifdef DIM_OUT_NV21 |
| |
| static unsigned int cfg_nv21/* = DI_BIT0*/; |
| module_param_named(cfg_nv21, cfg_nv21, uint, 0664); |
| |
| #ifdef NV21_DBG |
| static unsigned int cfg_vf; |
| module_param_named(cfg_vf, cfg_vf, uint, 0664); |
| #endif |
| |
| unsigned int dim_cfg_nv21(void) |
| { |
| if (cfg_nv21 & DI_BIT0) |
| return 1; /* nv21 */ |
| else if (cfg_nv21 & DI_BIT5) |
| return 2; /* nv12 */ |
| else |
| return 0; |
| |
| return false; |
| } |
| |
| bool dim_cfg_pre_nv21(unsigned int cmd) |
| { |
| if (!cmd && (cfg_nv21 & DI_BIT8)) { /*nv21 */ |
| return true; |
| } else if (cmd && (cfg_nv21 & DI_BIT9)) { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| /********************************************************** |
| * canvans |
| * set vfm canvas by config | planes | index |
| * set vf->canvas0Addr |
| * |
| **********************************************************/ |
| static void dim_canvas_set2(struct vframe_s *vf, u32 *index) |
| { |
| int i; |
| u32 *canvas_index = index; |
| unsigned int shift; |
| struct canvas_config_s *cfg = &vf->canvas0_config[0]; |
| u32 planes = vf->plane_num; |
| |
| if (vf->canvas0Addr != ((u32)-1)) |
| return; |
| if (planes > 3) { |
| PR_ERR("%s:planes overflow[%d]\n", __func__, planes); |
| return; |
| } |
| dim_print("%s:p[%d]\n", __func__, planes); |
| |
| vf->canvas0Addr = 0; |
| for (i = 0; i < planes; i++, canvas_index++, cfg++) { |
| canvas_config_config(*canvas_index, cfg); |
| dim_print("\tw[%d],h[%d],cid[%d],0x%x\n", |
| cfg->width, cfg->height, |
| *canvas_index, cfg->phy_addr); |
| shift = 8 * i; |
| vf->canvas0Addr |= (*canvas_index << shift); |
| //vf->plane_num = planes; |
| } |
| } |
| |
| static void di_cnt_cvs_nv21(unsigned int mode, |
| unsigned int *h, |
| unsigned int *v, |
| unsigned int ch) |
| { |
| struct div2_mm_s *mm = dim_mm_get(ch); /*mm-0705*/ |
| int width = mm->cfg.di_w; |
| int height = mm->cfg.di_h; |
| int canvas_height = height + 8; |
| unsigned int nr_width = width; |
| unsigned int nr_canvas_width = width; |
| unsigned int canvas_align_width = 32; |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| canvas_align_width = 64; |
| |
| nr_width = width; |
| nr_canvas_width = nr_width;//nr_width << 1; |
| nr_canvas_width = roundup(nr_canvas_width, canvas_align_width); |
| *h = nr_canvas_width; |
| *v = canvas_height; |
| } |
| |
| /* @ary_note: use di_buf to fill vfm */ |
| static void dimpst_fill_outvf(struct vframe_s *vfm, |
| struct di_buf_s *di_buf, |
| enum EDPST_OUT_MODE mode) |
| { |
| struct canvas_config_s *cvsp, *cvsf; |
| unsigned int cvsh, cvsv, csize; |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| struct di_buffer *buffer; //for ext buff |
| unsigned int ch; |
| struct di_ch_s *pch; |
| bool ext_buf = false; |
| |
| //check ext buffer: |
| ch = di_buf->channel; |
| pch = get_chdata(ch); |
| |
| if (dip_itf_is_ins_exbuf(pch)) { |
| ext_buf = true; |
| if (!di_buf->c.buffer) { |
| PR_ERR("%s:ext_buf,no buffer\n", __func__); |
| return; |
| } |
| buffer = (struct di_buffer *)di_buf->c.buffer; |
| if (!buffer->vf) { |
| PR_ERR("%s:ext_buf,no vf\n", __func__); |
| return; |
| } |
| dim_print("%s:buffer %px\n", __func__, buffer); |
| cvsf = &buffer->vf->canvas0_config[0]; |
| } |
| // unsigned int tmp; |
| if (vfm != di_buf->vframe) //@ary_note |
| memcpy(vfm, di_buf->vframe, sizeof(*vfm)); |
| |
| /* canvas */ |
| vfm->canvas0Addr = (u32)-1; |
| |
| if (mode == EDPST_OUT_MODE_DEF) { |
| vfm->plane_num = 1; |
| cvsp = &vfm->canvas0_config[0]; |
| cvsp->phy_addr = di_buf->nr_adr; |
| cvsp->block_mode = 0; |
| cvsp->endian = 0; |
| cvsp->width = di_buf->canvas_width[NR_CANVAS]; |
| cvsp->height = di_buf->canvas_height; |
| } else { |
| vfm->plane_num = 2; |
| /* count canvs size */ |
| di_cnt_cvs_nv21(0, &cvsh, &cvsv, di_buf->channel); |
| /* 0 */ |
| cvsp = &vfm->canvas0_config[0]; |
| if (ext_buf) { |
| cvsp->phy_addr = cvsf->phy_addr; |
| cvsp->width = cvsf->width; |
| cvsp->height = cvsf->height; |
| } else { |
| cvsp->phy_addr = di_buf->nr_adr; |
| cvsp->width = cvsh; |
| cvsp->height = cvsv; |
| } |
| cvsp->block_mode = 0; |
| cvsp->endian = 0; |
| |
| csize = roundup((cvsh * cvsv), PAGE_SIZE); |
| /* 1 */ |
| cvsp = &vfm->canvas0_config[1]; |
| |
| if (ext_buf) { |
| cvsf = &buffer->vf->canvas0_config[1]; |
| cvsp->phy_addr = cvsf->phy_addr; |
| cvsp->width = cvsf->width; |
| cvsp->height = cvsf->height; |
| } else { |
| cvsp->phy_addr = di_buf->nr_adr + csize; |
| cvsp->width = cvsh; |
| cvsp->height = cvsv; |
| } |
| cvsp->block_mode = 0; |
| cvsp->endian = 0; |
| } |
| #ifdef CVS_UINT |
| dim_print("%s:%d:addr0[0x%x], 1[0x%x],w[%d,%d]\n", |
| __func__, |
| ext_buf, vfm->canvas0_config[0].phy_addr, |
| vfm->canvas0_config[1].phy_addr, |
| vfm->canvas0_config[0].width, |
| vfm->canvas0_config[0].height); |
| #else |
| dim_print("%s:%d:addr0[0x%lx], 1[0x%lx],w[%d,%d]\n", |
| __func__, |
| ext_buf, |
| vfm->canvas0_config[0].phy_addr, |
| vfm->canvas0_config[1].phy_addr, |
| vfm->canvas0_config[0].width, |
| vfm->canvas0_config[0].height); |
| #endif |
| /* type */ |
| if (mode == EDPST_OUT_MODE_NV21 || |
| mode == EDPST_OUT_MODE_NV12) { |
| /*clear*/ |
| vfm->type &= ~(VIDTYPE_VIU_NV12 | |
| VIDTYPE_VIU_444 | |
| VIDTYPE_VIU_NV21 | |
| VIDTYPE_VIU_422 | |
| VIDTYPE_VIU_SINGLE_PLANE | |
| VIDTYPE_COMPRESS | |
| VIDTYPE_PRE_INTERLACE); |
| vfm->type |= VIDTYPE_VIU_FIELD; |
| vfm->type |= VIDTYPE_DI_PW; |
| if (mode == EDPST_OUT_MODE_NV21) |
| vfm->type |= VIDTYPE_VIU_NV21; |
| else |
| vfm->type |= VIDTYPE_VIU_NV12; |
| |
| /* bit */ |
| vfm->bitdepth &= ~(BITDEPTH_MASK); |
| vfm->bitdepth &= ~(FULL_PACK_422_MODE); |
| vfm->bitdepth |= (BITDEPTH_Y8 | |
| BITDEPTH_U8 | |
| BITDEPTH_V8); |
| } |
| |
| if (de_devp->pps_enable && |
| dimp_get(edi_mp_pps_position) == 0) { |
| if (dimp_get(edi_mp_pps_dstw)) |
| vfm->width = dimp_get(edi_mp_pps_dstw); |
| |
| if (dimp_get(edi_mp_pps_dsth)) |
| vfm->height = dimp_get(edi_mp_pps_dsth); |
| } |
| |
| if (di_buf->afbc_info & DI_BIT0) |
| vfm->height = vfm->height / 2; |
| |
| //dim_print("%s:h[%d]\n", __func__, vfm->height); |
| #ifdef NV21_DBG |
| if (cfg_vf) |
| vfm->type = cfg_vf; |
| #endif |
| } |
| |
| #ifdef MARK_HIS |
| /* for exit buffer */ |
| /* only change addr */ |
| static void dimpst_fill_outvf_ext(struct vframe_s *vfm, |
| struct di_buf_s *di_buf, |
| enum EDPST_OUT_MODE mode) |
| { |
| struct canvas_config_s *cvsp, *cvsf; |
| unsigned int cvsh, cvsv, csize; |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| // unsigned int tmp; |
| struct di_buffer *buffer; //for ext buff |
| |
| if (!di_buf->c.buffer) { |
| PR_ERR("%s:no buffer\n", __func__); |
| return; |
| } |
| buffer = (struct di_buffer *)di_buf->c.buffer; |
| if (!buffer->vf) { |
| PR_ERR("%s:no buffer vf\n", __func__); |
| return; |
| } |
| if (vfm != di_buf->vframe) //@ary_note |
| memcpy(vfm, di_buf->vframe, sizeof(*vfm)); |
| |
| /* canvas */ |
| vfm->canvas0Addr = (u32)-1; |
| |
| if (mode == EDPST_OUT_MODE_DEF) { |
| vfm->plane_num = 1; |
| cvsp = &vfm->canvas0_config[0]; |
| cvsf = &buffer->vf->canvas0_config[0]; |
| cvsp->phy_addr = cvsf->phy_addr; |
| cvsp->block_mode = 0; |
| cvsp->endian = 0; |
| cvsp->width = di_buf->canvas_width[NR_CANVAS]; |
| cvsp->height = di_buf->canvas_height; |
| } else { |
| vfm->plane_num = 2; |
| /* count canvs size */ |
| di_cnt_cvs_nv21(0, &cvsh, &cvsv, di_buf->channel); |
| /* 0 */ |
| cvsp = &vfm->canvas0_config[0]; |
| cvsf = &buffer->vf->canvas0_config[0]; |
| cvsp->phy_addr = cvsf->phy_addr; |
| cvsp->block_mode = 0; |
| cvsp->endian = 0; |
| cvsp->width = cvsh; |
| cvsp->height = cvsv; |
| csize = roundup((cvsh * cvsv), PAGE_SIZE); |
| /* 1 */ |
| cvsp = &vfm->canvas0_config[1]; |
| cvsf = &buffer->vf->canvas0_config[1]; |
| cvsp->width = cvsh; |
| cvsp->height = cvsv; |
| cvsp->phy_addr = cvsf->phy_addr; |
| cvsp->block_mode = 0; |
| cvsp->endian = 0; |
| } |
| |
| /* type */ |
| if (mode == EDPST_OUT_MODE_NV21 || |
| mode == EDPST_OUT_MODE_NV12) { |
| /*clear*/ |
| vfm->type &= ~(VIDTYPE_VIU_NV12 | |
| VIDTYPE_VIU_444 | |
| VIDTYPE_VIU_NV21 | |
| VIDTYPE_VIU_422 | |
| VIDTYPE_VIU_SINGLE_PLANE | |
| VIDTYPE_COMPRESS | |
| VIDTYPE_PRE_INTERLACE); |
| vfm->type |= VIDTYPE_VIU_FIELD; |
| vfm->type |= VIDTYPE_DI_PW; |
| if (mode == EDPST_OUT_MODE_NV21) |
| vfm->type |= VIDTYPE_VIU_NV21; |
| else |
| vfm->type |= VIDTYPE_VIU_NV12; |
| |
| /* bit */ |
| vfm->bitdepth &= ~(BITDEPTH_MASK); |
| vfm->bitdepth &= ~(FULL_PACK_422_MODE); |
| vfm->bitdepth |= (BITDEPTH_Y8 | |
| BITDEPTH_U8 | |
| BITDEPTH_V8); |
| } |
| |
| if (de_devp->pps_enable && |
| dimp_get(edi_mp_pps_position) == 0) { |
| if (dimp_get(edi_mp_pps_dstw)) |
| vfm->width = dimp_get(edi_mp_pps_dstw); |
| |
| if (dimp_get(edi_mp_pps_dsth)) |
| vfm->height = dimp_get(edi_mp_pps_dsth); |
| } |
| |
| if (di_buf->afbc_info & DI_BIT0) |
| vfm->height = vfm->height / 2; |
| |
| dim_print("%s:h[%d]\n", __func__, vfm->height); |
| #ifdef NV21_DBG |
| if (cfg_vf) |
| vfm->type = cfg_vf; |
| #endif |
| } |
| #endif |
| |
| #if 1/* move to di_hw_v2.c */ |
| static void dim_cfg_s_mif(struct DI_SIM_MIF_s *smif, |
| struct vframe_s *vf, |
| struct di_win_s *win) |
| { |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| |
| //vframe_t *vf = di_buf->vframe; |
| |
| //smif->canvas_num = di_buf->nr_canvas_idx; |
| /* bit mode config */ |
| if (vf->bitdepth & BITDEPTH_Y10) { |
| if (vf->type & VIDTYPE_VIU_444) { |
| smif->bit_mode = (vf->bitdepth & FULL_PACK_422_MODE) ? |
| 3 : 2; |
| } else { |
| smif->bit_mode = (vf->bitdepth & FULL_PACK_422_MODE) ? |
| 3 : 1; |
| } |
| } else { |
| smif->bit_mode = 0; |
| } |
| |
| /* video mode */ |
| if (vf->type & VIDTYPE_VIU_444) |
| smif->video_mode = 1; |
| else |
| smif->video_mode = 0; |
| |
| /* separate */ |
| if (vf->type & VIDTYPE_VIU_422) |
| smif->set_separate_en = 0; |
| else |
| smif->set_separate_en = 2; /*nv12 ? nv 21?*/ |
| |
| /*x,y,*/ |
| |
| if (de_devp->pps_enable && |
| dimp_get(edi_mp_pps_position) == 0) { |
| //dim_pps_config(0, di_width, di_height, |
| // dimp_get(edi_mp_pps_dstw), |
| // dimp_get(edi_mp_pps_dsth)); |
| if (win) { |
| smif->start_x = win->x_st; |
| smif->end_x = win->x_st + |
| dimp_get(edi_mp_pps_dstw) - 1; |
| smif->start_y = win->y_st; |
| smif->end_y = win->y_st + |
| dimp_get(edi_mp_pps_dsth) - 1; |
| } else { |
| smif->start_x = 0; |
| smif->end_x = |
| dimp_get(edi_mp_pps_dstw) - 1; |
| smif->start_y = 0; |
| smif->end_y = |
| dimp_get(edi_mp_pps_dsth) - 1; |
| } |
| } else { |
| if (win) { |
| smif->start_x = win->x_st; |
| smif->end_x = win->x_st + win->x_size - 1; |
| smif->start_y = win->y_st; |
| smif->end_y = win->y_st + win->y_size - 1; |
| |
| } else { |
| smif->start_x = 0; |
| smif->end_x = vf->width - 1; |
| smif->start_y = 0; |
| smif->end_y = vf->height - 1; |
| } |
| } |
| } |
| #endif |
| void dbg_vfm(struct vframe_s *vf, unsigned int dbgpos) |
| { |
| int i; |
| struct canvas_config_s *cvsp; |
| |
| if (!(cfg_nv21 & DI_BIT1)) |
| return; |
| PR_INF("%d:type=0x%x\n", dbgpos, vf->type); |
| PR_INF("plane_num=0x%x\n", vf->plane_num); |
| PR_INF("0Addr=0x%x\n", vf->canvas0Addr); |
| PR_INF("1Addr=0x%x\n", vf->canvas1Addr); |
| PR_INF("plane_num=0x%x\n", vf->plane_num); |
| for (i = 0; i < vf->plane_num; i++) { |
| PR_INF("%d:\n", i); |
| cvsp = &vf->canvas0_config[i]; |
| #ifdef CVS_UINT |
| PR_INF("\tph=0x%x\n", cvsp->phy_addr); |
| #else |
| PR_INF("\tph=0x%lx\n", cvsp->phy_addr); |
| #endif |
| PR_INF("\tw=%d\n", cvsp->width); |
| PR_INF("\th=%d\n", cvsp->height); |
| PR_INF("\tb=%d\n", cvsp->block_mode); |
| PR_INF("\tendian=%d\n", cvsp->endian); |
| } |
| } |
| #endif /* DIM_OUT_NV21 */ |
| |
| int dim_post_process(void *arg, unsigned int zoom_start_x_lines, |
| unsigned int zoom_end_x_lines, |
| unsigned int zoom_start_y_lines, |
| unsigned int zoom_end_y_lines, |
| vframe_t *disp_vf) |
| { |
| struct di_buf_s *di_buf = (struct di_buf_s *)arg; |
| struct di_buf_s *di_pldn_buf = NULL; |
| unsigned int di_width, di_height, di_start_x, di_end_x, mv_offset; |
| unsigned int di_start_y, di_end_y, hold_line; |
| unsigned int post_blend_en = 0, post_blend_mode = 0, |
| blend_mtn_en = 0, ei_en = 0, post_field_num = 0; |
| int di_vpp_en, di_ddr_en; |
| int tmptest; |
| unsigned char mc_pre_flag = 0; |
| bool invert_mv = false; |
| static int post_index = -1; |
| unsigned char tmp_idx = 0; |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| struct di_hpst_s *pst = get_hw_pst(); |
| |
| unsigned char channel = pst->curr_ch; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| struct di_post_stru_s *ppost = get_post_stru(channel); |
| struct di_cvs_s *cvss; |
| struct pst_cfg_afbc_s *acfg; |
| union afbc_blk_s *en_set_pst; |
| #ifdef DIM_OUT_NV21 |
| u32 cvs_nv21[2]; |
| #endif |
| union hw_sc2_ctr_pst_s *sc2_post_cfg; |
| union hw_sc2_ctr_pst_s *sc2_post_cfg_set; |
| unsigned int tmp; |
| unsigned int dbg_r; |
| |
| struct di_ch_s *pch; |
| |
| dimp_inc(edi_mp_post_cnt); |
| if (ppost->vscale_skip_flag) |
| return 0; |
| |
| dim_mp_update_post(); |
| get_vscale_skip_count(zoom_start_x_lines); |
| |
| if (IS_ERR_OR_NULL(di_buf)) |
| return 0; |
| else if (IS_ERR_OR_NULL(di_buf->di_buf_dup_p[0])) |
| return 0; |
| |
| pch = get_chdata(channel); |
| cvss = &get_datal()->cvs; |
| acfg = &ppost->afbc_cfg; |
| hold_line = dimp_get(edi_mp_post_hold_line); |
| di_pldn_buf = di_buf->di_buf_dup_p[pldn_dly]; |
| |
| if (di_que_is_in_que(channel, QUE_POST_FREE, di_buf) && |
| post_index != di_buf->index) { |
| post_index = di_buf->index; |
| PR_ERR("%s:post_buf[%d] is in post free list.\n", |
| __func__, di_buf->index); |
| return 0; |
| } |
| hpst_dbg_mem_pd_trig(0); |
| |
| if (ppost->toggle_flag && di_buf->di_buf_dup_p[1]) |
| top_bot_config(di_buf->di_buf_dup_p[1]); |
| |
| ppost->toggle_flag = false; |
| |
| ppost->cur_disp_index = di_buf->index; |
| |
| if (get_vpp_reg_update_flag(zoom_start_x_lines) || |
| dimp_get(edi_mp_post_refresh)) |
| ppost->update_post_reg_flag = 1; |
| |
| zoom_start_x_lines = zoom_start_x_lines & 0xffff; |
| zoom_end_x_lines = zoom_end_x_lines & 0xffff; |
| zoom_start_y_lines = zoom_start_y_lines & 0xffff; |
| zoom_end_y_lines = zoom_end_y_lines & 0xffff; |
| |
| if (!get_init_flag(channel) && IS_ERR_OR_NULL(ppost->keep_buf)) { |
| PR_ERR("%s 2:\n", __func__); |
| return 0; |
| } |
| if (di_buf->vframe) |
| dim_tr_ops.post_set(di_buf->vframe->index_disp); |
| else |
| return 0; |
| /*dbg*/ |
| if (ppost->frame_cnt == 1 && kpi_frame_num > 0) { |
| pr_dbg("[di_kpi] di:ch[%d]:queue 1st frame to post ready.\n", |
| channel); |
| } |
| |
| dim_secure_sw_post(channel); |
| |
| dim_ddbg_mod_save(EDI_DBG_MOD_POST_SETB, channel, ppost->frame_cnt); |
| dbg_post_cnt(channel, "ps1"); |
| di_start_x = zoom_start_x_lines; |
| di_end_x = zoom_end_x_lines; |
| di_width = di_end_x - di_start_x + 1; |
| di_start_y = zoom_start_y_lines; |
| di_end_y = zoom_end_y_lines; |
| di_height = di_end_y - di_start_y + 1; |
| di_height = di_height / (dimp_get(edi_mp_di_vscale_skip_real) + 1); |
| /* make sure the height is even number */ |
| if (di_height % 2) { |
| /*for skip mode,post only half line-1*/ |
| if (!dimp_get(edi_mp_post_wr_en) && |
| (di_height > 150 && |
| di_height < 1080) && |
| dimp_get(edi_mp_di_vscale_skip_real)) |
| di_height = di_height - 3; |
| else |
| di_height++; |
| } |
| if (dip_itf_is_ins(pch) && dim_dbg_new_int(2)) |
| dim_dbg_buffer2(di_buf->c.buffer, 7); |
| |
| #ifdef DIM_OUT_NV21 |
| /* nv 21*/ |
| if (is_mask(SC2_DW_EN)) |
| dw_fill_outvf(&pst->vf_post, di_buf); |
| //else if (cfg_nv21 & DI_BIT0) |
| else if (cfggch(pch, IOUT_FMT) == 1) |
| dimpst_fill_outvf(&pst->vf_post, di_buf, EDPST_OUT_MODE_NV21); |
| else if (cfggch(pch, IOUT_FMT) == 2) |
| dimpst_fill_outvf(&pst->vf_post, di_buf, EDPST_OUT_MODE_NV12); |
| else |
| dimpst_fill_outvf(&pst->vf_post, di_buf, EDPST_OUT_MODE_DEF); |
| /*************************************************/ |
| #endif |
| if (is_mask(SC2_POST_TRIG)) { |
| pst->last_pst_size = 0; |
| //PR_INF("%s:trig\n", __func__); |
| } |
| |
| if (di_buf->trig_post_update) { |
| pst->last_pst_size = 0; |
| //PR_INF("post trig\n"); |
| ppost->seq = 0; |
| } |
| di_buf->seq = ppost->seq; |
| if (/*RD(DI_POST_SIZE)*/pst->last_pst_size != ((di_width - 1) | |
| ((di_height - 1) << 16)) || |
| ppost->buf_type != di_buf->di_buf_dup_p[0]->type || |
| ppost->di_buf0_mif.luma_x_start0 != di_start_x || |
| (ppost->di_buf0_mif.luma_y_start0 != di_start_y / 2)) { |
| dim_ddbg_mod_save(EDI_DBG_MOD_POST_RESIZE, channel, |
| ppost->frame_cnt);/*dbg*/ |
| ppost->buf_type = di_buf->di_buf_dup_p[0]->type; |
| |
| dimh_initial_di_post_2(di_width, di_height, |
| hold_line, |
| (dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support))); |
| |
| if (!di_buf->di_buf_dup_p[0]->vframe) { |
| PR_ERR("%s 3:\n", __func__); |
| return 0; |
| } |
| sc2_post_cfg = &ppost->pst_top_cfg;//&pst->pst_top_cfg; |
| if (DIM_IS_IC_EF(SC2) && dim_afds() && dim_afds()->pst_check) |
| dim_afds()->pst_check(&pst->vf_post, pch); |
| if (DIM_IS_IC_EF(SC2)) { |
| if (sc2_post_cfg->b.afbc_wr) |
| sc2_post_cfg->b.mif_en = 0; |
| else |
| sc2_post_cfg->b.mif_en = 1; |
| |
| if (dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) |
| sc2_post_cfg->b.post_frm_sel = 1; |
| else |
| sc2_post_cfg->b.post_frm_sel = 0; |
| //dim_sc2_contr_pst(sc2_post_cfg); |
| if (cfgg(LINEAR)) { |
| ppost->di_diwr_mif.linear = 1; |
| ppost->di_diwr_mif.buf_crop_en = 1; |
| ppost->di_diwr_mif.buf_hsize = |
| di_buf->buf_hsize;//1920; tmp; |
| ppost->di_buf0_mif.linear = 1; |
| ppost->di_buf0_mif.buf_crop_en = 1; |
| ppost->di_buf0_mif.buf_hsize = |
| di_buf->buf_hsize; /*tmp*/; |
| ppost->di_buf1_mif.linear = 1; |
| ppost->di_buf1_mif.buf_crop_en = 1; |
| ppost->di_buf1_mif.buf_hsize = |
| di_buf->buf_hsize; /*tmp*/; |
| ppost->di_buf2_mif.linear = 1; |
| ppost->di_buf2_mif.buf_crop_en = 1; |
| ppost->di_buf2_mif.buf_hsize = |
| di_buf->buf_hsize; /*tmp*/; |
| |
| ppost->di_mtnprd_mif.linear = 1; |
| ppost->di_mcvecrd_mif.linear = 1; |
| } |
| } |
| pst->last_pst_size = ((di_width - 1) | ((di_height - 1) << 16)); |
| #ifdef DIM_OUT_NV21 |
| /* nv 21*/ |
| if ((di_buf->flg_nv21 == 2) || cfggch(pch, IOUT_FMT) == 2) |
| ppost->di_diwr_mif.cbcr_swap = 1; |
| else |
| ppost->di_diwr_mif.cbcr_swap = 0; |
| |
| if (dip_itf_is_o_linear(pch) && |
| (cfggch(pch, IOUT_FMT) == 2 || |
| cfggch(pch, IOUT_FMT) == 1)) { |
| ppost->di_diwr_mif.reg_swap = 0; |
| ppost->di_diwr_mif.l_endian = 1; |
| } else { |
| ppost->di_diwr_mif.reg_swap = 1; |
| ppost->di_diwr_mif.l_endian = 0; |
| } |
| dbg_r = dim_get_dbg_dec21(); |
| if (dbg_r & 0xf0) { |
| ppost->di_diwr_mif.reg_swap = bget(&dbg_r, 4); |
| ppost->di_diwr_mif.l_endian = bget(&dbg_r, 5); |
| ppost->di_diwr_mif.cbcr_swap = bget(&dbg_r, 6); |
| } |
| dim_print("%s1:reg_swap[%d],%d,%d\n", __func__, |
| ppost->di_diwr_mif.reg_swap, |
| dip_itf_is_o_linear(pch), |
| di_buf->flg_nv21); |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->wr_cfg_mif(&ppost->di_diwr_mif, |
| EDI_MIFSM_WR, |
| &pst->vf_post, NULL); |
| else |
| dim_cfg_s_mif(&ppost->di_diwr_mif, &pst->vf_post, NULL); |
| #endif |
| /******************************************/ |
| /* bit mode config */ |
| if (di_buf->vframe->bitdepth & BITDEPTH_Y10) { |
| if (di_buf->vframe->type & VIDTYPE_VIU_444) { |
| ppost->di_buf0_mif.bit_mode = |
| (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 2; |
| ppost->di_buf1_mif.bit_mode = |
| (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 2; |
| ppost->di_buf2_mif.bit_mode = |
| (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 2; |
| |
| } else { |
| ppost->di_buf0_mif.bit_mode = |
| (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 1; |
| ppost->di_buf1_mif.bit_mode = |
| (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 1; |
| ppost->di_buf2_mif.bit_mode = |
| (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 1; |
| |
| } |
| } else { |
| ppost->di_buf0_mif.bit_mode = 0; |
| ppost->di_buf1_mif.bit_mode = 0; |
| ppost->di_buf2_mif.bit_mode = 0; |
| } |
| if (di_buf->vframe->type & VIDTYPE_VIU_444) { |
| if (DIM_IS_IC_EF(SC2)) { |
| ppost->di_buf0_mif.video_mode = 2; |
| ppost->di_buf1_mif.video_mode = 2; |
| ppost->di_buf2_mif.video_mode = 2; |
| } else { |
| ppost->di_buf0_mif.video_mode = 1; |
| ppost->di_buf1_mif.video_mode = 1; |
| ppost->di_buf2_mif.video_mode = 1; |
| } |
| } else if (di_buf->vframe->type & VIDTYPE_VIU_422) { |
| if (DIM_IS_IC_EF(SC2)) { |
| if (opl1()->info.main_version >= 3) { |
| ppost->di_buf0_mif.video_mode = 1; |
| ppost->di_buf1_mif.video_mode = 1; |
| ppost->di_buf2_mif.video_mode = 1; |
| } |
| } else { |
| ppost->di_buf0_mif.video_mode = 0; |
| ppost->di_buf1_mif.video_mode = 0; |
| ppost->di_buf2_mif.video_mode = 0; |
| } |
| |
| } else { |
| ppost->di_buf0_mif.video_mode = 0; |
| ppost->di_buf1_mif.video_mode = 0; |
| ppost->di_buf2_mif.video_mode = 0; |
| } |
| if (ppost->buf_type == VFRAME_TYPE_IN && |
| !(di_buf->di_buf_dup_p[0]->vframe->type & |
| VIDTYPE_VIU_FIELD)) { |
| if ((di_buf->vframe->type & VIDTYPE_VIU_NV21) || |
| (di_buf->vframe->type & VIDTYPE_VIU_NV12)) { |
| ppost->di_buf0_mif.set_separate_en = 1; |
| ppost->di_buf1_mif.set_separate_en = 1; |
| ppost->di_buf2_mif.set_separate_en = 1; |
| } else { |
| ppost->di_buf0_mif.set_separate_en = 0; |
| ppost->di_buf1_mif.set_separate_en = 0; |
| ppost->di_buf2_mif.set_separate_en = 0; |
| } |
| ppost->di_buf0_mif.luma_y_start0 = di_start_y; |
| ppost->di_buf0_mif.luma_y_end0 = di_end_y; |
| } else { /* from vdin or local vframe process by di pre */ |
| ppost->di_buf0_mif.set_separate_en = 0; |
| ppost->di_buf0_mif.luma_y_start0 = |
| di_start_y >> 1; |
| ppost->di_buf0_mif.luma_y_end0 = di_end_y >> 1; |
| ppost->di_buf1_mif.set_separate_en = 0; |
| ppost->di_buf1_mif.luma_y_start0 = |
| di_start_y >> 1; |
| ppost->di_buf1_mif.luma_y_end0 = di_end_y >> 1; |
| ppost->di_buf2_mif.set_separate_en = 0; |
| ppost->di_buf2_mif.luma_y_end0 = di_end_y >> 1; |
| ppost->di_buf2_mif.luma_y_start0 = |
| di_start_y >> 1; |
| } |
| ppost->di_buf0_mif.luma_x_start0 = di_start_x; |
| ppost->di_buf0_mif.luma_x_end0 = di_end_x; |
| ppost->di_buf1_mif.luma_x_start0 = di_start_x; |
| ppost->di_buf1_mif.luma_x_end0 = di_end_x; |
| ppost->di_buf2_mif.luma_x_start0 = di_start_x; |
| ppost->di_buf2_mif.luma_x_end0 = di_end_x; |
| |
| ppost->di_buf0_mif.reg_swap = 1; |
| ppost->di_buf0_mif.l_endian = 0; |
| ppost->di_buf0_mif.cbcr_swap = 0; |
| |
| ppost->di_buf1_mif.reg_swap = 1; |
| ppost->di_buf1_mif.l_endian = 0; |
| ppost->di_buf1_mif.cbcr_swap = 0; |
| ppost->di_buf2_mif.reg_swap = 1; |
| ppost->di_buf2_mif.l_endian = 0; |
| ppost->di_buf2_mif.cbcr_swap = 0; |
| if (dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) { |
| if (de_devp->pps_enable && |
| dimp_get(edi_mp_pps_position) == 0) { |
| dim_pps_config(0, di_width, di_height, |
| dimp_get(edi_mp_pps_dstw), |
| dimp_get(edi_mp_pps_dsth)); |
| } |
| } |
| |
| ppost->di_mtnprd_mif.start_x = di_start_x; |
| ppost->di_mtnprd_mif.end_x = di_end_x; |
| ppost->di_mtnprd_mif.start_y = di_start_y >> 1; |
| ppost->di_mtnprd_mif.end_y = di_end_y >> 1; |
| ppost->di_mtnprd_mif.per_bits = 4; |
| if (dimp_get(edi_mp_mcpre_en)) { |
| ppost->di_mcvecrd_mif.start_x = di_start_x / 5; |
| mv_offset = (di_start_x % 5) ? (5 - di_start_x % 5) : 0; |
| ppost->di_mcvecrd_mif.vecrd_offset = |
| overturn ? (di_end_x + 1) % 5 : mv_offset; |
| ppost->di_mcvecrd_mif.start_y = |
| (di_start_y >> 1); |
| ppost->di_mcvecrd_mif.size_x = |
| (di_end_x + 1 + 4) / 5 - 1 - di_start_x / 5; |
| ppost->di_mcvecrd_mif.end_y = |
| (di_end_y >> 1); |
| ppost->di_mcvecrd_mif.per_bits = 16; |
| } |
| ppost->update_post_reg_flag = 1; |
| /* if height decrease, mtn will not enough */ |
| if (di_buf->pd_config.global_mode != PULL_DOWN_BUF1 && |
| !dimp_get(edi_mp_post_wr_en)) |
| di_buf->pd_config.global_mode = PULL_DOWN_EI; |
| } |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA |
| if (is_vsync_rdma_enable()) { |
| #ifdef DIM_OUT_NV21 |
| if (dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) |
| ppost->canvas_id = 0; |
| else |
| ppost->canvas_id = ppost->next_canvas_id; |
| |
| #endif |
| } else { |
| ppost->canvas_id = 0; |
| ppost->next_canvas_id = 1; |
| if (dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) |
| ppost->canvas_id = |
| ppost->next_canvas_id; |
| } |
| #endif |
| /*post_blend = di_buf->pd_config.global_mode;*/ |
| dimp_set(edi_mp_post_blend, di_buf->pd_config.global_mode); |
| dim_print("%s:ch[%d]\n", __func__, channel); |
| switch (dimp_get(edi_mp_post_blend)) { |
| case PULL_DOWN_BLEND_0: |
| case PULL_DOWN_NORMAL: |
| config_canvas_idx(di_buf->di_buf_dup_p[1], |
| cvss->post_idx[ppost->canvas_id][0], -1); |
| config_canvas_idx(di_buf->di_buf_dup_p[2], -1, |
| cvss->post_idx[ppost->canvas_id][2]); |
| config_canvas_idx(di_buf->di_buf_dup_p[0], |
| cvss->post_idx[ppost->canvas_id][1], -1); |
| config_canvas_idx(di_buf->di_buf_dup_p[2], |
| cvss->post_idx[ppost->canvas_id][3], -1); |
| if (dimp_get(edi_mp_mcpre_en)) { |
| tmptest = cvss->post_idx[ppost->canvas_id][4]; |
| config_mcvec_canvas_idx(di_buf->di_buf_dup_p[2], |
| tmptest); |
| } |
| break; |
| case PULL_DOWN_BLEND_2: |
| case PULL_DOWN_NORMAL_2: |
| config_canvas_idx(di_buf->di_buf_dup_p[0], |
| cvss->post_idx[ppost->canvas_id][3], -1); |
| config_canvas_idx(di_buf->di_buf_dup_p[1], |
| cvss->post_idx[ppost->canvas_id][0], -1); |
| config_canvas_idx(di_buf->di_buf_dup_p[2], -1, |
| cvss->post_idx[ppost->canvas_id][2]); |
| config_canvas_idx(di_buf->di_buf_dup_p[2], |
| cvss->post_idx[ppost->canvas_id][1], -1); |
| if (dimp_get(edi_mp_mcpre_en)) { |
| tmptest = cvss->post_idx[ppost->canvas_id][4]; |
| config_mcvec_canvas_idx(di_buf->di_buf_dup_p[2], |
| tmptest); |
| } |
| break; |
| case PULL_DOWN_MTN: |
| config_canvas_idx(di_buf->di_buf_dup_p[1], |
| cvss->post_idx[ppost->canvas_id][0], -1); |
| config_canvas_idx(di_buf->di_buf_dup_p[2], -1, |
| cvss->post_idx[ppost->canvas_id][2]); |
| config_canvas_idx(di_buf->di_buf_dup_p[0], |
| cvss->post_idx[ppost->canvas_id][1], -1); |
| break; |
| case PULL_DOWN_BUF1:/* wave with buf1 */ |
| config_canvas_idx(di_buf->di_buf_dup_p[1], |
| cvss->post_idx[ppost->canvas_id][0], -1); |
| config_canvas_idx(di_buf->di_buf_dup_p[1], -1, |
| cvss->post_idx[ppost->canvas_id][2]); |
| config_canvas_idx(di_buf->di_buf_dup_p[0], |
| cvss->post_idx[ppost->canvas_id][1], -1); |
| break; |
| case PULL_DOWN_EI: |
| if (di_buf->di_buf_dup_p[1]) |
| config_canvas_idx(di_buf->di_buf_dup_p[1], |
| cvss->post_idx[ppost->canvas_id][0], |
| -1); |
| break; |
| default: |
| break; |
| } |
| ppost->next_canvas_id = ppost->canvas_id ? 0 : 1; |
| |
| if (!di_buf->di_buf_dup_p[1]) { |
| PR_ERR("%s 4:\n", __func__); |
| return 0; |
| } |
| if (!di_buf->di_buf_dup_p[1]->vframe || |
| !di_buf->di_buf_dup_p[0]->vframe) { |
| PR_ERR("%s 5:\n", __func__); |
| return 0; |
| } |
| |
| if (is_meson_txl_cpu() && overturn && di_buf->di_buf_dup_p[2]) { |
| /*sync from kernel 3.14 txl*/ |
| if (dimp_get(edi_mp_post_blend) == PULL_DOWN_BLEND_2) |
| dimp_set(edi_mp_post_blend, PULL_DOWN_BLEND_0); |
| else if (dimp_get(edi_mp_post_blend) == PULL_DOWN_BLEND_0) |
| dimp_set(edi_mp_post_blend, PULL_DOWN_BLEND_2); |
| } |
| |
| switch (dimp_get(edi_mp_post_blend)) { |
| case PULL_DOWN_BLEND_0: |
| case PULL_DOWN_NORMAL: |
| post_field_num = |
| (di_buf->di_buf_dup_p[1]->vframe->type & |
| VIDTYPE_TYPEMASK) |
| == VIDTYPE_INTERLACE_TOP ? 0 : 1; |
| ppost->di_buf0_mif.canvas0_addr0 = |
| di_buf->di_buf_dup_p[1]->nr_canvas_idx; |
| ppost->di_buf1_mif.canvas0_addr0 = |
| di_buf->di_buf_dup_p[0]->nr_canvas_idx; |
| ppost->di_buf2_mif.canvas0_addr0 = |
| di_buf->di_buf_dup_p[2]->nr_canvas_idx; |
| //t7 |
| ppost->di_buf0_mif.addr0 = di_buf->di_buf_dup_p[1]->nr_adr; |
| ppost->di_buf1_mif.addr0 = |
| di_buf->di_buf_dup_p[0]->nr_adr; |
| ppost->di_buf2_mif.addr0 = |
| di_buf->di_buf_dup_p[2]->nr_adr; |
| |
| /* afbc dec */ |
| acfg->buf_mif[0] = di_buf->di_buf_dup_p[1]; |
| acfg->buf_mif[1] = di_buf->di_buf_dup_p[0]; |
| acfg->buf_mif[2] = di_buf->di_buf_dup_p[2]; |
| /************/ |
| ppost->di_mtnprd_mif.canvas_num = |
| di_buf->di_buf_dup_p[2]->mtn_canvas_idx; |
| ppost->di_mtnprd_mif.addr = di_buf->di_buf_dup_p[2]->mtn_adr; |
| /*mc_pre_flag = is_meson_txl_cpu()?2:(overturn?0:1);*/ |
| if (is_meson_txl_cpu() && overturn) { |
| /* swap if1&if2 mean negation of mv for normal di*/ |
| tmp_idx = ppost->di_buf1_mif.canvas0_addr0; |
| ppost->di_buf1_mif.canvas0_addr0 = |
| ppost->di_buf2_mif.canvas0_addr0; |
| ppost->di_buf2_mif.canvas0_addr0 = tmp_idx; |
| /* afbc dec */ |
| acfg->buf_mif[1] = di_buf->di_buf_dup_p[2]; |
| acfg->buf_mif[2] = di_buf->di_buf_dup_p[0]; |
| } |
| mc_pre_flag = overturn ? 0 : 1; |
| if (di_buf->pd_config.global_mode == PULL_DOWN_NORMAL) { |
| post_blend_mode = 3; |
| /*if pulldown, mcdi_mcpreflag is 1,*/ |
| /*it means use previous field for MC*/ |
| /*else not pulldown,mcdi_mcpreflag is 2*/ |
| /*it means use forward & previous field for MC*/ |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD)) |
| mc_pre_flag = 2; |
| } else { |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD)) |
| mc_pre_flag = 1; |
| post_blend_mode = 1; |
| } |
| if (is_meson_txl_cpu() && overturn) |
| mc_pre_flag = 1; |
| |
| if (dimp_get(edi_mp_mcpre_en)) { |
| ppost->di_mcvecrd_mif.canvas_num = |
| di_buf->di_buf_dup_p[2]->mcvec_canvas_idx; |
| ppost->di_mcvecrd_mif.addr = |
| di_buf->di_buf_dup_p[2]->mcvec_adr; |
| } |
| blend_mtn_en = 1; |
| ei_en = 1; |
| dimp_set(edi_mp_post_ei, 1); |
| post_blend_en = 1; |
| break; |
| case PULL_DOWN_BLEND_2: |
| case PULL_DOWN_NORMAL_2: |
| post_field_num = |
| (di_buf->di_buf_dup_p[1]->vframe->type & |
| VIDTYPE_TYPEMASK) |
| == VIDTYPE_INTERLACE_TOP ? 0 : 1; |
| ppost->di_buf0_mif.canvas0_addr0 = |
| di_buf->di_buf_dup_p[1]->nr_canvas_idx; |
| ppost->di_buf1_mif.canvas0_addr0 = |
| di_buf->di_buf_dup_p[2]->nr_canvas_idx; |
| ppost->di_buf2_mif.canvas0_addr0 = |
| di_buf->di_buf_dup_p[0]->nr_canvas_idx; |
| |
| ppost->di_buf0_mif.addr0 = |
| di_buf->di_buf_dup_p[1]->nr_adr; |
| ppost->di_buf1_mif.addr0 = |
| di_buf->di_buf_dup_p[2]->nr_adr; |
| ppost->di_buf2_mif.addr0 = |
| di_buf->di_buf_dup_p[0]->nr_adr; |
| |
| /* afbc dec */ |
| acfg->buf_mif[0] = di_buf->di_buf_dup_p[1]; |
| acfg->buf_mif[1] = di_buf->di_buf_dup_p[2]; |
| acfg->buf_mif[2] = di_buf->di_buf_dup_p[0]; |
| /************/ |
| ppost->di_mtnprd_mif.canvas_num = |
| di_buf->di_buf_dup_p[2]->mtn_canvas_idx; |
| ppost->di_mtnprd_mif.addr = |
| di_buf->di_buf_dup_p[2]->mtn_adr; |
| if (is_meson_txl_cpu() && overturn) { |
| ppost->di_buf1_mif.canvas0_addr0 = |
| ppost->di_buf2_mif.canvas0_addr0; |
| /* afbc dec */ |
| acfg->buf_mif[1] = di_buf->di_buf_dup_p[0]; |
| } |
| if (dimp_get(edi_mp_mcpre_en)) { |
| ppost->di_mcvecrd_mif.canvas_num = |
| di_buf->di_buf_dup_p[2]->mcvec_canvas_idx; |
| ppost->di_mcvecrd_mif.addr = |
| di_buf->di_buf_dup_p[2]->mcvec_adr; |
| mc_pre_flag = is_meson_txl_cpu() ? 0 : |
| (overturn ? 1 : 0); |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) { |
| invert_mv = true; |
| } else if (!overturn) { |
| ppost->di_buf2_mif.canvas0_addr0 = |
| di_buf->di_buf_dup_p[2]->nr_canvas_idx; |
| /* afbc dec */ |
| acfg->buf_mif[2] = di_buf->di_buf_dup_p[2]; |
| } |
| } |
| if (di_buf->pd_config.global_mode == PULL_DOWN_NORMAL_2) { |
| post_blend_mode = 3; |
| /*if pulldown, mcdi_mcpreflag is 1,*/ |
| /*it means use previous field for MC*/ |
| /*else not pulldown,mcdi_mcpreflag is 2*/ |
| /*it means use forward & previous field for MC*/ |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD)) |
| mc_pre_flag = 2; |
| } else { |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD)) |
| mc_pre_flag = 1; |
| post_blend_mode = 1; |
| } |
| blend_mtn_en = 1; |
| ei_en = 1; |
| dimp_set(edi_mp_post_ei, 1); |
| post_blend_en = 1; |
| break; |
| case PULL_DOWN_MTN: |
| post_field_num = |
| (di_buf->di_buf_dup_p[1]->vframe->type & |
| VIDTYPE_TYPEMASK) |
| == VIDTYPE_INTERLACE_TOP ? 0 : 1; |
| ppost->di_buf0_mif.canvas0_addr0 = |
| di_buf->di_buf_dup_p[1]->nr_canvas_idx; |
| ppost->di_buf1_mif.canvas0_addr0 = |
| di_buf->di_buf_dup_p[0]->nr_canvas_idx; |
| //t7 |
| ppost->di_buf0_mif.addr0 = |
| di_buf->di_buf_dup_p[1]->nr_adr; |
| ppost->di_buf1_mif.addr0 = |
| di_buf->di_buf_dup_p[0]->nr_adr; |
| /* afbc dec */ |
| acfg->buf_mif[0] = di_buf->di_buf_dup_p[1]; |
| acfg->buf_mif[1] = di_buf->di_buf_dup_p[0]; |
| acfg->buf_mif[2] = NULL; |
| /************/ |
| ppost->di_mtnprd_mif.canvas_num = |
| di_buf->di_buf_dup_p[2]->mtn_canvas_idx; |
| ppost->di_mtnprd_mif.addr = |
| di_buf->di_buf_dup_p[2]->mtn_adr; |
| post_blend_mode = 0; |
| blend_mtn_en = 1; |
| ei_en = 1; |
| dimp_set(edi_mp_post_ei, 1); |
| post_blend_en = 1; |
| break; |
| case PULL_DOWN_BUF1: |
| post_field_num = |
| (di_buf->di_buf_dup_p[1]->vframe->type & |
| VIDTYPE_TYPEMASK) |
| == VIDTYPE_INTERLACE_TOP ? 0 : 1; |
| ppost->di_buf0_mif.canvas0_addr0 = |
| di_buf->di_buf_dup_p[1]->nr_canvas_idx; |
| //t7: |
| ppost->di_buf0_mif.addr0 = |
| di_buf->di_buf_dup_p[1]->nr_adr; |
| ppost->di_mtnprd_mif.canvas_num = |
| di_buf->di_buf_dup_p[1]->mtn_canvas_idx; |
| ppost->di_mtnprd_mif.addr = |
| di_buf->di_buf_dup_p[1]->mtn_adr; |
| ppost->di_buf1_mif.canvas0_addr0 = |
| di_buf->di_buf_dup_p[0]->nr_canvas_idx; |
| ppost->di_buf1_mif.addr0 = |
| di_buf->di_buf_dup_p[0]->nr_adr; |
| /* afbc dec */ |
| acfg->buf_mif[0] = di_buf->di_buf_dup_p[1]; |
| acfg->buf_mif[1] = di_buf->di_buf_dup_p[0]; |
| acfg->buf_mif[2] = NULL; |
| /************/ |
| post_blend_mode = 1; |
| blend_mtn_en = 0; |
| ei_en = 0; |
| dimp_set(edi_mp_post_ei, 0); |
| post_blend_en = 0; |
| break; |
| case PULL_DOWN_EI: |
| if (di_buf->di_buf_dup_p[1]) { |
| ppost->di_buf0_mif.canvas0_addr0 = |
| di_buf->di_buf_dup_p[1]->nr_canvas_idx; |
| ppost->di_buf0_mif.addr0 = |
| di_buf->di_buf_dup_p[1]->nr_adr; |
| /* afbc dec */ |
| acfg->buf_mif[0] = di_buf->di_buf_dup_p[1]; |
| acfg->buf_mif[1] = NULL; |
| acfg->buf_mif[2] = NULL; |
| /************/ |
| post_field_num = |
| (di_buf->di_buf_dup_p[1]->vframe->type & |
| VIDTYPE_TYPEMASK) |
| == VIDTYPE_INTERLACE_TOP ? 0 : 1; |
| } else { |
| post_field_num = |
| (di_buf->di_buf_dup_p[0]->vframe->type & |
| VIDTYPE_TYPEMASK) |
| == VIDTYPE_INTERLACE_TOP ? 0 : 1; |
| ppost->di_buf0_mif.src_field_mode = |
| post_field_num; |
| } |
| post_blend_mode = 2; |
| blend_mtn_en = 0; |
| ei_en = 1; |
| dimp_set(edi_mp_post_ei, 1); |
| post_blend_en = 0; |
| break; |
| default: |
| break; |
| } |
| |
| if (dimp_get(edi_mp_post_wr_en) && dimp_get(edi_mp_post_wr_support)) { |
| #ifdef DIM_OUT_NV21 |
| cvs_nv21[0] = cvss->post_idx[0][5]; |
| cvs_nv21[1] = cvss->post_idx[1][0]; |
| dim_canvas_set2(&pst->vf_post, &cvs_nv21[0]); |
| ppost->di_diwr_mif.canvas_num = pst->vf_post.canvas0Addr; |
| ppost->di_diwr_mif.addr = |
| pst->vf_post.canvas0_config[0].phy_addr; |
| ppost->di_diwr_mif.addr1 = |
| pst->vf_post.canvas0_config[1].phy_addr; |
| |
| ppost->di_diwr_mif.ddr_en = 1; |
| |
| #endif |
| |
| di_vpp_en = 0; |
| di_ddr_en = 1; |
| } else { |
| di_vpp_en = 1; |
| di_ddr_en = 0; |
| #ifdef DIM_OUT_NV21 |
| ppost->di_diwr_mif.ddr_en = 0; |
| #endif |
| } |
| |
| /* if post size < MIN_POST_WIDTH, force ei */ |
| if (di_width < MIN_BLEND_WIDTH && |
| (di_buf->pd_config.global_mode == PULL_DOWN_BLEND_0 || |
| di_buf->pd_config.global_mode == PULL_DOWN_BLEND_2 || |
| di_buf->pd_config.global_mode == PULL_DOWN_NORMAL |
| )) { |
| post_blend_mode = 1; |
| blend_mtn_en = 0; |
| ei_en = 0; |
| dimp_set(edi_mp_post_ei, 0); |
| post_blend_en = 0; |
| } |
| |
| if (dimp_get(edi_mp_mcpre_en)) |
| ppost->di_mcvecrd_mif.blend_en = post_blend_en; |
| invert_mv = overturn ? (!invert_mv) : invert_mv; |
| if (DIM_IS_IC_EF(SC2)) { |
| sc2_post_cfg_set = &pst->pst_top_cfg; |
| sc2_post_cfg = &ppost->pst_top_cfg; |
| |
| en_set_pst = &ppost->en_set; |
| if (en_set_pst->b.if0 && acfg->buf_mif[0]) |
| en_set_pst->b.if0 = 1; |
| else |
| en_set_pst->b.if0 = 0; |
| |
| if (en_set_pst->b.if1 && acfg->buf_mif[1]) |
| en_set_pst->b.if1 = 1; |
| else |
| en_set_pst->b.if1 = 0; |
| |
| if (en_set_pst->b.if2 && acfg->buf_mif[2]) |
| en_set_pst->b.if2 = 1; |
| else |
| en_set_pst->b.if2 = 0; |
| |
| if (en_set_pst->b.if0) |
| sc2_post_cfg->b.afbc_if0 = 1; |
| else |
| sc2_post_cfg->b.afbc_if0 = 0; |
| |
| if (en_set_pst->b.if1) |
| sc2_post_cfg->b.afbc_if1 = 1; |
| else |
| sc2_post_cfg->b.afbc_if1 = 0; |
| |
| if (en_set_pst->b.if2) |
| sc2_post_cfg->b.afbc_if2 = 1; |
| else |
| sc2_post_cfg->b.afbc_if2 = 0; |
| |
| if (sc2_post_cfg_set->d32 != sc2_post_cfg->d32) { |
| sc2_post_cfg_set->d32 = sc2_post_cfg->d32; |
| dim_sc2_contr_pst(sc2_post_cfg_set); |
| } |
| } |
| if (IS_COMP_MODE(acfg->buf_mif[0]->vframe->type)) { |
| dim_print("%s:afbc1\n", __func__); |
| if (is_mask(SC2_ROT_WR)) { |
| tmp = di_buf->vframe->width; |
| di_buf->vframe->width = di_buf->vframe->height; |
| di_buf->vframe->height = tmp; |
| } |
| acfg->buf_o = di_buf; |
| acfg->ei_en = ei_en; /* ei en*/ |
| acfg->blend_en = post_blend_en; /* blend en */ |
| acfg->blend_mtn_en = blend_mtn_en; /* blend mtn en */ |
| acfg->blend_mode = post_blend_mode; /* blend mode. */ |
| acfg->di_vpp_en = di_vpp_en; /* di_vpp_en. */ |
| acfg->di_ddr_en = di_ddr_en; /* di_ddr_en. */ |
| acfg->post_field_num = post_field_num;/* 1bottom gen top */ |
| acfg->hold_line = hold_line; |
| acfg->urgent = dimp_get(edi_mp_post_urgent); |
| acfg->invert_mv = (invert_mv ? 1 : 0); |
| acfg->vskip_cnt = dimp_get(edi_mp_di_vscale_skip_real); |
| acfg->di_mtnprd_mif = &ppost->di_mtnprd_mif; |
| acfg->di_diwr_mif = &ppost->di_diwr_mif; |
| } |
| #ifdef MARK_SC2 |
| if (!is_mask(SC2_DW_EN)) { |
| if (opl2() && opl2()->shrk_disable) |
| opl2()->shrk_disable(); |
| } |
| #endif |
| if (ppost->update_post_reg_flag) { |
| if (DIM_IS_IC_EF(SC2) && |
| IS_COMP_MODE(acfg->buf_mif[0]->vframe->type)) { |
| dimh_enable_di_post_afbc(acfg); |
| /**/ |
| if ((!is_mask(SC2_DW_SHOW)) && |
| pst->pst_top_cfg.b.afbc_wr) { |
| pst->vf_post.type = acfg->buf_o->vframe->type; |
| #ifdef VFRAME_FLAG_DI_422_DW |
| pst->vf_post.flag |= VFRAME_FLAG_DI_422_DW; |
| #endif |
| pst->vf_post.canvas0Addr = -1; |
| pst->vf_post.canvas1Addr = -1; |
| |
| pst->vf_post.compHeadAddr = |
| di_buf->vframe->compHeadAddr; |
| pst->vf_post.compBodyAddr = |
| di_buf->vframe->compBodyAddr; |
| pst->vf_post.compHeight = |
| di_buf->vframe->compHeight; |
| pst->vf_post.compWidth = |
| di_buf->vframe->compWidth; |
| } |
| /* */ |
| } else { |
| dimh_enable_di_post_2 |
| (&ppost->di_buf0_mif, |
| &ppost->di_buf1_mif, |
| &ppost->di_buf2_mif, |
| &ppost->di_diwr_mif, |
| &ppost->di_mtnprd_mif, |
| ei_en, /* ei en*/ |
| post_blend_en, /* blend en */ |
| blend_mtn_en, /* blend mtn en */ |
| post_blend_mode, /* blend mode. */ |
| di_vpp_en, /* di_vpp_en. */ |
| di_ddr_en, /* di_ddr_en. */ |
| post_field_num,/* 1bottom gen top */ |
| hold_line, |
| dimp_get(edi_mp_post_urgent), |
| (invert_mv ? 1 : 0), |
| dimp_get(edi_mp_di_vscale_skip_real)); |
| } |
| if (dimp_get(edi_mp_mcpre_en)) { |
| tmptest = dimp_get(edi_mp_post_urgent); |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| dimh_en_mc_di_post_g12(&ppost->di_mcvecrd_mif, |
| tmptest, |
| overturn, |
| (invert_mv ? 1 : 0)); |
| else |
| dimh_enable_mc_di_post(&ppost->di_mcvecrd_mif, |
| tmptest, |
| overturn, |
| (invert_mv ? 1 : 0)); |
| } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) { |
| DIM_VSC_WR_MPG_BT(MCDI_MC_CRTL, 0, 0, 2); |
| } |
| } else { |
| if (DIM_IS_IC_EF(SC2) && |
| IS_COMP_MODE(acfg->buf_mif[0]->vframe->type)) { |
| dimh_enable_di_post_afbc(acfg); |
| dim_print("%s:di_buf:[0x%px],tp[%d],ind[%d],vf:0x%px\n", |
| __func__, di_buf, di_buf->type, |
| di_buf->index, di_buf->vframe); |
| if (is_mask(SC2_DW_SHOW)) { |
| dim_print("%s:dw show\n", __func__); |
| } else if (pst->pst_top_cfg.b.afbc_wr) { |
| pst->vf_post.type = acfg->buf_o->vframe->type; |
| |
| #ifdef VFRAME_FLAG_DI_422_DW |
| pst->vf_post.flag |= VFRAME_FLAG_DI_422_DW; |
| #endif |
| pst->vf_post.canvas0Addr = -1; |
| pst->vf_post.canvas1Addr = -1; |
| pst->vf_post.compHeadAddr = |
| di_buf->vframe->compHeadAddr; |
| pst->vf_post.compBodyAddr = |
| di_buf->vframe->compBodyAddr; |
| pst->vf_post.compHeight = |
| di_buf->vframe->compHeight; |
| pst->vf_post.compWidth = |
| di_buf->vframe->compWidth; |
| dim_print("%s:after afbce 0x%px :vtype[0x%x]\n", |
| __func__, di_buf->vframe, |
| di_buf->vframe->type); |
| dim_print("0x%px:\n", acfg->buf_o->vframe); |
| } |
| } else { |
| dimh_post_switch_buffer |
| (&ppost->di_buf0_mif, |
| &ppost->di_buf1_mif, |
| &ppost->di_buf2_mif, |
| &ppost->di_diwr_mif, |
| &ppost->di_mtnprd_mif, |
| &ppost->di_mcvecrd_mif, |
| ei_en, /* ei enable */ |
| post_blend_en, /* blend enable */ |
| blend_mtn_en, /* blend mtn enable */ |
| post_blend_mode, /* blend mode. */ |
| di_vpp_en, /* di_vpp_en. */ |
| di_ddr_en, /* di_ddr_en. */ |
| post_field_num,/*1bottom gen top */ |
| hold_line, |
| dimp_get(edi_mp_post_urgent), |
| (invert_mv ? 1 : 0), |
| dimp_get(edi_mp_pulldown_enable), |
| dimp_get(edi_mp_mcpre_en), |
| dimp_get(edi_mp_di_vscale_skip_real)); |
| } |
| } |
| |
| if (is_meson_gxtvbb_cpu() || |
| is_meson_txl_cpu() || |
| is_meson_txlx_cpu() || |
| is_meson_gxlx_cpu() || |
| is_meson_txhd_cpu() || |
| is_meson_g12a_cpu() || |
| is_meson_g12b_cpu() || |
| is_meson_tl1_cpu() || |
| is_meson_tm2_cpu() || |
| is_meson_sm1_cpu() || |
| DIM_IS_IC(T5) || |
| DIM_IS_IC(T5D) || |
| DIM_IS_IC_EF(SC2)) { |
| if (di_cfg_top_get(EDI_CFG_REF_2) && |
| mc_pre_flag && |
| dimp_get(edi_mp_post_wr_en)) { /*OTT-3210*/ |
| dbg_once("mc_old=%d\n", mc_pre_flag); |
| mc_pre_flag = 1; |
| } |
| dim_post_read_reverse_irq(overturn, mc_pre_flag, |
| post_blend_en ? |
| dimp_get(edi_mp_mcpre_en) : false); |
| /* disable mc for first 2 fieldes mv unreliable */ |
| if (di_buf->seq < 2) |
| DIM_VSC_WR_MPG_BT(MCDI_MC_CRTL, 0, 0, 2); |
| } |
| if (dimp_get(edi_mp_mcpre_en)) { |
| if (di_buf->di_buf_dup_p[2]) |
| set_post_mcinfo(&di_buf->di_buf_dup_p[2] |
| ->curr_field_mcinfo); |
| } else if (is_meson_gxlx_cpu() || |
| is_meson_txl_cpu() || |
| is_meson_txlx_cpu()) { |
| DIM_VSC_WR_MPG_BT(MCDI_MC_CRTL, 0, 0, 2); |
| } |
| |
| /* set pull down region (f(t-1) */ |
| |
| if (di_pldn_buf && |
| dimp_get(edi_mp_pulldown_enable) && |
| !ppre->cur_prog_flag) { |
| unsigned short offset = (di_start_y >> 1); |
| |
| if (overturn) |
| offset = ((di_buf->vframe->height - di_end_y) >> 1); |
| else |
| offset = 0; |
| /*pulldown_vof_win_vshift*/ |
| get_ops_pd()->vof_win_vshift(&di_pldn_buf->pd_config, offset); |
| dimh_pulldown_vof_win_config(&di_pldn_buf->pd_config); |
| } |
| //post_mif_sw(true); /*position?*/ |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pst_mif_sw(true, DI_MIF0_SEL_PST_ALL); |
| else |
| post_mif_sw(true); |
| |
| if (DIM_IS_IC_EF(SC2)) { |
| if (opl1()->wrmif_trig) |
| opl1()->wrmif_trig(EDI_MIFSM_WR); |
| } else { |
| /*add by wangfeng 2018-11-15 bit[31]: Pending_ddr_wrrsp_Diwr*/ |
| DIM_VSC_WR_MPG_BT(DI_DIWR_CTRL, 1, 31, 1); |
| DIM_VSC_WR_MPG_BT(DI_DIWR_CTRL, 0, 31, 1); |
| } |
| |
| /*ary add for post crash*/ |
| if (DIM_IS_IC_EF(SC2)) |
| opl1()->pst_set_flow((dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)), |
| EDI_POST_FLOW_STEP2_START); |
| else |
| di_post_set_flow((dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)), |
| EDI_POST_FLOW_STEP2_START); |
| if (ppost->update_post_reg_flag > 0) |
| ppost->update_post_reg_flag--; |
| |
| di_buf->seq_post = ppost->post_wr_cnt; |
| pst->flg_have_set = true; |
| /*dbg*/ |
| dim_ddbg_mod_save(EDI_DBG_MOD_POST_SETE, channel, ppost->frame_cnt); |
| dbg_post_cnt(channel, "ps2"); |
| ppost->frame_cnt++; |
| ppost->seq++; |
| pch->sum_pst++; |
| |
| return 0; |
| } |
| |
| #ifndef DI_DEBUG_POST_BUF_FLOW |
| static void post_ready_buf_set(unsigned int ch, struct di_buf_s *di_buf) |
| { |
| struct vframe_s *vframe_ret = NULL; |
| struct di_buf_s *nr_buf = NULL; |
| #ifdef VFM_ORI |
| struct vframe_s **pvframe_in = get_vframe_in(ch); |
| #else |
| struct dim_nins_s *ins; |
| #endif |
| struct vframe_s *vf; |
| |
| struct di_hpst_s *pst = get_hw_pst(); |
| struct di_ch_s *pch; |
| struct di_buffer *buffer; |
| struct di_buf_s *buf_in; |
| |
| pch = get_chdata(ch); |
| |
| vframe_ret = di_buf->vframe; |
| nr_buf = di_buf->di_buf_dup_p[1]; |
| if ((dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) && |
| di_buf->process_fun_index != PROCESS_FUN_NULL) { |
| #ifdef DIM_OUT_NV21 |
| vframe_ret->type = pst->vf_post.type; |
| vframe_ret->bitdepth = pst->vf_post.bitdepth; |
| vframe_ret->plane_num = pst->vf_post.plane_num; |
| vframe_ret->canvas0Addr = -1; |
| vframe_ret->canvas1Addr = -1; |
| vframe_ret->flag = pst->vf_post.flag; |
| vframe_ret->height = pst->vf_post.height; |
| vframe_ret->width = pst->vf_post.width; |
| memcpy(&vframe_ret->canvas0_config[0], |
| &pst->vf_post.canvas0_config[0], |
| sizeof(vframe_ret->canvas0_config[0])); |
| memcpy(&vframe_ret->canvas0_config[1], |
| &pst->vf_post.canvas0_config[1], |
| sizeof(vframe_ret->canvas0_config[1])); |
| #endif |
| if (di_mp_uit_get(edi_mp_show_nrwr)) { |
| vframe_ret->canvas0_config[0].phy_addr = |
| nr_buf->nr_adr; |
| vframe_ret->canvas0_config[0].width = |
| nr_buf->canvas_width[NR_CANVAS]; |
| vframe_ret->canvas0_config[0].height = |
| nr_buf->canvas_height; |
| } |
| |
| vframe_ret->early_process_fun = dim_do_post_wr_fun; |
| vframe_ret->process_fun = NULL; |
| |
| /* 2019-04-22 Suggestions from brian.zhu*/ |
| vframe_ret->mem_handle = NULL; |
| vframe_ret->type |= VIDTYPE_DI_PW; |
| #ifdef VFRAME_FLAG_DI_PW_VFM |
| vframe_ret->flag &= |
| ~(VFRAME_FLAG_DI_PW_VFM | |
| VFRAME_FLAG_DI_PW_N_LOCAL | |
| VFRAME_FLAG_DI_PW_N_EXT); |
| if (dip_itf_is_vfm(pch)) |
| vframe_ret->flag |= VFRAME_FLAG_DI_PW_VFM; |
| else if (dip_itf_is_ins_lbuf(pch)) |
| vframe_ret->flag |= VFRAME_FLAG_DI_PW_N_LOCAL; |
| else |
| vframe_ret->flag |= VFRAME_FLAG_DI_PW_N_EXT; |
| #endif |
| if (!dip_itf_is_o_linear(pch)) |
| vframe_ret->flag &= (~VFRAME_FLAG_VIDEO_LINEAR); |
| |
| /* 2019-04-22 */ |
| |
| /* dec vf keep */ |
| if (di_buf->in_buf) { |
| vframe_ret->flag |= VFRAME_FLAG_DOUBLE_FRAM; |
| //vframe_ret->vf_ext = |
| //pvframe_in[di_buf->in_buf->index]; |
| if (dip_itf_is_vfm(pch)) { |
| ins = (struct dim_nins_s *)di_buf->in_buf->c.in; |
| vframe_ret->vf_ext = ins->c.ori; |
| } else { |
| ins = (struct dim_nins_s *)di_buf->in_buf->c.in; |
| buffer = (struct di_buffer *)ins->c.ori; |
| vframe_ret->vf_ext = buffer->vf; |
| } |
| |
| if (vframe_ret->vf_ext) { |
| //vf = pvframe_in[di_buf->in_buf->index]; |
| vf = &ins->c.vfm_cp; //@ary_note: need change |
| if (vf->type & VIDTYPE_COMPRESS) { |
| vf->width = di_buf->dw_width_bk; |
| vf->height = di_buf->dw_height_bk; |
| } |
| dim_print("dim:dec vf:post:p[%d],i[%d],v[%p]\n", |
| di_buf->index, di_buf->in_buf->index, |
| vframe_ret->vf_ext); |
| dim_print("dim:dec vf:omx[%d][%d]\n", |
| di_buf->in_buf->vframe->index_disp, |
| vf->index_disp); |
| } else { |
| PR_ERR("%s:dec vf:buf:t[%d],i[%d],%d null\n", |
| __func__, di_buf->type, di_buf->index, |
| di_buf->in_buf->index); |
| dim_print("dec vf:post:p[%d],i[%d],v[NULL]\n", |
| di_buf->index, di_buf->in_buf->index); |
| } |
| } |
| if (dimp_get(edi_mp_force_width)) { |
| if (IS_COMP_MODE(di_buf->vframe->type)) { |
| vframe_ret->compWidth = |
| dimp_get(edi_mp_force_width); |
| } else { |
| vframe_ret->width = |
| dimp_get(edi_mp_force_width); |
| } |
| } |
| /* dbg_vfm(vframe_ret, 2);*/ |
| } else if (di_buf->flg_nr) { |
| vframe_ret->mem_handle = NULL; |
| vframe_ret->type |= VIDTYPE_DI_PW; |
| #ifdef VFRAME_FLAG_DI_PW_VFM |
| vframe_ret->flag &= |
| ~(VFRAME_FLAG_DI_PW_VFM | |
| VFRAME_FLAG_DI_PW_N_LOCAL | |
| VFRAME_FLAG_DI_PW_N_EXT); |
| if (dip_itf_is_vfm(pch)) |
| vframe_ret->flag |= VFRAME_FLAG_DI_PW_VFM; |
| else if (dip_itf_is_ins_lbuf(pch)) |
| vframe_ret->flag |= VFRAME_FLAG_DI_PW_N_LOCAL; |
| else |
| vframe_ret->flag |= VFRAME_FLAG_DI_PW_N_EXT; |
| #endif |
| if (!dip_itf_is_o_linear(pch)) |
| vframe_ret->flag &= (~VFRAME_FLAG_VIDEO_LINEAR); |
| if (di_buf->flg_nv21) { |
| //vframe_ret->plane_num = di_buf->vframe->plane_num; |
| vframe_ret->canvas0Addr = -1; |
| vframe_ret->canvas1Addr = -1; |
| #ifdef ERR_CODE |
| memcpy(&vframe_ret->canvas0_config[0], |
| &di_buf->vframe->canvas0_config[0], |
| sizeof(vframe_ret->canvas0_config[0])); |
| memcpy(&vframe_ret->canvas0_config[1], |
| &di_buf->vframe->canvas0_config[1], |
| sizeof(vframe_ret->canvas0_config[1])); |
| #endif |
| |
| } else { |
| vframe_ret->plane_num = 1; |
| vframe_ret->canvas0Addr = -1; |
| vframe_ret->canvas1Addr = -1; |
| vframe_ret->canvas0_config[0].phy_addr = di_buf->nr_adr; |
| vframe_ret->canvas0_config[0].endian = 0; |
| vframe_ret->canvas0_config[0].height = |
| di_buf->canvas_height; |
| vframe_ret->canvas0_config[0].width = |
| di_buf->canvas_width[NR_CANVAS]; |
| vframe_ret->canvas0_config[0].block_mode = 0; |
| } |
| dim_print("%s:flg_nv21[%d] cvs_h[%d]\n", __func__, |
| di_buf->flg_nv21, |
| di_buf->vframe->canvas0_config[0].height); |
| |
| /* dec vf keep */ |
| if (di_buf->in_buf) { |
| vframe_ret->flag |= VFRAME_FLAG_DOUBLE_FRAM; |
| if (dip_itf_is_vfm(pch)) { |
| ins = (struct dim_nins_s *)di_buf->in_buf->c.in; |
| vframe_ret->vf_ext = ins->c.ori; |
| } else { |
| ins = (struct dim_nins_s *)di_buf->in_buf->c.in; |
| buffer = (struct di_buffer *)ins->c.ori; |
| vframe_ret->vf_ext = buffer->vf; |
| } |
| |
| if (vframe_ret->vf_ext) { |
| //vf = pvframe_in[di_buf->in_buf->index]; |
| vf = &ins->c.vfm_cp; //@ary_note:need change |
| if (vf->type & VIDTYPE_COMPRESS) { |
| vf->width = di_buf->dw_width_bk; |
| vf->height = di_buf->dw_height_bk; |
| } |
| dim_print("dim:2decvf:post:p[%d],i[%d],v[%p]\n", |
| di_buf->index, di_buf->in_buf->index, |
| vframe_ret->vf_ext); |
| dim_print("dim:2dec vf:omx[%d][%d]\n", |
| di_buf->in_buf->vframe->index_disp, |
| vf->index_disp); |
| } else { |
| PR_ERR("%s:2dec vf:buf:t[%d],i[%d],%d null\n", |
| __func__, di_buf->type, di_buf->index, |
| di_buf->in_buf->index); |
| dim_print("2dec vf:post:p[%d],i[%d],v[NULL]\n", |
| di_buf->index, di_buf->in_buf->index); |
| } |
| } |
| } else if (di_buf->is_bypass_pst) { |
| if (di_buf->di_buf_dup_p[0] && |
| di_buf->di_buf_dup_p[0]->type == 2) { |
| buf_in = di_buf->di_buf_dup_p[0]; |
| PR_INF("post bypass:\n"); |
| vframe_ret->mem_handle = NULL; |
| #ifdef VFRAME_FLAG_DI_PW_VFM |
| if (dip_itf_is_vfm(pch)) |
| vframe_ret->flag |= VFRAME_FLAG_DI_PW_VFM; |
| else if (dip_itf_is_ins_lbuf(pch)) |
| vframe_ret->flag |= VFRAME_FLAG_DI_PW_N_LOCAL; |
| else |
| vframe_ret->flag |= VFRAME_FLAG_DI_PW_N_EXT; |
| #endif |
| if (!dip_itf_is_o_linear(pch)) |
| vframe_ret->flag &= (~VFRAME_FLAG_VIDEO_LINEAR); |
| vframe_ret->type |= VIDTYPE_DI_PW; |
| vframe_ret->type &= (~0xf); |
| vframe_ret->plane_num = 1; |
| di_buf->buf_hsize = buf_in->buf_hsize; |
| if (IS_COMP_MODE(di_buf->vframe->type)) { |
| vframe_ret->compHeight = |
| buf_in->vframe->compHeight / 2; |
| } else { |
| vframe_ret->height = buf_in->vframe->height / 2; |
| vframe_ret->canvas0_config[0].phy_addr = |
| buf_in->nr_adr; |
| vframe_ret->canvas0_config[0].width = |
| buf_in->canvas_width[0]; |
| vframe_ret->canvas0_config[0].block_mode = 0; |
| } |
| if (dimp_get(edi_mp_force_width)) { |
| if (IS_COMP_MODE(di_buf->vframe->type)) |
| vframe_ret->compWidth = |
| dimp_get(edi_mp_force_width); |
| else |
| vframe_ret->width = |
| dimp_get(edi_mp_force_width); |
| } |
| PR_INF("\t:buf[%d,%d],vfm[%d,%d,0x%x]\n", |
| di_buf->type, di_buf->index, |
| di_buf->vframe->width, di_buf->vframe->height, |
| di_buf->vframe->type); |
| #ifdef CVS_UINT |
| PR_INF("\t:0x%x,0x%x\n", |
| di_buf->vframe->canvas0_config[0].phy_addr, |
| di_buf->vframe->canvas0_config[1].phy_addr); |
| #else |
| PR_INF("\t:0x%lx,0x%lx\n", |
| di_buf->vframe->canvas0_config[0].phy_addr, |
| di_buf->vframe->canvas0_config[1].phy_addr); |
| #endif |
| PR_INF("\t:cmp[%d,%d]\n", di_buf->vframe->compWidth, |
| di_buf->vframe->compHeight); |
| PR_INF("\t:0x%x,0x%x\n", |
| di_buf->vframe->compBodyAddr, |
| di_buf->vframe->compHeadAddr); |
| } |
| |
| } else { |
| dim_print("%s:c\n", __func__); |
| } |
| if (dip_itf_is_ins_exbuf(pch)) { |
| vframe_ret->type &= (~VIDTYPE_DI_PW); |
| } else { |
| #ifdef MARK_HIS |
| if ((vframe_ret->type & VIDTYPE_DI_PW) && |
| cfgg(LINEAR) && |
| !IS_COMP_MODE(vframe_ret->type)) { |
| vframe_ret->canvas0_config[0].width = di_buf->buf_hsize; |
| vframe_ret->canvas0_config[1].width = di_buf->buf_hsize; |
| dbg_ic("set w buf_size[%d]:\n", di_buf->buf_hsize); |
| } |
| #endif |
| } |
| } |
| |
| #endif |
| void dim_post_de_done_buf_config(unsigned int channel) |
| { |
| //2020-12-07 ulong irq_flag2 = 0; |
| struct di_buf_s *di_buf = NULL; |
| struct di_post_stru_s *ppost = get_post_stru(channel); |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| struct di_ch_s *pch; |
| unsigned int datacrc = 0xffffffff; |
| |
| if (!ppost->cur_post_buf) { |
| PR_ERR("%s:no cur\n", __func__); |
| return; |
| } |
| pch = get_chdata(channel); |
| dbg_post_cnt(channel, "pd1"); |
| /*dbg*/ |
| dim_ddbg_mod_save(EDI_DBG_MOD_POST_DB, channel, ppost->frame_cnt); |
| di_buf = ppost->cur_post_buf; |
| |
| //2020-12-07 di_lock_irqfiq_save(irq_flag2); |
| queue_out(channel, ppost->cur_post_buf);/*? which que?post free*/ |
| |
| if (de_devp->pps_enable && dimp_get(edi_mp_pps_position) == 0) { |
| di_buf->vframe->width = dimp_get(edi_mp_pps_dstw); |
| di_buf->vframe->height = dimp_get(edi_mp_pps_dsth); |
| } |
| if (di_buf->flg_afbce_set) { /*afbce check cec*/ |
| di_buf->flg_afbce_set = 0; |
| } |
| #ifdef DI_DEBUG_POST_BUF_FLOW |
| #else |
| post_ready_buf_set(channel, di_buf); |
| #endif |
| if (di_buf->is_lastp) { |
| dbg_mem2("pst:lastp\n"); |
| di_buf->is_lastp = 0; |
| } |
| |
| //ary 2020-12-07di_que_in(channel, QUE_POST_READY, ppost->cur_post_buf); |
| |
| #ifdef DI_DEBUG_POST_BUF_FLOW |
| #else |
| /*add by ary:*/ |
| if (!di_buf->is_bypass_pst) |
| recycle_post_ready_local(ppost->cur_post_buf, channel); |
| #endif |
| //2020-12-07 di_unlock_irqfiq_restore(irq_flag2); |
| dim_tr_ops.post_ready(di_buf->vframe->index_disp); |
| if (dimp_get(edi_mp_pstcrc_ctrl) == 1) { |
| if (DIM_IS_IC(T5) || |
| DIM_IS_IC(T5D)) { |
| datacrc = RD(DI_T5_RO_CRC_DEINT); |
| DIM_DI_WR_REG_BITS(DI_T5_CRC_CHK0, |
| 0x1, 30, 1); |
| } else if (DIM_IS_IC_EF(SC2)) { |
| datacrc = RD(DI_RO_CRC_DEINT); |
| DIM_DI_WR_REG_BITS(DI_CRC_CHK0, |
| 0x1, 30, 1); |
| } |
| dbg_post_ref("DEINT ==ch[=0x%x]\n", datacrc); |
| //dbg_post_ref("irq p= 0x%p\n",ppost->cur_post_buf); |
| ppost->cur_post_buf->datacrc = datacrc; |
| } |
| pch->itf.op_fill_ready(pch, ppost->cur_post_buf); |
| mtask_wake_m(); |
| #ifdef MARK_HIS//2020-12-07 move to ndis_fill_ready |
| pw_vf_notify_receiver(channel, |
| VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); |
| #endif |
| ppost->cur_post_buf = NULL; |
| /*dbg*/ |
| dim_ddbg_mod_save(EDI_DBG_MOD_POST_DE, channel, ppost->frame_cnt); |
| dbg_post_cnt(channel, "pd2"); |
| } |
| |
| static void recycle_vframe_type_post(struct di_buf_s *di_buf, |
| unsigned int channel) |
| { |
| int i; |
| struct div2_mm_s *mm; |
| struct di_ch_s *pch = get_chdata(channel); |
| bool release_flg = false; |
| bool sct_buf = false;//for sct |
| |
| if (!di_buf) { |
| PR_ERR("%s:\n", __func__); |
| if (recovery_flag == 0) |
| recovery_log_reason = 15; |
| |
| recovery_flag++; |
| return; |
| } |
| if (di_buf->process_fun_index == PROCESS_FUN_DI) |
| dec_post_ref_count(di_buf); |
| |
| for (i = 0; i < 2; i++) { |
| if (di_buf->di_buf[i]) { |
| queue_in(channel, di_buf->di_buf[i], QUEUE_RECYCLE); |
| dim_print("%s: ch[%d]:di_buf[%d],type=%d\n", __func__, |
| channel, di_buf->di_buf[i]->index, |
| di_buf->di_buf[i]->type); |
| if (dimp_get(edi_mp_bypass_post_state)) { |
| PR_INF("%s: ch[%d]:di_buf[%d],type=%d\n", |
| __func__, |
| channel, di_buf->di_buf[i]->index, |
| di_buf->di_buf[i]->type); |
| } |
| } |
| } |
| queue_out(channel, di_buf); /* remove it from display_list_head */ |
| if (di_buf->queue_index != -1) { |
| PR_ERR("qout err:index[%d],typ[%d],qindex[%d]\n", |
| di_buf->index, di_buf->type, di_buf->queue_index); |
| /* queue_out_dbg(channel, di_buf);*/ |
| } |
| di_buf->invert_top_bot_flag = 0; |
| di_buf->flg_nr = 0; |
| di_buf->flg_nv21 = 0; |
| mm = dim_mm_get(channel); |
| if (di_buf->blk_buf) { |
| if (di_buf->blk_buf->flg.d32 != mm->cfg.pbuf_flg.d32) { |
| mem_release_one_inused(pch, di_buf->blk_buf); |
| dbg_mem2("keep_buf:3:flg trig realloc,0x%x->0x%x\n", |
| di_buf->blk_buf->flg.d32, |
| mm->cfg.pbuf_flg.d32); |
| di_buf->blk_buf = NULL; |
| di_que_in(channel, QUE_PST_NO_BUF, di_buf); |
| release_flg = true; |
| mm->sts.flg_realloc++; |
| dbg_mem2("%s:stsflg_realloc[%d]\n", __func__, |
| mm->sts.flg_realloc); |
| } else if (di_buf->blk_buf->flg.b.typ == EDIM_BLK_TYP_PSCT) { |
| if (di_buf->blk_buf->sct) { |
| qsct_used_some_to_recycle(pch, |
| (struct dim_sct_s *)di_buf->blk_buf->sct); |
| di_buf->blk_buf->sct = NULL; |
| di_buf->blk_buf->pat_buf = NULL; |
| di_que_in(channel, QUE_PST_NO_BUF_WAIT, di_buf); |
| sct_buf = true; |
| } |
| } |
| } else { |
| release_flg = true; |
| di_que_in(channel, QUE_PST_NO_BUF, di_buf); |
| } |
| if ((!release_flg) && (!sct_buf)) |
| di_que_in(channel, QUE_POST_FREE, di_buf); |
| } |
| |
| void recycle_post_ready_local(struct di_buf_s *di_buf, |
| unsigned int channel) |
| { |
| int i; |
| |
| if (di_buf->type != VFRAME_TYPE_POST) |
| return; |
| |
| if (di_buf->process_fun_index == PROCESS_FUN_NULL) /*bypass?*/ |
| return; |
| |
| if (di_buf->process_fun_index == PROCESS_FUN_DI) |
| dec_post_ref_count(di_buf); |
| |
| for (i = 0; i < 2; i++) { |
| if (di_buf->di_buf[i]) { |
| queue_in(channel, di_buf->di_buf[i], QUEUE_RECYCLE); |
| dim_print("%s: ch[%d]:di_buf[%d],type=%d\n", |
| __func__, |
| channel, |
| di_buf->di_buf[i]->index, |
| di_buf->di_buf[i]->type); |
| di_buf->di_buf[i] = NULL; |
| } |
| } |
| } |
| |
| #ifdef DI_BUFFER_DEBUG |
| static void |
| recycle_vframe_type_post_print(struct di_buf_s *di_buf, |
| const char *func, |
| const int line) |
| { |
| int i; |
| |
| dim_print("%s:%d ", func, line); |
| for (i = 0; i < 2; i++) { |
| if (di_buf->di_buf[i]) |
| dim_print("%s[%d]<%d>=>recycle_list; ", |
| vframe_type_name[di_buf->di_buf[i]->type], |
| di_buf->di_buf[i]->index, i); |
| } |
| dim_print("%s[%d] =>post_free_list\n", |
| vframe_type_name[di_buf->type], di_buf->index); |
| } |
| #endif |
| |
| static unsigned int pldn_dly1 = 1; |
| static void set_pulldown_mode(struct di_buf_s *di_buf, unsigned int channel) |
| { |
| struct di_buf_s *pre_buf_p = di_buf->di_buf_dup_p[pldn_dly1]; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXBB)) { |
| if (dimp_get(edi_mp_pulldown_enable) && |
| !ppre->cur_prog_flag) { |
| if (pre_buf_p) { |
| di_buf->pd_config.global_mode = |
| pre_buf_p->pd_config.global_mode; |
| } else { |
| /* ary add 2019-06-19*/ |
| di_buf->pd_config.global_mode = |
| PULL_DOWN_EI; |
| PR_ERR("[%s]: index out of range.\n", |
| __func__); |
| } |
| } else { |
| di_buf->pd_config.global_mode = PULL_DOWN_NORMAL; |
| } |
| } |
| } |
| |
| static void drop_frame(int check_drop, int throw_flag, struct di_buf_s *di_buf, |
| unsigned int channel) |
| { |
| //ary 2020-12-09 ulong irq_flag2 = 0; |
| int i = 0, drop_flag = 0; |
| struct di_post_stru_s *ppost = get_post_stru(channel); |
| |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); |
| if (frame_count == 0 && check_drop) { |
| ppost->start_pts = di_buf->vframe->pts; |
| ppost->start_pts64 = di_buf->vframe->pts_us64; |
| } |
| if ((check_drop && |
| frame_count < dimp_get(edi_mp_start_frame_drop_count)) || |
| throw_flag) { |
| drop_flag = 1; |
| } else { |
| if (check_drop && frame_count |
| == dimp_get(edi_mp_start_frame_drop_count)) { |
| if (ppost->start_pts && |
| di_buf->vframe->pts == 0) { |
| di_buf->vframe->pts = ppost->start_pts; |
| di_buf->vframe->pts_us64 = ppost->start_pts64; |
| } |
| ppost->start_pts = 0; |
| } |
| for (i = 0; i < 3; i++) { |
| if (di_buf->di_buf_dup_p[i]) { |
| if (di_buf->di_buf_dup_p[i]->vframe->bitdepth != |
| di_buf->vframe->bitdepth) { |
| pr_info("%s buf[%d] not match bit mode\n", |
| __func__, i); |
| drop_flag = 1; |
| break; |
| } |
| } |
| } |
| } |
| if (drop_flag) { |
| dim_print("%s:drop:t[%d],indx[%d]\n", __func__, |
| di_buf->type, di_buf->index); |
| |
| /*dec vf keep*/ |
| if (di_buf->in_buf) { |
| queue_in(channel, di_buf->in_buf, QUEUE_RECYCLE); |
| di_buf->in_buf = NULL; |
| } |
| queue_in(channel, di_buf, QUEUE_TMP); |
| recycle_vframe_type_post(di_buf, channel); |
| |
| #ifdef DI_BUFFER_DEBUG |
| recycle_vframe_type_post_print(di_buf, __func__, __LINE__); |
| #endif |
| } else { |
| dim_print("%s:wr_en[%d],support[%d]\n", __func__, |
| dimp_get(edi_mp_post_wr_en), |
| dimp_get(edi_mp_post_wr_support)); |
| |
| if (dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) { |
| //queue_in(channel, di_buf, QUEUE_POST_DOING); |
| di_que_in(channel, QUE_POST_DOING, di_buf); |
| } else { |
| //no use di_que_in(channel, QUE_POST_READY, di_buf); |
| } |
| dim_tr_ops.post_do(di_buf->vframe->index_disp); |
| dim_print("di:ch[%d]:%dth %s[%d] => post ready %u ms.\n", |
| channel, |
| frame_count, |
| vframe_type_name[di_buf->type], di_buf->index, |
| jiffies_to_msecs(jiffies_64 - |
| di_buf->vframe->ready_jiffies64)); |
| } |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| } |
| |
| static bool dim_pst_vfm_bypass(struct di_ch_s *pch, struct di_buf_s *ready_buf) |
| { |
| unsigned int ch; |
| struct di_buf_s *di_buf, *p; |
| |
| ch = pch->ch_id; |
| if (ready_buf && ready_buf->is_eos && !ready_buf->c.in) { |
| /* int eos */ |
| dbg_bypass("%s:only int eos\n", __func__); |
| p = di_que_out_to_di_buf(ch, QUE_PRE_READY); |
| p->is_eos = 0; |
| queue_in(ch, p, QUEUE_RECYCLE); |
| return true; |
| } |
| |
| //dbg_bypass("%s:1\n", __func__); |
| di_buf = di_que_out_to_di_buf(ch, QUE_PST_NO_BUF); |
| if (dim_check_di_buf(di_buf, 19, ch)) { |
| PR_ERR("%s:no pst_no_buf", __func__); |
| return false; |
| } |
| //dbg_bypass("%s:2\n", __func__); |
| p = di_que_out_to_di_buf(ch, QUE_PRE_READY); |
| //dbg_bypass("%s:3\n", __func__); |
| di_buf->di_buf_dup_p[0] = p; |
| di_buf->di_buf_dup_p[1] = NULL; |
| di_buf->di_buf_dup_p[2] = NULL; |
| di_buf->process_fun_index = PROCESS_FUN_NULL; |
| di_buf->is_nbypass = p->is_nbypass; |
| //dbg_bypass("%s:4\n", __func__); |
| di_que_in(ch, QUE_POST_DOING, di_buf); |
| //dbg_bypass("%s:5\n", __func__); |
| //dbg_bypass("%s:0x%px:%d,%d\n", __func__, p, p->type, p->index); |
| //dbg_bypass("%s:\n", __func__); |
| return true; |
| } |
| |
| int dim_process_post_vframe(unsigned int channel) |
| { |
| /* |
| * 1) get buf from post_free_list, config it according to buf |
| * in pre_ready_list, send it to post_ready_list |
| * (it will be send to post_free_list in di_vf_put()) |
| * 2) get buf from pre_ready_list, attach it to buf from post_free_list |
| * (it will be send to recycle_list in di_vf_put() ) |
| */ |
| //ary 2020-12-09 ulong irq_flag2 = 0; |
| int i = 0; |
| int tmp = 0; |
| int tmp0 = 0; |
| int tmp1 = 0; |
| unsigned int tmp2; |
| int ret = 0; |
| int buffer_keep_count = 3; |
| struct di_buf_s *di_buf = NULL; |
| struct di_buf_s *ready_di_buf; |
| struct di_buf_s *p = NULL;/* , *ptmp; */ |
| int itmp; |
| /* new que int ready_count = list_count(channel, QUEUE_PRE_READY);*/ |
| int ready_count = di_que_list_count(channel, QUE_PRE_READY); |
| bool check_drop = false; |
| unsigned int tmpa[MAX_FIFO_SIZE]; /*new que*/ |
| unsigned int psize; /*new que*/ |
| struct di_ch_s *pch = get_chdata(channel); |
| struct di_buf_s *tmp_buf[3]; |
| bool flg_eos = false; |
| //struct dim_nins_s *nins; //add for eos |
| |
| #ifdef MARK_SC2 /* */ |
| if (di_que_is_empty(channel, QUE_POST_FREE)) |
| return 0; |
| #endif |
| /*add : for now post buf only 3.*/ |
| //if (list_count(channel, QUEUE_POST_DOING) > 2) |
| if (di_que_list_count(channel, QUE_POST_DOING) > 2) |
| return 0; |
| |
| if (ready_count == 0) |
| return 0; |
| |
| ready_di_buf = di_que_peek(channel, QUE_PRE_READY); |
| if (!ready_di_buf || !ready_di_buf->vframe) { |
| pr_dbg("%s:Error1\n", __func__); |
| |
| if (recovery_flag == 0) |
| recovery_log_reason = 16; |
| |
| recovery_flag++; |
| return 0; |
| } |
| if (!ready_di_buf->flg_null && !ready_di_buf->buf_is_i) { |
| if (!pp_check_buf_post(pch)) |
| return 0; |
| } |
| /*dim_print("%s:1 ready_count[%d]:post_proc_flag[%d]\n", __func__,*/ |
| /* ready_count, ready_di_buf->post_proc_flag); */ |
| if (ready_di_buf->post_proc_flag && |
| ready_count >= buffer_keep_count) { |
| i = 0; |
| |
| di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize); |
| for (itmp = 0; itmp < psize; itmp++) { |
| p = pw_qindex_2_buf(channel, tmpa[itmp]); |
| /* if(p->post_proc_flag == 0){ */ |
| #ifdef HIS_CODE |
| if (p->type == VFRAME_TYPE_IN) { |
| ready_di_buf->post_proc_flag = -1; |
| ready_di_buf->new_format_flag = 1; |
| } |
| #endif |
| if (p->is_eos) |
| flg_eos = true; |
| i++; |
| if (i > 2) |
| break; |
| } |
| } |
| if (ready_count == 1 && ready_di_buf->is_eos) { |
| PR_INF("%s:only eos\n", __func__); |
| dim_pst_vfm_bypass(pch, ready_di_buf); |
| return 1; |
| } |
| if (ready_di_buf->is_nbypass) { |
| dbg_bypass("%s:bypass?\n", __func__); |
| dim_pst_vfm_bypass(pch, NULL); |
| return 1; |
| } |
| |
| if (ready_di_buf->post_proc_flag > 0) { |
| if ((ready_count >= buffer_keep_count) && flg_eos) { |
| for (i = 0; i < 3; i++) |
| tmp_buf[i] = NULL; |
| i = 0; |
| di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize); |
| |
| for (itmp = 0; itmp < psize; itmp++) { |
| p = pw_qindex_2_buf(channel, tmpa[itmp]); |
| dim_print("di:keep[%d]:t[%d]:idx[%d]\n", |
| i, tmpa[itmp], p->index); |
| //di_buf->di_buf_dup_p[i++] = p; |
| tmp_buf[i++] = p; |
| |
| if (i >= buffer_keep_count) |
| break; |
| } |
| |
| if (!tmp_buf[1]->is_eos && tmp_buf[1]->di_buf_post) { |
| di_buf = tmp_buf[1]->di_buf_post; |
| tmp_buf[1]->di_buf_post = NULL; |
| if (!di_buf) { |
| PR_ERR("%s: eos pst null\n", __func__); |
| return 0; |
| } |
| dbg_bypass("%s:eos:post_buf:t[%d]idx[%d]\n", |
| __func__, di_buf->type, |
| di_buf->index); |
| memcpy(di_buf->vframe, |
| tmp_buf[1]->vframe, |
| sizeof(vframe_t)); |
| di_buf->vframe->private_data = di_buf; |
| di_buf->pd_config.global_mode = PULL_DOWN_EI; |
| di_buf->vframe->type = |
| VIDTYPE_PROGRESSIVE | |
| VIDTYPE_VIU_422 | |
| VIDTYPE_VIU_SINGLE_PLANE | |
| VIDTYPE_VIU_FIELD | |
| VIDTYPE_PRE_INTERLACE; |
| |
| di_buf->vframe->width = |
| tmp_buf[1]->width_bk; |
| di_buf->dw_width_bk = ready_di_buf->dw_width_bk; |
| di_buf->dw_height_bk = |
| ready_di_buf->dw_height_bk; |
| |
| di_buf->vframe->early_process_fun = |
| do_nothing_fun; |
| |
| di_buf->vframe->process_fun = NULL; |
| di_buf->process_fun_index = PROCESS_FUN_DI; |
| di_buf->di_buf_dup_p[0] = tmp_buf[0]; |
| di_buf->di_buf_dup_p[1] = tmp_buf[1]; |
| di_buf->di_buf_dup_p[2] = NULL; |
| inc_post_ref_count(di_buf); |
| |
| di_buf->di_buf[0] = tmp_buf[0]; |
| di_buf->di_buf[1] = tmp_buf[1]; |
| di_buf->di_buf[0]->pre_ref_count = 0; |
| di_buf->di_buf[1]->pre_ref_count = 0; |
| queue_out(channel, tmp_buf[0]); |
| queue_out(channel, tmp_buf[1]); |
| PR_INF("eos:que out 0:t[%d]idx[%d]\n", |
| tmp_buf[0]->type, |
| tmp_buf[0]->index); |
| PR_INF("eos:que out 1:t[%d]idx[%d]\n", |
| tmp_buf[1]->type, |
| tmp_buf[1]->index); |
| // tmp = di_buf->di_buf_dup_p[0]->throw_flag; |
| // tmp0 = di_buf->di_buf_dup_p[1]->throw_flag; |
| // tmp1 = di_buf->di_buf_dup_p[2]->throw_flag; |
| drop_frame(true, 0, di_buf, channel); |
| |
| frame_count++; |
| |
| ret = true; |
| } |
| |
| if (tmp_buf[2] && tmp_buf[2]->is_eos) { |
| #ifdef HIS_CODE |
| tmp_buf[2]->is_eos = 0; |
| queue_out(channel, tmp_buf[2]); |
| di_que_in(channel, QUE_PRE_NO_BUF, tmp_buf[2]); |
| #endif |
| dim_pst_vfm_bypass(pch, tmp_buf[2]); |
| PR_INF("eos:que out 2:t[%d]idx[%d]\n", |
| tmp_buf[2]->type, tmp_buf[2]->index); |
| } else { |
| PR_ERR("tmp_buf[2] is not eos\n"); |
| } |
| } else if (ready_count >= buffer_keep_count) {/* i ?*/ |
| i = 0; |
| |
| di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize); |
| |
| for (itmp = 0; itmp < psize; itmp++) { |
| p = pw_qindex_2_buf(channel, tmpa[itmp]); |
| dim_print("di:keep[%d]:t[%d]:idx[%d]\n", |
| i, tmpa[itmp], p->index); |
| //di_buf->di_buf_dup_p[i++] = p; |
| tmp_buf[i++] = p; |
| |
| if (i >= buffer_keep_count) |
| break; |
| } |
| if (i < buffer_keep_count) { |
| PR_ERR("%s:3\n", __func__); |
| |
| if (recovery_flag == 0) |
| recovery_log_reason = 18; |
| recovery_flag++; |
| return 0; |
| } |
| di_buf = tmp_buf[1]->di_buf_post; |
| tmp_buf[1]->di_buf_post = NULL; |
| if (!di_buf) { |
| PR_ERR("%s:di_buf_post is null\n", __func__); |
| return 0; |
| } |
| for (i = 0; i < 3; i++) |
| di_buf->di_buf_dup_p[i] = tmp_buf[i]; |
| |
| memcpy(di_buf->vframe, |
| di_buf->di_buf_dup_p[1]->vframe, |
| sizeof(vframe_t)); |
| di_buf->vframe->private_data = di_buf; |
| di_buf->afbc_sgn_cfg = |
| di_buf->di_buf_dup_p[1]->afbc_sgn_cfg; |
| memcpy(&di_buf->pq_rpt, |
| &di_buf->di_buf_dup_p[1]->pq_rpt, |
| sizeof(di_buf->pq_rpt)); |
| if (di_buf->di_buf_dup_p[1]->post_proc_flag == 3) { |
| /* dummy, not for display */ |
| inc_post_ref_count(di_buf); |
| di_buf->di_buf[0] = di_buf->di_buf_dup_p[0]; |
| di_buf->di_buf[1] = NULL; |
| queue_out(channel, di_buf->di_buf[0]); |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); |
| queue_in(channel, di_buf, QUEUE_TMP); |
| recycle_vframe_type_post(di_buf, channel); |
| |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| dim_print("%s <dummy>: ", __func__); |
| |
| } else { |
| tmp2 = di_buf->di_buf_dup_p[1]->field_count; |
| if (di_buf->di_buf_dup_p[1]->post_proc_flag |
| == 2) { |
| di_buf->pd_config.global_mode = |
| PULL_DOWN_BLEND_2; |
| /* blend with di_buf->di_buf_dup_p[2] */ |
| } else if (tmp2 < 2) { |
| di_buf->pd_config.global_mode = |
| PULL_DOWN_EI; |
| } else { |
| set_pulldown_mode(di_buf, channel); |
| if (tmp2 == 2) |
| di_buf->trig_post_update = 1; |
| } |
| di_buf->vframe->type = |
| VIDTYPE_PROGRESSIVE | |
| VIDTYPE_VIU_422 | |
| VIDTYPE_VIU_SINGLE_PLANE | |
| VIDTYPE_VIU_FIELD | |
| VIDTYPE_PRE_INTERLACE; |
| |
| di_buf->vframe->width = |
| di_buf->di_buf_dup_p[1]->width_bk; |
| di_buf->dw_width_bk = ready_di_buf->dw_width_bk; |
| di_buf->dw_height_bk = ready_di_buf->dw_height_bk; |
| |
| if (di_buf->di_buf_dup_p[1]->new_format_flag) { |
| /* if (di_buf->di_buf_dup_p[1] |
| * ->post_proc_flag == 2) { |
| */ |
| di_buf->vframe->early_process_fun = |
| de_post_disable_fun; |
| } else { |
| di_buf->vframe->early_process_fun = |
| do_nothing_fun; |
| } |
| |
| if (di_buf->di_buf_dup_p[1]->type == VFRAME_TYPE_IN) { |
| /* next will be bypass */ |
| di_buf->vframe->type = |
| VIDTYPE_PROGRESSIVE | |
| VIDTYPE_VIU_422 | |
| VIDTYPE_VIU_SINGLE_PLANE | |
| VIDTYPE_VIU_FIELD | |
| VIDTYPE_PRE_INTERLACE; |
| di_buf->vframe->height >>= 1; |
| di_buf->vframe->canvas0Addr = |
| di_buf->di_buf_dup_p[0] |
| ->nr_canvas_idx; /* top */ |
| di_buf->vframe->canvas1Addr = |
| di_buf->di_buf_dup_p[0] |
| ->nr_canvas_idx; |
| di_buf->vframe->process_fun = |
| NULL; |
| di_buf->process_fun_index = PROCESS_FUN_NULL; |
| } else { |
| /*for debug*/ |
| if (dimp_get(edi_mp_debug_blend_mode) != -1) |
| di_buf->pd_config.global_mode = |
| dimp_get(edi_mp_debug_blend_mode); |
| |
| di_buf->vframe->process_fun = |
| ((dimp_get(edi_mp_post_wr_en) && dimp_get(edi_mp_post_wr_support)) ? |
| NULL : dim_post_process); |
| di_buf->process_fun_index = PROCESS_FUN_DI; |
| inc_post_ref_count(di_buf); |
| } |
| di_buf->di_buf[0] = /*ary:di_buf_di_buf*/ |
| di_buf->di_buf_dup_p[0]; |
| di_buf->di_buf[1] = NULL; |
| queue_out(channel, di_buf->di_buf[0]); |
| |
| tmp = di_buf->di_buf_dup_p[0]->throw_flag; |
| tmp0 = di_buf->di_buf_dup_p[1]->throw_flag; |
| tmp1 = di_buf->di_buf_dup_p[2]->throw_flag; |
| drop_frame(true, tmp || tmp0 || tmp1, |
| di_buf, channel); |
| |
| frame_count++; |
| |
| if (!(dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support))) |
| pw_vf_notify_receiver(channel, |
| VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); |
| } |
| if (dip_itf_is_ins(pch) && dim_dbg_new_int(2)) |
| dim_dbg_buffer2(di_buf->c.buffer, 5); |
| ret = 1; |
| } |
| } else { |
| if (is_progressive(ready_di_buf->vframe) && |
| !ready_di_buf->flg_null && |
| !ready_di_buf->buf_is_i && |
| ready_di_buf->type != VFRAME_TYPE_IN) { |
| /******************************************************************************/ |
| /* p as p */ |
| struct di_buf_s *di_buf_i; |
| |
| //dim_print("%s:p as p\n", __func__); |
| |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); |
| |
| queue_out(channel, ready_di_buf); |
| |
| di_buf = pp_local_2_post(pch, ready_di_buf); |
| //di_que_out_to_di_buf(channel, QUE_POST_FREE); |
| if (dim_check_di_buf(di_buf, 19, channel)) { |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| return 0; |
| } |
| |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| memcpy(&di_buf->pq_rpt, &ready_di_buf->pq_rpt, |
| sizeof(di_buf->pq_rpt)); |
| di_buf->di_buf_dup_p[0] = di_buf;//ready_di_buf; |
| di_buf->di_buf_dup_p[1] = NULL; |
| di_buf->di_buf_dup_p[2] = NULL; |
| |
| di_buf_i = ready_di_buf; |
| dim_print |
| ("p as p ready_buf:pnub[%d],cvs_w[%d]\n", |
| ready_di_buf->vframe->plane_num, |
| ready_di_buf->vframe->canvas0_config[0].width); |
| memcpy(di_buf->vframe, di_buf_i->vframe, |
| sizeof(vframe_t)); |
| |
| di_buf->vframe->width = di_buf_i->width_bk; |
| di_buf->dw_width_bk = ready_di_buf->dw_width_bk; |
| di_buf->dw_height_bk = ready_di_buf->dw_height_bk; |
| di_buf->vframe->private_data = di_buf; |
| |
| di_buf->vframe->early_process_fun = |
| do_pre_only_fun; |
| |
| di_buf->vframe->process_fun = NULL; |
| di_buf->process_fun_index = PROCESS_FUN_NULL; |
| di_buf->pd_config.global_mode = PULL_DOWN_NORMAL; |
| |
| di_buf->di_buf[0] = NULL;//ready_di_buf; |
| di_buf->di_buf[1] = NULL; |
| di_buf->flg_nr = 1; |
| if (ready_di_buf->is_lastp) { |
| ready_di_buf->is_lastp = 0; |
| di_buf->is_lastp = 1; |
| } |
| di_buf->flg_nv21 = di_buf_i->flg_nv21; |
| pp_drop_frame(di_buf, channel); |
| |
| di_que_in(channel, QUE_PRE_NO_BUF, ready_di_buf); |
| |
| frame_count++; |
| |
| ret = 1; |
| #ifdef MARK_HIS |
| pw_vf_notify_receiver |
| (channel, |
| VFRAME_EVENT_PROVIDER_VFRAME_READY, |
| NULL); |
| #endif |
| /******************************************************************************/ |
| |
| } else if (is_progressive(ready_di_buf->vframe) || |
| ready_di_buf->type == VFRAME_TYPE_IN || |
| ready_di_buf->post_proc_flag < 0 || |
| dimp_get(edi_mp_bypass_post_state) |
| ){ |
| int vframe_process_count = 1; |
| |
| if (dimp_get(edi_mp_skip_top_bot) && |
| (!is_progressive(ready_di_buf->vframe))) |
| vframe_process_count = 2; |
| |
| if (ready_count >= vframe_process_count) { |
| struct di_buf_s *di_buf_i; |
| |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); |
| #ifdef MARK_SC2 |
| di_buf = di_que_out_to_di_buf(channel, QUE_POST_FREE); |
| #else |
| di_buf = di_que_out_to_di_buf(channel, QUE_PST_NO_BUF); |
| #endif |
| if (dim_check_di_buf(di_buf, 19, channel)) { |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| return 0; |
| } |
| |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| |
| i = 0; |
| |
| di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize); |
| |
| for (itmp = 0; itmp < psize; itmp++) { |
| p = pw_qindex_2_buf(channel, |
| tmpa[itmp]); |
| di_buf->di_buf_dup_p[i++] = p; |
| if (i >= vframe_process_count) { |
| di_buf->di_buf_dup_p[i] = |
| NULL; |
| di_buf->di_buf_dup_p[i + 1] = |
| NULL; |
| break; |
| } |
| } |
| if (i < vframe_process_count) { |
| PR_ERR("%s:6\n", __func__); |
| if (recovery_flag == 0) |
| recovery_log_reason = 22; |
| |
| recovery_flag++; |
| return 0; |
| } |
| |
| di_buf_i = di_buf->di_buf_dup_p[0]; |
| if (!is_progressive(ready_di_buf->vframe) && |
| ((dimp_get(edi_mp_skip_top_bot) == 1) || |
| (dimp_get(edi_mp_skip_top_bot) == 2))) { |
| unsigned int frame_type = |
| di_buf->di_buf_dup_p[1]-> |
| vframe->type & |
| VIDTYPE_TYPEMASK; |
| if (dimp_get(edi_mp_skip_top_bot) |
| == 1) { |
| di_buf_i = (frame_type == |
| VIDTYPE_INTERLACE_TOP) |
| ? di_buf->di_buf_dup_p[1] |
| : di_buf->di_buf_dup_p[0]; |
| } else if (dimp_get(edi_mp_skip_top_bot) |
| == 2) { |
| di_buf_i = (frame_type == |
| VIDTYPE_INTERLACE_BOTTOM) |
| ? di_buf->di_buf_dup_p[1] |
| : di_buf->di_buf_dup_p[0]; |
| } |
| } |
| |
| memcpy(di_buf->vframe, di_buf_i->vframe, |
| sizeof(vframe_t)); |
| |
| di_buf->vframe->width = di_buf_i->width_bk; |
| di_buf->dw_width_bk = ready_di_buf->dw_width_bk; |
| di_buf->dw_height_bk = |
| ready_di_buf->dw_height_bk; |
| di_buf->vframe->private_data = di_buf; |
| di_buf->is_nbypass = di_buf_i->is_nbypass; |
| if (dimp_get(edi_mp_bypass_post_state)) { |
| di_buf->is_bypass_pst = 1; |
| di_buf_i->pre_ref_count = 0; |
| di_buf->process_fun_index = 0; |
| //PROCESS_FUN_NULL; |
| PR_INF("%s:pst bypass buf[%d:%d]\n", |
| __func__, |
| di_buf->type, di_buf->index); |
| } |
| if (ready_di_buf->new_format_flag && |
| ready_di_buf->type == VFRAME_TYPE_IN) { |
| pr_info("DI:ch[%d],%d disable post.\n", |
| channel, |
| __LINE__); |
| di_buf->vframe->early_process_fun = |
| de_post_disable_fun; |
| } else { |
| if (ready_di_buf->type == |
| VFRAME_TYPE_IN) |
| di_buf->vframe-> |
| early_process_fun = |
| do_nothing_fun; |
| |
| else |
| di_buf->vframe-> |
| early_process_fun = |
| do_pre_only_fun; |
| } |
| dim_print("%s:2\n", __func__); |
| if (di_buf->is_bypass_pst) { |
| di_buf->vframe->process_fun = |
| NULL; |
| } else if (ready_di_buf->post_proc_flag == -2) { |
| di_buf->vframe->type |= |
| VIDTYPE_VIU_FIELD; |
| di_buf->vframe->type &= |
| ~(VIDTYPE_TYPEMASK); |
| di_buf->vframe->process_fun |
| = (dimp_get(edi_mp_post_wr_en) && dimp_get(edi_mp_post_wr_support)) ? NULL : |
| dim_post_process; |
| di_buf->process_fun_index = |
| PROCESS_FUN_DI; |
| di_buf->pd_config.global_mode = |
| PULL_DOWN_EI; |
| } else { |
| di_buf->vframe->process_fun = |
| NULL; |
| di_buf->process_fun_index = |
| PROCESS_FUN_NULL; |
| di_buf->pd_config.global_mode = |
| PULL_DOWN_NORMAL; |
| } |
| di_buf->di_buf[0] = ready_di_buf; |
| di_buf->di_buf[1] = NULL; |
| queue_out(channel, ready_di_buf); |
| |
| tmp = di_buf->di_buf[0]->throw_flag; |
| drop_frame(check_drop, tmp, di_buf, channel); |
| |
| frame_count++; |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s <prog by frame>: ", __func__); |
| #endif |
| ret = 1; |
| #ifdef MARK_HIS |
| pw_vf_notify_receiver |
| (channel, |
| VFRAME_EVENT_PROVIDER_VFRAME_READY, |
| NULL); |
| #endif |
| } |
| } else if (ready_count >= 2) { |
| /*for progressive input,type |
| * 1:separate tow fields,type |
| * 2:bypass post as frame |
| */ |
| unsigned char prog_tb_field_proc_type = |
| (dimp_get(edi_mp_prog_proc_config) >> 1) & 0x3; |
| |
| i = 0; |
| |
| di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize); |
| |
| for (itmp = 0; itmp < psize; itmp++) { |
| p = pw_qindex_2_buf(channel, tmpa[itmp]); |
| //di_buf->di_buf_dup_p[i++] = p; |
| tmp_buf[i++] = p; |
| if (i >= 2) { |
| di_buf->di_buf_dup_p[i] = NULL; |
| break; |
| } |
| } |
| if (i < 2) { |
| PR_ERR("%s:Error6\n", __func__); |
| |
| if (recovery_flag == 0) |
| recovery_log_reason = 21; |
| |
| recovery_flag++; |
| return 0; |
| } |
| |
| di_buf = tmp_buf[0]->di_buf_post; |
| tmp_buf[0]->di_buf_post = NULL; |
| for (i = 0; i < 2; i++) |
| di_buf->di_buf_dup_p[i] = tmp_buf[i]; |
| |
| memcpy(di_buf->vframe, |
| di_buf->di_buf_dup_p[0]->vframe, |
| sizeof(vframe_t)); |
| |
| di_buf->dw_width_bk = ready_di_buf->dw_width_bk; |
| di_buf->dw_height_bk = ready_di_buf->dw_height_bk; |
| |
| di_buf->vframe->private_data = di_buf; |
| di_buf->afbc_sgn_cfg = |
| di_buf->di_buf_dup_p[0]->afbc_sgn_cfg; |
| /*separate one progressive frame |
| * as two interlace fields |
| */ |
| if (prog_tb_field_proc_type == 1) { |
| /* do weave by di post */ |
| di_buf->vframe->type = |
| VIDTYPE_PROGRESSIVE | |
| VIDTYPE_VIU_422 | |
| VIDTYPE_VIU_SINGLE_PLANE | |
| VIDTYPE_VIU_FIELD | |
| VIDTYPE_PRE_INTERLACE; |
| if (di_buf->di_buf_dup_p[0]->new_format_flag) |
| di_buf->vframe->early_process_fun = |
| de_post_disable_fun; |
| else |
| di_buf->vframe->early_process_fun = |
| do_nothing_fun; |
| |
| di_buf->pd_config.global_mode = |
| PULL_DOWN_BUF1; |
| di_buf->vframe->process_fun = |
| (dimp_get(edi_mp_post_wr_en) && dimp_get(edi_mp_post_wr_support)) ? NULL : |
| dim_post_process; |
| di_buf->process_fun_index = PROCESS_FUN_DI; |
| } else if (prog_tb_field_proc_type == 0) { |
| /* to do: need change for |
| * DI_USE_FIXED_CANVAS_IDX |
| */ |
| /* do weave by vpp */ |
| di_buf->vframe->type = |
| VIDTYPE_PROGRESSIVE | |
| VIDTYPE_VIU_422 | |
| VIDTYPE_VIU_SINGLE_PLANE; |
| if (di_buf->di_buf_dup_p[0]->new_format_flag || |
| (RD(DI_IF1_GEN_REG) & 1)) |
| di_buf->vframe->early_process_fun = |
| de_post_disable_fun; |
| else |
| di_buf->vframe->early_process_fun = |
| do_nothing_fun; |
| di_buf->vframe->process_fun = NULL; |
| di_buf->process_fun_index = PROCESS_FUN_NULL; |
| di_buf->vframe->canvas0Addr = |
| di_buf->di_buf_dup_p[0]->nr_canvas_idx; |
| di_buf->vframe->canvas1Addr = |
| di_buf->di_buf_dup_p[1]->nr_canvas_idx; |
| } else { |
| /* to do: need change for |
| * DI_USE_FIXED_CANVAS_IDX |
| */ |
| di_buf->vframe->type = |
| VIDTYPE_PROGRESSIVE | |
| VIDTYPE_VIU_422 | |
| VIDTYPE_VIU_SINGLE_PLANE | |
| VIDTYPE_VIU_FIELD | |
| VIDTYPE_PRE_INTERLACE; |
| di_buf->vframe->height >>= 1; |
| |
| di_buf->vframe->width = |
| di_buf->di_buf_dup_p[0]->width_bk; |
| if (di_buf->di_buf_dup_p[0]->new_format_flag || |
| (RD(DI_IF1_GEN_REG) & 1)) |
| di_buf->vframe->early_process_fun = |
| de_post_disable_fun; |
| else |
| di_buf->vframe->early_process_fun = |
| do_nothing_fun; |
| if (prog_tb_field_proc_type == 2) { |
| di_buf->vframe->canvas0Addr = |
| di_buf->di_buf_dup_p[0] |
| ->nr_canvas_idx; |
| /* top */ |
| di_buf->vframe->canvas1Addr = |
| di_buf->di_buf_dup_p[0] |
| ->nr_canvas_idx; |
| } else { |
| di_buf->vframe->canvas0Addr = |
| di_buf->di_buf_dup_p[1] |
| ->nr_canvas_idx; /* top */ |
| di_buf->vframe->canvas1Addr = |
| di_buf->di_buf_dup_p[1] |
| ->nr_canvas_idx; |
| } |
| } |
| |
| di_buf->di_buf[0] = di_buf->di_buf_dup_p[0]; |
| queue_out(channel, di_buf->di_buf[0]); |
| /*check if the field is error,then drop*/ |
| if ((di_buf->di_buf_dup_p[0]->vframe->type & |
| VIDTYPE_TYPEMASK) == |
| VIDTYPE_INTERLACE_BOTTOM) { |
| di_buf->di_buf[1] = |
| di_buf->di_buf_dup_p[1] = NULL; |
| queue_in(channel, di_buf, QUEUE_TMP); |
| recycle_vframe_type_post(di_buf, channel); |
| pr_dbg("%s drop field %d.\n", __func__, |
| di_buf->di_buf_dup_p[0]->seq); |
| } else { |
| di_buf->di_buf[1] = |
| di_buf->di_buf_dup_p[1]; |
| queue_out(channel, di_buf->di_buf[1]); |
| /* dec vf keep */ |
| if (di_buf->di_buf[1]->in_buf) { |
| di_buf->in_buf = |
| di_buf->di_buf[1]->in_buf; |
| di_buf->di_buf[1]->in_buf = NULL; |
| dim_print("dim:dec:p[%d]\n", |
| di_buf->in_buf->index); |
| } |
| dim_print("%s:bottom ctrl\n", __func__); |
| tmp = di_buf->di_buf_dup_p[0]->throw_flag; |
| tmp0 = di_buf->di_buf_dup_p[1]->throw_flag; |
| drop_frame(dimp_get(edi_mp_check_start_drop), |
| tmp || tmp0, di_buf, channel); |
| } |
| frame_count++; |
| #ifdef DI_BUFFER_DEBUG |
| dim_print("%s <prog by field>: ", __func__); |
| #endif |
| ret = 1; |
| #ifdef MARK_HIS |
| pw_vf_notify_receiver |
| (channel, |
| VFRAME_EVENT_PROVIDER_VFRAME_READY, |
| NULL); |
| #endif |
| } |
| } |
| |
| return ret; |
| } |
| |
| /* |
| * di task |
| */ |
| |
| void di_unreg_setting(void) |
| { |
| /*unsigned int mirror_disable = get_blackout_policy();*/ |
| unsigned int mirror_disable = 0; |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| |
| if (!get_hw_reg_flg()) { |
| PR_ERR("%s:have unsetting?do nothing\n", __func__); |
| return; |
| } |
| |
| dbg_pl("%s:\n", __func__); |
| sc2_dbg_set(0); |
| /*set flg*/ |
| set_hw_reg_flg(false); |
| |
| dimh_enable_di_pre_mif(false, dimp_get(edi_mp_mcpre_en)); |
| post_close_new(); /*2018-11-29*/ |
| //dimh_afbc_reg_sw(false); |
| if (dim_afds()) |
| dim_afds()->reg_sw(false); |
| dimh_hw_uninit(); |
| if (is_meson_txlx_cpu() || |
| is_meson_txhd_cpu() || |
| is_meson_g12a_cpu() || |
| is_meson_g12b_cpu() || |
| is_meson_tl1_cpu() || |
| is_meson_tm2_cpu() || |
| DIM_IS_IC(T5) || |
| DIM_IS_IC(T5D) || |
| is_meson_sm1_cpu()) { |
| dim_pre_gate_control(false, dimp_get(edi_mp_mcpre_en)); |
| get_ops_nr()->nr_gate_control(false); |
| } else if (DIM_IS_IC_EF(SC2)) { |
| dim_pre_gate_control_sc2(false, dimp_get(edi_mp_mcpre_en)); |
| get_ops_nr()->nr_gate_control(false); |
| } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) { |
| DIM_DI_WR(DI_CLKG_CTRL, 0x80f60000); |
| DIM_DI_WR(DI_PRE_CTRL, 0); |
| } else { |
| DIM_DI_WR(DI_CLKG_CTRL, 0xf60000); |
| } |
| /*ary add for switch to post wr, can't display*/ |
| dbg_pl("dimh_disable_post_deinterlace_2\n"); |
| dimh_disable_post_deinterlace_2(); |
| /* nr/blend0/ei0/mtn0 clock gate */ |
| |
| dim_hw_disable(dimp_get(edi_mp_mcpre_en)); |
| |
| if (is_meson_txlx_cpu() || |
| is_meson_txhd_cpu() || |
| is_meson_g12a_cpu() || |
| is_meson_g12b_cpu() || |
| is_meson_tl1_cpu() || |
| is_meson_tm2_cpu() || |
| DIM_IS_IC(T5) || |
| DIM_IS_IC(T5D) || |
| is_meson_sm1_cpu()) { |
| dimh_enable_di_post_mif(GATE_OFF); |
| dim_post_gate_control(false); |
| dim_top_gate_control(false, false); |
| } else if (DIM_IS_IC_EF(SC2)) { |
| dim_post_gate_control_sc2(false); |
| dim_top_gate_control_sc2(false, false); |
| } else { |
| DIM_DI_WR(DI_CLKG_CTRL, 0x80000000); |
| } |
| if (!is_meson_gxl_cpu() && |
| !is_meson_gxm_cpu() && |
| !is_meson_gxbb_cpu() && |
| !is_meson_txlx_cpu()) |
| diext_clk_b_sw(false); |
| dbg_pl("%s disable di mirror image.\n", __func__); |
| |
| if ((dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) || |
| mirror_disable) { |
| /*diwr_set_power_control(0);*/ |
| hpst_mem_pd_sw(0); |
| } |
| if (mirror_disable) |
| hpst_vd1_sw(0); |
| |
| get_hw_pre()->pre_top_cfg.d32 = 0; |
| get_hw_pst()->last_pst_size = 0; |
| disp_frame_count = 0;/* debug only*/ |
| |
| /*set clkb to low ratio*/ |
| if (DIM_IS_IC(T5) || DIM_IS_IC(T5D)) { |
| #ifdef CLK_TREE_SUPPORT |
| if (dimp_get(edi_mp_clock_low_ratio)) |
| clk_set_rate(de_devp->vpu_clkb, |
| dimp_get(edi_mp_clock_low_ratio)); |
| #endif |
| } |
| dbg_pl("%s:end\n", __func__); |
| } |
| |
| void di_unreg_variable(unsigned int channel) |
| { |
| //ary 2020-12-09 ulong irq_flag2 = 0; |
| unsigned int mirror_disable = 0; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| struct di_ch_s *pch = get_chdata(channel); |
| enum EDI_CMA_ST cma_st; |
| struct mtsk_cmd_s blk_cmd; |
| struct div2_mm_s *mm = dim_mm_get(channel); |
| |
| #if (defined ENABLE_SPIN_LOCK_ALWAYS) |
| // ulong flags = 0; |
| #endif |
| |
| #if (defined ENABLE_SPIN_LOCK_ALWAYS) |
| //ary 2020-12-09 spin_lock_irqsave(&plist_lock, flags); |
| #endif |
| pr_info("%s:\n", __func__); |
| set_init_flag(channel, false); /*init_flag = 0;*/ |
| pch->itf.op_m_unreg(pch); |
| dim_sumx_clear(channel); |
| dim_polic_unreg(pch); |
| mm->sts.flg_realloc = 0; |
| dim_recycle_post_back(channel);// ? |
| /*mirror_disable = get_blackout_policy();*/ |
| if ((cfgg(KEEP_CLEAR_AUTO) == 2) || dip_itf_is_ins_exbuf(pch)) |
| mirror_disable = 1; |
| else |
| mirror_disable = 0; |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); |
| //dim_print("%s: dim_uninit_buf\n", __func__); |
| pch->src_type = 0; |
| pch->ponly = 0; |
| dim_uninit_buf(mirror_disable, channel); |
| ndrd_reset(pch); |
| #ifdef CONFIG_AMLOGIC_MEDIA_RDMA |
| if (di_pre_rdma_enable) |
| rdma_clear(de_devp->rdma_handle); |
| #endif |
| get_ops_mtn()->adpative_combing_exit(); |
| |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| |
| #if (defined ENABLE_SPIN_LOCK_ALWAYS) |
| // spin_unlock_irqrestore(&plist_lock, flags); |
| #endif |
| dimh_patch_post_update_mc_sw(DI_MC_SW_REG, false); |
| sct_sw_off(pch); |
| |
| ppre->force_unreg_req_flag = 0; |
| ppre->disable_req_flag = 0; |
| recovery_flag = 0; |
| ppre->cur_prog_flag = 0; |
| |
| cma_st = dip_cma_get_st(channel); |
| if ((cfgeq(MEM_FLAG, EDI_MEM_M_CMA) || |
| cfgeq(MEM_FLAG, EDI_MEM_M_CODEC_A) || |
| cfgeq(MEM_FLAG, EDI_MEM_M_CODEC_B))) { |
| //dip_wq_cma_run(channel, ECMA_CMD_RELEASE); |
| //dip_wq_check_unreg(channel); |
| //mtsk_release(channel, ECMD_BLK_RELEASE_ALL); |
| if (cfgg(MEM_RELEASE_BLOCK_MODE)) { |
| mtsk_release_block(channel, ECMD_BLK_RELEASE_ALL); |
| } else { |
| blk_cmd.cmd = ECMD_BLK_RELEASE_ALL; |
| mtask_send_cmd(channel, &blk_cmd); |
| } |
| // mtsk_release_block(channel, ECMD_BLK_RELEASE_ALL); |
| } |
| |
| sum_g_clear(channel); |
| sum_p_clear(channel); |
| sum_pst_g_clear(channel); |
| sum_pst_p_clear(channel); |
| pch->sum_pre = 0; |
| pch->sum_pst = 0; |
| pch->sum_ext_buf_in = 0; |
| pch->sum_ext_buf_in2 = 0; |
| dbg_reg("ndis_used[%d], nout[%d],flg_realloc[%d]\n", |
| ndis_cnt(pch, QBF_NDIS_Q_USED), |
| ndrd_cnt(pch), mm->sts.flg_realloc); |
| dbg_reg("%s:end\n", __func__); |
| } |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_RDMA |
| /* di pre rdma operation */ |
| static void di_rdma_irq(void *arg) |
| { |
| struct di_dev_s *di_devp = (struct di_dev_s *)arg; |
| unsigned int channel = 0; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| |
| if (IS_ERR_OR_NULL(di_devp)) |
| return; |
| if (di_devp->rdma_handle <= 0) { |
| PR_ERR("%s rdma handle %d error.\n", __func__, |
| di_devp->rdma_handle); |
| return; |
| } |
| if (dimp_get(edi_mp_di_printk_flag)) |
| pr_dbg("%s...%d.\n", __func__, |
| ppre->field_count_for_cont); |
| } |
| |
| static struct rdma_op_s di_rdma_op = { |
| di_rdma_irq, |
| NULL |
| }; |
| #endif |
| |
| void dim_rdma_init(void) |
| { |
| #ifdef CONFIG_AMLOGIC_MEDIA_RDMA |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| /* rdma handle */ |
| if (di_pre_rdma_enable) { |
| di_rdma_op.arg = de_devp; |
| de_devp->rdma_handle = rdma_register(&di_rdma_op, |
| de_devp, RDMA_TABLE_SIZE); |
| } |
| |
| #endif |
| } |
| |
| void dim_rdma_exit(void) |
| { |
| #ifdef CONFIG_AMLOGIC_MEDIA_RDMA |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| |
| /* rdma handle */ |
| if (de_devp->rdma_handle > 0) |
| rdma_unregister(de_devp->rdma_handle); |
| #endif |
| } |
| |
| static void di_load_pq_table(void) |
| { |
| struct di_pq_parm_s *pos = NULL, *tmp = NULL; |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| |
| if (atomic_read(&de_devp->pq_flag) == 0 && |
| (de_devp->flags & DI_LOAD_REG_FLAG)) { |
| atomic_set(&de_devp->pq_flag, 1); |
| list_for_each_entry_safe(pos, tmp, |
| &de_devp->pq_table_list, list) { |
| dimh_load_regs(pos); |
| list_del(&pos->list); |
| di_pq_parm_destroy(pos); |
| } |
| de_devp->flags &= ~DI_LOAD_REG_FLAG; |
| atomic_set(&de_devp->pq_flag, 0); |
| } |
| } |
| |
| static void di_pre_size_change(unsigned short width, |
| unsigned short height, |
| unsigned short vf_type, |
| unsigned int channel) |
| { |
| unsigned int blkhsize = 0; |
| int pps_w = 0, pps_h = 0; |
| int tmp = 0; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| union hw_sc2_ctr_pre_s *sc2_pre_cfg; |
| |
| /*pr_info("%s:\n", __func__);*/ |
| /*debug only:*/ |
| /*di_pause(channel, true);*/ |
| get_ops_nr()->nr_all_config(width, height, vf_type); |
| #ifdef DET3D |
| /*det3d_config*/ |
| get_ops_3d()->det3d_config(dimp_get(edi_mp_det3d_en) ? 1 : 0); |
| #endif |
| if (dimp_get(edi_mp_pulldown_enable)) { |
| /*pulldown_init(width, height);*/ |
| get_ops_pd()->init(width, height); |
| dimh_init_field_mode(height); |
| |
| if (is_meson_txl_cpu() || |
| is_meson_txlx_cpu() || |
| is_meson_gxlx_cpu() || |
| is_meson_txhd_cpu() || |
| is_meson_g12a_cpu() || |
| is_meson_g12b_cpu() || |
| is_meson_tl1_cpu() || |
| is_meson_tm2_cpu() || |
| DIM_IS_IC(T5) || |
| DIM_IS_IC(T5D) || |
| is_meson_sm1_cpu() || |
| DIM_IS_IC_EF(SC2)) |
| dim_film_mode_win_config(width, height); |
| } |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) |
| dimh_combing_pd22_window_config(width, height); |
| DIM_RDMA_WR(DI_PRE_SIZE, (width - 1) | |
| ((height - 1) << 16)); |
| |
| if (dimp_get(edi_mp_mcpre_en)) { |
| blkhsize = (width + 4) / 5; |
| DIM_RDMA_WR(MCDI_HV_SIZEIN, height |
| | (width << 16)); |
| DIM_RDMA_WR(MCDI_HV_BLKSIZEIN, (overturn ? 3 : 0) << 30 |
| | blkhsize << 16 | height); |
| DIM_RDMA_WR(MCDI_BLKTOTAL, blkhsize * height); |
| if (is_meson_gxlx_cpu()) { |
| DIM_RDMA_WR(MCDI_PD_22_CHK_FLG_CNT, 0); |
| DIM_RDMA_WR(MCDI_FIELD_MV, 0); |
| } |
| } |
| if (channel == 0 || |
| (channel == 1 && !get_reg_flag(0))) |
| di_load_pq_table(); |
| |
| if (de_devp->nrds_enable) |
| dim_nr_ds_init(width, height); |
| if (de_devp->pps_enable && dimp_get(edi_mp_pps_position)) { |
| pps_w = ppre->cur_width; |
| if (vf_type & VIDTYPE_TYPEMASK) { |
| pps_h = ppre->cur_height >> 1; |
| dim_pps_config(1, pps_w, pps_h, |
| dimp_get(edi_mp_pps_dstw), |
| (dimp_get(edi_mp_pps_dsth) >> 1)); |
| } else { |
| pps_h = ppre->cur_height; |
| dim_pps_config(1, pps_w, pps_h, |
| dimp_get(edi_mp_pps_dstw), |
| (dimp_get(edi_mp_pps_dsth))); |
| } |
| } |
| if (is_meson_sm1_cpu() || is_meson_tm2_cpu() || |
| DIM_IS_IC(T5) || DIM_IS_IC(T5D) || DIM_IS_IC_EF(SC2)) { |
| if (de_devp->h_sc_down_en) { |
| pps_w = ppre->cur_width; |
| tmp = di_mp_uit_get(edi_mp_pre_hsc_down_width); |
| dim_inp_hsc_setting(pps_w, tmp); |
| } else { |
| dim_inp_hsc_setting(ppre->cur_width, |
| ppre->cur_width); |
| } |
| } |
| #ifdef MARK_HIS |
| dimh_interrupt_ctrl(ppre->madi_enable, |
| det3d_en ? 1 : 0, |
| de_devp->nrds_enable, |
| post_wr_en, |
| ppre->mcdi_enable); |
| #else |
| /*dimh_int_ctr(0, 0, 0, 0, 0, 0);*/ |
| dimh_int_ctr(1, ppre->madi_enable, |
| dimp_get(edi_mp_det3d_en) ? 1 : 0, |
| de_devp->nrds_enable, |
| dimp_get(edi_mp_post_wr_en), |
| ppre->mcdi_enable); |
| #endif |
| if (DIM_IS_IC_EF(SC2) && |
| ppre->input_size_change_flag && |
| ppre->di_inp_buf && |
| ppre->di_inp_buf->vframe) { |
| //for crash test if (!ppre->cur_prog_flag) |
| dim_pulldown_info_clear_g12a(); |
| dim_sc2_afbce_rst(0); |
| dbg_mem2("pre reset-----\n"); |
| |
| sc2_pre_cfg = &ppre->pre_top_cfg;//&get_hw_pre()->pre_top_cfg; |
| dim_print("%s:cfg[%px]:inp[%d]\n", __func__, |
| sc2_pre_cfg, sc2_pre_cfg->b.afbc_inp); |
| #ifdef MARK_SC2 |
| if (sc2_pre_cfg->b.afbc_inp || sc2_pre_cfg->b.afbc_mem) |
| sc2_pre_cfg->b.mif_en = 0; /*ary temp*/ |
| else |
| sc2_pre_cfg->b.mif_en = 1; |
| dim_print("%s:mem_en[%d]\n", __func__, |
| sc2_pre_cfg->b.mif_en); |
| #endif |
| sc2_pre_cfg->b.is_4k = 0; /*ary temp*/ |
| sc2_pre_cfg->b.nr_ch0_en = 1; |
| if (dbg_di_prelink_v3()) |
| sc2_pre_cfg->b.pre_frm_sel = 2; |
| else |
| sc2_pre_cfg->b.pre_frm_sel = 0; |
| //dim_sc2_contr_pre(sc2_pre_cfg); |
| } |
| } |
| |
| #define DIM_BYPASS_VF_TYPE (VIDTYPE_MVC | VIDTYPE_VIU_444 | \ |
| VIDTYPE_PIC | VIDTYPE_RGB_444) |
| |
| void dim_vf_x_y(struct vframe_s *vf, unsigned int *x, unsigned int *y) |
| { |
| *x = 0; |
| *y = 0; |
| |
| if (!vf) |
| return; |
| *x = vf->width; |
| *y = vf->height; |
| |
| if (IS_COMP_MODE(vf->type)) { |
| *x = vf->compWidth; |
| *y = vf->compHeight; |
| } |
| } |
| |
| static unsigned int dim_bypass_check(struct vframe_s *vf) |
| { |
| unsigned int reason = 0; |
| unsigned int x, y; |
| |
| if ((dimp_get(edi_mp_di_debug_flag) >> 20) & 0x1) |
| reason = 1; |
| |
| if (reason || !vf) |
| return reason; |
| |
| dim_vf_x_y(vf, &x, &y); |
| /*check vf*/ |
| if (vf->type & DIM_BYPASS_VF_TYPE) { |
| reason = 2; |
| } else if (vf->source_type == VFRAME_SOURCE_TYPE_PPMGR) { |
| reason = 6; |
| /*support G12A and TXLX platform*/ |
| } else if (VFMT_IS_I(vf->type) && |
| ((vf->width > 1920) || |
| (vf->height > 1088))) { |
| reason = 9; |
| } else if (VFMT_IS_P(vf->type) && |
| (x > default_width || |
| y > (default_height + 8))) { |
| reason = 4; |
| #ifdef P_NOT_SUPPORT |
| } else if (VFMT_IS_P(vf->type)) { |
| reason = 8; |
| #endif//temp bypass p |
| /*true bypass for 720p above*/ |
| } else if ((vf->flag & VFRAME_FLAG_GAME_MODE) && |
| (vf->width > 720)) { |
| reason = 7; |
| } else if (vf->type & VIDTYPE_COMPRESS) { |
| if (dim_afds() && !dim_afds()->is_supported()) { |
| reason = 3; |
| } else { |
| if ((y > (default_height + 8)) || |
| x > default_width) { |
| reason = 5; |
| } |
| } |
| } |
| |
| return reason; |
| } |
| |
| bool dim_need_bypass(unsigned int ch, struct vframe_s *vf) |
| { |
| unsigned int reason = 0; |
| struct di_ch_s *pch = get_chdata(ch); |
| |
| reason = dim_bypass_check(vf); |
| |
| if (reason) { |
| dim_bypass_set(pch, 0, reason); |
| return true; |
| } |
| |
| reason = dim_polic_is_bypass(pch, vf); |
| dim_bypass_set(pch, 0, reason); |
| if (reason) |
| return true; |
| |
| return false; |
| } |
| |
| /********************************* |
| * |
| * setting register only call when |
| * from di_reg_process_irq |
| *********************************/ |
| void di_reg_setting(unsigned int channel, struct vframe_s *vframe) |
| { |
| unsigned short nr_height = 0, first_field_type; |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| |
| dbg_pl("%s:ch[%d]:for first ch reg:\n", __func__, channel); |
| |
| if (get_hw_reg_flg()) { |
| PR_ERR("%s:have setting?do nothing\n", __func__); |
| return; |
| } |
| /*set flg*/ |
| set_hw_reg_flg(true); |
| |
| diext_clk_b_sw(true); |
| |
| dim_ddbg_mod_save(EDI_DBG_MOD_REGB, channel, 0); |
| |
| if (dimp_get(edi_mp_post_wr_en) && |
| dimp_get(edi_mp_post_wr_support)) |
| dim_set_power_control(1); |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) { |
| /*if (!use_2_interlace_buff) {*/ |
| if (1) { |
| if (DIM_IS_IC_EF(SC2)) |
| dim_top_gate_control_sc2(true, true); |
| else |
| dim_top_gate_control(true, true); |
| /*dim_post_gate_control(true);*/ |
| /* freerun for reg configuration */ |
| /*dimh_enable_di_post_mif(GATE_AUTO);*/ |
| hpst_power_ctr(true); |
| } else { |
| dim_top_gate_control(true, false); |
| } |
| de_devp->flags |= DI_VPU_CLKB_SET; |
| /*set clkb to max */ |
| if (is_meson_g12a_cpu() || |
| is_meson_g12b_cpu() || |
| is_meson_tl1_cpu() || |
| is_meson_tm2_cpu() || |
| DIM_IS_IC(T5) || |
| DIM_IS_IC(T5D) || |
| is_meson_sm1_cpu() || |
| DIM_IS_IC_EF(SC2)) { |
| #ifdef CLK_TREE_SUPPORT |
| clk_set_rate(de_devp->vpu_clkb, |
| de_devp->clkb_max_rate); |
| #endif |
| } |
| |
| dimh_enable_di_pre_mif(false, dimp_get(edi_mp_mcpre_en)); |
| if (DIM_IS_IC_EF(SC2)) |
| dim_pre_gate_control_sc2(true, |
| dimp_get(edi_mp_mcpre_en)); |
| else |
| dim_pre_gate_control(true, dimp_get(edi_mp_mcpre_en)); |
| dim_pre_gate_control(true, dimp_get(edi_mp_mcpre_en)); |
| |
| /*2019-01-22 by VLSI feng.wang*/ |
| // |
| if (DIM_IS_IC_EF(SC2)) { |
| if (opl1()->wr_rst_protect) |
| opl1()->wr_rst_protect(true); |
| } else { |
| dim_rst_protect(true); |
| } |
| |
| dim_pre_nr_wr_done_sel(true); |
| get_ops_nr()->nr_gate_control(true); |
| } else { |
| /* if mcdi enable DI_CLKG_CTRL should be 0xfef60000 */ |
| DIM_DI_WR(DI_CLKG_CTRL, 0xfef60001); |
| /* nr/blend0/ei0/mtn0 clock gate */ |
| } |
| /*--------------------------*/ |
| dim_init_setting_once(); |
| /*--------------------------*/ |
| /*di_post_reset();*/ /*add by feijun 2018-11-19 */ |
| if (DIM_IS_IC_EF(SC2)) { |
| opl1()->pst_mif_sw(false, DI_MIF0_SEL_PST_ALL); |
| opl1()->pst_dbg_contr(); |
| } else { |
| post_mif_sw(false); |
| post_dbg_contr(); |
| } |
| |
| /*--------------------------*/ |
| |
| nr_height = (vframe->height >> 1);/*temp*/ |
| /*--------------------------*/ |
| dimh_calc_lmv_init(); |
| first_field_type = (vframe->type & VIDTYPE_TYPEMASK); |
| di_pre_size_change(vframe->width, nr_height, |
| first_field_type, channel); |
| get_ops_nr()->cue_int(vframe); |
| dim_ddbg_mod_save(EDI_DBG_MOD_REGE, channel, 0); |
| |
| /*--------------------------*/ |
| /*test*/ |
| dimh_int_ctr(0, 0, 0, 0, 0, 0); |
| sc2_dbg_set(DI_BIT0 | DI_BIT1); |
| } |
| |
| /********************************* |
| * |
| * setting variable |
| * from di_reg_process_irq |
| * |
| *********************************/ |
| void di_reg_variable(unsigned int channel, struct vframe_s *vframe) |
| { |
| //ary 2020-12-09 ulong irq_flag2 = 0; |
| #ifndef RUN_DI_PROCESS_IN_IRQ |
| //ary 2020-12-09 ulong flags = 0; |
| #endif |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| struct di_ch_s *pch; |
| struct div2_mm_s *mm; |
| |
| #ifdef HIS_CODE |
| if (pre_run_flag != DI_RUN_FLAG_RUN && |
| pre_run_flag != DI_RUN_FLAG_STEP) |
| return; |
| if (pre_run_flag == DI_RUN_FLAG_STEP) |
| pre_run_flag = DI_RUN_FLAG_STEP_DONE; |
| #endif |
| dbg_reg("%s:=%x\n", __func__, channel); |
| |
| dim_print("%s:0x%p\n", __func__, vframe); |
| pch = get_chdata(channel); |
| mm = dim_mm_get(channel); |
| if (vframe) { |
| // if (DIM_IS_IC_EF(SC2) && dim_afds()) |
| // di_set_default(); |
| dip_init_value_reg(channel, vframe);/*add 0404 for post*/ |
| dim_ddbg_mod_save(EDI_DBG_MOD_RVB, channel, 0); |
| //if (!dip_itf_is_ins_exbuf(pch)) { |
| if (dip_itf_is_vfm(pch)) { |
| if (dim_need_bypass(channel, vframe)) { |
| if (!ppre->bypass_flag) { |
| PR_INF("%ux%u-0x%x.\n", |
| vframe->width, |
| vframe->height, |
| vframe->type); |
| } |
| ppre->bypass_flag = true; |
| ppre->sgn_lv = EDI_SGN_OTHER; |
| dimh_patch_post_update_mc_sw |
| (DI_MC_SW_OTHER, false); |
| return; |
| } |
| } |
| dim_mp_update_reg(); |
| ppre->bypass_flag = false; |
| /* patch for vdin progressive input */ |
| if ((is_from_vdin(vframe) && is_progressive(vframe)) || |
| #ifdef DET3D |
| dimp_get(edi_mp_det3d_en) || |
| #endif |
| (dimp_get(edi_mp_use_2_interlace_buff) & 0x2)) { |
| dimp_set(edi_mp_use_2_interlace_buff, 1); |
| } else { |
| dimp_set(edi_mp_use_2_interlace_buff, 0); |
| } |
| de_devp->nrds_enable = dimp_get(edi_mp_nrds_en); |
| de_devp->pps_enable = dimp_get(edi_mp_pps_en); |
| /*di pre h scaling down: sm1 tm2*/ |
| de_devp->h_sc_down_en = di_mp_uit_get(edi_mp_pre_hsc_down_en); |
| |
| if (dimp_get(edi_mp_di_printk_flag) & 2) |
| dimp_set(edi_mp_di_printk_flag, 1); |
| |
| // dim_print("%s: vframe come => di_init_buf\n", __func__); |
| |
| if (cfgeq(MEM_FLAG, EDI_MEM_M_REV) && !de_devp->mem_flg) |
| dim_rev_mem_check(); |
| |
| /*need before set buffer*/ |
| if (dim_afds()) |
| dim_afds()->reg_val(pch); |
| |
| /*(is_progressive(vframe) && (prog_proc_config & 0x10)) {*/ |
| if (0) { |
| #if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS) |
| //ary 2020-12-09 spin_lock_irqsave(&plist_lock, flags); |
| #endif |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); |
| /* |
| * 10 bit mode need 1.5 times buffer size of |
| * 8 bit mode, init the buffer size as 10 bit |
| * mode size, to make sure can switch bit mode |
| * smoothly. |
| */ |
| // di_init_buf(default_width, default_height, 1, channel); |
| |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| |
| #if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS) |
| //ary 2020-12-09 spin_unlock_irqrestore(&plist_lock, flags); |
| #endif |
| } else { |
| #if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS) |
| //ary 2020-12-09 spin_lock_irqsave(&plist_lock, flags); |
| #endif |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); |
| /* |
| * 10 bit mode need 1.5 times buffer size of |
| * 8 bit mode, init the buffer size as 10 bit |
| * mode size, to make sure can switch bit mode |
| * smoothly. |
| */ |
| #ifdef TEST_4K_NR |
| //di_init_buf(mm->cfg.di_w, mm->cfg.di_h, |
| // is_progressive(vframe), channel); |
| di_init_buf_new(pch); |
| #else |
| // di_init_buf(default_width, default_height, 0, channel); |
| #endif |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| |
| #if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS) |
| //ary 2020-12-09 spin_unlock_irqrestore(&plist_lock, flags); |
| #endif |
| } |
| |
| if (mm->cfg.pbuf_flg.b.typ == EDIM_BLK_TYP_PSCT) |
| sct_sw_on(pch, |
| mm->cfg.num_post, |
| mm->cfg.pbuf_flg.b.tvp, |
| mm->cfg.pst_buf_size); |
| |
| pre_sec_alloc(pch, mm->cfg.dat_idat_flg.d32); |
| pst_sec_alloc(pch, mm->cfg.dat_pafbct_flg.d32); |
| ppre->mtn_status = |
| get_ops_mtn()->adpative_combing_config |
| (vframe->width, |
| (vframe->height >> 1), |
| (vframe->source_type), |
| is_progressive(vframe), |
| vframe->sig_fmt); |
| |
| dimh_patch_post_update_mc_sw(DI_MC_SW_REG, true); |
| di_sum_reg_init(channel); |
| #ifdef MARK_HIS //must before init buffer |
| if (dim_afds()) |
| dim_afds()->reg_val(pch); |
| #endif |
| |
| dcntr_reg(1); |
| |
| set_init_flag(channel, true);/*init_flag = 1;*/ |
| |
| dim_ddbg_mod_save(EDI_DBG_MOD_RVE, channel, 0); |
| } |
| } |
| |
| /*para 1 not use*/ |
| |
| /* |
| * provider/receiver interface |
| */ |
| |
| /*************************/ |
| void di_block_set(int val) |
| { |
| di_blocking = val; |
| } |
| |
| int di_block_get(void) |
| { |
| return di_blocking; |
| } |
| |
| #ifdef MARK_HIS//move to di_vframe |
| int di_ori_event_qurey_vdin2nr(unsigned int channel) |
| { |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| |
| return ppre->vdin2nr; |
| } |
| |
| int di_ori_event_reset(unsigned int channel) |
| { |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| struct vframe_s **pvframe_in = get_vframe_in(channel); |
| int i; |
| ulong flags; |
| |
| /*block*/ |
| di_blocking = 1; |
| |
| /*dbg_ev("%s: VFRAME_EVENT_PROVIDER_RESET\n", __func__);*/ |
| if (dim_is_bypass(NULL, channel) || |
| di_bypass_state_get(channel) || |
| ppre->bypass_flag) { |
| pw_vf_notify_receiver(channel, |
| VFRAME_EVENT_PROVIDER_RESET, |
| NULL); |
| } |
| |
| spin_lock_irqsave(&plist_lock, flags); |
| for (i = 0; i < MAX_IN_BUF_NUM; i++) { |
| if (pvframe_in[i]) |
| pr_dbg("DI:clear vframe_in[%d]\n", i); |
| |
| pvframe_in[i] = NULL; |
| } |
| spin_unlock_irqrestore(&plist_lock, flags); |
| di_blocking = 0; |
| |
| return 0; |
| } |
| |
| int di_ori_event_light_unreg(unsigned int channel) |
| { |
| struct vframe_s **pvframe_in = get_vframe_in(channel); |
| int i; |
| ulong flags; |
| |
| di_blocking = 1; |
| |
| pr_dbg("%s: vf_notify_receiver ligth unreg\n", __func__); |
| |
| spin_lock_irqsave(&plist_lock, flags); |
| for (i = 0; i < MAX_IN_BUF_NUM; i++) { |
| if (pvframe_in[i]) |
| pr_dbg("DI:clear vframe_in[%d]\n", i); |
| |
| pvframe_in[i] = NULL; |
| } |
| spin_unlock_irqrestore(&plist_lock, flags); |
| di_blocking = 0; |
| |
| return 0; |
| } |
| |
| int di_ori_event_light_unreg_revframe(unsigned int channel) |
| { |
| struct vframe_s **pvframe_in = get_vframe_in(channel); |
| int i; |
| ulong flags; |
| |
| unsigned char vf_put_flag = 0; |
| |
| pr_info("%s:VFRAME_EVENT_PROVIDER_LIGHT_UNREG_RETURN_VFRAME\n", |
| __func__); |
| /* |
| * do not display garbage when 2d->3d or 3d->2d |
| */ |
| spin_lock_irqsave(&plist_lock, flags); |
| for (i = 0; i < MAX_IN_BUF_NUM; i++) { |
| if (pvframe_in[i]) { |
| pw_vf_put(pvframe_in[i], channel); |
| pr_dbg("DI:clear vframe_in[%d]\n", i); |
| vf_put_flag = 1; |
| } |
| pvframe_in[i] = NULL; |
| } |
| if (vf_put_flag) |
| pw_vf_notify_provider(channel, |
| VFRAME_EVENT_RECEIVER_PUT, NULL); |
| |
| spin_unlock_irqrestore(&plist_lock, flags); |
| |
| return 0; |
| } |
| |
| int di_irq_ori_event_ready(unsigned int channel) |
| { |
| return 0; |
| } |
| |
| int di_ori_event_ready(unsigned int channel) |
| { |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| |
| if (ppre->bypass_flag) |
| pw_vf_notify_receiver(channel, |
| VFRAME_EVENT_PROVIDER_VFRAME_READY, |
| NULL); |
| |
| if (dip_chst_get(channel) == EDI_TOP_STATE_REG_STEP1) |
| task_send_cmd(LCMD1(ECMD_READY, channel)); |
| else |
| task_send_ready(); |
| |
| di_irq_ori_event_ready(channel); |
| return 0; |
| } |
| |
| int di_ori_event_qurey_state(unsigned int channel) |
| { |
| /*int in_buf_num = 0;*/ |
| struct vframe_states states; |
| |
| if (recovery_flag) |
| return RECEIVER_INACTIVE; |
| |
| /*fix for ucode reset method be break by di.20151230*/ |
| di_vf_l_states(&states, channel); |
| if (states.buf_avail_num > 0) |
| return RECEIVER_ACTIVE; |
| |
| if (pw_vf_notify_receiver(channel, |
| VFRAME_EVENT_PROVIDER_QUREY_STATE, |
| NULL) == RECEIVER_ACTIVE) |
| return RECEIVER_ACTIVE; |
| |
| return RECEIVER_INACTIVE; |
| } |
| |
| void di_ori_event_set_3D(int type, void *data, unsigned int channel) |
| { |
| #ifdef DET3D |
| |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| |
| if (type == VFRAME_EVENT_PROVIDER_SET_3D_VFRAME_INTERLEAVE) { |
| int flag = (long)data; |
| |
| ppre->vframe_interleave_flag = flag; |
| } |
| |
| #endif |
| } |
| |
| /*************************/ |
| /************************************/ |
| /************************************/ |
| struct vframe_s *di_vf_l_get(unsigned int channel) |
| { |
| vframe_t *vframe_ret = NULL; |
| struct di_buf_s *di_buf = NULL; |
| //struct di_ch_s *pch; |
| #ifdef DI_DEBUG_POST_BUF_FLOW |
| struct di_buf_s *nr_buf = NULL; |
| #endif |
| ulong irq_flag2 = 0; |
| //struct di_post_stru_s *ppost = get_post_stru(channel); |
| |
| dim_print("%s:ch[%d]\n", __func__, channel); |
| |
| if (!get_init_flag(channel) || |
| recovery_flag || |
| di_blocking || |
| !get_reg_flag(channel) || |
| dump_state_flag) { |
| dim_tr_ops.post_get2(1); |
| return NULL; |
| } |
| |
| /**************************/ |
| if (list_count(channel, QUEUE_DISPLAY) > DI_POST_GET_LIMIT) { |
| dim_tr_ops.post_get2(2); |
| return NULL; |
| } |
| /**************************/ |
| |
| if (!di_que_is_empty(channel, QUE_POST_READY)) { |
| dim_log_buffer_state("ge_", channel); |
| di_lock_irqfiq_save(irq_flag2); |
| |
| di_buf = di_que_out_to_di_buf(channel, QUE_POST_READY); |
| if (dim_check_di_buf(di_buf, 21, channel)) { |
| di_unlock_irqfiq_restore(irq_flag2); |
| return NULL; |
| } |
| /* add it into display_list */ |
| queue_in(channel, di_buf, QUEUE_DISPLAY); |
| |
| di_unlock_irqfiq_restore(irq_flag2); |
| |
| if (di_buf) { |
| vframe_ret = di_buf->vframe; |
| |
| di_buf->seq = disp_frame_count; |
| atomic_set(&di_buf->di_cnt, 1); |
| } |
| disp_frame_count++; |
| |
| dim_log_buffer_state("get", channel); |
| } |
| if (vframe_ret) { |
| dim_print("%s: %s[%d]:vtype[0x%x],0x%p %u ms\n", __func__, |
| vframe_type_name[di_buf->type], |
| di_buf->index, |
| vframe_ret->type, |
| vframe_ret, |
| jiffies_to_msecs(jiffies_64 - |
| vframe_ret->ready_jiffies64)); |
| didbg_vframe_out_save(channel, vframe_ret); |
| |
| if (disp_frame_count == 1 && kpi_frame_num > 0) { |
| pr_dbg("[di_kpi] %s: 1st frame get success. %s[%d]:0x%p %u ms\n", |
| __func__, |
| vframe_type_name[di_buf->type], |
| di_buf->index, |
| vframe_ret, |
| jiffies_to_msecs(jiffies_64 - |
| vframe_ret->ready_jiffies64)); |
| } |
| dim_tr_ops.post_get(vframe_ret->index_disp); |
| } else { |
| dim_tr_ops.post_get2(3); |
| } |
| |
| return vframe_ret; |
| } |
| |
| void di_vf_l_put(struct vframe_s *vf, unsigned char channel) |
| { |
| struct di_buf_s *di_buf = NULL; |
| ulong irq_flag2 = 0; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| // struct di_post_stru_s *ppost = get_post_stru(channel); |
| |
| dim_print("%s:ch[%d]\n", __func__, channel); |
| |
| if (ppre->bypass_flag) { |
| pw_vf_put(vf, channel); |
| pw_vf_notify_provider(channel, |
| VFRAME_EVENT_RECEIVER_PUT, NULL); |
| |
| //if (!IS_ERR_OR_NULL(ppost->keep_buf)) |
| // recycle_keep_buffer(channel); |
| return; |
| } |
| /* struct di_buf_s *p = NULL; */ |
| /* int itmp = 0; */ |
| if (!get_init_flag(channel) || |
| recovery_flag || |
| IS_ERR_OR_NULL(vf)) { |
| PR_ERR("%s: 0x%p\n", __func__, vf); |
| return; |
| } |
| if (di_blocking) |
| return; |
| dim_log_buffer_state("pu_", channel); |
| di_buf = (struct di_buf_s *)vf->private_data; |
| if (IS_ERR_OR_NULL(di_buf)) { |
| pw_vf_put(vf, channel); |
| pw_vf_notify_provider(channel, |
| VFRAME_EVENT_RECEIVER_PUT, NULL); |
| PR_WARN("%s: get vframe %p without di buf\n", |
| __func__, vf); |
| return; |
| } |
| |
| if (di_buf->type == VFRAME_TYPE_POST) { |
| di_lock_irqfiq_save(irq_flag2); |
| |
| if (is_in_queue(channel, di_buf, QUEUE_DISPLAY)) { |
| di_buf->queue_index = -1; |
| di_que_in(channel, QUE_POST_BACK, di_buf); |
| di_unlock_irqfiq_restore(irq_flag2); |
| } else { |
| task_send_cmd2(channel, |
| LCMD2(ECMD_RL_KEEP, |
| channel, di_buf->index)); |
| di_unlock_irqfiq_restore(irq_flag2); |
| PR_WARN("%s:ch[%d]not in display %d\n", |
| __func__, channel, |
| di_buf->index); |
| } |
| } else { |
| di_lock_irqfiq_save(irq_flag2); |
| queue_in(channel, di_buf, QUEUE_RECYCLE); |
| di_unlock_irqfiq_restore(irq_flag2); |
| |
| dim_print("%s: %s[%d] =>recycle_list\n", __func__, |
| vframe_type_name[di_buf->type], di_buf->index); |
| } |
| |
| task_send_ready(); |
| } |
| #endif |
| void dim_recycle_post_back(unsigned int channel) |
| { |
| struct di_buf_s *di_buf = NULL; |
| //ary 2020-12-09 ulong irq_flag2 = 0; |
| unsigned int i = 0; |
| |
| if (di_que_is_empty(channel, QUE_POST_BACK)) |
| return; |
| |
| while (i < MAX_FIFO_SIZE) { |
| i++; |
| |
| di_buf = di_que_peek(channel, QUE_POST_BACK); |
| /*pr_info("dp2:%d\n", post_buf_index);*/ |
| if (!di_buf) |
| break; |
| |
| if (di_buf->type != VFRAME_TYPE_POST) { |
| queue_out(channel, di_buf); |
| PR_ERR("%s:type is not post\n", __func__); |
| continue; |
| } |
| |
| dim_print("di_back:%d\n", di_buf->index); |
| //ary 2020-12-09 di_lock_irqfiq_save(irq_flag2); /**/ |
| #ifdef MARK_HIS /*@ary_note: */ |
| di_que_out(channel, QUE_POST_BACK, di_buf); |
| di_buf->queue_index = QUEUE_DISPLAY; |
| #endif |
| /*dec vf keep*/ |
| if (di_buf->in_buf) { |
| dim_print("dim:dec vf:b:p[%d],i[%d]\n", |
| di_buf->index, di_buf->in_buf->index); |
| queue_in(channel, di_buf->in_buf, QUEUE_RECYCLE); |
| di_buf->in_buf = NULL; |
| } |
| /*queue_out(channel, di_buf);*/ |
| |
| if (!atomic_dec_and_test(&di_buf->di_cnt)) |
| PR_ERR("%s,di_cnt > 0\n", __func__); |
| |
| recycle_vframe_type_post(di_buf, channel); |
| //di_buf->invert_top_bot_flag = 0; |
| //di_que_in(channel, QUE_POST_FREE, di_buf); |
| |
| //ary 2020-12-09 di_unlock_irqfiq_restore(irq_flag2); |
| } |
| |
| if (di_cfg_top_get(EDI_CFG_KEEP_CLEAR_AUTO)) |
| ;//dim_post_keep_release_all_2free(channel); |
| } |
| |
| #ifdef MARK_HIS |
| struct vframe_s *di_vf_l_peek(unsigned int channel) |
| { |
| struct vframe_s *vframe_ret = NULL; |
| struct di_buf_s *di_buf = NULL; |
| struct di_pre_stru_s *ppre = get_pre_stru(channel); |
| |
| /*dim_print("%s:ch[%d]\n",__func__, channel);*/ |
| |
| di_sum_inc(channel, EDI_SUM_O_PEEK_CNT); |
| if (ppre->bypass_flag) { |
| dim_tr_ops.post_peek(0); |
| return pw_vf_peek(channel); |
| } |
| if (!get_init_flag(channel) || |
| recovery_flag || |
| di_blocking || |
| !get_reg_flag(channel) || |
| dump_state_flag) { |
| dim_tr_ops.post_peek(1); |
| return NULL; |
| } |
| |
| /**************************/ |
| if (list_count(channel, QUEUE_DISPLAY) > DI_POST_GET_LIMIT) { |
| dim_tr_ops.post_peek(2); |
| return NULL; |
| } |
| /**************************/ |
| dim_log_buffer_state("pek", channel); |
| |
| if (!di_que_is_empty(channel, QUE_POST_READY)) { |
| di_buf = di_que_peek(channel, QUE_POST_READY); |
| if (di_buf) |
| vframe_ret = di_buf->vframe; |
| } |
| #ifdef DI_BUFFER_DEBUG |
| if (vframe_ret) |
| dim_print("%s: %s[%d]:%x\n", __func__, |
| vframe_type_name[di_buf->type], |
| di_buf->index, vframe_ret); |
| #endif |
| if (vframe_ret) { |
| dim_tr_ops.post_peek(9); |
| } else { |
| task_send_ready(); |
| dim_tr_ops.post_peek(4); |
| } |
| return vframe_ret; |
| } |
| |
| int di_vf_l_states(struct vframe_states *states, unsigned int channel) |
| { |
| struct div2_mm_s *mm = dim_mm_get(channel); |
| struct dim_sum_s *psumx = get_sumx(channel); |
| |
| /*pr_info("%s: ch[%d]\n", __func__, channel);*/ |
| if (!states) |
| return -1; |
| states->vf_pool_size = mm->sts.num_local; |
| states->buf_free_num = psumx->b_pre_free; |
| |
| states->buf_avail_num = psumx->b_pst_ready; |
| states->buf_recycle_num = psumx->b_recyc; |
| if (dimp_get(edi_mp_di_dbg_mask) & 0x1) { |
| di_pr_info("di-pre-ready-num:%d\n", psumx->b_pre_ready); |
| di_pr_info("di-display-num:%d\n", psumx->b_display); |
| } |
| return 0; |
| } |
| #endif |
| /**********************************************/ |
| |
| /***************************** |
| * di driver file_operations |
| * |
| ******************************/ |
| #ifdef MARK_HIS /*move to di_sys.c*/ |
| static int di_open(struct inode *node, struct file *file) |
| { |
| di_dev_t *di_in_devp; |
| |
| /* Get the per-device structure that contains this cdev */ |
| di_in_devp = container_of(node->i_cdev, di_dev_t, cdev); |
| file->private_data = di_in_devp; |
| |
| return 0; |
| } |
| |
| static int di_release(struct inode *node, struct file *file) |
| { |
| /* di_dev_t *di_in_devp = file->private_data; */ |
| |
| /* Reset file pointer */ |
| |
| /* Release some other fields */ |
| file->private_data = NULL; |
| return 0; |
| } |
| |
| #endif /*move to di_sys.c*/ |
| |
| static struct di_pq_parm_s *di_pq_parm_create(struct am_pq_parm_s *pq_parm_p) |
| { |
| struct di_pq_parm_s *pq_ptr = NULL; |
| struct am_reg_s *am_reg_p = NULL; |
| size_t mem_size = 0; |
| |
| pq_ptr = vzalloc(sizeof(*pq_ptr)); |
| mem_size = sizeof(struct am_pq_parm_s); |
| memcpy(&pq_ptr->pq_parm, pq_parm_p, mem_size); |
| mem_size = sizeof(struct am_reg_s) * pq_parm_p->table_len; |
| am_reg_p = vzalloc(mem_size); |
| if (!am_reg_p) { |
| vfree(pq_ptr); |
| PR_ERR("alloc pq table memory errors\n"); |
| return NULL; |
| } |
| pq_ptr->regs = am_reg_p; |
| |
| return pq_ptr; |
| } |
| |
| static void di_pq_parm_destroy(struct di_pq_parm_s *pq_ptr) |
| { |
| if (!pq_ptr) { |
| PR_ERR("%s pq parm pointer null.\n", __func__); |
| return; |
| } |
| vfree(pq_ptr->regs); |
| vfree(pq_ptr); |
| } |
| |
| /*move from ioctrl*/ |
| long dim_pq_load_io(unsigned long arg) |
| { |
| long ret = 0, tab_flag = 0; |
| di_dev_t *di_devp; |
| void __user *argp = (void __user *)arg; |
| size_t mm_size = 0; |
| struct am_pq_parm_s tmp_pq_s = {0}; |
| struct di_pq_parm_s *di_pq_ptr = NULL; |
| struct di_dev_s *de_devp = get_dim_de_devp(); |
| /*unsigned int channel = 0;*/ /*fix to channel 0*/ |
| |
| di_devp = de_devp; |
| |
| mm_size = sizeof(struct am_pq_parm_s); |
| if (copy_from_user(&tmp_pq_s, argp, mm_size)) { |
| PR_ERR("set pq parm errors\n"); |
| return -EFAULT; |
| } |
| if (tmp_pq_s.table_len >= DIMTABLE_LEN_MAX) { |
| PR_ERR("load 0x%x wrong pq table_len.\n", |
| tmp_pq_s.table_len); |
| return -EFAULT; |
| } |
| tab_flag = TABLE_NAME_DI | TABLE_NAME_NR | TABLE_NAME_MCDI | |
| TABLE_NAME_DEBLOCK | TABLE_NAME_DEMOSQUITO; |
| |
| //tab_flag |= TABLE_NAME_SMOOTHPLUS;//mark for undefine |
| if (tmp_pq_s.table_name & tab_flag) { |
| PR_INF("load 0x%x pq table len %u %s.\n", |
| tmp_pq_s.table_name, tmp_pq_s.table_len, |
| get_reg_flag_all() ? "directly" : "later"); |
| } else { |
| PR_ERR("load 0x%x wrong pq table.\n", |
| tmp_pq_s.table_name); |
| return -EFAULT; |
| } |
| di_pq_ptr = di_pq_parm_create(&tmp_pq_s); |
| if (!di_pq_ptr) { |
| PR_ERR("allocat pq parm struct error.\n"); |
| return -EFAULT; |
| } |
| argp = (void __user *)tmp_pq_s.table_ptr; |
| mm_size = tmp_pq_s.table_len * sizeof(struct am_reg_s); |
| if (copy_from_user(di_pq_ptr->regs, argp, mm_size)) { |
| PR_ERR("user copy pq table errors\n"); |
| return -EFAULT; |
| } |
| if (get_reg_flag_all()) { |
| dimh_load_regs(di_pq_ptr); |
| di_pq_parm_destroy(di_pq_ptr); |
| |
| return ret; |
| } |
| if (atomic_read(&de_devp->pq_flag) == 0) { |
| atomic_set(&de_devp->pq_flag, 1); |
| if (di_devp->flags & DI_LOAD_REG_FLAG) { |
| struct di_pq_parm_s *pos = NULL, *tmp = NULL; |
| |
| list_for_each_entry_safe(pos, tmp, |
| &di_devp->pq_table_list, |
| list) { |
| if (di_pq_ptr->pq_parm.table_name == |
| pos->pq_parm.table_name) { |
| PR_INF("remove 0x%x table.\n", |
| pos->pq_parm.table_name); |
| list_del(&pos->list); |
| di_pq_parm_destroy(pos); |
| } |
| } |
| } |
| list_add_tail(&di_pq_ptr->list, |
| &di_devp->pq_table_list); |
| di_devp->flags |= DI_LOAD_REG_FLAG; |
| atomic_set(&de_devp->pq_flag, 0); |
| } else { |
| PR_ERR("please retry table name 0x%x.\n", |
| di_pq_ptr->pq_parm.table_name); |
| di_pq_parm_destroy(di_pq_ptr); |
| ret = -EFAULT; |
| } |
| |
| return ret; |
| } |
| |
| unsigned int rd_reg_bits(unsigned int adr, unsigned int start, |
| unsigned int len) |
| { |
| return ((aml_read_vcbus(adr) & |
| (((1UL << (len)) - 1UL) << (start))) >> (start)); |
| } |
| |
| |
| unsigned int DIM_RDMA_RD_BITS(unsigned int adr, unsigned int start, |
| unsigned int len) |
| { |
| return rd_reg_bits(adr, start, len); |
| } |
| |
| unsigned int DIM_RDMA_WR(unsigned int adr, unsigned int val) |
| { |
| DIM_DI_WR(adr, val); |
| return 1; |
| } |
| |
| unsigned int DIM_RDMA_RD(unsigned int adr) |
| { |
| return RD(adr); |
| } |
| |
| unsigned int DIM_RDMA_WR_BITS(unsigned int adr, unsigned int val, |
| unsigned int start, unsigned int len) |
| { |
| DIM_DI_WR_REG_BITS(adr, val, start, len); |
| return 1; |
| } |
| |
| void dim_set_di_flag(void) |
| { |
| if (is_meson_txl_cpu() || |
| is_meson_txlx_cpu() || |
| is_meson_gxlx_cpu() || |
| is_meson_txhd_cpu() || |
| is_meson_g12a_cpu() || |
| is_meson_g12b_cpu() || |
| is_meson_tl1_cpu() || |
| is_meson_tm2_cpu() || |
| DIM_IS_IC(T5) || |
| DIM_IS_IC(T5D) || |
| is_meson_sm1_cpu() || |
| DIM_IS_IC_EF(SC2)) { |
| dimp_set(edi_mp_mcpre_en, 1); |
| mc_mem_alloc = true; |
| dimp_set(edi_mp_pulldown_enable, 0); |
| di_pre_rdma_enable = false; |
| /* |
| * txlx atsc 1080i ei only will cause flicker |
| * when full to small win in home screen |
| */ |
| |
| dimp_set(edi_mp_di_vscale_skip_enable, |
| (is_meson_txlx_cpu() || |
| is_meson_txhd_cpu()) ? 12 : 4); |
| /*use_2_interlace_buff = is_meson_gxlx_cpu()?0:1;*/ |
| dimp_set(edi_mp_use_2_interlace_buff, |
| is_meson_gxlx_cpu() ? 0 : 1); |
| if (is_meson_txl_cpu() || |
| is_meson_txlx_cpu() || |
| is_meson_gxlx_cpu() || |
| is_meson_txhd_cpu() || |
| is_meson_g12a_cpu() || |
| is_meson_g12b_cpu() || |
| is_meson_tl1_cpu() || |
| is_meson_tm2_cpu() || |
| DIM_IS_IC(T5) || |
| DIM_IS_IC(T5D) || |
| is_meson_sm1_cpu() || |
| DIM_IS_IC_EF(SC2)) { |
| dimp_set(edi_mp_full_422_pack, 1); |
| } |
| |
| if (dimp_get(edi_mp_nr10bit_support)) { |
| dimp_set(edi_mp_di_force_bit_mode, 10); |
| } else { |
| dimp_set(edi_mp_di_force_bit_mode, 8); |
| dimp_set(edi_mp_full_422_pack, 0); |
| } |
| |
| dimp_set(edi_mp_post_hold_line, |
| (is_meson_g12a_cpu() || |
| is_meson_g12b_cpu() || |
| is_meson_tl1_cpu() || |
| is_meson_tm2_cpu() || |
| DIM_IS_IC(T5) || |
| DIM_IS_IC(T5D) || |
| is_meson_sm1_cpu() || |
| DIM_IS_IC_EF(SC2)) ? 10 : 17); |
| } else { |
| /*post_hold_line = 8;*/ /*2019-01-10: from VLSI feijun*/ |
| dimp_set(edi_mp_post_hold_line, 8); |
| dimp_set(edi_mp_mcpre_en, 0); |
| dimp_set(edi_mp_pulldown_enable, 0); |
| di_pre_rdma_enable = false; |
| dimp_set(edi_mp_di_vscale_skip_enable, 4); |
| dimp_set(edi_mp_use_2_interlace_buff, 0); |
| dimp_set(edi_mp_di_force_bit_mode, 8); |
| } |
| /*if (is_meson_tl1_cpu() || is_meson_tm2_cpu())*/ |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| dimp_set(edi_mp_pulldown_enable, 1); |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| intr_mode = 3; |
| if (di_pre_rdma_enable) { |
| pldn_dly = 1; |
| pldn_dly1 = 1; |
| } else { |
| pldn_dly = 2; |
| pldn_dly1 = 2; |
| } |
| |
| if (DIM_IS_IC(T5) || DIM_IS_IC(TM2B) || DIM_IS_IC(T5D) || |
| DIM_IS_IC(T7)) |
| di_cfg_set(ECFG_DIM_BYPASS_P, 0);//for t5 enable p |
| |
| get_ops_mtn()->mtn_int_combing_glbmot(); |
| } |
| |
| #ifdef MARK_HIS /*move to di_sys.c*/ |
| static const struct reserved_mem_ops rmem_di_ops = { |
| .device_init = rmem_di_device_init, |
| .device_release = rmem_di_device_release, |
| }; |
| |
| static int __init rmem_di_setup(struct reserved_mem *rmem) |
| { |
| rmem->ops = &rmem_di_ops; |
| /* rmem->priv = cma; */ |
| |
| di_pr_info("DI reserved mem:creat CMA mem pool at %pa, size %ld MiB\n", |
| &rmem->base, (unsigned long)rmem->size / SZ_1M); |
| |
| return 0; |
| } |
| |
| RESERVEDMEM_OF_DECLARE(di, "amlogic, di-mem", rmem_di_setup); |
| #endif |
| |
| void dim_get_vpu_clkb(struct device *dev, struct di_dev_s *pdev) |
| { |
| int ret = 0; |
| unsigned int tmp_clk[2] = {0, 0}; |
| struct clk *vpu_clk = NULL; |
| |
| if (DIM_IS_IC_EF(SC2)) |
| vpu_clk = clk_get(dev, "vpu_clkb_tmp_mux"); |
| else if (DIM_IS_IC(T5) || DIM_IS_IC(T5D)) |
| vpu_clk = clk_get(dev, "t5_vpu_clkb_tmp_gate"); |
| else |
| vpu_clk = clk_get(dev, "vpu_mux"); |
| if (IS_ERR(vpu_clk)) |
| PR_ERR("%s: get clk vpu error.\n", __func__); |
| else |
| clk_prepare_enable(vpu_clk); |
| |
| ret = of_property_read_u32_array(dev->of_node, "clock-range", |
| tmp_clk, 2); |
| if (ret) { |
| pdev->clkb_min_rate = 250000000; |
| pdev->clkb_max_rate = 500000000; |
| } else { |
| pdev->clkb_min_rate = tmp_clk[0] * 1000000; |
| pdev->clkb_max_rate = tmp_clk[1] * 1000000; |
| } |
| pr_info("DI: vpu clkb <%lu, %lu>\n", pdev->clkb_min_rate, |
| pdev->clkb_max_rate); |
| #ifdef CLK_TREE_SUPPORT |
| if (DIM_IS_IC_EF(SC2)) |
| pdev->vpu_clkb = clk_get(dev, "vpu_clkb_gate"); |
| else if (DIM_IS_IC(T5) || DIM_IS_IC(T5D)) |
| pdev->vpu_clkb = clk_get(dev, "t5_vpu_clkb_gate"); |
| else |
| pdev->vpu_clkb = clk_get(dev, "vpu_clkb_composite"); |
| |
| if (IS_ERR(pdev->vpu_clkb)) |
| PR_ERR("%s: get vpu clkb gate error.\n", __func__); |
| #endif |
| } |
| |
| module_param_named(invert_top_bot, invert_top_bot, int, 0664); |
| |
| #ifdef DET3D |
| |
| MODULE_PARM_DESC(det3d_mode, "\n det3d_mode\n"); |
| module_param(det3d_mode, uint, 0664); |
| #endif |
| |
| module_param_array(di_stop_reg_addr, uint, &num_di_stop_reg_addr, |
| 0664); |
| |
| module_param_named(overturn, overturn, bool, 0664); |
| |
| #ifdef DEBUG_SUPPORT |
| #ifdef RUN_DI_PROCESS_IN_IRQ |
| module_param_named(input2pre, input2pre, uint, 0664); |
| module_param_named(input2pre_buf_miss_count, input2pre_buf_miss_count, |
| uint, 0664); |
| module_param_named(input2pre_proc_miss_count, input2pre_proc_miss_count, |
| uint, 0664); |
| module_param_named(input2pre_miss_policy, input2pre_miss_policy, uint, 0664); |
| module_param_named(input2pre_throw_count, input2pre_throw_count, uint, 0664); |
| #endif |
| #ifdef SUPPORT_MPEG_TO_VDIN |
| module_param_named(mpeg2vdin_en, mpeg2vdin_en, int, 0664); |
| module_param_named(mpeg2vdin_flag, mpeg2vdin_flag, int, 0664); |
| #endif |
| module_param_named(di_pre_rdma_enable, di_pre_rdma_enable, uint, 0664); |
| module_param_named(pldn_dly, pldn_dly, uint, 0644); |
| module_param_named(pldn_dly1, pldn_dly1, uint, 0644); |
| module_param_named(di_reg_unreg_cnt, di_reg_unreg_cnt, int, 0664); |
| module_param_named(bypass_pre, bypass_pre, int, 0664); |
| module_param_named(frame_count, frame_count, int, 0664); |
| #endif |
| |
| int dim_seq_file_module_para_di(struct seq_file *seq) |
| { |
| seq_puts(seq, "di---------------\n"); |
| |
| #ifdef DET3D |
| seq_printf(seq, "%-15s:%d\n", "det3d_frame_cnt", det3d_frame_cnt); |
| #endif |
| seq_printf(seq, "%-15s:%ld\n", "same_field_top_count", |
| same_field_top_count); |
| seq_printf(seq, "%-15s:%ld\n", "same_field_bot_count", |
| same_field_bot_count); |
| |
| seq_printf(seq, "%-15s:%d\n", "overturn", overturn); |
| |
| #ifdef DEBUG_SUPPORT |
| #ifdef RUN_DI_PROCESS_IN_IRQ |
| seq_printf(seq, "%-15s:%d\n", "input2pre", input2pre); |
| seq_printf(seq, "%-15s:%d\n", "input2pre_buf_miss_count", |
| input2pre_buf_miss_count); |
| seq_printf(seq, "%-15s:%d\n", "input2pre_proc_miss_count", |
| input2pre_proc_miss_count); |
| seq_printf(seq, "%-15s:%d\n", "input2pre_miss_policy", |
| input2pre_miss_policy); |
| seq_printf(seq, "%-15s:%d\n", "input2pre_throw_count", |
| input2pre_throw_count); |
| #endif |
| #ifdef SUPPORT_MPEG_TO_VDIN |
| |
| seq_printf(seq, "%-15s:%d\n", "mpeg2vdin_en", mpeg2vdin_en); |
| seq_printf(seq, "%-15s:%d\n", "mpeg2vdin_flag", mpeg2vdin_flag); |
| #endif |
| seq_printf(seq, "%-15s:%d\n", "di_pre_rdma_enable", |
| di_pre_rdma_enable); |
| seq_printf(seq, "%-15s:%d\n", "pldn_dly", pldn_dly); |
| seq_printf(seq, "%-15s:%d\n", "pldn_dly1", pldn_dly1); |
| seq_printf(seq, "%-15s:%d\n", "di_reg_unreg_cnt", di_reg_unreg_cnt); |
| seq_printf(seq, "%-15s:%d\n", "bypass_pre", bypass_pre); |
| seq_printf(seq, "%-15s:%d\n", "frame_count", frame_count); |
| #endif |
| /******************************/ |
| |
| #ifdef DET3D |
| seq_printf(seq, "%-15s:%d\n", "det3d_mode", det3d_mode); |
| #endif |
| return 0; |
| } |
| |
| #ifdef MARK_HIS /*move to di_sys.c*/ |
| MODULE_DESCRIPTION("AMLOGIC DEINTERLACE driver"); |
| MODULE_LICENSE("GPL"); |
| MODULE_VERSION("4.0.0"); |
| #endif |