blob: 2da60d846e491a7bf45d86f3ee06d9a555753cb0 [file] [log] [blame]
// 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 &reg_afbc[eidx][0];
return &reg_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 &reg_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 &reg_afbc[pafd_ctr->fb.pre_dec][0];
return &reg_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 = &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 = &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 = &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 = &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);
}