| // SPDX-License-Identifier: (GPL-2.0+ OR MIT) |
| /* |
| * drivers/amlogic/media/deinterlace/sc2/di_afbc_v3.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/of_device.h> |
| |
| #include <linux/amlogic/media/vfm/vframe.h> |
| |
| /*dma_get_cma_size_int_byte*/ |
| #include <linux/amlogic/media/codec_mm/codec_mm.h> |
| |
| #include "deinterlace_dbg.h" |
| #include "deinterlace.h" |
| #include "di_data_l.h" |
| |
| #include "register.h" |
| #include "nr_downscale.h" |
| #include "deinterlace_hw.h" |
| #include "register_nr4.h" |
| #include "di_reg_v3.h" |
| #include "di_prc.h" |
| |
| #include "di_afbc_v3.h" |
| #include "sc2/di_hw_v3.h" |
| |
| //#include "di_pqa.h" |
| #include "../deinterlace/di_pqa.h" |
| |
| /*di multi*/ |
| #include "di_sys.h" |
| #include <linux/amlogic/media/vpu/vpu.h> |
| |
| #define DI_BIT0 0x00000001 |
| #define DI_BIT1 0x00000002 |
| #define DI_BIT2 0x00000004 |
| #define DI_BIT3 0x00000008 |
| #define DI_BIT4 0x00000010 |
| #define DI_BIT5 0x00000020 |
| #define DI_BIT6 0x00000040 |
| #define DI_BIT7 0x00000080 |
| |
| #define di_print dim_print |
| #define di_vmap dim_vmap |
| #define di_unmap_phyaddr dim_unmap_phyaddr |
| |
| static unsigned int reg_rd(unsigned int addr) |
| { |
| return aml_read_vcbus(addr); |
| } |
| |
| static unsigned int reg_rdb(unsigned int adr, unsigned int start, |
| unsigned int len) |
| { |
| return rd_reg_bits(adr, start, len); |
| } |
| |
| static void reg_wr(unsigned int addr, unsigned int val) |
| { |
| WR(addr, val); |
| } |
| |
| static unsigned int reg_wrb(unsigned int adr, unsigned int val, |
| unsigned int start, unsigned int len) |
| { |
| wr_reg_bits(adr, val, start, len); |
| return 1; |
| } |
| |
| static const struct reg_acc di_normal_regset = { |
| .wr = reg_wr, |
| .rd = reg_rd, |
| .bwr = reg_wrb, |
| .brd = reg_rdb, |
| }; |
| |
| /*tmp*/ |
| /*static struct afd_s di_afd;*/ |
| #define BITS_EAFBC_CFG_DISABLE DI_BIT0 |
| #define BITS_EAFBC_CFG_INP_AFBC DI_BIT1 |
| #define BITS_EAFBC_CFG_EMODE DI_BIT2 |
| #define BITS_EAFBC_CFG_ETEST DI_BIT3 |
| #define BITS_EAFBC_CFG_4K DI_BIT4 |
| #define BITS_EAFBC_CFG_PRE_LINK DI_BIT5 |
| #define BITS_EAFBC_CFG_PAUSE DI_BIT6 |
| #define BITS_EAFBC_CFG_LEVE3 DI_BIT7 |
| |
| #define BITS_EAFBC_CFG_6DEC_2ENC DI_BIT8 |
| #define BITS_EAFBC_CFG_6DEC_2ENC2 DI_BIT9 |
| #define BITS_EAFBC_CFG_6DEC_1ENC3 DI_BIT10 |
| #define BITS_EAFBC_CFG_FORCE_MEM DI_BIT15 |
| #define BITS_EAFBC_CFG_FORCE_CHAN2 DI_BIT14 |
| #define BITS_EAFBC_CFG_FORCE_NR DI_BIT13 |
| #define BITS_EAFBC_CFG_FORCE_IF1 DI_BIT12 |
| |
| #define BITS_EAFBC_CFG_MEM DI_BIT31 |
| |
| /************************************ |
| * bit[0]: on/off |
| * bit[1]: p -> need proce p use 2 i buf |
| * bit[2]: mode |
| ************************************/ |
| static u32 afbc_cfg;// = BITS_EAFBC_CFG_4K; |
| /************************************ |
| * base function: |
| * 0x3: afbcd x 1 |
| * 0x07: afbcd x 2 + afbce x 1 |
| * 0x101: |
| ************************************/ |
| module_param_named(afbc_cfg, afbc_cfg, uint, 0664); |
| |
| #ifdef DBG_AFBC |
| static u32 afbc_cfg_vf; |
| module_param_named(afbc_cfg_vf, afbc_cfg_vf, uint, 0664); |
| static u32 afbc_cfg_bt; |
| module_param_named(afbc_cfg_bt, afbc_cfg_bt, uint, 0664); |
| #endif |
| static struct afbcd_ctr_s *di_get_afd_ctr(void); |
| |
| /************************************************ |
| * [0]: enable afbc |
| * [1]: p use 2 ibuf mode |
| * [2]: 2afbcd + 1afbce mode ([1] must 1) |
| * [3]: 2afbcd + 1afbce test mode (mem use inp vf) |
| * [4]: 4k test mode; i need bypass; |
| * [5]: pre_link mode |
| * [6]: stop when first frame display |
| * [7]: change level always 3 |
| * [8]: 6afbcd + 2afbce |
| * [31]: afbce enable (get memory) |
| ***********************************************/ |
| |
| static bool is_cfg(enum EAFBC_CFG cfg_cmd) |
| { |
| bool ret; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (pafd_ctr->fb.ver < AFBCD_V4) { |
| if (cfg_cmd > EAFBC_CFG_INP_AFBC) |
| return false; |
| |
| } else if (pafd_ctr->fb.ver == AFBCD_V4) { |
| if (cfg_cmd > EAFBC_CFG_MEM) |
| return false; |
| } |
| |
| ret = false; |
| switch (cfg_cmd) { |
| case EAFBC_CFG_DISABLE: |
| if (afbc_cfg & BITS_EAFBC_CFG_DISABLE) |
| ret = true; |
| break; |
| case EAFBC_CFG_INP_AFBC: |
| if (afbc_cfg & BITS_EAFBC_CFG_INP_AFBC) |
| ret = true; |
| break; |
| case EAFBC_CFG_ETEST2: |
| if (afbc_cfg & BITS_EAFBC_CFG_EMODE) |
| ret = true; |
| break; |
| case EAFBC_CFG_ETEST: |
| if (afbc_cfg & BITS_EAFBC_CFG_ETEST) |
| ret = true; |
| break; |
| case EAFBC_CFG_4K: |
| if (afbc_cfg & BITS_EAFBC_CFG_4K) |
| ret = true; |
| break; |
| case EAFBC_CFG_PRE_LINK: |
| if (afbc_cfg & BITS_EAFBC_CFG_PRE_LINK) |
| ret = true; |
| break; |
| case EAFBC_CFG_PAUSE: |
| if (afbc_cfg & BITS_EAFBC_CFG_PAUSE) |
| ret = true; |
| break; |
| case EAFBC_CFG_LEVE3: |
| if (afbc_cfg & BITS_EAFBC_CFG_LEVE3) |
| ret = true; |
| break; |
| case EAFBC_CFG_FORCE_MEM: |
| if (afbc_cfg & BITS_EAFBC_CFG_FORCE_MEM) |
| ret = true; |
| break; |
| case EAFBC_CFG_FORCE_CHAN2: |
| if (afbc_cfg & BITS_EAFBC_CFG_FORCE_CHAN2) |
| ret = true; |
| break; |
| case EAFBC_CFG_FORCE_NR: |
| if (afbc_cfg & BITS_EAFBC_CFG_FORCE_NR) |
| ret = true; |
| break; |
| case EAFBC_CFG_FORCE_IF1: |
| if (afbc_cfg & BITS_EAFBC_CFG_FORCE_IF1) |
| ret = true; |
| break; |
| case EAFBC_CFG_6DEC_2ENC: |
| if (afbc_cfg & BITS_EAFBC_CFG_6DEC_2ENC) |
| ret = true; |
| break; |
| case EAFBC_CFG_6DEC_2ENC2: |
| if (afbc_cfg & BITS_EAFBC_CFG_6DEC_2ENC2) |
| ret = true; |
| break; |
| case EAFBC_CFG_6DEC_1ENC3: |
| if (afbc_cfg & BITS_EAFBC_CFG_6DEC_1ENC3) |
| ret = true; |
| break; |
| case EAFBC_CFG_MEM: |
| if (afbc_cfg & (BITS_EAFBC_CFG_MEM | |
| BITS_EAFBC_CFG_EMODE | |
| BITS_EAFBC_CFG_6DEC_2ENC | |
| BITS_EAFBC_CFG_6DEC_2ENC2 | |
| BITS_EAFBC_CFG_6DEC_1ENC3)) |
| ret = true; |
| break; |
| } |
| return ret; |
| } |
| |
| static bool is_status(enum EAFBC_STS status) |
| { |
| bool ret = false; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| switch (status) { |
| case EAFBC_MEM_NEED: |
| ret = pafd_ctr->fb.mem_alloc; |
| break; |
| case EAFBC_MEMI_NEED: |
| ret = pafd_ctr->fb.mem_alloci; |
| break; |
| case EAFBC_EN_6CH: |
| if (pafd_ctr->fb.mode >= AFBC_WK_6D) |
| ret = true; |
| break; |
| case EAFBC_EN_ENC: |
| if (pafd_ctr->fb.mode >= AFBC_WK_P) |
| ret = true; |
| break; |
| } |
| |
| return ret; |
| } |
| |
| static bool prelink_status; |
| |
| bool dbg_di_prelink_v3(void) |
| { |
| if (is_cfg(EAFBC_CFG_PRE_LINK)) |
| return true; |
| |
| return false; |
| } |
| EXPORT_SYMBOL(dbg_di_prelink_v3); |
| |
| void dbg_di_prelink_reg_check_v3(void) |
| { |
| unsigned int val; |
| |
| if (DIM_IS_IC_BF(TM2B)) { |
| dim_print("%s:check return;\n", __func__); |
| return; |
| } |
| |
| if (!prelink_status && is_cfg(EAFBC_CFG_PRE_LINK)) { |
| /* set on*/ |
| if (DIM_IS_IC_EF(SC2)) { |
| /* ? */ |
| } else { |
| reg_wrb(DI_AFBCE_CTRL, 1, 3, 1); |
| reg_wr(VD1_AFBCD0_MISC_CTRL, 0x100100); |
| } |
| prelink_status = true; |
| } else if (prelink_status && !is_cfg(EAFBC_CFG_PRE_LINK)) { |
| /* set off */ |
| if (DIM_IS_IC_EF(SC2)) |
| di_pr_info("%s\n", __func__); |
| else |
| reg_wrb(DI_AFBCE_CTRL, 0, 3, 1); |
| |
| prelink_status = false; |
| } |
| |
| if (!is_cfg(EAFBC_CFG_PRE_LINK)) |
| return; |
| |
| val = reg_rd(VD1_AFBCD0_MISC_CTRL); |
| if (val != 0x100100) { |
| di_pr_info("%s:change 0x%x\n", __func__, val); |
| reg_wr(VD1_AFBCD0_MISC_CTRL, 0x100100); |
| } |
| } |
| |
| static struct afd_s *di_afdp; |
| |
| static struct afbcd_ctr_s *di_get_afd_ctr(void) |
| { |
| //return &di_afd.ctr; |
| return &di_afdp->ctr; |
| } |
| |
| static struct afd_s *get_afdp(void) |
| { |
| return di_afdp; |
| } |
| |
| static bool is_src_i(struct vframe_s *vf) |
| { |
| bool ret = false; |
| struct di_buf_s *di_buf; |
| |
| if (!vf->private_data) |
| return false; |
| |
| di_buf = (struct di_buf_s *)vf->private_data; |
| if (di_buf->afbc_info & DI_BIT0) |
| ret = true; |
| |
| return ret; |
| } |
| |
| static bool is_src_real_i(struct vframe_s *vf) |
| { |
| bool ret = false; |
| struct di_buf_s *di_buf; |
| |
| if (!vf->private_data) |
| return false; |
| |
| di_buf = (struct di_buf_s *)vf->private_data; |
| if (di_buf->afbc_info & DI_BIT1) |
| ret = true; |
| |
| return ret; |
| } |
| |
| static bool src_i_set(struct vframe_s *vf) |
| { |
| bool ret = false; |
| struct di_buf_s *di_buf; |
| |
| if (!vf->private_data) { |
| #ifdef PRINT_BASIC |
| PR_ERR("%s:novf\n", __func__); |
| #endif |
| return false; |
| } |
| |
| di_buf = (struct di_buf_s *)vf->private_data; |
| di_buf->afbc_info |= DI_BIT0; |
| |
| ret = true; |
| |
| return ret; |
| } |
| |
| static const unsigned int reg_afbc[AFBC_DEC_NUB][AFBC_REG_INDEX_NUB] = { |
| { |
| AFBC_ENABLE, |
| AFBC_MODE, |
| AFBC_SIZE_IN, |
| AFBC_DEC_DEF_COLOR, |
| AFBC_CONV_CTRL, |
| AFBC_LBUF_DEPTH, |
| AFBC_HEAD_BADDR, |
| AFBC_BODY_BADDR, |
| AFBC_SIZE_OUT, |
| AFBC_OUT_YSCOPE, |
| AFBC_STAT, |
| AFBC_VD_CFMT_CTRL, |
| AFBC_VD_CFMT_W, |
| AFBC_MIF_HOR_SCOPE, |
| AFBC_MIF_VER_SCOPE, |
| AFBC_PIXEL_HOR_SCOPE, |
| AFBC_PIXEL_VER_SCOPE, |
| AFBC_VD_CFMT_H, |
| }, |
| { |
| VD2_AFBC_ENABLE, |
| VD2_AFBC_MODE, |
| VD2_AFBC_SIZE_IN, |
| VD2_AFBC_DEC_DEF_COLOR, |
| VD2_AFBC_CONV_CTRL, |
| VD2_AFBC_LBUF_DEPTH, |
| VD2_AFBC_HEAD_BADDR, |
| VD2_AFBC_BODY_BADDR, |
| VD2_AFBC_OUT_XSCOPE, |
| VD2_AFBC_OUT_YSCOPE, |
| VD2_AFBC_STAT, |
| VD2_AFBC_VD_CFMT_CTRL, |
| VD2_AFBC_VD_CFMT_W, |
| VD2_AFBC_MIF_HOR_SCOPE, |
| VD2_AFBC_MIF_VER_SCOPE, |
| VD2_AFBC_PIXEL_HOR_SCOPE, |
| VD2_AFBC_PIXEL_VER_SCOPE, |
| VD2_AFBC_VD_CFMT_H, |
| |
| }, |
| { |
| DI_INP_AFBC_ENABLE, |
| DI_INP_AFBC_MODE, |
| DI_INP_AFBC_SIZE_IN, |
| DI_INP_AFBC_DEC_DEF_COLOR, |
| DI_INP_AFBC_CONV_CTRL, |
| DI_INP_AFBC_LBUF_DEPTH, |
| DI_INP_AFBC_HEAD_BADDR, |
| DI_INP_AFBC_BODY_BADDR, |
| DI_INP_AFBC_SIZE_OUT, |
| DI_INP_AFBC_OUT_YSCOPE, |
| DI_INP_AFBC_STAT, |
| DI_INP_AFBC_VD_CFMT_CTRL, |
| DI_INP_AFBC_VD_CFMT_W, |
| DI_INP_AFBC_MIF_HOR_SCOPE, |
| DI_INP_AFBC_MIF_VER_SCOPE, |
| DI_INP_AFBC_PIXEL_HOR_SCOPE, |
| DI_INP_AFBC_PIXEL_VER_SCOPE, |
| DI_INP_AFBC_VD_CFMT_H, |
| |
| }, |
| { |
| DI_MEM_AFBC_ENABLE, |
| DI_MEM_AFBC_MODE, |
| DI_MEM_AFBC_SIZE_IN, |
| DI_MEM_AFBC_DEC_DEF_COLOR, |
| DI_MEM_AFBC_CONV_CTRL, |
| DI_MEM_AFBC_LBUF_DEPTH, |
| DI_MEM_AFBC_HEAD_BADDR, |
| DI_MEM_AFBC_BODY_BADDR, |
| DI_MEM_AFBC_SIZE_OUT, |
| DI_MEM_AFBC_OUT_YSCOPE, |
| DI_MEM_AFBC_STAT, |
| DI_MEM_AFBC_VD_CFMT_CTRL, |
| DI_MEM_AFBC_VD_CFMT_W, |
| DI_MEM_AFBC_MIF_HOR_SCOPE, |
| DI_MEM_AFBC_MIF_VER_SCOPE, |
| DI_MEM_AFBC_PIXEL_HOR_SCOPE, |
| DI_MEM_AFBC_PIXEL_VER_SCOPE, |
| DI_MEM_AFBC_VD_CFMT_H, |
| }, |
| |
| }; |
| |
| static const unsigned int reg_afbc_v5[AFBC_DEC_NUB_V5][AFBC_REG_INDEX_NUB] = { |
| [EAFBC_DEC0] = { |
| AFBCDM_VD1_ENABLE, |
| AFBCDM_VD1_MODE, |
| AFBCDM_VD1_SIZE_IN, |
| AFBCDM_VD1_DEC_DEF_COLOR, |
| AFBCDM_VD1_CONV_CTRL, |
| AFBCDM_VD1_LBUF_DEPTH, |
| AFBCDM_VD1_HEAD_BADDR, |
| AFBCDM_VD1_BODY_BADDR, |
| AFBCDM_VD1_SIZE_OUT, |
| AFBCDM_VD1_OUT_YSCOPE, |
| AFBCDM_VD1_STAT, |
| AFBCDM_VD1_VD_CFMT_CTRL, |
| AFBCDM_VD1_VD_CFMT_W, |
| AFBCDM_VD1_MIF_HOR_SCOPE, |
| AFBCDM_VD1_MIF_VER_SCOPE, |
| AFBCDM_VD1_PIXEL_HOR_SCOPE, |
| AFBCDM_VD1_PIXEL_VER_SCOPE, |
| AFBCDM_VD1_VD_CFMT_H, |
| }, |
| [EAFBC_DEC1] = { |
| AFBCDM_VD1_ENABLE, |
| AFBCDM_VD1_MODE, |
| AFBCDM_VD1_SIZE_IN, |
| AFBCDM_VD1_DEC_DEF_COLOR, |
| AFBCDM_VD1_CONV_CTRL, |
| AFBCDM_VD1_LBUF_DEPTH, |
| AFBCDM_VD1_HEAD_BADDR, |
| AFBCDM_VD1_BODY_BADDR, |
| AFBCDM_VD1_SIZE_OUT, |
| AFBCDM_VD1_OUT_YSCOPE, |
| AFBCDM_VD1_STAT, |
| AFBCDM_VD1_VD_CFMT_CTRL, |
| AFBCDM_VD1_VD_CFMT_W, |
| AFBCDM_VD1_MIF_HOR_SCOPE, |
| AFBCDM_VD1_MIF_VER_SCOPE, |
| AFBCDM_VD1_PIXEL_HOR_SCOPE, |
| AFBCDM_VD1_PIXEL_VER_SCOPE, |
| AFBCDM_VD1_VD_CFMT_H, |
| |
| }, |
| [EAFBC_DEC2_DI] = { |
| AFBCDM_INP_ENABLE, |
| AFBCDM_INP_MODE, |
| AFBCDM_INP_SIZE_IN, |
| AFBCDM_INP_DEC_DEF_COLOR, |
| AFBCDM_INP_CONV_CTRL, |
| AFBCDM_INP_LBUF_DEPTH, |
| AFBCDM_INP_HEAD_BADDR, |
| AFBCDM_INP_BODY_BADDR, |
| AFBCDM_INP_SIZE_OUT, |
| AFBCDM_INP_OUT_YSCOPE, |
| AFBCDM_INP_STAT, |
| AFBCDM_INP_VD_CFMT_CTRL, |
| AFBCDM_INP_VD_CFMT_W, |
| AFBCDM_INP_MIF_HOR_SCOPE, |
| AFBCDM_INP_MIF_VER_SCOPE, |
| AFBCDM_INP_PIXEL_HOR_SCOPE, |
| AFBCDM_INP_PIXEL_VER_SCOPE, |
| AFBCDM_INP_VD_CFMT_H, |
| |
| }, |
| [EAFBC_DEC_CHAN2] = { |
| AFBCDM_CHAN2_ENABLE, |
| AFBCDM_CHAN2_MODE, |
| AFBCDM_CHAN2_SIZE_IN, |
| AFBCDM_CHAN2_DEC_DEF_COLOR, |
| AFBCDM_CHAN2_CONV_CTRL, |
| AFBCDM_CHAN2_LBUF_DEPTH, |
| AFBCDM_CHAN2_HEAD_BADDR, |
| AFBCDM_CHAN2_BODY_BADDR, |
| AFBCDM_CHAN2_SIZE_OUT, |
| AFBCDM_CHAN2_OUT_YSCOPE, |
| AFBCDM_CHAN2_STAT, |
| AFBCDM_CHAN2_VD_CFMT_CTRL, |
| AFBCDM_CHAN2_VD_CFMT_W, |
| AFBCDM_CHAN2_MIF_HOR_SCOPE, |
| AFBCDM_CHAN2_MIF_VER_SCOPE, |
| AFBCDM_CHAN2_PIXEL_HOR_SCOPE, |
| AFBCDM_CHAN2_PIXEL_VER_SCOPE, |
| AFBCDM_CHAN2_VD_CFMT_H, |
| }, |
| [EAFBC_DEC3_MEM] = { |
| AFBCDM_MEM_ENABLE, |
| AFBCDM_MEM_MODE, |
| AFBCDM_MEM_SIZE_IN, |
| AFBCDM_MEM_DEC_DEF_COLOR, |
| AFBCDM_MEM_CONV_CTRL, |
| AFBCDM_MEM_LBUF_DEPTH, |
| AFBCDM_MEM_HEAD_BADDR, |
| AFBCDM_MEM_BODY_BADDR, |
| AFBCDM_MEM_SIZE_OUT, |
| AFBCDM_MEM_OUT_YSCOPE, |
| AFBCDM_MEM_STAT, |
| AFBCDM_MEM_VD_CFMT_CTRL, |
| AFBCDM_MEM_VD_CFMT_W, |
| AFBCDM_MEM_MIF_HOR_SCOPE, |
| AFBCDM_MEM_MIF_VER_SCOPE, |
| AFBCDM_MEM_PIXEL_HOR_SCOPE, |
| AFBCDM_MEM_PIXEL_VER_SCOPE, |
| AFBCDM_MEM_VD_CFMT_H, |
| }, |
| [EAFBC_DEC_IF1] = { |
| AFBCDM_IF1_ENABLE, |
| AFBCDM_IF1_MODE, |
| AFBCDM_IF1_SIZE_IN, |
| AFBCDM_IF1_DEC_DEF_COLOR, |
| AFBCDM_IF1_CONV_CTRL, |
| AFBCDM_IF1_LBUF_DEPTH, |
| AFBCDM_IF1_HEAD_BADDR, |
| AFBCDM_IF1_BODY_BADDR, |
| AFBCDM_IF1_SIZE_OUT, |
| AFBCDM_IF1_OUT_YSCOPE, |
| AFBCDM_IF1_STAT, |
| AFBCDM_IF1_VD_CFMT_CTRL, |
| AFBCDM_IF1_VD_CFMT_W, |
| AFBCDM_IF1_MIF_HOR_SCOPE, |
| AFBCDM_IF1_MIF_VER_SCOPE, |
| AFBCDM_IF1_PIXEL_HOR_SCOPE, |
| AFBCDM_IF1_PIXEL_VER_SCOPE, |
| AFBCDM_IF1_VD_CFMT_H, |
| }, |
| [EAFBC_DEC_IF0] = { |
| AFBCDM_IF0_ENABLE, |
| AFBCDM_IF0_MODE, |
| AFBCDM_IF0_SIZE_IN, |
| AFBCDM_IF0_DEC_DEF_COLOR, |
| AFBCDM_IF0_CONV_CTRL, |
| AFBCDM_IF0_LBUF_DEPTH, |
| AFBCDM_IF0_HEAD_BADDR, |
| AFBCDM_IF0_BODY_BADDR, |
| AFBCDM_IF0_SIZE_OUT, |
| AFBCDM_IF0_OUT_YSCOPE, |
| AFBCDM_IF0_STAT, |
| AFBCDM_IF0_VD_CFMT_CTRL, |
| AFBCDM_IF0_VD_CFMT_W, |
| AFBCDM_IF0_MIF_HOR_SCOPE, |
| AFBCDM_IF0_MIF_VER_SCOPE, |
| AFBCDM_IF0_PIXEL_HOR_SCOPE, |
| AFBCDM_IF0_PIXEL_VER_SCOPE, |
| AFBCDM_IF0_VD_CFMT_H, |
| }, |
| [EAFBC_DEC_IF2] = { |
| AFBCDM_IF2_ENABLE, |
| AFBCDM_IF2_MODE, |
| AFBCDM_IF2_SIZE_IN, |
| AFBCDM_IF2_DEC_DEF_COLOR, |
| AFBCDM_IF2_CONV_CTRL, |
| AFBCDM_IF2_LBUF_DEPTH, |
| AFBCDM_IF2_HEAD_BADDR, |
| AFBCDM_IF2_BODY_BADDR, |
| AFBCDM_IF2_SIZE_OUT, |
| AFBCDM_IF2_OUT_YSCOPE, |
| AFBCDM_IF2_STAT, |
| AFBCDM_IF2_VD_CFMT_CTRL, |
| AFBCDM_IF2_VD_CFMT_W, |
| AFBCDM_IF2_MIF_HOR_SCOPE, |
| AFBCDM_IF2_MIF_VER_SCOPE, |
| AFBCDM_IF2_PIXEL_HOR_SCOPE, |
| AFBCDM_IF2_PIXEL_VER_SCOPE, |
| AFBCDM_IF2_VD_CFMT_H, |
| }, |
| |
| }; |
| |
| /*keep order with struct afbce_bits_s*/ |
| static const unsigned int reg_afbc_e[AFBC_ENC_NUB_V5][DIM_AFBCE_NUB] = { |
| { |
| DI_AFBCE_ENABLE, /* 0 */ |
| DI_AFBCE_MODE, /* 1 */ |
| DI_AFBCE_SIZE_IN, /* 2 */ |
| DI_AFBCE_BLK_SIZE_IN, /* 3 */ |
| DI_AFBCE_HEAD_BADDR, /* 4 */ |
| |
| DI_AFBCE_MIF_SIZE, /* 5 */ |
| DI_AFBCE_PIXEL_IN_HOR_SCOPE, /* 6 */ |
| DI_AFBCE_PIXEL_IN_VER_SCOPE, /* 7 */ |
| DI_AFBCE_CONV_CTRL, /* 8 */ |
| DI_AFBCE_MIF_HOR_SCOPE, /* 9 */ |
| DI_AFBCE_MIF_VER_SCOPE, /* 10 */ |
| /**/ |
| DI_AFBCE_FORMAT, /* 11 */ |
| /**/ |
| DI_AFBCE_DEFCOLOR_1, /* 12 */ |
| DI_AFBCE_DEFCOLOR_2, /* 13 */ |
| DI_AFBCE_QUANT_ENABLE, /* 14 */ |
| //unsigned int mmu_num, |
| DI_AFBCE_MMU_RMIF_CTRL1, /* 15 */ |
| DI_AFBCE_MMU_RMIF_CTRL2, /* 16 */ |
| DI_AFBCE_MMU_RMIF_CTRL3, /* 17 */ |
| DI_AFBCE_MMU_RMIF_CTRL4, /* 18 */ |
| DI_AFBCE_MMU_RMIF_SCOPE_X, /* 19 */ |
| DI_AFBCE_MMU_RMIF_SCOPE_Y, /* 20 */ |
| |
| /**********************/ |
| DI_AFBCE_MODE_EN, |
| DI_AFBCE_DWSCALAR, |
| DI_AFBCE_IQUANT_LUT_1, |
| DI_AFBCE_IQUANT_LUT_2, |
| DI_AFBCE_IQUANT_LUT_3, |
| DI_AFBCE_IQUANT_LUT_4, |
| DI_AFBCE_RQUANT_LUT_1, |
| DI_AFBCE_RQUANT_LUT_2, |
| DI_AFBCE_RQUANT_LUT_3, |
| DI_AFBCE_RQUANT_LUT_4, |
| DI_AFBCE_YUV_FORMAT_CONV_MODE, |
| DI_AFBCE_DUMMY_DATA, |
| DI_AFBCE_CLR_FLAG, |
| DI_AFBCE_STA_FLAGT, |
| DI_AFBCE_MMU_NUM, |
| DI_AFBCE_STAT1, /*read only*/ |
| DI_AFBCE_STAT2, |
| DI_AFBCE_MMU_RMIF_RO_STAT, |
| /*add for sc2*/ |
| DI_AFBCE_PIP_CTRL, |
| DI_AFBCE_ROT_CTRL, |
| DI_AFBCE_DIMM_CTRL, |
| DI_AFBCE_BND_DEC_MISC, |
| DI_AFBCE_RD_ARB_MISC, |
| }, |
| { |
| DI_AFBCE1_ENABLE, /* 0 */ |
| DI_AFBCE1_MODE, /* 1 */ |
| DI_AFBCE1_SIZE_IN, /* 2 */ |
| DI_AFBCE1_BLK_SIZE_IN, /* 3 */ |
| DI_AFBCE1_HEAD_BADDR, /* 4 */ |
| |
| DI_AFBCE1_MIF_SIZE, /* 5 */ |
| DI_AFBCE1_PIXEL_IN_HOR_SCOPE, /* 6 */ |
| DI_AFBCE1_PIXEL_IN_VER_SCOPE, /* 7 */ |
| DI_AFBCE1_CONV_CTRL, /* 8 */ |
| DI_AFBCE1_MIF_HOR_SCOPE, /* 9 */ |
| DI_AFBCE1_MIF_VER_SCOPE, /* 10 */ |
| /**/ |
| DI_AFBCE1_FORMAT, /* 11 */ |
| /**/ |
| DI_AFBCE1_DEFCOLOR_1, /* 12 */ |
| DI_AFBCE1_DEFCOLOR_2, /* 13 */ |
| DI_AFBCE1_QUANT_ENABLE, /* 14 */ |
| //unsigned int mmu_num, |
| DI_AFBCE1_MMU_RMIF_CTRL1, /* 15 */ |
| DI_AFBCE1_MMU_RMIF_CTRL2, /* 16 */ |
| DI_AFBCE1_MMU_RMIF_CTRL3, /* 17 */ |
| DI_AFBCE1_MMU_RMIF_CTRL4, /* 18 */ |
| DI_AFBCE1_MMU_RMIF_SCOPE_X, /* 19 */ |
| DI_AFBCE1_MMU_RMIF_SCOPE_Y, /* 20 */ |
| |
| /**********************/ |
| DI_AFBCE1_MODE_EN, |
| DI_AFBCE1_DWSCALAR, |
| DI_AFBCE1_IQUANT_LUT_1, |
| DI_AFBCE1_IQUANT_LUT_2, |
| DI_AFBCE1_IQUANT_LUT_3, |
| DI_AFBCE1_IQUANT_LUT_4, |
| DI_AFBCE1_RQUANT_LUT_1, |
| DI_AFBCE1_RQUANT_LUT_2, |
| DI_AFBCE1_RQUANT_LUT_3, |
| DI_AFBCE1_RQUANT_LUT_4, |
| DI_AFBCE1_YUV_FORMAT_CONV_MODE, |
| DI_AFBCE1_DUMMY_DATA, |
| DI_AFBCE1_CLR_FLAG, |
| DI_AFBCE1_STA_FLAGT, |
| DI_AFBCE1_MMU_NUM, |
| DI_AFBCE1_STAT1, /*read only*/ |
| DI_AFBCE1_STAT2, |
| DI_AFBCE1_MMU_RMIF_RO_STAT, |
| /*from sc2*/ |
| DI_AFBCE1_PIP_CTRL, |
| DI_AFBCE1_ROT_CTRL, |
| DI_AFBCE1_DIMM_CTRL, |
| DI_AFBCE1_BND_DEC_MISC, |
| DI_AFBCE1_RD_ARB_MISC, |
| }, |
| }; |
| |
| static const unsigned int *afbc_get_addrp(enum EAFBC_DEC eidx) |
| { |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (pafd_ctr->fb.ver < AFBCD_V5) |
| return ®_afbc[eidx][0]; |
| |
| return ®_afbc_v5[eidx][0]; |
| } |
| |
| static void afbcd_reg_bwr(enum EAFBC_DEC eidx, enum EAFBC_REG adr_idx, |
| unsigned int val, |
| unsigned int start, unsigned int len) |
| { |
| const unsigned int *reg;// = afbc_get_regbase(); |
| // struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| unsigned int reg_addr; |
| |
| reg = afbc_get_addrp(eidx); |
| reg_addr = reg[adr_idx]; |
| |
| //di_print("%s:reg[0x%x] sw[%d]\n", __func__, reg_AFBC_ENABLE, on); |
| |
| reg_wrb(reg_addr, val, start, len); |
| } |
| |
| static const unsigned int *afbce_get_addrp(enum EAFBC_ENC eidx) |
| { |
| return ®_afbc_e[eidx][0]; |
| } |
| |
| static void dump_afbcd_reg(void) |
| { |
| u32 i; |
| u32 afbc_reg; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| pr_info("---- dump afbc EAFBC_DEC0 reg -----\n"); |
| for (i = 0; i < AFBC_REG_INDEX_NUB; i++) { |
| if (pafd_ctr->fb.ver < AFBCD_V5) |
| afbc_reg = reg_afbc[EAFBC_DEC0][i]; |
| else |
| afbc_reg = reg_afbc_v5[EAFBC_DEC0][i]; |
| pr_info("reg 0x%x val:0x%x\n", afbc_reg, reg_rd(afbc_reg)); |
| } |
| pr_info("---- dump afbc EAFBC_DEC1 reg -----\n"); |
| for (i = 0; i < AFBC_REG_INDEX_NUB; i++) { |
| if (pafd_ctr->fb.ver < AFBCD_V5) |
| afbc_reg = reg_afbc[EAFBC_DEC1][i]; |
| else |
| afbc_reg = reg_afbc_v5[EAFBC_DEC1][i]; |
| pr_info("reg 0x%x val:0x%x\n", afbc_reg, reg_rd(afbc_reg)); |
| } |
| pr_info("reg 0x%x val:0x%x\n", |
| VD1_AFBCD0_MISC_CTRL, reg_rd(VD1_AFBCD0_MISC_CTRL)); |
| pr_info("reg 0x%x val:0x%x\n", |
| VD2_AFBCD1_MISC_CTRL, reg_rd(VD2_AFBCD1_MISC_CTRL)); |
| } |
| |
| static void dbg_afbc_blk(struct seq_file *s, union afbc_blk_s *blk, char *name) |
| { |
| seq_printf(s, "%10s:[%d]\n", name, blk->d8); |
| seq_printf(s, "\t%5s:[%d],\n", "inp", blk->b.inp); |
| seq_printf(s, "\t%5s:[%d],\n", "mem", blk->b.mem); |
| seq_printf(s, "\t%5s:[%d],\n", "chan2", blk->b.chan2); |
| seq_printf(s, "\t%5s:[%d],\n", "if0", blk->b.if0); |
| seq_printf(s, "\t%5s:[%d],\n", "if1", blk->b.if1); |
| seq_printf(s, "\t%5s:[%d],\n", "if2", blk->b.if2); |
| seq_printf(s, "\t%5s:[%d],\n", "enc_nr", blk->b.enc_nr); |
| seq_printf(s, "\t%5s:[%d],\n", "enc_wr", blk->b.enc_wr); |
| } |
| |
| int dbg_afbc_cfg_v3_show(struct seq_file *s, void *v) |
| { |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (!pafd_ctr) |
| return 0; |
| |
| seq_printf(s, "%10s:%d\n", "version", pafd_ctr->fb.ver); |
| |
| dbg_afbc_blk(s, &pafd_ctr->fb.sp, "support"); |
| |
| seq_printf(s, "%10s:%d\n", "mode", pafd_ctr->fb.mode); |
| seq_printf(s, "%10s:inp[%d],mem[%d]\n", "dec", |
| pafd_ctr->fb.pre_dec, |
| pafd_ctr->fb.mem_dec); |
| |
| seq_printf(s, "%10s:%d\n", "int_flg", pafd_ctr->b.int_flg); |
| seq_printf(s, "%10s:%d\n", "en", pafd_ctr->b.en); |
| seq_printf(s, "%10s:%d\n", "level", pafd_ctr->b.chg_level); |
| |
| dbg_afbc_blk(s, &pafd_ctr->en_cfg, "cfg"); |
| dbg_afbc_blk(s, &pafd_ctr->en_sgn, "sgn"); |
| dbg_afbc_blk(s, &pafd_ctr->en_set, "set"); |
| return 0; |
| } |
| EXPORT_SYMBOL(dbg_afbc_cfg_v3_show); |
| |
| static u32 di_requeset_afbc(bool onoff) |
| { |
| u32 afbc_busy; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (!pafd_ctr || pafd_ctr->fb.ver >= AFBCD_V4) { |
| afbc_busy = 0; |
| return afbc_busy; |
| } |
| |
| if (onoff) |
| afbc_busy = di_request_afbc_hw(pafd_ctr->fb.pre_dec, true); |
| else |
| afbc_busy = di_request_afbc_hw(pafd_ctr->fb.pre_dec, false); |
| |
| di_pr_info("%s:busy:%d\n", __func__, afbc_busy); |
| return afbc_busy; |
| } |
| |
| static u32 dbg_requeset_afbc(bool onoff) |
| { |
| u32 afbc_busy; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (!pafd_ctr) |
| return 0; |
| if (onoff) |
| afbc_busy = di_request_afbc_hw(pafd_ctr->fb.pre_dec, true); |
| else |
| afbc_busy = di_request_afbc_hw(pafd_ctr->fb.pre_dec, false); |
| |
| return afbc_busy; |
| } |
| |
| static const unsigned int *afbc_get_inp_base(void) |
| { |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (!pafd_ctr) |
| return NULL; |
| if (pafd_ctr->fb.ver < AFBCD_V5) |
| return ®_afbc[pafd_ctr->fb.pre_dec][0]; |
| |
| return ®_afbc_v5[pafd_ctr->fb.pre_dec][0]; |
| } |
| |
| static bool afbc_is_supported(void) |
| { |
| bool ret = false; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (!pafd_ctr || is_cfg(EAFBC_CFG_DISABLE)) { |
| #ifdef PRINT_BASIC |
| dim_print("%s:false\n", __func__); |
| #endif |
| return false; |
| } |
| if (pafd_ctr->fb.ver != AFBCD_NONE) |
| ret = true; |
| |
| return ret; |
| } |
| |
| static const char *afbc_ver_name[6] = { |
| "_none", |
| "_gxl", |
| "_g12a", |
| "_tl1", |
| "_tm2_vb", |
| "_sc2", |
| }; |
| |
| static const char *afbc_get_version(void) |
| { |
| unsigned int version; |
| |
| version = di_get_afd_ctr()->fb.ver; |
| |
| if (version >= ARRAY_SIZE(afbc_ver_name)) |
| return "overflow"; |
| |
| return afbc_ver_name[version]; |
| } |
| |
| static const struct afbc_fb_s cafbc_v5_sc2 = { |
| .ver = AFBCD_V5, |
| .sp.b.inp = 1, |
| .sp.b.mem = 1, |
| .sp.b.chan2 = 1, |
| .sp.b.if0 = 1, |
| .sp.b.if1 = 1, |
| .sp.b.if2 = 1, |
| .sp.b.enc_nr = 1, |
| .sp.b.enc_wr = 1, |
| .pre_dec = EAFBC_DEC2_DI, |
| .mem_dec = EAFBC_DEC3_MEM, |
| .ch2_dec = EAFBC_DEC_CHAN2, |
| .if0_dec = EAFBC_DEC_IF0, |
| .if1_dec = EAFBC_DEC_IF1, |
| .if2_dec = EAFBC_DEC_IF2, |
| }; |
| |
| static const struct afbc_fb_s cafbc_v4_tm2 = { |
| .ver = AFBCD_V4, |
| .sp.b.inp = 1, |
| .sp.b.mem = 1, |
| .sp.b.chan2 = 0, |
| .sp.b.if0 = 0, |
| .sp.b.if1 = 0, |
| .sp.b.if2 = 0, |
| .sp.b.enc_nr = 1, |
| .sp.b.enc_wr = 0, |
| .pre_dec = EAFBC_DEC2_DI, |
| .mem_dec = EAFBC_DEC3_MEM, |
| .ch2_dec = 0, |
| .if0_dec = 0, |
| .if1_dec = 0, |
| .if2_dec = 0, |
| }; |
| |
| static const struct afbc_fb_s cafbc_v3_tl1 = { |
| .ver = AFBCD_V3, |
| .sp.b.inp = 1, |
| .sp.b.mem = 0, |
| .sp.b.chan2 = 0, |
| .sp.b.if0 = 0, |
| .sp.b.if1 = 0, |
| .sp.b.if2 = 0, |
| .sp.b.enc_nr = 1, |
| .sp.b.enc_wr = 0, |
| .pre_dec = EAFBC_DEC2_DI, |
| .mem_dec = 0, |
| .ch2_dec = 0, |
| .if0_dec = 0, |
| .if1_dec = 0, |
| .if2_dec = 0, |
| }; |
| |
| static const union afbc_blk_s cafbc_cfg_mode[] = { |
| [AFBC_WK_NONE] = { |
| .b.inp = 0, |
| .b.mem = 0, |
| .b.chan2 = 0, |
| .b.if0 = 0, |
| .b.if1 = 0, |
| .b.if2 = 0, |
| .b.enc_nr = 0, |
| .b.enc_wr = 0, |
| }, |
| [AFBC_WK_IN] = { |
| .b.inp = 1, |
| .b.mem = 0, |
| .b.chan2 = 0, |
| .b.if0 = 0, |
| .b.if1 = 0, |
| .b.if2 = 0, |
| .b.enc_nr = 0, |
| .b.enc_wr = 0, |
| }, |
| [AFBC_WK_P] = { |
| .b.inp = 1, |
| .b.mem = 1, |
| .b.chan2 = 0, |
| .b.if0 = 0, |
| .b.if1 = 0, |
| .b.if2 = 0, |
| .b.enc_nr = 1, |
| .b.enc_wr = 0, |
| }, |
| [AFBC_WK_6D] = { |
| .b.inp = 1, |
| .b.mem = 1, |
| .b.chan2 = 1, |
| .b.if0 = 1, |
| .b.if1 = 1, |
| .b.if2 = 1, |
| .b.enc_nr = 1, |
| .b.enc_wr = 1, |
| }, |
| [AFBC_WK_6D_ALL] = { |
| .b.inp = 1, |
| .b.mem = 1, |
| .b.chan2 = 1, |
| .b.if0 = 1, |
| .b.if1 = 1, |
| .b.if2 = 1, |
| .b.enc_nr = 1, |
| .b.enc_wr = 1, |
| }, |
| [AFBC_WK_6D_NV21] = { |
| .b.inp = 1, |
| .b.mem = 1, |
| .b.chan2 = 1, |
| .b.if0 = 1, |
| .b.if1 = 1, |
| .b.if2 = 1, |
| .b.enc_nr = 1, |
| .b.enc_wr = 0, |
| } |
| }; |
| |
| static const union afbc_blk_s cafbc_cfg_sgn[] = { |
| [AFBC_SGN_BYPSS] = { |
| .b.inp = 0, |
| .b.mem = 0, |
| .b.chan2 = 0, |
| .b.if0 = 0, |
| .b.if1 = 0, |
| .b.if2 = 0, |
| .b.enc_nr = 0, |
| .b.enc_wr = 0, |
| }, |
| [AFBC_SGN_P_H265] = { |
| .b.inp = 1, |
| .b.mem = 1, |
| .b.chan2 = 0, |
| .b.if0 = 0, |
| .b.if1 = 0, |
| .b.if2 = 0, |
| .b.enc_nr = 1, |
| .b.enc_wr = 0, |
| }, |
| [AFBC_SGN_P] = { |
| .b.inp = 0, |
| .b.mem = 1, |
| .b.chan2 = 0, |
| .b.if0 = 0, |
| .b.if1 = 0, |
| .b.if2 = 0, |
| .b.enc_nr = 1, |
| .b.enc_wr = 0, |
| }, |
| [AFBC_SGN_P_SINP] = { |
| .b.inp = 0, |
| .b.mem = 0, |
| .b.chan2 = 0, |
| .b.if0 = 0, |
| .b.if1 = 0, |
| .b.if2 = 0, |
| .b.enc_nr = 1, |
| .b.enc_wr = 0, |
| }, |
| [AFBC_SGN_P_H265_AS_P] = { |
| .b.inp = 1, |
| .b.mem = 0, |
| .b.chan2 = 0, |
| .b.if0 = 0, |
| .b.if1 = 0, |
| .b.if2 = 0, |
| .b.enc_nr = 0, |
| .b.enc_wr = 0, |
| }, |
| [AFBC_SGN_H265_SINP] = { |
| .b.inp = 1, |
| .b.mem = 1, |
| .b.chan2 = 0, |
| .b.if0 = 0, |
| .b.if1 = 0, |
| .b.if2 = 0, |
| .b.enc_nr = 0, |
| .b.enc_wr = 0, |
| }, |
| [AFBC_SGN_I_H265] = { |
| .b.inp = 1, |
| .b.mem = 1, |
| .b.chan2 = 0, |
| .b.if0 = 1, |
| .b.if1 = 1, |
| .b.if2 = 1, |
| .b.enc_nr = 1, |
| .b.enc_wr = 1, |
| }, |
| [AFBC_SGN_I] = { |
| .b.inp = 0, |
| .b.mem = 1, |
| .b.chan2 = 1, |
| .b.if0 = 1, |
| .b.if1 = 1, |
| .b.if2 = 1, |
| .b.enc_nr = 1, |
| .b.enc_wr = 1, |
| } |
| }; |
| |
| #ifdef HIS_CODE |
| static void afbc_sgn_mode_set(unsigned int sgn_mode) |
| { |
| struct afbcd_ctr_s *pafd_ctr; |
| |
| pafd_ctr = &di_afdp->ctr; |
| |
| if (sgn_mode <= AFBC_SGN_I_H265) { |
| memcpy(&pafd_ctr->en_sgn, |
| &cafbc_cfg_sgn[sgn_mode], sizeof(pafd_ctr->en_sgn)); |
| } else { |
| #ifdef PRINT_BASIC |
| PR_ERR("%s:overflow %d\n", __func__, sgn_mode); |
| #endif |
| pafd_ctr->en_sgn.d8 = 0; |
| } |
| } |
| #else |
| static void afbc_sgn_mode_set(unsigned char *sgn_mode, enum EAFBC_SNG_SET cmd) |
| { |
| union afbc_blk_s *en_cfg; |
| |
| en_cfg = (union afbc_blk_s *)sgn_mode; |
| switch (cmd) { |
| case EAFBC_SNG_CLR_NR: |
| en_cfg->b.enc_nr = 0; |
| break; |
| case EAFBC_SNG_CLR_WR: |
| en_cfg->b.enc_wr = 0; |
| break; |
| case EAFBC_SNG_SET_NR: |
| en_cfg->b.enc_nr = 1; |
| break; |
| case EAFBC_SNG_SET_WR: |
| en_cfg->b.enc_wr = 1; |
| break; |
| }; |
| } |
| |
| #endif |
| static unsigned char afbc_cnt_sgn_mode(unsigned int sgn) |
| { |
| // struct afbcd_ctr_s *pafd_ctr; |
| unsigned char sgn_mode; |
| |
| if (sgn <= AFBC_SGN_I_H265) { |
| //memcpy(&sgn_mode, &cafbc_cfg_sgn[sgn], sizeof(sgn_mode)); |
| sgn_mode = cafbc_cfg_sgn[sgn].d8; |
| } else { |
| //PR_ERR("%s:overflow %d\n", __func__, sgn); |
| sgn_mode = 0; |
| } |
| |
| return sgn_mode; |
| } |
| |
| static void afbc_cfg_mode_set(unsigned int mode, union afbc_blk_s *en_cfg) |
| { |
| if (!en_cfg) |
| return; |
| |
| if (is_cfg(EAFBC_CFG_DISABLE)) { |
| en_cfg->d8 = 0; |
| return; |
| } |
| |
| en_cfg->d8 = 0; |
| if (mode <= AFBC_WK_6D_NV21) |
| en_cfg->d8 = cafbc_cfg_mode[mode].d8; |
| |
| //dim_print("%s:0x%x\n", __func__, en_cfg->d8); |
| } |
| |
| static void afbc_get_mode_from_cfg(void) |
| { |
| struct afbcd_ctr_s *pafd_ctr; |
| |
| pafd_ctr = &di_afdp->ctr; |
| /******************************* |
| * cfg for debug: |
| ******************************/ |
| if (!afbc_cfg) |
| return; |
| if (is_cfg(EAFBC_CFG_DISABLE)) { |
| pafd_ctr->fb.mode = 0; |
| } else if (afbc_cfg & (BITS_EAFBC_CFG_INP_AFBC | |
| BITS_EAFBC_CFG_6DEC_2ENC | |
| BITS_EAFBC_CFG_6DEC_2ENC2 | |
| BITS_EAFBC_CFG_6DEC_1ENC3)) { |
| if (is_cfg(EAFBC_CFG_INP_AFBC)) |
| pafd_ctr->fb.mode = AFBC_WK_IN; |
| else if (is_cfg(EAFBC_CFG_6DEC_2ENC)) |
| pafd_ctr->fb.mode = AFBC_WK_6D; |
| else if (is_cfg(EAFBC_CFG_6DEC_2ENC2)) |
| pafd_ctr->fb.mode = AFBC_WK_6D_ALL; |
| else if (is_cfg(EAFBC_CFG_6DEC_1ENC3)) |
| pafd_ctr->fb.mode = AFBC_WK_6D_NV21; |
| } else { |
| if (pafd_ctr->fb.ver >= AFBCD_V5) |
| pafd_ctr->fb.mode = AFBC_WK_6D_NV21; |
| else if (pafd_ctr->fb.ver >= AFBCD_V4) |
| pafd_ctr->fb.mode = AFBC_WK_P; |
| else if (pafd_ctr->fb.ver >= AFBCD_V1) |
| pafd_ctr->fb.mode = AFBC_WK_IN; |
| else |
| pafd_ctr->fb.mode = AFBC_WK_NONE; |
| } |
| } |
| |
| static void afbc_prob(unsigned int cid, struct afd_s *p) |
| { |
| struct afbcd_ctr_s *pafd_ctr;// = di_get_afd_ctr(); |
| |
| afbc_cfg = BITS_EAFBC_CFG_DISABLE; |
| di_afdp = p; |
| |
| if (!di_afdp) { |
| pr_error("%s:no data\n", __func__); |
| return; |
| } |
| pafd_ctr = &di_afdp->ctr; |
| |
| if (IS_IC_EF(cid, SC2)) { |
| //afbc_cfg = BITS_EAFBC_CFG_4K; |
| afbc_cfg = 0; |
| memcpy(&pafd_ctr->fb, &cafbc_v5_sc2, sizeof(pafd_ctr->fb)); |
| pafd_ctr->fb.mode = AFBC_WK_P;//AFBC_WK_6D_NV21; |
| //AFBC_WK_6D_ALL;//AFBC_WK_IN;// |
| } else if (IS_IC_EF(cid, T5D)) { //unsupport afbc |
| pafd_ctr->fb.ver = AFBCD_NONE; |
| pafd_ctr->fb.sp.b.inp = 0; |
| pafd_ctr->fb.sp.b.mem = 0; |
| pafd_ctr->fb.pre_dec = EAFBC_DEC0; |
| pafd_ctr->fb.mode = AFBC_WK_NONE; |
| } else if (IS_IC_EF(cid, T5)) { //afbc config same with tm2b |
| afbc_cfg = 0; |
| memcpy(&pafd_ctr->fb, &cafbc_v4_tm2, sizeof(pafd_ctr->fb)); |
| pafd_ctr->fb.mode = AFBC_WK_P; |
| } else if (IS_IC_EF(cid, TM2B)) { |
| afbc_cfg = 0; |
| memcpy(&pafd_ctr->fb, &cafbc_v4_tm2, sizeof(pafd_ctr->fb)); |
| pafd_ctr->fb.mode = AFBC_WK_P; |
| } else if (IS_IC_EF(cid, TL1)) { |
| memcpy(&pafd_ctr->fb, &cafbc_v3_tl1, sizeof(pafd_ctr->fb)); |
| pafd_ctr->fb.mode = AFBC_WK_IN; |
| } else if (IS_IC_EF(cid, G12A)) { |
| pafd_ctr->fb.ver = AFBCD_V2; |
| pafd_ctr->fb.sp.b.inp = 1; |
| pafd_ctr->fb.sp.b.mem = 0; |
| pafd_ctr->fb.pre_dec = EAFBC_DEC1; |
| pafd_ctr->fb.mode = AFBC_WK_IN; |
| } else if (IS_IC_EF(cid, GXL)) { |
| pafd_ctr->fb.ver = AFBCD_V1; |
| pafd_ctr->fb.sp.b.inp = 1; |
| pafd_ctr->fb.sp.b.mem = 0; |
| pafd_ctr->fb.pre_dec = EAFBC_DEC0; |
| pafd_ctr->fb.mode = AFBC_WK_IN; |
| } else { |
| pafd_ctr->fb.ver = AFBCD_NONE; |
| pafd_ctr->fb.sp.b.inp = 0; |
| pafd_ctr->fb.sp.b.mem = 0; |
| pafd_ctr->fb.pre_dec = EAFBC_DEC0; |
| pafd_ctr->fb.mode = AFBC_WK_NONE; |
| } |
| /******************************* |
| * cfg for debug: |
| ******************************/ |
| afbc_get_mode_from_cfg(); |
| |
| //afbc_cfg_mode_set(pafd_ctr->fb.mode); |
| /******************************/ |
| if (pafd_ctr->fb.mode >= AFBC_WK_6D) { |
| pafd_ctr->fb.mem_alloc = 1; |
| pafd_ctr->fb.mem_alloci = 1; |
| } else if (pafd_ctr->fb.mode >= AFBC_WK_P) { |
| pafd_ctr->fb.mem_alloc = 1; |
| pafd_ctr->fb.mem_alloci = 0; |
| } else if (is_cfg(EAFBC_CFG_MEM)) { |
| pafd_ctr->fb.mem_alloc = 1; |
| pafd_ctr->fb.mem_alloci = 1; |
| } else { |
| pafd_ctr->fb.mem_alloc = 0; |
| pafd_ctr->fb.mem_alloci = 0; |
| } |
| |
| //afbc_cfg = BITS_EAFBC_CFG_DISABLE; |
| di_pr_info("%s:ver[%d],%s,mode[%d]\n", __func__, pafd_ctr->fb.ver, |
| afbc_get_version(), pafd_ctr->fb.mode); |
| } |
| |
| /* |
| * after g12a, framereset will not reset simple |
| * wr mif of pre such as mtn&cont&mv&mcinfo wr |
| */ |
| |
| static void afbc_reg_sw(bool on); |
| |
| //unsigned int test_afbc_en; |
| static void afbc_sw(bool on); |
| #define AFBCP (1) |
| |
| static void afbc_pre_check(struct vframe_s *vf, void *a)/*pch*/ |
| { |
| union hw_sc2_ctr_pre_s *cfg; |
| struct afbcd_ctr_s *pctr; |
| union afbc_blk_s *pblk; |
| struct di_buf_s *di_buf; |
| union afbc_blk_s *en_set_pre; |
| union afbc_blk_s *en_cfg_pre; |
| struct di_ch_s *pch; |
| |
| if (!vf || |
| !get_afdp() || |
| !a) |
| return; |
| |
| pch = (struct di_ch_s *)a; |
| |
| di_buf = (struct di_buf_s *)vf->private_data; |
| if (!di_buf) |
| return; |
| |
| // cfg = di_afdp->top_cfg_pre; |
| |
| pctr = di_get_afd_ctr(); |
| |
| pctr->en_sgn.d8 = di_buf->afbc_sgn_cfg; |
| |
| en_cfg_pre = &pch->rse_ori.di_pre_stru.en_cfg; |
| en_set_pre = &pch->rse_ori.di_pre_stru.en_set; |
| en_set_pre->d8 = en_cfg_pre->d8 & pctr->en_sgn.d8; |
| pctr->en_set.d8 = en_set_pre->d8; |
| pctr->en_cfg.d8 = en_cfg_pre->d8; |
| |
| cfg = &pch->rse_ori.di_pre_stru.pre_top_cfg; |
| |
| pblk = &pctr->en_set; |
| if (pblk->b.inp) { |
| cfg->b.afbc_inp = 1; |
| if (di_buf->is_4k) |
| cfg->b.is_inp_4k = 1; |
| else |
| cfg->b.is_inp_4k = 0; |
| } else { |
| cfg->b.afbc_inp = 0; |
| cfg->b.is_inp_4k = 0; |
| } |
| |
| if (pblk->b.mem) { |
| cfg->b.afbc_mem = 1; |
| |
| if (di_buf->is_4k) |
| cfg->b.is_mem_4k = 1; |
| else |
| cfg->b.is_mem_4k = 0; |
| } else { |
| cfg->b.afbc_mem = 0; |
| cfg->b.is_mem_4k = 0; |
| } |
| |
| if (pblk->b.chan2) { |
| cfg->b.afbc_chan2 = 1; |
| |
| if (di_buf->is_4k) |
| cfg->b.is_chan2_4k = 1; |
| else |
| cfg->b.is_chan2_4k = 0; |
| } else { |
| cfg->b.afbc_chan2 = 0; |
| cfg->b.is_chan2_4k = 0; |
| } |
| cfg->b.mode_4k = 0; |
| if (pblk->b.enc_nr) { |
| cfg->b.afbc_nr_en = 1; |
| cfg->b.mif_en = 0; |
| if (di_buf->is_4k) |
| cfg->b.mode_4k = 1; |
| } else { |
| cfg->b.afbc_nr_en = 0; |
| cfg->b.mif_en = 1; |
| } |
| |
| //dim_print("%s:\n", __func__); |
| } |
| |
| static void afbc_pst_check(struct vframe_s *vf, void *a) |
| { |
| union hw_sc2_ctr_pst_s *cfg; |
| struct afbcd_ctr_s *pctr; |
| struct di_buf_s *di_buf; |
| struct di_ch_s *pch; |
| union afbc_blk_s *en_set_pst; |
| union afbc_blk_s *en_cfg_pst; |
| |
| if (!vf || |
| !di_afdp || |
| !a) |
| return; |
| |
| pch = (struct di_ch_s *)a; |
| di_buf = (struct di_buf_s *)vf->private_data; |
| |
| if (!di_buf) |
| return; |
| |
| //cfg = di_afdp->top_cfg_pst; |
| pctr = di_get_afd_ctr(); |
| |
| pctr->en_sgn_pst.d8 = di_buf->afbc_sgn_cfg; |
| en_set_pst = &pch->rse_ori.di_post_stru.en_set; |
| en_cfg_pst = &pch->rse_ori.di_post_stru.en_cfg; |
| en_set_pst->d8 = pctr->en_sgn_pst.d8 & en_cfg_pst->d8; |
| |
| pctr->en_set_pst.d8 = en_set_pst->d8; |
| pctr->en_cfg.d8 = en_cfg_pst->d8; |
| cfg = &pch->rse_ori.di_post_stru.pst_top_cfg; |
| |
| if (pctr->en_set_pst.b.if0) |
| cfg->b.afbc_if0 = 1; |
| else |
| cfg->b.afbc_if0 = 0; |
| |
| if (pctr->en_set_pst.b.if1) |
| cfg->b.afbc_if1 = 1; |
| else |
| cfg->b.afbc_if1 = 0; |
| |
| if (pctr->en_set_pst.b.if2) |
| cfg->b.afbc_if2 = 1; |
| else |
| cfg->b.afbc_if2 = 0; |
| |
| if (pctr->en_set_pst.b.enc_wr) |
| cfg->b.afbc_wr = 1; |
| else |
| cfg->b.afbc_wr = 0; |
| |
| //dim_print("%s:\n", __func__); |
| //dim_print("%s:0x%x=0x%x\n", __func__, |
| //AFBCDM_MEM_HEAD_BADDR, reg_rd(AFBCDM_MEM_HEAD_BADDR)); |
| } |
| |
| static void afbc_check_chg_level(struct vframe_s *vf, |
| struct vframe_s *mem_vf, |
| struct vframe_s *chan2_vf, |
| struct afbcd_ctr_s *pctr) |
| { |
| #ifdef AFBCP |
| struct di_buf_s *di_buf = NULL; |
| #endif |
| /*check support*/ |
| if (pctr->fb.ver == AFBCD_NONE) |
| return; |
| if (is_cfg(EAFBC_CFG_DISABLE)) |
| return; |
| |
| if (pctr->fb.ver < AFBCD_V4 || pctr->fb.mode < AFBC_WK_P) { |
| if (!(vf->type & VIDTYPE_COMPRESS)) { |
| if (pctr->b.en) { |
| /*from en to disable*/ |
| pctr->b.en = 0; |
| } |
| //dim_print("%s:not compress\n", __func__); |
| return; |
| } |
| } |
| /* pach for not mask nv21 */ |
| if ((vf->type & AFBC_VTYPE_MASK_CHG) != |
| (pctr->l_vtype & AFBC_VTYPE_MASK_CHG) || |
| vf->height != pctr->l_h || |
| vf->width != pctr->l_w || |
| vf->bitdepth != pctr->l_bitdepth) { |
| pctr->b.chg_level = 3; |
| pctr->l_vtype = (vf->type & AFBC_VTYPE_MASK_SAV); |
| pctr->l_h = vf->height; |
| pctr->l_w = vf->width; |
| pctr->l_bitdepth = vf->bitdepth; |
| } else { |
| if (vf->type & VIDTYPE_INTERLACE) { |
| pctr->b.chg_level = 2; |
| pctr->l_vtype = (vf->type & AFBC_VTYPE_MASK_SAV); |
| } else { |
| pctr->b.chg_level = 1; |
| } |
| } |
| if (is_cfg(EAFBC_CFG_LEVE3)) |
| pctr->b.chg_level = 3; |
| pctr->addr_h = vf->compHeadAddr; |
| pctr->addr_b = vf->compBodyAddr; |
| #ifdef MARK_SC2 |
| di_print("%s:\n", __func__); |
| di_print("\tvf:type[0x%x],[0x%x]\n", |
| vf->type, |
| AFBC_VTYPE_MASK_SAV); |
| di_print("\t\t:body[0x%x] inf[0x%x]\n", |
| vf->compBodyAddr, vf->compHeadAddr); |
| di_print("\tinofo:type[0x%x]\n", pctr->l_vtype); |
| |
| di_print("\t\th[%d],w[%d],b[0x%x]\n", pctr->l_h, |
| pctr->l_w, pctr->l_bitdepth); |
| di_print("\t\tchg_level[%d],is_srci[%d]\n", |
| pctr->b.chg_level, is_src_i(vf)); |
| #endif |
| if (!pctr->fb.mode || !mem_vf) { |
| pctr->b.chg_mem = 0; |
| pctr->l_vt_mem = 0; |
| di_print("\t not check mem"); |
| return; |
| } |
| #ifdef AFBCP |
| /* mem */ |
| if (pctr->fb.mode >= AFBC_WK_P) { |
| if ((mem_vf->type & AFBC_VTYPE_MASK_CHG) != |
| (pctr->l_vt_mem & AFBC_VTYPE_MASK_CHG)) { |
| pctr->b.chg_mem = 3; |
| pctr->l_vt_mem = (mem_vf->type & AFBC_VTYPE_MASK_SAV); |
| } else { |
| pctr->b.chg_mem = 1; |
| } |
| di_buf = (struct di_buf_s *)mem_vf->private_data; |
| if (di_buf && (di_buf->type == VFRAME_TYPE_LOCAL)) { |
| #ifdef AFBC_MODE1 |
| di_print("buf t[%d]:nr_adr[0x%lx], afbc_adr[0x%lx]\n", |
| di_buf->index, |
| di_buf->nr_adr, |
| di_buf->afbc_adr); |
| #endif |
| //mem_vf->compBodyAddr = di_buf->nr_adr; |
| //mem_vf->compHeadAddr = di_buf->afbc_adr; |
| } |
| } |
| #endif |
| #ifdef MARK_SC2 |
| di_print("\tmem:type[0x%x]\n", mem_vf->type); |
| di_print("\t\t:body[0x%x] inf[0x%x]\n", |
| mem_vf->compBodyAddr, mem_vf->compHeadAddr); |
| di_print("\t\th[%d],w[%d],b[0x%x]\n", mem_vf->height, |
| mem_vf->width, mem_vf->bitdepth); |
| |
| di_print("\t\tchg_mem[%d],is_srci[%d]\n", |
| pctr->b.chg_mem, is_src_i(vf)); |
| #endif |
| /* chan2 */ |
| if (!chan2_vf) |
| return; |
| if (pctr->en_set.b.chan2) { |
| if ((chan2_vf->type & AFBC_VTYPE_MASK_CHG) != |
| (pctr->l_vt_chan2 & AFBC_VTYPE_MASK_CHG)) { |
| pctr->b.chg_chan2 = 3; |
| pctr->l_vt_chan2 = |
| (chan2_vf->type & AFBC_VTYPE_MASK_SAV); |
| } else { |
| pctr->b.chg_chan2 = 1; |
| } |
| } |
| #ifdef MARK_SC2 |
| di_print("\tchan2:type[0x%x]\n", chan2_vf->type); |
| di_print("\t\t:body[0x%x] inf[0x%x]\n", |
| chan2_vf->compBodyAddr, chan2_vf->compHeadAddr); |
| di_print("\t\th[%d],w[%d],b[0x%x]\n", chan2_vf->height, |
| chan2_vf->width, chan2_vf->bitdepth); |
| |
| di_print("\t\tchg[%d],is_srci[%d]\n", |
| pctr->b.chg_chan2, is_src_i(vf)); |
| #endif |
| } |
| |
| static void afbc_update_level1(struct vframe_s *vf, enum EAFBC_DEC dec) |
| { |
| const unsigned int *reg = afbc_get_addrp(dec); |
| |
| //di_print("%s:%d:0x%x\n", __func__, dec, vf->type); |
| //dim_print("%s:head2:0x%x=0x%x\n", __func__, |
| //AFBCDM_MEM_HEAD_BADDR, reg_rd(AFBCDM_MEM_HEAD_BADDR)); |
| reg_wr(reg[EAFBC_HEAD_BADDR], vf->compHeadAddr >> 4); |
| reg_wr(reg[EAFBC_BODY_BADDR], vf->compBodyAddr >> 4); |
| } |
| |
| void dbg_afbc_update_level1(struct vframe_s *vf, enum EAFBC_DEC dec) |
| { |
| afbc_update_level1(vf, dec); |
| } |
| |
| /* ary add for v5 sc2 */ |
| struct AFBCD_CFG_S { |
| unsigned int pip_src_mode; |
| // 1 bits 0: src from vdin/dos 1:src from pip |
| unsigned int rot_ofmt_mode; |
| // 2 bits default = 2, 0:yuv444 1:yuv422 2:yuv420 |
| unsigned int rot_ocompbit; |
| // 2 bits rot output bit width,0:8bit 1:9bit 2:10bit |
| unsigned int rot_drop_mode; //rot_drop_mode |
| unsigned int rot_vshrk; //rot_vshrk |
| unsigned int rot_hshrk; //rot_hshrk |
| unsigned int rot_hbgn; //5 bits |
| unsigned int rot_vbgn; //2 bits |
| unsigned int rot_en; //1 bits |
| |
| unsigned int reg_lossy_en; /* def 0*/ |
| }; |
| |
| static unsigned int afbcd_v5_get_offset(enum EAFBC_DEC dec) |
| { |
| unsigned int module_sel; |
| unsigned int regs_ofst; |
| |
| switch (dec) { |
| case EAFBC_DEC0: |
| module_sel = 6; |
| break; |
| case EAFBC_DEC1: |
| module_sel = 7; |
| break; |
| case EAFBC_DEC2_DI: |
| module_sel = 0; |
| break; |
| case EAFBC_DEC3_MEM: |
| module_sel = 2; |
| break; |
| case EAFBC_DEC_CHAN2: |
| module_sel = 1; |
| break; |
| case EAFBC_DEC_IF0: |
| module_sel = 4; |
| break; |
| case EAFBC_DEC_IF1: |
| module_sel = 3; |
| break; |
| case EAFBC_DEC_IF2: |
| module_sel = 5; |
| break; |
| default: |
| PR_ERR("%s:err\n", __func__); |
| module_sel = 6; |
| break; |
| } |
| |
| regs_ofst = module_sel == 6 ? -24 : //vd1 0x48 0x0-0x7f |
| module_sel == 7 ? -23 : //vd2 0x48 0x80-0xff |
| module_sel;//di_m0-m5 0x54-0x56 |
| //regs_ofst = 128 * 4 * regs_ofst; |
| regs_ofst = 0x80 * regs_ofst; |
| return regs_ofst; |
| } |
| |
| static u32 enable_afbc_input_local(struct vframe_s *vf, enum EAFBC_DEC dec, |
| struct AFBCD_CFG_S *cfg) |
| { |
| unsigned int r, u, v, w_aligned, h_aligned; |
| const unsigned int *reg = afbc_get_addrp(dec); |
| unsigned int vfmt_rpt_first = 1, vt_ini_phase = 0; |
| unsigned int out_height = 0; |
| /*ary add*/ |
| unsigned int cvfmt_en = 0; |
| unsigned int cvfm_h, rpt_pix, phase_step = 16, hold_line = 8; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| /* add from sc2 */ |
| unsigned int fmt_mode = 0; |
| unsigned int compbits_yuv; // 2 bits 0-8bits 1-9bits 2-10bits |
| unsigned int compbits_eq8 ; /* add for sc2 */ |
| unsigned int conv_lbuf_len; |
| unsigned int regs_ofst; |
| /* */ |
| unsigned int dec_lbuf_depth ; //12 bits |
| unsigned int mif_lbuf_depth ; //12 bits |
| //ary tmp unsigned int fmt_size_h ; //13 bits |
| //ary tmp unsigned int fmt_size_v ; //13 bits |
| |
| di_print("afbc_in:[%d]:vf typ[0x%x] 0x%x, 0x%x\n", |
| dec, |
| vf->type, |
| vf->compHeadAddr, |
| vf->compBodyAddr); |
| |
| w_aligned = round_up((vf->width), 32); |
| /* add from sc2 */ |
| |
| /* TL1 add bit[13:12]: fmt_mode; 0:yuv444; 1:yuv422; 2:yuv420 |
| * di does not support yuv444, so for fmt yuv444 di will bypass+ |
| */ |
| if (pafd_ctr->fb.ver >= AFBCD_V3) { |
| if (vf->type & VIDTYPE_VIU_444) |
| fmt_mode = 0; |
| else if (vf->type & VIDTYPE_VIU_422) |
| fmt_mode = 1; |
| else |
| fmt_mode = 2; |
| } |
| |
| compbits_yuv = (vf->bitdepth & BITDEPTH_MASK) >> BITDEPTH_Y_SHIFT; |
| compbits_eq8 = (compbits_yuv == 0); |
| |
| if (pafd_ctr->fb.ver <= AFBCD_V4) { |
| conv_lbuf_len = 256; |
| } else { |
| if (((w_aligned > 1024) && (fmt_mode == 0) && |
| (compbits_eq8 == 0)) || |
| (w_aligned > 2048)) |
| conv_lbuf_len = 256; |
| else |
| conv_lbuf_len = 128; |
| } |
| dec_lbuf_depth = 128; |
| mif_lbuf_depth = 128; |
| /*****************************************/ |
| /*if (di_pre_stru.cur_inp_type & VIDTYPE_INTERLACE)*/ |
| if (((vf->type & VIDTYPE_INTERLACE) || is_src_i(vf)) && |
| (vf->type & VIDTYPE_VIU_422)) /*from vdin and is i */ |
| h_aligned = round_up((vf->height / 2), 4); |
| else |
| h_aligned = round_up((vf->height), 4); |
| |
| /*AFBCD working mode config*/ |
| r = (3 << 24) | |
| (hold_line << 16) | /* hold_line_num : 2020 from 10 to 8*/ |
| (2 << 14) | /*burst1 1:2020:ary change from 1 to 2*/ |
| (vf->bitdepth & BITDEPTH_MASK); |
| |
| if (vf->bitdepth & BITDEPTH_SAVING_MODE) |
| r |= (1 << 28); /* mem_saving_mode */ |
| if (vf->type & VIDTYPE_SCATTER) |
| r |= (1 << 29); |
| |
| out_height = h_aligned; |
| if (!(vf->type & VIDTYPE_VIU_422)) { |
| /*from dec, process P as i*/ |
| if ((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP) { |
| r |= 0x40; |
| vt_ini_phase = 0xc; |
| vfmt_rpt_first = 1; |
| out_height = h_aligned >> 1; |
| } else if ((vf->type & VIDTYPE_TYPEMASK) == |
| VIDTYPE_INTERLACE_BOTTOM) { |
| r |= 0x80; |
| vt_ini_phase = 0x4; |
| vfmt_rpt_first = 0; |
| out_height = h_aligned >> 1; |
| } |
| } |
| |
| if (IS_420P_SRC(vf->type)) { |
| cvfmt_en = 1; |
| vt_ini_phase = 0xc; |
| cvfm_h = out_height >> 1; |
| rpt_pix = 1; |
| phase_step = 8; |
| } else { |
| cvfm_h = out_height; |
| rpt_pix = 0; |
| } |
| reg_wr(reg[EAFBC_MODE], r); |
| |
| r = 0x1600; |
| //if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) { |
| if (pafd_ctr->fb.ver >= AFBCD_V3) { |
| /* un compress mode data from vdin bit block order is |
| * different with from dos |
| */ |
| if (!(vf->type & VIDTYPE_VIU_422) && |
| (dec == EAFBC_DEC2_DI)) |
| /* ary note: frame afbce, set 0*/ |
| r |= (1 << 19); /* dos_uncomp */ |
| |
| if (vf->type & VIDTYPE_COMB_MODE) |
| r |= (1 << 20); |
| } |
| #ifdef MARK_SC2 /* ary: tm2 no this setting */ |
| if (pafd_ctr->fb.ver >= AFBCD_V4) { |
| r |= (1 << 21); /*reg_addr_link_en*/ |
| r |= (0x43700 << 0); /*??*/ |
| } |
| #endif |
| reg_wr(reg[EAFBC_ENABLE], r); |
| |
| /*pr_info("AFBC_ENABLE:0x%x\n", reg_rd(reg[eAFBC_ENABLE]));*/ |
| |
| /**/ |
| |
| //r = 0x100; |
| #ifdef MARK_SC2 /* add fmt_mode */ |
| /* TL1 add bit[13:12]: fmt_mode; 0:yuv444; 1:yuv422; 2:yuv420 |
| * di does not support yuv444, so for fmt yuv444 di will bypass+ |
| */ |
| //if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) { |
| |
| if (pafd_ctr->fb.ver >= AFBCD_V3) { |
| if (vf->type & VIDTYPE_VIU_444) |
| r |= (0 << 12); |
| else if (vf->type & VIDTYPE_VIU_422) |
| r |= (1 << 12); |
| else |
| r |= (2 << 12); |
| } |
| #endif |
| //r |= fmt_mode << 12; |
| |
| reg_wr(reg[EAFBC_CONV_CTRL], |
| fmt_mode << 12 | |
| conv_lbuf_len << 0);/*fmt_mode before sc2 is 0x100*/ |
| |
| u = (vf->bitdepth >> (BITDEPTH_U_SHIFT)) & 0x3; |
| v = (vf->bitdepth >> (BITDEPTH_V_SHIFT)) & 0x3; |
| reg_wr(reg[EAFBC_DEC_DEF_COLOR], |
| 0x3FF00000 | /*Y,bit20+*/ |
| 0x80 << (u + 10) | |
| 0x80 << v); |
| |
| /* chroma formatter */ |
| reg_wr(reg[EAFBC_VD_CFMT_CTRL], |
| (rpt_pix << 28) | |
| (1 << 21) | /* HFORMATTER_YC_RATIO_2_1 */ |
| (1 << 20) | /* HFORMATTER_EN */ |
| (vfmt_rpt_first << 16) | /* VFORMATTER_RPTLINE0_EN */ |
| (vt_ini_phase << 8) | |
| (phase_step << 1) | /* VFORMATTER_PHASE_BIT */ |
| cvfmt_en);/* different with inp */ |
| |
| /*if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) { *//*ary add for g12a*/ |
| if (pafd_ctr->fb.ver >= AFBCD_V3) { |
| if (vf->type & VIDTYPE_VIU_444) |
| reg_wr(reg[EAFBC_VD_CFMT_W], |
| (w_aligned << 16) | (w_aligned / 2)); |
| else |
| reg_wr(reg[EAFBC_VD_CFMT_W], |
| (w_aligned << 16) | (w_aligned)); |
| } else { /*ary add for g12a*/ |
| reg_wr(reg[EAFBC_VD_CFMT_W], |
| (w_aligned << 16) | (w_aligned / 2)); |
| } |
| reg_wr(reg[EAFBC_MIF_HOR_SCOPE], |
| (0 << 16) | ((w_aligned >> 5) - 1)); |
| reg_wr(reg[EAFBC_MIF_VER_SCOPE], |
| (0 << 16) | ((h_aligned >> 2) - 1)); |
| |
| reg_wr(reg[EAFBC_PIXEL_HOR_SCOPE], |
| (0 << 16) | (vf->width - 1)); |
| reg_wr(reg[EAFBC_PIXEL_VER_SCOPE], |
| 0 << 16 | (vf->height - 1)); |
| |
| reg_wr(reg[EAFBC_VD_CFMT_H], /*out_height*/cvfm_h); |
| |
| reg_wr(reg[EAFBC_SIZE_IN], (vf->height) | w_aligned << 16); |
| di_print("\t:size:%d\n", vf->height); |
| if (pafd_ctr->fb.ver <= AFBCD_V4) |
| reg_wr(reg[EAFBC_SIZE_OUT], out_height | w_aligned << 16); |
| |
| reg_wr(reg[EAFBC_HEAD_BADDR], vf->compHeadAddr >> 4); |
| reg_wr(reg[EAFBC_BODY_BADDR], vf->compBodyAddr >> 4); |
| |
| if (pafd_ctr->fb.ver >= AFBCD_V5 && cfg) { |
| regs_ofst = afbcd_v5_get_offset(dec); |
| reg_wrb((regs_ofst + AFBCDM_IQUANT_ENABLE), |
| (cfg->reg_lossy_en & 0x1), 0, 1);//lossy_luma_en |
| reg_wrb((regs_ofst + AFBCDM_IQUANT_ENABLE), |
| (cfg->reg_lossy_en & 0x2), 4, 1);//lossy_chrm_en |
| reg_wr((regs_ofst + AFBCDM_ROT_CTRL), |
| ((cfg->pip_src_mode & 0x1) << 27) | |
| //pip_src_mode |
| ((cfg->rot_drop_mode & 0x7) << 24) | |
| //rot_uv_vshrk_drop_mode |
| ((cfg->rot_drop_mode & 0x7) << 20) | |
| //rot_uv_hshrk_drop_mode |
| ((cfg->rot_vshrk & 0x3) << 18) | |
| //rot_uv_vshrk_ratio |
| ((cfg->rot_hshrk & 0x3) << 16) | |
| //rot_uv_hshrk_ratio |
| ((cfg->rot_drop_mode & 0x7) << 12) | |
| //rot_y_vshrk_drop_mode |
| ((cfg->rot_drop_mode & 0x7) << 8) | |
| //rot_y_hshrk_drop_mode |
| ((cfg->rot_vshrk & 0x3) << 6) | |
| //rot_y_vshrk_ratio |
| ((cfg->rot_hshrk & 0x3) << 4) | |
| //rot_y_hshrk_ratio |
| ((0 & 0x3) << 2) | |
| //rot_uv422_drop_mode |
| ((0 & 0x3) << 1) | |
| //rot_uv422_omode |
| ((cfg->rot_en & 0x1) << 0) |
| //rot_enable |
| ); |
| |
| reg_wr((regs_ofst + AFBCDM_ROT_SCOPE), |
| ((1 & 0x1) << 16) | //reg_rot_ifmt_force444 |
| ((cfg->rot_ofmt_mode & 0x3) << 14) | |
| //reg_rot_ofmt_mode |
| ((cfg->rot_ocompbit & 0x3) << 12) | |
| //reg_rot_compbits_out_y |
| ((cfg->rot_ocompbit & 0x3) << 10) | |
| //reg_rot_compbits_out_uv |
| ((cfg->rot_vbgn & 0x3) << 8) | //rot_wrbgn_v |
| ((cfg->rot_hbgn & 0x1f) << 0) //rot_wrbgn_h |
| ); |
| } |
| return true; |
| } |
| |
| static void afbc_update_level2_inp(struct afbcd_ctr_s *pctr) |
| { |
| const unsigned int *reg = afbc_get_addrp(pctr->fb.pre_dec); |
| unsigned int vfmt_rpt_first = 1, vt_ini_phase = 12; |
| unsigned int old_mode, old_cfmt_ctrl; |
| |
| di_print("%s\n", __func__); |
| old_mode = reg_rd(reg[EAFBC_MODE]); |
| old_cfmt_ctrl = reg_rd(reg[EAFBC_VD_CFMT_CTRL]); |
| old_mode &= (~(0x03 << 6)); |
| if (!(pctr->l_vtype & VIDTYPE_VIU_422)) { |
| /*from dec, process P as i*/ |
| if ((pctr->l_vtype & VIDTYPE_TYPEMASK) == |
| VIDTYPE_INTERLACE_TOP) { |
| old_mode |= 0x40; |
| |
| vt_ini_phase = 0xc; |
| vfmt_rpt_first = 1; |
| //out_height = h_aligned>>1; |
| } else if ((pctr->l_vtype & VIDTYPE_TYPEMASK) == |
| VIDTYPE_INTERLACE_BOTTOM) { |
| old_mode |= 0x80; |
| vt_ini_phase = 0x4; |
| vfmt_rpt_first = 0; |
| //out_height = h_aligned>>1; |
| } else { //for p as p? |
| //out_height = h_aligned>>1; |
| } |
| } |
| reg_wr(reg[EAFBC_MODE], old_mode); |
| /* chroma formatter */ |
| reg_wr(reg[EAFBC_VD_CFMT_CTRL], |
| old_cfmt_ctrl | |
| (vfmt_rpt_first << 16) | /* VFORMATTER_RPTLINE0_EN */ |
| (vt_ini_phase << 8)); /* different with inp */ |
| |
| reg_wr(reg[EAFBC_HEAD_BADDR], pctr->addr_h >> 4); |
| reg_wr(reg[EAFBC_BODY_BADDR], pctr->addr_b >> 4); |
| } |
| |
| static void afbce_set(struct vframe_s *vf, enum EAFBC_ENC enc); |
| static void afbce_update_level1(struct vframe_s *vf, |
| const struct reg_acc *op, |
| enum EAFBC_ENC enc); |
| static void afbc_tm2_sw_inp(bool on); |
| /* only for tm2, sc2 is chang*/ |
| static void afbc_tm2_sw_mem(bool on); |
| /* only for tm2, sc2 is chang*/ |
| static void afbce_tm2_sw(bool on); |
| |
| static u32 enable_afbc_input(struct vframe_s *inp_vf, |
| struct vframe_s *mem_vf, |
| struct vframe_s *chan2_vf, |
| struct vframe_s *nr_vf) |
| { |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| //enum eAFBC_DEC dec = afbc_get_decnub(); |
| struct vframe_s *mem_vf2, *inp_vf2; |
| struct AFBCD_CFG_S cfg; |
| struct AFBCD_CFG_S *pcfg; |
| |
| if (!afbc_is_supported()) |
| return false; |
| |
| inp_vf2 = inp_vf; |
| mem_vf2 = mem_vf; |
| |
| if (is_cfg(EAFBC_CFG_ETEST)) |
| mem_vf2 = inp_vf; |
| else if (is_cfg(EAFBC_CFG_ETEST2)) |
| inp_vf2 = mem_vf; |
| |
| if (!inp_vf2) { |
| PR_ERR("%s:no input\n", __func__); |
| return 0; |
| } |
| |
| if (pafd_ctr->fb.ver < AFBCD_V4) { |
| if (inp_vf2->type & VIDTYPE_COMPRESS) { |
| afbc_sw(true); |
| } else { |
| afbc_sw(false); |
| return false; |
| } |
| } else { |
| /* AFBCD_V5 */ |
| if (!pafd_ctr->en_set.d8) { |
| dim_print("%s:%d\n", __func__, pafd_ctr->en_set.d8); |
| afbc_sw(false); |
| return false; |
| } |
| afbc_sw(true); |
| } |
| #ifdef MARK_SC2 |
| if (is_cfg(EAFBC_CFG_ETEST)) |
| mem_vf2 = inp_vf; |
| else |
| mem_vf2 = mem_vf; |
| #endif |
| if (pafd_ctr->fb.ver >= AFBCD_V5) { |
| pcfg = &cfg; |
| memset(pcfg, 0, sizeof(*pcfg)); |
| } else { |
| pcfg = NULL; |
| } |
| |
| afbc_check_chg_level(inp_vf2, mem_vf, chan2_vf, pafd_ctr); |
| if (is_src_real_i(mem_vf)) |
| //dim_print("%s:real i\n", __func__); |
| pafd_ctr->b.chg_mem = 3; |
| |
| if (pafd_ctr->b.chg_level == 3 || pafd_ctr->b.chg_mem == 3 || |
| pafd_ctr->b.chg_chan2 == 3) { |
| if (pafd_ctr->fb.ver == AFBCD_V4) { |
| if (pafd_ctr->en_set.b.inp) |
| afbc_tm2_sw_inp(true); |
| else |
| afbc_tm2_sw_inp(false); |
| if (mem_vf2 && pafd_ctr->en_set.b.mem) |
| afbc_tm2_sw_mem(true); |
| else |
| afbc_tm2_sw_mem(false); |
| |
| if (pafd_ctr->en_set.b.enc_nr) |
| afbce_tm2_sw(true); |
| else |
| afbce_tm2_sw(false); |
| } |
| /*inp*/ |
| if (pafd_ctr->en_set.b.inp) |
| enable_afbc_input_local(inp_vf2, |
| pafd_ctr->fb.pre_dec, pcfg); |
| if (is_src_i(inp_vf2) || VFMT_IS_I(inp_vf2->type)) |
| src_i_set(nr_vf); |
| //dim_print("%s:set srci\n", __func__); |
| |
| if (mem_vf2 && pafd_ctr->en_set.b.mem) |
| /* mem */ |
| enable_afbc_input_local(mem_vf2, |
| pafd_ctr->fb.mem_dec, |
| pcfg); |
| if (chan2_vf && pafd_ctr->en_set.b.chan2) |
| /* chan2 */ |
| enable_afbc_input_local(chan2_vf, |
| pafd_ctr->fb.ch2_dec, |
| pcfg); |
| |
| /*nr*/ |
| if (pafd_ctr->en_set.b.enc_nr) |
| afbce_set(nr_vf, EAFBC_ENC0); |
| |
| } else if (pafd_ctr->b.chg_level == 2) { |
| if (pafd_ctr->en_set.b.inp) |
| afbc_update_level2_inp(pafd_ctr); |
| |
| if (is_src_i(inp_vf2) || VFMT_IS_I(inp_vf2->type)) { |
| src_i_set(nr_vf); |
| dim_print("%s:set srci\n", __func__); |
| } |
| |
| /*mem*/ |
| if (pafd_ctr->en_set.b.mem) { |
| if (is_cfg(EAFBC_CFG_FORCE_MEM)) |
| enable_afbc_input_local(mem_vf2, |
| pafd_ctr->fb.mem_dec, |
| pcfg); |
| else |
| afbc_update_level1(mem_vf2, |
| pafd_ctr->fb.mem_dec); |
| #ifdef MARK_SC2 |
| if (is_cfg(EAFBC_CFG_FORCE_IF1)) { |
| enable_afbc_input_local(mem_vf2, |
| pafd_ctr->fb.if1_dec, |
| pcfg); |
| afbcd_reg_bwr(EAFBC_DEC_IF1, |
| EAFBC_ENABLE, 1, 8, 1); |
| } |
| #endif |
| } |
| |
| if (pafd_ctr->en_set.b.chan2 && chan2_vf) { |
| if (is_cfg(EAFBC_CFG_FORCE_CHAN2)) |
| enable_afbc_input_local |
| (chan2_vf, |
| pafd_ctr->fb.ch2_dec, |
| pcfg); |
| else |
| afbc_update_level1(chan2_vf, |
| pafd_ctr->fb.ch2_dec); |
| } |
| |
| /*nr*/ |
| if (pafd_ctr->en_set.b.enc_nr) { |
| if (is_cfg(EAFBC_CFG_FORCE_NR)) |
| afbce_set(nr_vf, EAFBC_ENC0); |
| else |
| afbce_update_level1(nr_vf, |
| &di_normal_regset, |
| EAFBC_ENC0); |
| } |
| } else if (pafd_ctr->b.chg_level == 1) { |
| /*inp*/ |
| if (pafd_ctr->en_set.b.inp) |
| afbc_update_level1(inp_vf2, pafd_ctr->fb.pre_dec); |
| |
| /*mem*/ |
| if (pafd_ctr->en_set.b.mem) |
| afbc_update_level1(mem_vf2, pafd_ctr->fb.mem_dec); |
| |
| if (pafd_ctr->en_set.b.chan2 && chan2_vf) |
| afbc_update_level1(chan2_vf, pafd_ctr->fb.ch2_dec); |
| |
| /*nr*/ |
| if (pafd_ctr->en_set.b.enc_nr) |
| afbce_update_level1(nr_vf, |
| &di_normal_regset, EAFBC_ENC0); |
| } |
| return 0; |
| } |
| |
| /* post */ |
| static void afbc_pst_check_chg_l(struct vframe_s *if0_vf, |
| struct vframe_s *if1_vf, |
| struct vframe_s *if2_vf, |
| struct afbcd_ctr_s *pctr) |
| { |
| /*check support*/ |
| if (pctr->fb.ver == AFBCD_NONE) |
| return; |
| |
| if (!(if0_vf->type & VIDTYPE_COMPRESS)) { |
| #ifdef MARK_SC2 |
| if (pctr->b.en) { |
| /*from en to disable*/ |
| pctr->b.en = 0; |
| } |
| #endif |
| pctr->b.pst_chg_level = 0; |
| pctr->b.pst_chg_if1 = 0; |
| pctr->b.pst_chg_if2 = 0; |
| return; |
| } |
| /* if0 check */ |
| if ((if0_vf->type & AFBC_VTYPE_MASK_CHG) != |
| (pctr->pst_in_vtp & AFBC_VTYPE_MASK_CHG) || |
| if0_vf->height != pctr->pst_in_h || |
| if0_vf->width != pctr->pst_in_w || |
| if0_vf->bitdepth != pctr->pst_in_bitdepth) { |
| pctr->b.pst_chg_level = 3; |
| pctr->b.pst_chg_if1 = 3; |
| pctr->b.pst_chg_if2 = 3; |
| |
| pctr->pst_in_vtp = (if0_vf->type & AFBC_VTYPE_MASK_SAV); |
| pctr->pst_in_h = if0_vf->height; |
| pctr->pst_in_w = if0_vf->width; |
| pctr->pst_in_bitdepth = if0_vf->bitdepth; |
| } else { |
| pctr->b.pst_chg_level = 1; |
| //pctr->b.pst_chg_if1 = 1; |
| //pctr->b.pst_chg_if2 = 1; |
| } |
| /* if1 check */ |
| if (!if1_vf) { |
| pctr->b.pst_chg_if1 = 0; |
| } else if (!pctr->b.pst_chg_if1) { |
| /* no to have */ |
| pctr->b.pst_chg_if1 = 3; |
| } else if (pctr->b.pst_chg_if1 == 3) { |
| } else { |
| pctr->b.pst_chg_if1 = 1; |
| } |
| |
| /* if2 check */ |
| if (!if2_vf) { |
| pctr->b.pst_chg_if2 = 0; |
| } else if (!pctr->b.en_pst_if2) { |
| /* no to have */ |
| pctr->b.pst_chg_if2 = 3; |
| } else if (pctr->b.pst_chg_if2 == 3) { |
| } else { |
| pctr->b.pst_chg_if2 = 1; |
| } |
| |
| if (is_cfg(EAFBC_CFG_LEVE3)) { |
| pctr->b.chg_level = 3; |
| |
| pctr->b.pst_chg_level = 3; |
| pctr->b.pst_chg_if1 = 3; |
| pctr->b.pst_chg_if2 = 3; |
| } |
| #ifdef PRINT_BASIC |
| di_print("%s:\n", __func__); |
| di_print("\tif0:type[0x%x]\n", if0_vf->type); |
| di_print("\t\t:body[0x%x] inf[0x%x]\n", |
| if0_vf->compBodyAddr, if0_vf->compHeadAddr); |
| di_print("\t\th[%d],w[%d],b[0x%x]\n", if0_vf->height, |
| if0_vf->width, if0_vf->bitdepth); |
| |
| di_print("\t\tchg[%d],is_srci[%d]\n", |
| pctr->b.pst_chg_level, is_src_i(if0_vf)); |
| |
| if (if1_vf) { |
| di_print("\tif1:type[0x%x]\n", if1_vf->type); |
| di_print("\t\t:body[0x%x] inf[0x%x]\n", |
| if1_vf->compBodyAddr, if1_vf->compHeadAddr); |
| di_print("\t\th[%d],w[%d],b[0x%x]\n", if1_vf->height, |
| if1_vf->width, if1_vf->bitdepth); |
| |
| di_print("\t\tchg[%d],is_srci[%d]\n", |
| pctr->b.pst_chg_if1, is_src_i(if1_vf)); |
| } |
| |
| if (if2_vf) { |
| di_print("\tif2:type[0x%x]\n", if2_vf->type); |
| di_print("\t\t:body[0x%x] inf[0x%x]\n", |
| if2_vf->compBodyAddr, if2_vf->compHeadAddr); |
| di_print("\t\th[%d],w[%d],b[0x%x]\n", if2_vf->height, |
| if2_vf->width, if2_vf->bitdepth); |
| |
| di_print("\t\tchg[%d],is_srci[%d]\n", |
| pctr->b.pst_chg_if2, is_src_i(if2_vf)); |
| |
| } else { |
| di_print("%s:no if2?\n", __func__); |
| } |
| |
| di_print("\t:if0_vf->type[0x%x]\n", pctr->pst_in_vtp); |
| |
| di_print("\th[%d],w[%d],b[0x%x]\n", |
| pctr->pst_in_h, |
| pctr->pst_in_w, |
| pctr->pst_in_bitdepth); |
| di_print("\tchg_level[%d] if1[%d], if2[%d]\n", |
| pctr->b.pst_chg_level, |
| pctr->b.pst_chg_if1, |
| pctr->b.pst_chg_if2); |
| #endif |
| } |
| |
| void afbc_sw_pst(bool sw) |
| { |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (!pafd_ctr->b.en_pst && sw) { |
| /*on*/ |
| pafd_ctr->b.en_pst = 1; |
| } else if (pafd_ctr->b.en_pst && !sw) { |
| pafd_ctr->b.en_pst = 0; |
| } |
| //dim_print("%s:%d\n", __func__, sw); |
| } |
| |
| static u32 afbc_pst_set(struct vframe_s *if0_vf, |
| struct vframe_s *if1_vf, |
| struct vframe_s *if2_vf, |
| struct vframe_s *wr_vf) |
| { |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| //enum eAFBC_DEC dec = afbc_get_decnub(); |
| struct vframe_s *if1_vf2, *if2_vf2; |
| //struct AFBCD_CFG_S cfg; |
| struct AFBCD_CFG_S *pcfg = NULL; |
| struct AFBCD_CFG_S cfg_afbcd; |
| union hw_sc2_ctr_pst_s *cfg; |
| |
| dim_print("%s:\n", __func__); |
| |
| if (!afbc_is_supported() || |
| pafd_ctr->fb.ver < AFBCD_V5) |
| return false; |
| |
| if (if0_vf->type & VIDTYPE_COMPRESS) { |
| afbc_sw_pst(true); //ary need check |
| } else { |
| afbc_sw_pst(false); |
| return false; |
| } |
| pcfg = &cfg_afbcd; |
| memset(pcfg, 0, sizeof(*pcfg)); |
| |
| cfg = di_afdp->top_cfg_pst; |
| |
| if (is_cfg(EAFBC_CFG_ETEST)) { |
| if1_vf2 = if0_vf; |
| if2_vf2 = if0_vf; |
| } else { |
| if1_vf2 = if1_vf; |
| if2_vf2 = if2_vf; |
| } |
| // dim_print("%s:1 0x%x=0x%x\n", __func__, |
| //AFBCDM_MEM_HEAD_BADDR, reg_rd(AFBCDM_MEM_HEAD_BADDR)); |
| afbc_pst_check_chg_l(if0_vf, if1_vf2, if2_vf2, pafd_ctr); |
| |
| // dim_print("%s:0x%x=0x%x\n", __func__, |
| //AFBCDM_MEM_HEAD_BADDR, reg_rd(AFBCDM_MEM_HEAD_BADDR)); |
| |
| if (pafd_ctr->en_set_pst.b.if1 && |
| pafd_ctr->b.pst_chg_if1 == 3 && if1_vf2) { |
| dim_print("%s:if1:chg 3\n", __func__); |
| // cfg->b.afbc_if1 = 1; |
| // reg_wrb(DI_TOP_POST_CTRL, 1, 4, 1); |
| enable_afbc_input_local(if1_vf2, pafd_ctr->fb.if1_dec, pcfg); |
| afbcd_reg_bwr(EAFBC_DEC_IF1, EAFBC_ENABLE, 1, 8, 1); |
| pafd_ctr->b.en_pst_if1 = 1; |
| } else if (pafd_ctr->en_set_pst.b.if1 && |
| pafd_ctr->b.pst_chg_if1 == 1 && if1_vf2) { |
| dim_print("%s:if1:chg 2\n", __func__); |
| afbc_update_level1(if1_vf2, pafd_ctr->fb.if1_dec); |
| } else if (!if1_vf2 || !pafd_ctr->en_set_pst.b.if1) { |
| afbcd_reg_bwr(EAFBC_DEC_IF1, EAFBC_ENABLE, 0, 8, 1); |
| pafd_ctr->b.en_pst_if1 = 0; |
| // cfg->b.afbc_if1 = 0; |
| // reg_wrb(DI_TOP_POST_CTRL, 0, 4, 1); |
| di_print("%s:%d\n", __func__, pafd_ctr->en_set_pst.b.if1); |
| } |
| |
| if (pafd_ctr->en_set_pst.b.if2 && |
| pafd_ctr->b.pst_chg_if2 == 3 && if2_vf2) { |
| dim_print("%s:if2:chg 3\n", __func__); |
| // cfg->b.afbc_if2 = 1; |
| // reg_wrb(DI_TOP_POST_CTRL, 1, 6, 1); |
| enable_afbc_input_local(if2_vf2, pafd_ctr->fb.if2_dec, pcfg); |
| afbcd_reg_bwr(EAFBC_DEC_IF2, EAFBC_ENABLE, 1, 8, 1); |
| pafd_ctr->b.en_pst_if2 = 1; |
| |
| } else if (pafd_ctr->en_set_pst.b.if2 && |
| pafd_ctr->b.pst_chg_if2 == 1 && if2_vf2) { |
| dim_print("%s:if2:chg 2\n", __func__); |
| afbc_update_level1(if2_vf2, pafd_ctr->fb.if2_dec); |
| } else if (!if2_vf2 || !pafd_ctr->en_set_pst.b.if2) { |
| afbcd_reg_bwr(EAFBC_DEC_IF2, EAFBC_ENABLE, 0, 8, 1); |
| pafd_ctr->b.en_pst_if2 = 0; |
| // cfg->b.afbc_if2 = 0; |
| // reg_wrb(DI_TOP_POST_CTRL, 0, 6, 1); |
| } |
| |
| if (((pafd_ctr->b.pst_chg_level == 3) || |
| (pafd_ctr->b.pst_chg_if1 == 3)) && |
| pafd_ctr->en_set_pst.b.if0) { |
| dim_print("%s:if0:chg 3\n", __func__); |
| // cfg->b.afbc_if0 = 1; |
| |
| // reg_wrb(DI_TOP_POST_CTRL, 1, 5, 1); |
| enable_afbc_input_local(if0_vf, pafd_ctr->fb.if0_dec, pcfg); |
| afbcd_reg_bwr(EAFBC_DEC_IF0, EAFBC_ENABLE, 1, 8, 1); |
| |
| if (pafd_ctr->en_set_pst.b.enc_wr) { |
| /* double write */ |
| if (is_mask(SC2_DW_EN)) |
| reg_wrb(DI_TOP_POST_CTRL, 1, 0, 1); |
| /*mif disable temp*/ |
| else |
| reg_wrb(DI_TOP_POST_CTRL, 0, 0, 1); |
| /*mif disable temp*/ |
| |
| // reg_wrb(DI_TOP_POST_CTRL, 1, 1, 1); /*afbce*/ |
| /*wr*/ |
| afbce_set(wr_vf, EAFBC_ENC1); |
| } |
| } else if (pafd_ctr->en_set_pst.b.if0) { |
| dim_print("%s:if0:other\n", __func__); |
| afbc_update_level1(if0_vf, pafd_ctr->fb.if0_dec); |
| |
| if (pafd_ctr->en_set_pst.b.enc_wr) |
| /*wr*/ |
| afbce_update_level1(wr_vf, &di_normal_regset, |
| EAFBC_ENC1); |
| |
| } else { |
| dim_print("%s:noif0,0x%x\n", __func__, pafd_ctr->en_set_pst.d8); |
| } |
| |
| return 0; |
| } |
| |
| /*************************************************/ |
| /* only for tm2, sc2 is chang*/ |
| static void afbc_tm2_sw_inp(bool on) |
| { |
| if (on) |
| reg_wrb(DI_AFBCE_CTRL, 0x03, 10, 2); |
| else |
| reg_wrb(DI_AFBCE_CTRL, 0x00, 10, 2); |
| } |
| |
| /* only for tm2, sc2 is chang*/ |
| static void afbc_tm2_sw_mem(bool on) |
| { |
| if (on) |
| reg_wrb(DI_AFBCE_CTRL, 0x03, 12, 2); |
| else |
| reg_wrb(DI_AFBCE_CTRL, 0x00, 12, 2); |
| } |
| |
| /* only for tm2, sc2 is chang*/ |
| static void afbce_tm2_sw(bool on) |
| { |
| if (on) { |
| /*1: nr channel 0 to afbce*/ |
| reg_wrb(DI_AFBCE_CTRL, 0x01, 0, 1); |
| /* nr_en: important! 1:enable nr write to DDR; */ |
| reg_wrb(DI_AFBCE_CTRL, 0x01, 4, 1); |
| } else { |
| reg_wrb(DI_AFBCE_CTRL, 0x00, 0, 1); |
| reg_wrb(DI_AFBCE_CTRL, 0x01, 4, 1); |
| } |
| |
| if (DIM_IS_IC(T5)) { |
| if (on) |
| reg_wrb(DI_AFBCE_CTRL, 0x01, 30, 1); |
| else |
| reg_wrb(DI_AFBCE_CTRL, 0x00, 30, 1); |
| } |
| } |
| |
| static void afbcx_sw(bool on) /*g12a*/ |
| { |
| unsigned int tmp; |
| unsigned int mask; |
| unsigned int reg_ctrl, reg_en; |
| enum EAFBC_DEC dec_sel; |
| const unsigned int *reg = afbc_get_inp_base(); |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| dec_sel = pafd_ctr->fb.pre_dec; |
| |
| if (dec_sel == EAFBC_DEC0) |
| reg_ctrl = VD1_AFBCD0_MISC_CTRL; |
| else |
| reg_ctrl = VD2_AFBCD1_MISC_CTRL; |
| |
| reg_en = reg[EAFBC_ENABLE]; |
| |
| mask = (3 << 20) | (1 << 12) | (1 << 9); |
| /*clear*/ |
| tmp = reg_rd(reg_ctrl) & (~mask); |
| |
| if (on) { |
| tmp = tmp |
| /*0:go_file 1:go_filed_pre*/ |
| | (2 << 20) |
| /*0:afbc0 mif to axi 1:vd1 mif to axi*/ |
| | (1 << 12) |
| /*0:afbc0 to vpp 1:afbc0 to di*/ |
| | (1 << 9); |
| reg_wr(reg_ctrl, tmp); |
| /*0:vd1 to di 1:vd2 to di */ |
| reg_wrb(VD2_AFBCD1_MISC_CTRL, |
| (reg_ctrl == VD1_AFBCD0_MISC_CTRL) ? 0 : 1, 8, 1); |
| /*reg_wr(reg_en, 0x1600);*/ |
| reg_wrb(VIUB_MISC_CTRL0, 1, 16, 1); |
| /*TL1 add mem control bit */ |
| //if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) |
| if (pafd_ctr->fb.ver == AFBCD_V3) |
| reg_wrb(VD1_AFBCD0_MISC_CTRL, 1, 22, 1); |
| } else { |
| reg_wr(reg_ctrl, tmp); |
| reg_wr(reg_en, 0x1600); |
| reg_wrb(VIUB_MISC_CTRL0, 0, 16, 1); |
| //if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) |
| if (pafd_ctr->fb.ver == AFBCD_V3) |
| reg_wrb(VD1_AFBCD0_MISC_CTRL, 0, 22, 1); |
| } |
| } |
| |
| static void afbc_sw_old(bool on)/*txlx*/ |
| { |
| enum EAFBC_DEC dec_sel; |
| unsigned int reg_en; |
| const unsigned int *reg = afbc_get_inp_base(); |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| dec_sel = pafd_ctr->fb.pre_dec; |
| reg_en = reg[EAFBC_ENABLE]; |
| |
| if (on) { |
| /* DI inp(current data) switch to AFBC */ |
| if (reg_rdb(VIU_MISC_CTRL0, 29, 1) != 1) |
| reg_wrb(VIU_MISC_CTRL0, 1, 29, 1); |
| if (reg_rdb(VIUB_MISC_CTRL0, 16, 1) != 1) |
| reg_wrb(VIUB_MISC_CTRL0, 1, 16, 1); |
| if (reg_rdb(VIU_MISC_CTRL1, 0, 1) != 1) |
| reg_wrb(VIU_MISC_CTRL1, 1, 0, 1); |
| if (dec_sel == EAFBC_DEC0) { |
| /*gxl only?*/ |
| if (reg_rdb(VIU_MISC_CTRL0, 19, 1) != 1) |
| reg_wrb(VIU_MISC_CTRL0, 1, 19, 1); |
| } |
| if (reg_rd(reg_en) != 0x1600) |
| reg_wr(reg_en, 0x1600); |
| |
| } else { |
| reg_wr(reg_en, 0); |
| /* afbc to vpp(replace vd1) enable */ |
| if (reg_rdb(VIU_MISC_CTRL1, 0, 1) != 0 || |
| reg_rdb(VIUB_MISC_CTRL0, 16, 1) != 0) { |
| reg_wrb(VIU_MISC_CTRL1, 0, 0, 1); |
| reg_wrb(VIUB_MISC_CTRL0, 0, 16, 1); |
| } |
| } |
| } |
| |
| static bool afbc_is_used(void) |
| { |
| bool ret = false; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (pafd_ctr->en_set.d8) |
| ret = true; |
| |
| return ret; |
| } |
| |
| static bool afbc_is_used_inp(void) |
| { |
| bool ret = false; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (pafd_ctr->en_set.b.inp) |
| ret = true; |
| |
| return ret; |
| } |
| |
| static bool afbc_is_used_mem(void) |
| { |
| bool ret = false; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (pafd_ctr->en_set.b.mem) |
| ret = true; |
| |
| return ret; |
| } |
| |
| static bool afbc_is_used_chan2(void) |
| { |
| bool ret = false; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (pafd_ctr->en_set.b.chan2) |
| ret = true; |
| |
| return ret; |
| } |
| |
| static bool afbc_is_free(void) |
| { |
| bool sts = 0; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| u32 afbc_num = pafd_ctr->fb.pre_dec; |
| |
| if (afbc_num == EAFBC_DEC0) |
| sts = reg_rdb(VD1_AFBCD0_MISC_CTRL, 8, 2); |
| else if (afbc_num == EAFBC_DEC1) |
| sts = reg_rdb(VD2_AFBCD1_MISC_CTRL, 8, 2); |
| |
| if (sts) |
| return true; |
| else |
| return false; |
| |
| return sts; |
| } |
| |
| static void afbc_power_sw(bool on) |
| { |
| /*afbc*/ |
| enum EAFBC_DEC dec_sel; |
| unsigned int vpu_sel; |
| unsigned int reg_ctrl; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| dec_sel = pafd_ctr->fb.pre_dec; |
| if (dec_sel == EAFBC_DEC0) |
| vpu_sel = VPU_AFBC_DEC; |
| else |
| vpu_sel = VPU_AFBC_DEC1; |
| |
| ops_ext()->switch_vpu_mem_pd_vmod |
| (vpu_sel, on ? VPU_MEM_POWER_ON : VPU_MEM_POWER_DOWN); |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { |
| if (dec_sel == EAFBC_DEC0) |
| reg_ctrl = VD1_AFBCD0_MISC_CTRL; |
| else |
| reg_ctrl = VD2_AFBCD1_MISC_CTRL; |
| if (on) |
| reg_wrb(reg_ctrl, 0, 0, 8); |
| else |
| reg_wrb(reg_ctrl, 0x55, 0, 8); |
| } |
| /*afbcx_power_sw(dec_sel, on);*/ |
| } |
| |
| //int afbc_reg_unreg_flag; |
| |
| static void afbc_sw_tl2(bool en) |
| { |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (pafd_ctr->fb.mode == AFBC_WK_IN) { |
| afbc_tm2_sw_inp(en); |
| } else if (pafd_ctr->fb.mode == AFBC_WK_P) { |
| #ifdef MARK_SC2 |
| afbc_tm2_sw_inp(en); |
| afbc_tm2_sw_mem(en); |
| afbce_tm2_sw(en); |
| #else |
| if (!en) { |
| afbc_tm2_sw_inp(en); |
| afbc_tm2_sw_mem(en); |
| afbce_tm2_sw(en); |
| } |
| #endif |
| } |
| } |
| |
| static void afbc_sw_sc2(bool en) |
| { |
| #ifdef MARK_SC2 |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (!pafd_ctr->fb.mode) |
| PR_INF("%s:%d\n", __func__, en); |
| #endif |
| } |
| |
| static void afbc_sw(bool on) |
| { |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| bool act = false; |
| |
| /**/ |
| if (pafd_ctr->b.en && !on) |
| act = true; |
| else if (!pafd_ctr->b.en && on) |
| act = true; |
| |
| if (act) { |
| if (pafd_ctr->fb.ver == AFBCD_V1) |
| afbc_sw_old(on); |
| else if (pafd_ctr->fb.ver <= AFBCD_V3) |
| afbcx_sw(on); |
| else if (pafd_ctr->fb.ver == AFBCD_V4) |
| afbc_sw_tl2(on); |
| else if (pafd_ctr->fb.ver == AFBCD_V5) |
| afbc_sw_sc2(on); |
| |
| pafd_ctr->b.en = on; |
| pr_info("di:%s:%d\n", __func__, on); |
| } |
| } |
| |
| void dbg_afbc_sw_v3(bool on) |
| { |
| afbc_sw(on); |
| } |
| |
| static void afbc_input_sw(bool on); |
| |
| static void afbc_reg_variable(void *a) |
| { |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| union afbc_blk_s *en_cfg; |
| struct di_ch_s *pch; |
| unsigned char cfg_val; |
| |
| pch = (struct di_ch_s *)a; |
| /******************************* |
| * cfg for debug: |
| ******************************/ |
| afbc_get_mode_from_cfg(); |
| |
| en_cfg = &pch->rse_ori.di_pre_stru.en_cfg; |
| |
| afbc_cfg_mode_set(pafd_ctr->fb.mode, en_cfg); |
| |
| /******************************/ |
| if (pafd_ctr->fb.mode >= AFBC_WK_6D) { |
| pafd_ctr->fb.mem_alloc = 1; |
| pafd_ctr->fb.mem_alloci = 1; |
| } else if (pafd_ctr->fb.mode >= AFBC_WK_P) { |
| pafd_ctr->fb.mem_alloc = 1; |
| pafd_ctr->fb.mem_alloci = 0; |
| } else if (is_cfg(EAFBC_CFG_MEM)) { |
| pafd_ctr->fb.mem_alloc = 1; |
| pafd_ctr->fb.mem_alloci = 1; |
| } else { |
| pafd_ctr->fb.mem_alloc = 0; |
| pafd_ctr->fb.mem_alloci = 0; |
| } |
| |
| dim_print("%s:en_cfg:0x%x\n", __func__, en_cfg->d8); |
| /**********************************/ |
| en_cfg->d8 = en_cfg->d8 & pafd_ctr->fb.sp.d8; |
| cfg_val = en_cfg->d8; |
| /* post save as pre */ |
| en_cfg = &pch->rse_ori.di_post_stru.en_cfg; |
| en_cfg->d8 = cfg_val; |
| } |
| |
| static void afbc_val_reset_newformat(void) |
| { |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| //PR_INF("%s\n", __func__); |
| pafd_ctr->l_vtype = 0; |
| pafd_ctr->l_vt_mem = 0; |
| pafd_ctr->l_vt_chan2 = 0; |
| pafd_ctr->l_h = 0; |
| pafd_ctr->l_w = 0; |
| pafd_ctr->pst_in_vtp = 0; |
| pafd_ctr->pst_in_h = 0; |
| pafd_ctr->pst_in_w = 0; |
| } |
| |
| static void afbc_reg_sw(bool on) |
| { |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| struct afbc_fb_s tmp; |
| |
| if (!afbc_is_supported()) |
| return; |
| dbg_pl("%s:sw[%d]\n", __func__, on); |
| if (on) { |
| if (pafd_ctr->fb.ver <= AFBCD_V3) |
| afbc_power_sw(true); |
| else if (pafd_ctr->fb.ver == AFBCD_V4) |
| reg_wrb(DI_AFBCE_CTRL, 0x01, 4, 1); |
| } |
| if (!on) { |
| if (pafd_ctr->fb.ver <= AFBCD_V3) { |
| /*input*/ |
| afbc_input_sw(false); |
| |
| afbc_sw(false); |
| |
| afbc_power_sw(false); |
| } else { |
| /*AFBCD_V4*/ |
| afbc_sw(false); |
| } |
| memcpy(&tmp, &pafd_ctr->fb, sizeof(tmp)); |
| memset(pafd_ctr, 0, sizeof(*pafd_ctr)); |
| memcpy(&pafd_ctr->fb, &tmp, sizeof(tmp)); |
| } |
| } |
| |
| /********************************************* |
| * size v2 2020-08-24 |
| ********************************************/ |
| static unsigned int afbc_count_info_size(unsigned int w, unsigned int h, |
| unsigned int *blk_total) |
| { |
| unsigned int length = 0; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| unsigned int blk_num_total, blk_hsize, blk_vsize; |
| unsigned int blk_hsize_align, blk_vsize_align; |
| |
| if (!afbc_is_supported() || |
| ((pafd_ctr->fb.mode < AFBC_WK_P) && (!cfgg(FIX_BUF)))) { |
| pafd_ctr->blk_nub_total = 0; |
| pafd_ctr->size_info = 0; |
| return 0; |
| } |
| blk_hsize = ((w + 31) >> 5);//hsize 32 ?? ??32 |
| blk_vsize = ((h + 3) >> 2);//size 4 ?? ??4 |
| |
| blk_hsize_align = ((blk_hsize + 1) >> 1) << 1;//2?? |
| blk_vsize_align = ((blk_vsize + 15) >> 4) << 4;//8?? |
| blk_num_total = blk_hsize_align * blk_vsize_align; |
| |
| length = blk_num_total * 4; |
| length = PAGE_ALIGN(length); //ary add 2020-08-26 |
| pafd_ctr->blk_nub_total = blk_num_total; |
| *blk_total = blk_num_total; |
| pafd_ctr->size_info = length; |
| return length; |
| } |
| |
| static unsigned int v2_afbc_count_buffer_size(unsigned int format, |
| unsigned int blk_nub_total) |
| { |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| unsigned int sblk_num, src_bits, each_blk_bytes, body_buffer_size; |
| unsigned int fmt_mode, compbits; |
| |
| if (!afbc_is_supported() || |
| ((pafd_ctr->fb.mode < AFBC_WK_P) && (!cfgg(FIX_BUF)))) { |
| pafd_ctr->size_afbc_buf = 0; |
| return 0; |
| } |
| |
| fmt_mode = format & 0x0f; |
| compbits = (format >> 4) & 0x0f; |
| if (!fmt_mode) /*4:2:0*/ |
| sblk_num = 12; |
| else if (fmt_mode == 1) /*4:2:2*/ |
| sblk_num = 16; |
| else /*4:4:4*/ |
| sblk_num = 24; |
| |
| if (compbits == 0) |
| src_bits = 8; |
| else if (compbits == 1) |
| src_bits = 9; |
| else |
| src_bits = 10; |
| |
| each_blk_bytes = ((((sblk_num * 16 * src_bits + 7) >> 3) + |
| 63) >> 6) << 6; |
| body_buffer_size = ((blk_nub_total * each_blk_bytes) * 113 + 99) / 100; |
| PR_INF("%s:size=0x%x\n", __func__, body_buffer_size); |
| pafd_ctr->size_afbc_buf = body_buffer_size; |
| |
| return body_buffer_size; |
| } |
| |
| static unsigned int afbc_count_tab_size(unsigned int buf_size) |
| { |
| unsigned int length = 0; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| /* tmp: large */ |
| if (!afbc_is_supported() || |
| ((pafd_ctr->fb.mode < AFBC_WK_P) && (!cfgg(FIX_BUF)))) |
| return 0; |
| |
| length = PAGE_ALIGN(((buf_size + 0xfff) >> 12) * |
| sizeof(unsigned int)); |
| |
| pafd_ctr->size_tab = length; |
| return length; |
| } |
| |
| #ifdef HIST_CODE |
| static unsigned int afbc_count_info_size(unsigned int w, unsigned int h) |
| { |
| unsigned int length = 0; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if ((!afbc_is_supported()) || |
| ((pafd_ctr->fb.mode < AFBC_WK_P) && (!cfgg(FIX_BUF)))) |
| return 0; |
| |
| length = PAGE_ALIGN((roundup(w * 2, 32) * |
| roundup(h, 4)) / 32);//tmplarge |
| |
| pafd_ctr->size_info = length; |
| return length; |
| } |
| |
| static unsigned int afbc_count_tab_size(unsigned int buf_size) |
| { |
| unsigned int length = 0; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| /* tmp: large */ |
| if ((!afbc_is_supported()) || |
| ((pafd_ctr->fb.mode < AFBC_WK_P) && (!cfgg(FIX_BUF)))) |
| return 0; |
| |
| length = PAGE_ALIGN(((buf_size * 2 + 0xfff) >> 12) * |
| sizeof(unsigned int)); |
| |
| pafd_ctr->size_tab = length; |
| return length; |
| } |
| #endif |
| |
| static unsigned int afbc_int_tab(struct device *dev, |
| struct afbce_map_s *pcfg) |
| { |
| bool flg = 0; |
| unsigned int *p; |
| unsigned int i, cnt, last; |
| unsigned int body; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| unsigned int crc = 0; |
| unsigned long crc_tmp = 0; |
| //struct di_mm_s *mm = dim_mm_get(ch); |
| //struct di_dev_s *de_devp = get_dim_de_devp(); |
| |
| if (!afbc_is_supported() || |
| !pcfg || |
| !dev) |
| return 0; |
| if (pafd_ctr->fb.mode < AFBC_WK_P && (!cfgg(FIX_BUF))) |
| return 0; |
| |
| dma_sync_single_for_device(dev, |
| pcfg->tabadd, |
| pcfg->size_tab, |
| DMA_TO_DEVICE); |
| |
| p = (unsigned int *)dim_vmap(pcfg->tabadd, pcfg->size_tab, &flg); |
| if (!p) { |
| pafd_ctr->b.enc_err = 1; |
| pr_error("%s:vmap:0x%lx\n", __func__, pcfg->tabadd); |
| return 0; |
| } |
| |
| cnt = (pcfg->size_buf + 0xfff) >> 12; |
| body = (unsigned int)(pcfg->bodyadd >> 12); |
| for (i = 0; i < cnt; i++) { |
| *(p + i) = body; |
| crc_tmp += body; |
| body++; |
| } |
| |
| crc = (unsigned int)crc_tmp; |
| last = pcfg->size_tab - (cnt * sizeof(unsigned int)); |
| |
| memset((p + cnt), 0, last); |
| //memset((p + cnt), body, last); |
| |
| /*debug*/ |
| #ifdef DBG_AFBC |
| di_pr_info("%s:tab:[0x%lx]: body[0x%lx];cnt[%d];last[%d]\n", |
| __func__, |
| pcfg->tabadd, pcfg->bodyadd, cnt, last); |
| #endif |
| dma_sync_single_for_device(dev, |
| pcfg->tabadd, |
| pcfg->size_tab, |
| DMA_TO_DEVICE); |
| //PR_INF("%s:%d\n", __func__, flg); |
| if (flg) |
| di_unmap_phyaddr((u8 *)p); |
| |
| return crc; |
| } |
| |
| static unsigned int afbc_tab_cnt_crc(struct device *dev, |
| struct afbce_map_s *pcfg, |
| unsigned int check_mode, |
| unsigned int crc_old) |
| { |
| bool flg = 0; |
| unsigned int *p; |
| int i, cnt; |
| unsigned int body; |
| unsigned int crc = 0; |
| unsigned long crc_tmp = 0; |
| unsigned int err_cnt = 0; |
| unsigned int fist_err_pos = 0, fist_err = 0, first_right = 0; |
| unsigned int fist_s_pos = 0, right_cnt = 0; |
| |
| //p = (unsigned int *)dim_vmap(pcfg->tabadd, pcfg->size_buf, &flg); |
| dma_sync_single_for_cpu(dev, |
| pcfg->tabadd, |
| pcfg->size_tab, |
| DMA_FROM_DEVICE); |
| p = (unsigned int *)dim_vmap(pcfg->tabadd, pcfg->size_tab, &flg); |
| if (!p) { |
| pr_error("%s:vmap:0x%lx\n", __func__, pcfg->tabadd); |
| return 0; |
| } |
| if (!pcfg->size_tab) |
| return 0; |
| cnt = (pcfg->size_buf + 0xfff) >> 12; |
| body = (unsigned int)(pcfg->bodyadd >> 12); |
| for (i = 0; i < cnt; i++) { |
| if (check_mode == 1) { |
| if (*(p + i) != body) { |
| if (err_cnt == 0) { |
| fist_err_pos = i; |
| fist_err = *(p + i); |
| first_right = body; |
| } |
| |
| err_cnt++; |
| } else { |
| right_cnt++; |
| if (right_cnt > 3) |
| fist_s_pos = i; |
| } |
| } |
| crc_tmp += *(p + i); |
| |
| body++; |
| } |
| crc = (unsigned int)crc_tmp; |
| /*debug*/ |
| if ((crc_old != crc) || (err_cnt > 0)) { |
| PR_ERR("%s:crc[0x%x], err[%d]\n", |
| __func__, |
| crc, err_cnt); |
| PR_ERR("pos[%d],er1[0x%x],[0x%x],rightpos[%d]\n", |
| fist_err_pos, fist_err, first_right, fist_s_pos); |
| } |
| //dma_sync_single_for_device(dev, |
| // pcfg->tabadd, |
| // pcfg->size_tab, |
| // DMA_TO_DEVICE); |
| //PR_INF("%s:%d\n", __func__, flg); |
| if (flg) |
| di_unmap_phyaddr((u8 *)p); |
| |
| return crc; |
| } |
| |
| bool dbg_checkcrc(struct di_buf_s *di_buf, unsigned int cnt) |
| { |
| struct di_dev_s *devp = get_dim_de_devp(); |
| struct afbce_map_s pcfg; |
| unsigned int crc; |
| |
| pcfg.bodyadd = di_buf->nr_adr; |
| pcfg.tabadd = di_buf->afbct_adr; |
| |
| pcfg.size_buf = di_buf->nr_size; |
| pcfg.size_tab = di_buf->tab_size; |
| |
| if (!pcfg.size_tab && !di_buf->afbc_crc) |
| return true; |
| else if (!pcfg.size_tab) |
| return false; |
| |
| crc = afbc_tab_cnt_crc(&devp->pdev->dev, &pcfg, 1, di_buf->afbc_crc); |
| |
| if (crc != di_buf->afbc_crc) { |
| PR_ERR("%s:cnt[%d],0x%x->0x%x\n", |
| __func__, cnt, crc, di_buf->afbc_crc); |
| PR_INF("\t:bodyadd[0x%lx],tabadd[0x%lx]\n", |
| pcfg.bodyadd, pcfg.tabadd); |
| PR_INF("\t:sizebuf[0x%x], sizetab[0x%x]\n", |
| pcfg.size_buf, pcfg.size_tab); |
| |
| return false; |
| } |
| return true; |
| } |
| |
| static void afbc_input_sw(bool on) |
| { |
| const unsigned int *reg;// = afbc_get_regbase(); |
| unsigned int reg_AFBC_ENABLE; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| if (!afbc_is_supported()) |
| return; |
| |
| if (pafd_ctr->en_set.b.inp) { |
| reg = afbc_get_addrp(pafd_ctr->fb.pre_dec); |
| reg_AFBC_ENABLE = reg[EAFBC_ENABLE]; |
| |
| dim_print("%s:reg=0x%x:sw=%d\n", __func__, reg_AFBC_ENABLE, on); |
| if (on) |
| reg_wrb(reg_AFBC_ENABLE, 1, 8, 1); |
| else |
| ;//reg_wrb(reg_AFBC_ENABLE, 0, 8, 1); |
| } |
| |
| if (pafd_ctr->en_set.b.mem) { |
| /*mem*/ |
| reg = afbc_get_addrp(pafd_ctr->fb.mem_dec); |
| reg_AFBC_ENABLE = reg[EAFBC_ENABLE]; |
| if (on) |
| reg_wrb(reg_AFBC_ENABLE, 1, 8, 1); |
| else |
| reg_wrb(reg_AFBC_ENABLE, 0, 8, 1); |
| } |
| |
| if (pafd_ctr->en_set.b.chan2) { |
| /* chan2 */ |
| reg = afbc_get_addrp(pafd_ctr->fb.ch2_dec); |
| reg_AFBC_ENABLE = reg[EAFBC_ENABLE]; |
| if (on) |
| reg_wrb(reg_AFBC_ENABLE, 1, 8, 1); |
| else |
| reg_wrb(reg_AFBC_ENABLE, 0, 8, 1); |
| } |
| } |
| |
| void dbg_afd_reg_v3(struct seq_file *s, enum EAFBC_DEC eidx) |
| { |
| int i; |
| unsigned int addr; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| unsigned int regs_ofst; |
| |
| seq_printf(s, "dump reg:afd[%d]\n", eidx); |
| |
| if (pafd_ctr->fb.ver < AFBCD_V5) { |
| if (eidx > EAFBC_DEC3_MEM) { |
| seq_printf(s, "eidx[%d] is overflow for ver[%d]\n", |
| eidx, pafd_ctr->fb.ver); |
| return; |
| } |
| for (i = 0; i < AFBC_REG_INDEX_NUB; i++) { |
| addr = reg_afbc[eidx][i]; |
| seq_printf(s, "reg[0x%x]=0x%x.\n", addr, reg_rd(addr)); |
| } |
| } else { |
| for (i = 0; i < AFBC_REG_INDEX_NUB; i++) { |
| addr = reg_afbc_v5[eidx][i]; |
| seq_printf(s, "reg[0x%x]=0x%x.\n", addr, reg_rd(addr)); |
| } |
| |
| if (pafd_ctr->fb.ver >= AFBCD_V5) { |
| regs_ofst = afbcd_v5_get_offset(eidx); |
| |
| addr = regs_ofst + AFBCDM_ROT_CTRL; |
| seq_printf(s, "reg[0x%x]=0x%x.\n", addr, reg_rd(addr)); |
| |
| addr = regs_ofst + AFBCDM_ROT_SCOPE; |
| seq_printf(s, "reg[0x%x]=0x%x.\n", addr, reg_rd(addr)); |
| } |
| } |
| } |
| EXPORT_SYMBOL(dbg_afd_reg_v3); |
| |
| void dbg_afe_reg_v3(struct seq_file *s, enum EAFBC_ENC eidx) |
| { |
| int i; |
| unsigned int addr; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| |
| seq_printf(s, "dump reg:afe[%d]\n", eidx); |
| |
| if ((pafd_ctr->fb.ver < AFBCD_V5) && eidx > 0) { |
| PR_ERR("%s:eidx[%d] overflow\n", __func__, eidx); |
| return; |
| } |
| |
| for (i = 0; i < DIM_AFBCE_NUB; i++) { |
| addr = reg_afbc_e[eidx][i]; |
| seq_printf(s, "reg[0x%x]=0x%x.\n", addr, reg_rd(addr)); |
| } |
| } |
| EXPORT_SYMBOL(dbg_afe_reg_v3); |
| |
| struct afd_ops_s di_afd_ops_v3 = { |
| .prob = afbc_prob, |
| .is_supported = afbc_is_supported, |
| .en_pre_set = enable_afbc_input, |
| .en_pst_set = afbc_pst_set, |
| .inp_sw = afbc_input_sw, |
| .reg_sw = afbc_reg_sw, |
| .reg_val = afbc_reg_variable, |
| .rest_val = afbc_val_reset_newformat, |
| .is_used = afbc_is_used, |
| .is_used_inp = afbc_is_used_inp, |
| .is_used_mem = afbc_is_used_mem, |
| .is_used_chan2 = afbc_is_used_chan2, |
| .is_free = afbc_is_free, |
| .cnt_info_size = afbc_count_info_size, |
| .cnt_tab_size = afbc_count_tab_size, |
| .cnt_buf_size = v2_afbc_count_buffer_size, |
| .dump_reg = dump_afbcd_reg, |
| .rqst_share = di_requeset_afbc, |
| .get_d_addrp = afbc_get_addrp, |
| .get_e_addrp = afbce_get_addrp, |
| .dbg_rqst_share = dbg_requeset_afbc, |
| .dbg_afbc_blk = dbg_afbc_blk, |
| .int_tab = afbc_int_tab, |
| .tab_cnt_crc = afbc_tab_cnt_crc, |
| .is_cfg = is_cfg, |
| .pre_check = afbc_pre_check, |
| .pst_check = afbc_pst_check, |
| //.pre_check2 = afbc_pre_check2, |
| .is_sts = is_status, |
| .sgn_mode_set = afbc_sgn_mode_set, |
| .cnt_sgn_mode = afbc_cnt_sgn_mode, |
| .cfg_mode_set = afbc_cfg_mode_set, |
| }; |
| |
| bool di_attach_ops_afd_v3(const struct afd_ops_s **ops) |
| { |
| *ops = &di_afd_ops_v3; |
| return true; |
| } |
| EXPORT_SYMBOL(di_attach_ops_afd_v3); |
| |
| /*afbc e**********************************************************************/ |
| /*****************************************************************************/ |
| |
| /*don't change order*/ |
| |
| static const unsigned int afbce_default_val[DIM_AFBCE_UP_NUB] = { |
| /*need add*/ |
| 0x00000000, |
| 0x03044000, |
| 0x07800438, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| 0x00000000, |
| }; |
| |
| static void vf_set_for_com(struct di_buf_s *di_buf) |
| { |
| struct vframe_s *vf; |
| |
| vf = di_buf->vframe; |
| |
| vf->canvas0_config[0].phy_addr = di_buf->nr_adr; |
| vf->type |= (VIDTYPE_COMPRESS | VIDTYPE_SCATTER); |
| vf->canvas0_config[0].width = di_buf->canvas_width[NR_CANVAS], |
| vf->canvas0_config[0].height = di_buf->canvas_height; |
| vf->canvas0_config[0].block_mode = 0; |
| vf->plane_num = 1; |
| vf->canvas0Addr = -1; |
| vf->canvas1Addr = -1; |
| vf->compHeadAddr = di_buf->afbc_adr; |
| vf->compBodyAddr = di_buf->nr_adr; |
| vf->compHeight = vf->height; |
| vf->compWidth = vf->width; |
| vf->bitdepth |= (BITDEPTH_U10 | BITDEPTH_V10); |
| |
| if (di_buf->afbce_out_yuv420_10) { |
| vf->type &= ~VFMT_COLOR_MSK; |
| vf->type |= VIDTYPE_VIU_FIELD; |
| vf->bitdepth &= ~(FULL_PACK_422_MODE); |
| } |
| //dim_print("%s:%px:0x%x\n", __func__, vf, vf->type); |
| #ifdef DBG_AFBC |
| |
| if (afbc_cfg_vf) |
| vf->type |= afbc_cfg_vf; |
| if (afbc_cfg_bt) |
| vf->bitdepth |= afbc_cfg_bt; |
| #endif |
| } |
| |
| struct enc_cfg_s { |
| int enable; |
| int loosy_mode; |
| /* loosy_mode: |
| * 0:close 1:luma loosy 2:chrma loosy 3: luma & chrma loosy |
| */ |
| int head_baddr;/*head addr*/ |
| int mmu_info_baddr;/*mmu info linear addr*/ |
| int reg_format_mode;/*0:444 1:422 2:420*/ |
| int reg_compbits_y;/*bits num after compression*/ |
| int reg_compbits_c;/*bits num after compression*/ |
| |
| int hsize_in;/*input hsize*/ |
| int vsize_in;/*input hsize*/ |
| int enc_win_bgn_h;/*input scope*/ |
| int enc_win_end_h;/*input scope*/ |
| int enc_win_bgn_v;/*input scope*/ |
| int enc_win_end_v;/*input scope*/ |
| |
| /*from sc2*/ |
| u32 reg_init_ctrl;//pip init frame flag |
| u32 reg_pip_mode;//pip open bit |
| u32 reg_ram_comb;//ram split bit open in di mult write case |
| u32 hsize_bgnd;//hsize of background |
| u32 vsize_bgnd;//hsize of background |
| u32 rev_mode;//0:normal mode |
| u32 def_color_0;//def_color |
| u32 def_color_1;//def_color |
| u32 def_color_2;//def_color |
| u32 def_color_3;//def_color |
| u32 force_444_comb; |
| u32 rot_en; |
| u32 din_swt; |
| }; |
| |
| /*enc: set_di_afbce_cfg ******************/ |
| static void ori_afbce_cfg(struct enc_cfg_s *cfg, |
| const struct reg_acc *op, |
| enum EAFBC_ENC enc) |
| { |
| const unsigned int *reg; |
| int hold_line_num = 4; |
| int lbuf_depth = 256; |
| int rev_mode = 0; |
| int def_color_0 = 0x3ff; |
| int def_color_1 = 0x80; |
| int def_color_2 = 0x80; |
| int def_color_3 = 0; |
| int hblksize_out;//sc2 = (cfg->hsize_in + 31) >> 5; |
| int vblksize_out;//sc2 = (cfg->vsize_in + 3) >> 2; |
| /* output blk scope */ |
| int blk_out_end_h = cfg->enc_win_bgn_h >> 5; |
| /* output blk scope */ |
| int blk_out_bgn_h = (cfg->enc_win_end_h + 31) >> 5; |
| /*output blk scope */ |
| int blk_out_end_v = cfg->enc_win_bgn_v >> 2; |
| /* output blk scope */ |
| int blk_out_bgn_v = (cfg->enc_win_end_v + 3) >> 2; |
| |
| int lossy_luma_en; |
| int lossy_chrm_en; |
| int cur_mmu_used = 0;/*mmu info linear addr*/ |
| |
| int reg_fmt444_comb; |
| int uncmp_size ;/*calculate*/ |
| int uncmp_bits ;/*calculate*/ |
| int sblk_num ;/*calculate*/ |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| bool flg_v5 = false; |
| unsigned int hsize_buf; |
| unsigned int vsize_buf; |
| |
| /* sc2 */ |
| if (pafd_ctr->fb.ver >= AFBCD_V5) |
| flg_v5 = true; |
| |
| if (flg_v5) { |
| if (cfg->din_swt) |
| enc = 1 - enc; |
| op->bwr(DI_TOP_CTRL1, (cfg->din_swt ? 3 : 0), 0, 2); |
| //only di afbce have ram_comb |
| |
| hold_line_num = 0; |
| |
| /* yuv444 can only support 8bit,and must use comb_mode */ |
| reg_fmt444_comb = (cfg->reg_format_mode == 0) && |
| (cfg->force_444_comb); |
| } else { |
| /*yuv444 can only support 8bit,and must use comb_mode*/ |
| if (cfg->reg_format_mode == 0 && cfg->hsize_in > 2048) |
| reg_fmt444_comb = 1; |
| else |
| reg_fmt444_comb = 0; |
| } |
| /* for before sc2, pip mode is fix 0 */ |
| hsize_buf = cfg->reg_pip_mode ? cfg->hsize_bgnd : cfg->hsize_in; |
| vsize_buf = cfg->reg_pip_mode ? cfg->vsize_bgnd : cfg->vsize_in; |
| |
| hblksize_out = (hsize_buf + 31) >> 5; |
| vblksize_out = (vsize_buf + 3) >> 2; |
| |
| /***********************/ |
| |
| reg = ®_afbc_e[enc][0]; |
| |
| #ifdef MARK_SC2 |
| /*yuv444 can only support 8bit,and must use comb_mode*/ |
| if (cfg->reg_format_mode == 0 && cfg->hsize_in > 2048) |
| reg_fmt444_comb = 1; |
| else |
| reg_fmt444_comb = 0; |
| #endif |
| /* 4*4 subblock number in every 32*4 mblk */ |
| if (cfg->reg_format_mode == 2) |
| sblk_num = 12; |
| else if (cfg->reg_format_mode == 1) |
| sblk_num = 16; |
| else |
| sblk_num = 24; |
| |
| if (cfg->reg_compbits_y > cfg->reg_compbits_c) |
| uncmp_bits = cfg->reg_compbits_y; |
| else |
| uncmp_bits = cfg->reg_compbits_c; |
| |
| /*bit size of uncompression mode*/ |
| uncmp_size = (((((16 * uncmp_bits * sblk_num) + 7) >> 3) + |
| 31) / 32) << 1; |
| |
| /*chose loosy mode of luma and chroma */ |
| if (cfg->loosy_mode == 0) { |
| lossy_luma_en = 0; |
| lossy_chrm_en = 0; |
| } else if (cfg->loosy_mode == 1) { |
| lossy_luma_en = 1; |
| lossy_chrm_en = 0; |
| } else if (cfg->loosy_mode == 2) { |
| lossy_luma_en = 0; |
| lossy_chrm_en = 1; |
| } else { |
| lossy_luma_en = 1; |
| lossy_chrm_en = 1; |
| } |
| |
| op->wr(reg[EAFBCE_MODE], |
| (0 & 0x7) << 29 | |
| (rev_mode & 0x3) << 26 | |
| (3 & 0x3) << 24 | |
| (hold_line_num & 0x7f) << 16 | |
| (2 & 0x3) << 14 | |
| (reg_fmt444_comb & 0x1)); |
| /* loosy */ |
| op->bwr(reg[EAFBCE_QUANT_ENABLE], (lossy_luma_en & 0x1), 0, 1); |
| op->bwr(reg[EAFBCE_QUANT_ENABLE], (lossy_chrm_en & 0x1), 4, 1); |
| |
| /* hsize_in of afbc input*/ |
| /* vsize_in of afbc input*/ |
| if (flg_v5) { |
| op->wr(reg[EAFBCE_SIZE_IN], |
| ((hsize_buf & 0x1fff) << 16) | |
| ((vsize_buf & 0x1fff) << 0)); |
| |
| } else { |
| op->wr(reg[EAFBCE_SIZE_IN], |
| ((cfg->hsize_in & 0x1fff) << 16) | |
| ((cfg->vsize_in & 0x1fff) << 0)); |
| } |
| /* out blk hsize*/ |
| /* out blk vsize*/ |
| op->wr(reg[EAFBCE_BLK_SIZE_IN], |
| ((hblksize_out & 0x1fff) << 16) | |
| ((vblksize_out & 0x1fff) << 0) |
| ); |
| if (DIM_IS_IC_EF(T7)) |
| op->wr(reg[EAFBCE_HEAD_BADDR], cfg->head_baddr >> 4); |
| else |
| /*head addr of compressed data*/ |
| op->wr(reg[EAFBCE_HEAD_BADDR], cfg->head_baddr); |
| |
| /*uncmp_size*/ |
| op->bwr(reg[EAFBCE_MIF_SIZE], (uncmp_size & 0x1fff), 16, 5); |
| |
| /* scope of hsize_in ,should be a integer multiple of 32*/ |
| /* scope of vsize_in ,should be a integer multiple of 4*/ |
| op->wr(reg[EAFBCE_PIXEL_IN_HOR_SCOPE], |
| ((cfg->enc_win_end_h & 0x1fff) << 16) | |
| ((cfg->enc_win_bgn_h & 0x1fff) << 0)); |
| |
| /* scope of hsize_in ,should be a integer multiple of 32*/ |
| /* scope of vsize_in ,should be a integer multiple of 4*/ |
| op->wr(reg[EAFBCE_PIXEL_IN_VER_SCOPE], |
| ((cfg->enc_win_end_v & 0x1fff) << 16) | |
| ((cfg->enc_win_bgn_v & 0x1fff) << 0) |
| ); |
| |
| /*fix 256*/ |
| op->wr(reg[EAFBCE_CONV_CTRL], lbuf_depth); |
| |
| /* scope of out blk hsize*/ |
| /* scope of out blk vsize*/ |
| op->wr(reg[EAFBCE_MIF_HOR_SCOPE], |
| ((blk_out_bgn_h & 0x3ff) << 16) | |
| ((blk_out_end_h & 0x3ff) << 0) |
| ); |
| |
| /* scope of out blk hsize*/ |
| /* scope of out blk vsize*/ |
| op->wr(reg[EAFBCE_MIF_VER_SCOPE], |
| ((blk_out_bgn_v & 0xfff) << 16) | |
| ((blk_out_end_v & 0xfff) << 0) |
| ); |
| |
| op->wr(reg[EAFBCE_FORMAT], |
| (cfg->reg_format_mode & 0x3) << 8 | |
| (cfg->reg_compbits_c & 0xf) << 4 | |
| (cfg->reg_compbits_y & 0xf)); |
| |
| /* def_color_a*/ |
| /* def_color_y*/ |
| op->wr(reg[EAFBCE_DEFCOLOR_1], |
| ((def_color_3 & 0xfff) << 12) | |
| ((def_color_0 & 0xfff) << 0)); |
| |
| /* def_color_v*/ |
| /* def_color_u*/ |
| if (cfg->reg_compbits_c == 8) |
| def_color_2 = 0x80; |
| else if (cfg->reg_compbits_c == 9) |
| def_color_2 = 0x100; |
| else |
| def_color_2 = 0x200; |
| |
| def_color_1 = def_color_2; |
| op->wr(reg[EAFBCE_DEFCOLOR_2], |
| ((def_color_2 & 0xfff) << 12) | |
| ((def_color_1 & 0xfff) << 0)); |
| |
| /*4k addr have used in every frame;*/ |
| /*cur_mmu_used += Rd(DI_AFBCE_MMU_NUM);*/ |
| |
| if (DIM_IS_IC_EF(T7)) |
| op->wr(reg[EAFBCE_MMU_RMIF_CTRL4], cfg->mmu_info_baddr >> 4); |
| else |
| op->wr(reg[EAFBCE_MMU_RMIF_CTRL4], cfg->mmu_info_baddr); |
| |
| /**/ |
| if (flg_v5) |
| op->bwr(reg[EAFBCE_MMU_RMIF_CTRL1], 0x1, 6, 1); |
| //litter_endia ary ?? |
| if (cfg->reg_pip_mode) |
| op->bwr(reg[EAFBCE_MMU_RMIF_SCOPE_X], 0x0, 0, 13); /* ary ? */ |
| else |
| op->bwr(reg[EAFBCE_MMU_RMIF_SCOPE_X], cur_mmu_used, 0, 12); |
| |
| /**/ |
| //op->bwr(reg[EAFBCE_MMU_RMIF_SCOPE_X], cur_mmu_used, 0, 12); |
| op->bwr(reg[EAFBCE_MMU_RMIF_SCOPE_X], 0x1ffe, 16, 13); |
| op->bwr(reg[EAFBCE_MMU_RMIF_CTRL3], 0x1fff, 0, 13); |
| |
| if (flg_v5) { |
| op->bwr(reg[EAFBCE_PIP_CTRL], cfg->reg_init_ctrl, 1, 1); |
| //pii_moide |
| op->bwr(reg[EAFBCE_PIP_CTRL], cfg->reg_pip_mode, 0, 1); |
| |
| op->bwr(reg[EAFBCE_ROT_CTRL], cfg->rot_en, 4, 1); |
| |
| op->bwr(reg[EAFBCE_ENABLE], 0, 2, 1);//go_line_cnt start |
| op->bwr(reg[EAFBCE_ENABLE], cfg->enable, 8, 1);//enable afbce |
| op->bwr(reg[EAFBCE_ENABLE], cfg->enable, 0, 1);//enable afbce |
| /* ary : not setting DI_AFBCE_CTRL ?*/ |
| |
| } else { |
| if (DIM_IS_IC(TM2B))//dis afbce mode from vlsi xianjun.fan |
| op->bwr(reg[EAFBCE_MODE_EN], 0x01, 18, 1); |
| op->bwr(reg[EAFBCE_ENABLE], cfg->enable, 8, 1);//enable afbce |
| op->bwr(DI_AFBCE_CTRL, cfg->enable, 0, 1);//di pre to afbce |
| //op->bwr(DI_AFBCE_CTRL, cfg->enable, 4, 1);//di pre to afbce |
| } |
| } |
| |
| void afbce_sw(enum EAFBC_ENC enc, bool on) |
| { |
| const unsigned int *reg; |
| const struct reg_acc *op = &di_normal_regset; |
| |
| reg = ®_afbc_e[enc][0]; |
| |
| if (on) { |
| op->bwr(reg[EAFBCE_ENABLE], 1, 8, 1);//enable afbce |
| op->bwr(reg[EAFBCE_ENABLE], 1, 0, 1);//enable afbce |
| } else { |
| op->bwr(reg[EAFBCE_ENABLE], 0, 8, 1);//enable afbce |
| op->bwr(reg[EAFBCE_ENABLE], 0, 0, 1);//enable afbce |
| } |
| } |
| |
| unsigned int afbce_read_used(enum EAFBC_ENC enc) |
| { |
| const unsigned int *reg; |
| const struct reg_acc *op = &di_normal_regset; |
| unsigned int nub; |
| |
| reg = ®_afbc_e[enc][0]; |
| |
| nub = op->rd(reg[EAFBCE_MMU_NUM]); |
| return nub; |
| } |
| |
| /* set_di_afbce_cfg */ |
| static void afbce_set(struct vframe_s *vf, enum EAFBC_ENC enc) |
| { |
| struct enc_cfg_s cfg_data; |
| struct enc_cfg_s *cfg = &cfg_data; |
| struct di_buf_s *di_buf; |
| struct afbcd_ctr_s *pafd_ctr = di_get_afd_ctr(); |
| bool flg_v5 = false; |
| #ifdef DBG_CRC |
| bool crc_right; |
| #endif |
| |
| if (!vf) { |
| pr_error("%s:0:no vf\n", __func__); |
| return; |
| } |
| di_buf = (struct di_buf_s *)vf->private_data; |
| |
| if (!di_buf) { |
| pr_error("%s:1:no di buf\n", __func__); |
| return; |
| } |
| #ifdef DBG_CRC |
| crc_right = dbg_checkcrc(di_buf); |
| if (!crc_right /*&& (!dim_dbg_is_cnt())*/) { |
| PR_INF("afbce[%d]s:t[%d:%d],inf[0x%lx],adr[0x%lx],vty[0x%x]\n", |
| enc, |
| di_buf->type, di_buf->index, |
| di_buf->afbc_adr, di_buf->afbct_adr, vf->type); |
| } |
| #endif |
| di_buf->flg_afbce_set = 1; |
| cfg->enable = 1; |
| /* 0:close 1:luma lossy 2:chrma lossy 3: luma & chrma lossy*/ |
| cfg->loosy_mode = 0; |
| cfg->head_baddr = di_buf->afbc_adr;//head_baddr_enc;/*head addr*/ |
| cfg->mmu_info_baddr = di_buf->afbct_adr; |
| //vf->compHeadAddr = cfg->head_baddr; |
| //vf->compBodyAddr = di_buf->nr_adr; |
| #ifdef MARK_SC2 |
| if (enc == 1) { |
| di_buf->vframe->height = di_buf->win.y_size; |
| di_buf->vframe->width = di_buf->win.x_size; |
| } |
| #endif |
| vf_set_for_com(di_buf); |
| #ifdef AFBCP |
| di_print("%s:buf[%d],hadd[0x%x],info[0x%x]\n", |
| __func__, |
| di_buf->index, |
| cfg->head_baddr, |
| cfg->mmu_info_baddr); |
| #endif |
| if (di_buf->afbce_out_yuv420_10) |
| cfg->reg_format_mode = 2; |
| else |
| cfg->reg_format_mode = 1;/*0:444 1:422 2:420*/ |
| cfg->reg_compbits_y = 10;//8;/*bits num after compression*/ |
| cfg->reg_compbits_c = 10;//8;/*bits num after compression*/ |
| #ifdef MARK_SC2 |
| if (enc == 1) { |
| cfg->hsize_in = di_buf->win.x_size; |
| cfg->vsize_in = di_buf->win.y_size; |
| |
| /*input scope*/ |
| cfg->enc_win_bgn_h = di_buf->win.x_st; |
| cfg->enc_win_end_h = di_buf->win.x_st + cfg->hsize_in - 1; |
| cfg->enc_win_bgn_v = di_buf->win.y_st; |
| cfg->enc_win_end_v = di_buf->win.y_st + cfg->vsize_in - 1; |
| //vf->height - 1; |
| |
| } else { |
| /*input size*/ |
| cfg->hsize_in = vf->width;//src_w; |
| if (is_src_i(vf) && (enc == 0)) |
| cfg->vsize_in = vf->height >> 1; |
| else |
| cfg->vsize_in = vf->height;//src_h; |
| /*input scope*/ |
| cfg->enc_win_bgn_h = 0; |
| cfg->enc_win_end_h = vf->width - 1; |
| cfg->enc_win_bgn_v = 0; |
| cfg->enc_win_end_v = cfg->vsize_in - 1; //vf->height - 1; |
| } |
| #endif |
| /*input size*/ |
| cfg->hsize_in = vf->width;//src_w; |
| if ((is_src_i(vf) && (enc == 0)) || |
| (is_src_i(vf) && is_mask(SC2_MEM_CPY))) |
| cfg->vsize_in = vf->height >> 1; |
| else |
| cfg->vsize_in = vf->height;//src_h; |
| /*input scope*/ |
| cfg->enc_win_bgn_h = 0; |
| cfg->enc_win_end_h = vf->width - 1; |
| cfg->enc_win_bgn_v = 0; |
| cfg->enc_win_end_v = cfg->vsize_in - 1; //vf->height - 1; |
| if (is_mask(SC2_ROT_WR) && (enc == 1)) |
| cfg->rot_en = 1; |
| else |
| cfg->rot_en = 0; |
| |
| dim_print("%s:win:<%d><%d><%d><%d><%d><%d>\n", |
| __func__, |
| cfg->enc_win_bgn_h, |
| cfg->hsize_in, |
| cfg->enc_win_bgn_v, |
| cfg->vsize_in, |
| cfg->enc_win_end_h, |
| cfg->enc_win_end_v); |
| /*for sc2*/ |
| if (pafd_ctr->fb.ver >= AFBCD_V5) |
| flg_v5 = true; |
| #ifdef MARK_SC2 |
| if (enc == 1) { |
| cfg->reg_init_ctrl = 1;//pip init frame flag |
| cfg->reg_pip_mode = 1;//pip open bit |
| cfg->hsize_bgnd = 1920;//hsize of background |
| cfg->vsize_bgnd = 1080;//hsize of background |
| } else { |
| cfg->reg_init_ctrl = 0;//pip init frame flag |
| cfg->reg_pip_mode = 0;//pip open bit |
| cfg->hsize_bgnd = 0;//hsize of background |
| cfg->vsize_bgnd = 0;//hsize of background |
| } |
| #endif |
| cfg->reg_init_ctrl = 0;//pip init frame flag |
| cfg->reg_pip_mode = 0;//pip open bit |
| cfg->hsize_bgnd = 0;//hsize of background |
| cfg->vsize_bgnd = 0;//hsize of background |
| cfg->reg_ram_comb = 0;//ram split bit open in di mult write case |
| |
| cfg->rev_mode = 0;//0:normal mode |
| cfg->def_color_0 = 0;//def_color |
| cfg->def_color_1 = 0;//def_color |
| cfg->def_color_2 = 0;//def_color |
| cfg->def_color_3 = 0;//def_color |
| cfg->force_444_comb = 0; |
| //cfg->rot_en = 0; |
| cfg->din_swt = 0; |
| |
| ori_afbce_cfg(cfg, &di_normal_regset, enc); |
| } |
| |
| static void afbce_update_level1(struct vframe_s *vf, |
| const struct reg_acc *op, |
| enum EAFBC_ENC enc) |
| { |
| const unsigned int *reg; |
| struct di_buf_s *di_buf; |
| unsigned int cur_mmu_used = 0; |
| #ifdef DBG_CRC |
| bool crc_right; |
| #endif |
| di_buf = (struct di_buf_s *)vf->private_data; |
| |
| if (!di_buf) { |
| pr_error("%s:1:no di buf\n", __func__); |
| return; |
| } |
| #ifdef DBG_CRC // DBG_TEST_CRC |
| crc_right = dbg_checkcrc(di_buf); |
| if (!crc_right) { |
| PR_INF("afbce[%d]s:t[%d:%d],inf[0x%lx],adr[0x%lx],vty[0x%x]\n", |
| enc, |
| di_buf->type, di_buf->index, |
| di_buf->afbc_adr, di_buf->afbct_adr, vf->type); |
| } |
| #endif |
| reg = ®_afbc_e[enc][0]; |
| |
| #ifdef MARK_SC2 |
| if (dim_dbg_is_cnt()) { |
| PR_INF("afbce[%d]up:t[%d:%d],inf[0x%lx],adr[0x%lx],vty[0x%x]\n", |
| enc, |
| di_buf->type, di_buf->index, |
| di_buf->afbc_adr, di_buf->afbct_adr, vf->type); |
| } |
| #endif |
| di_buf->flg_afbce_set = 1; |
| |
| //vf->compHeadAddr = di_buf->afbc_adr; |
| //vf->compBodyAddr = di_buf->nr_adr; |
| vf_set_for_com(di_buf); |
| |
| //head addr of compressed data |
| if (DIM_IS_IC_EF(T7)) { |
| op->wr(reg[EAFBCE_HEAD_BADDR], di_buf->afbc_adr >> 4); |
| op->wr(reg[EAFBCE_MMU_RMIF_CTRL4], di_buf->afbct_adr >> 4); |
| |
| } else { |
| op->wr(reg[EAFBCE_HEAD_BADDR], di_buf->afbc_adr); |
| op->wr(reg[EAFBCE_MMU_RMIF_CTRL4], di_buf->afbct_adr); |
| } |
| op->bwr(reg[EAFBCE_MMU_RMIF_SCOPE_X], cur_mmu_used, 0, 12); |
| op->bwr(reg[EAFBCE_MMU_RMIF_SCOPE_X], 0x1ffe, 16, 13); |
| op->bwr(reg[EAFBCE_MMU_RMIF_CTRL3], 0x1fff, 0, 13); |
| afbce_sw(enc, true); |
| } |
| |
| void dbg_afbce_update_level1(struct vframe_s *vf, |
| const struct reg_acc *op, |
| enum EAFBC_ENC enc) |
| { |
| afbce_update_level1(vf, op, enc); |
| } |
| |