mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
di: request afbc when vpp use [1/2]
PD#SWPL-6033 Problem: afbc mode, when di bypass mode switch di path, will cause flashing Solution: when mode change, request hw afbc from vpp, when idle di use afbc, vpp need switch to none afbc mode, vf add VIDTYPE_PRE_DI_AFBC flag for vpp use. Verify: tl1 Change-Id: I4aaf96044249d5b79bdc627018f0c0714c85f941 Signed-off-by: Yong Qin <yong.qin@amlogic.com>
This commit is contained in:
@@ -131,7 +131,7 @@ static di_dev_t *de_devp;
|
||||
static dev_t di_devno;
|
||||
static struct class *di_clsp;
|
||||
|
||||
static const char version_s[] = "2019-0423a:src chg, post ready size is wrong";
|
||||
static const char version_s[] = "2019-06-20a: afbc switch from vpp";
|
||||
|
||||
static int bypass_state = 1;
|
||||
static int bypass_all;
|
||||
@@ -236,6 +236,7 @@ static int di_vscale_skip_count;
|
||||
static int di_vscale_skip_count_real;
|
||||
static int vpp_3d_mode;
|
||||
static bool det3d_en;
|
||||
|
||||
#ifdef DET3D
|
||||
static unsigned int det3d_mode;
|
||||
static void set3d_view(enum tvin_trans_fmt trans_fmt, struct vframe_s *vf);
|
||||
@@ -637,6 +638,14 @@ store_dbg(struct device *dev,
|
||||
afbc_sw(false);
|
||||
afbc_disable_flag = val > 0 ? 0:1;
|
||||
pr_info("afbc_disable_flag:%d\n", afbc_disable_flag);
|
||||
} else if (strncmp(buf, "reqafbc", 7) == 0) {
|
||||
val = di_requeset_afbc(true);
|
||||
di_pre_stru.wait_afbc = false;
|
||||
pr_info("request_afbc(%d)\n", val);
|
||||
} else if (strncmp(buf, "rlsafbc", 7) == 0) {
|
||||
val = di_requeset_afbc(false);
|
||||
di_pre_stru.wait_afbc = false;
|
||||
pr_info("rlease_afbc(%d)\n", val);
|
||||
} else {
|
||||
pr_info("DI no support cmd %s\n", buf);
|
||||
pr_info("supported cmd list:\n");
|
||||
@@ -656,7 +665,9 @@ store_dbg(struct device *dev,
|
||||
pr_info("\t recycle_buf\n");
|
||||
pr_info("\t recycle_post\n");
|
||||
pr_info("\t mem_map\n");
|
||||
pr_info("\t afbc_on 0/1\n");
|
||||
pr_info("\t reqafbc\n");
|
||||
pr_info("\t rlsafbc\n");
|
||||
pr_info("\n trigger val\n");
|
||||
}
|
||||
|
||||
kfree(buf_orig);
|
||||
@@ -3811,6 +3822,19 @@ module_param_named(pre_hsc_down_en, pre_hsc_down_en, bool, 0644);
|
||||
static int pre_hsc_down_width = 480;
|
||||
module_param_named(pre_hsc_down_width, pre_hsc_down_width, int, 0644);
|
||||
|
||||
|
||||
u32 di_requeset_afbc(u32 onoff)
|
||||
{
|
||||
u32 afbc_busy;
|
||||
|
||||
if (onoff)
|
||||
afbc_busy = di_request_afbc_hw(afbc_get_decnub(), true);
|
||||
else
|
||||
afbc_busy = di_request_afbc_hw(afbc_get_decnub(), false);
|
||||
|
||||
return afbc_busy;
|
||||
}
|
||||
|
||||
static unsigned char pre_de_buf_config(void)
|
||||
{
|
||||
struct di_buf_s *di_buf = NULL;
|
||||
@@ -3819,6 +3843,9 @@ static unsigned char pre_de_buf_config(void)
|
||||
unsigned char change_type = 0;
|
||||
bool bit10_pack_patch = false;
|
||||
unsigned int width_roundup = 2;
|
||||
u32 rls_timeout;
|
||||
u32 afbc_busy;
|
||||
u32 is_afbc_mode;
|
||||
|
||||
if (di_blocking || !atomic_read(&de_devp->mem_flag))
|
||||
return 0;
|
||||
@@ -3853,6 +3880,7 @@ static unsigned char pre_de_buf_config(void)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (di_pre_stru.di_inp_buf_next) {
|
||||
di_pre_stru.di_inp_buf = di_pre_stru.di_inp_buf_next;
|
||||
di_pre_stru.di_inp_buf_next = NULL;
|
||||
@@ -3880,13 +3908,15 @@ static unsigned char pre_de_buf_config(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
vframe = vf_get(VFM_NAME);
|
||||
|
||||
if (vframe == NULL)
|
||||
return 0;
|
||||
|
||||
vframe = vf_get(VFM_NAME);
|
||||
|
||||
/*for support compress from dec*/
|
||||
if (IS_COMP_MODE(vframe->type)) {
|
||||
if (IS_COMP_MODE(vframe->type) &&
|
||||
!is_bypass(vframe)) {
|
||||
is_afbc_mode = true;
|
||||
if (IS_VDIN_SRC(vframe->source_type)
|
||||
&& IS_I_SRC(vframe->type)) {
|
||||
vframe->width = vframe->compWidth;
|
||||
@@ -3907,11 +3937,38 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
|
||||
if (vframe->width > 10000 || vframe->height > 10000)
|
||||
di_pre_stru.bad_frame_throw_count = 10;
|
||||
di_pre_stru.bad_frame_throw_count--;
|
||||
|
||||
vf_put(vframe, VFM_NAME);
|
||||
vf_notify_provider(
|
||||
VFM_NAME, VFRAME_EVENT_RECEIVER_PUT, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* for afbc used by vpp and di, when di use it,
|
||||
* vpp need release afbc, waitting vpp release
|
||||
*/
|
||||
if (di_pre_stru.wait_afbc) {
|
||||
/*check time out and afbc release status*/
|
||||
rls_timeout =
|
||||
jiffies_to_msecs(jiffies_64 -
|
||||
di_pre_stru.afbc_rls_time);
|
||||
afbc_busy = di_requeset_afbc(true);
|
||||
if (afbc_busy && (rls_timeout < 80)) {
|
||||
vf_put(vframe, VFM_NAME);
|
||||
vf_notify_provider(
|
||||
VFM_NAME, VFRAME_EVENT_RECEIVER_PUT, NULL);
|
||||
pr_info("di: drop vframe (%d) t:%d\n",
|
||||
afbc_busy, rls_timeout);
|
||||
return 0;
|
||||
} else if (!afbc_busy) {
|
||||
/*afbc_busy = di_requeset_afbc(false);*/
|
||||
di_pre_stru.wait_afbc = 0;
|
||||
pr_info("di: afbc hw free\n");
|
||||
}
|
||||
}
|
||||
|
||||
bit10_pack_patch = (is_meson_gxtvbb_cpu() ||
|
||||
is_meson_gxl_cpu() ||
|
||||
is_meson_gxm_cpu());
|
||||
@@ -3983,6 +4040,9 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
|
||||
/* source change, when i mix p,force p as i*/
|
||||
if (change_type == 1 || (change_type == 2 &&
|
||||
di_pre_stru.cur_prog_flag == 1)) {
|
||||
|
||||
di_pre_stru.field_count_for_cont = 0;
|
||||
|
||||
if (di_pre_stru.di_mem_buf_dup_p) {
|
||||
/*avoid only 2 i field then p field*/
|
||||
if (
|
||||
@@ -4032,7 +4092,8 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
|
||||
di_buf->vframe->height,
|
||||
di_buf->vframe->source_type);
|
||||
|
||||
if (IS_COMP_MODE(di_buf->vframe->type)) {
|
||||
if (IS_COMP_MODE(di_buf->vframe->type) &&
|
||||
!is_bypass(vframe)) {
|
||||
if (IS_VDIN_SRC(di_buf->vframe->source_type) &&
|
||||
IS_I_SRC(di_buf->vframe->type)) {
|
||||
di_pre_stru.cur_width =
|
||||
@@ -4083,7 +4144,30 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
|
||||
mpeg2vdin_flag = 1;
|
||||
}
|
||||
#endif
|
||||
di_pre_stru.field_count_for_cont = 0;
|
||||
|
||||
/*
|
||||
* for afbc used by vpp and di, when di use it,
|
||||
* vpp need release afbc, waitting vpp release
|
||||
*/
|
||||
if (is_meson_tl1_cpu() || is_meson_sm1_cpu()) {
|
||||
/*compress mode and format changed*/
|
||||
if (!is_bypass(di_buf->vframe) &&
|
||||
di_pre_stru.source_change_flag &&
|
||||
IS_COMP_MODE(di_pre_stru.cur_inp_type)
|
||||
&& !afbc_is_free()
|
||||
&& !di_pre_stru.wait_afbc) {
|
||||
afbc_busy = di_requeset_afbc(true);
|
||||
vf_put(vframe, VFM_NAME);
|
||||
vf_notify_provider(VFM_NAME,
|
||||
VFRAME_EVENT_RECEIVER_PUT, NULL);
|
||||
recycle_vframe_type_pre(di_buf);
|
||||
di_pre_stru.afbc_rls_time = jiffies_64;
|
||||
di_pre_stru.wait_afbc = true;
|
||||
pr_info("di req afbc:%d\n", afbc_busy);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*di_pre_stru.field_count_for_cont = 0;*/
|
||||
} else if (di_pre_stru.cur_prog_flag == 0) {
|
||||
/* check if top/bot interleaved */
|
||||
if (change_type == 2)
|
||||
@@ -4410,6 +4494,12 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
|
||||
if (bypass_state == 0)
|
||||
di_buf->vframe->type |= VIDTYPE_PRE_INTERLACE;
|
||||
}
|
||||
|
||||
if (is_afbc_mode) {
|
||||
di_buf->vframe->type |= VIDTYPE_PRE_DI_AFBC;
|
||||
/*pr_info("vf type:0x%x\n", di_buf->vframe->type);*/
|
||||
}
|
||||
|
||||
if (is_bypass_post()) {
|
||||
if (bypass_post_state == 0)
|
||||
di_pre_stru.source_change_flag = 1;
|
||||
@@ -4438,6 +4528,7 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64));
|
||||
di_buf->post_proc_flag = 1;
|
||||
di_patch_post_update_mc_sw(DI_MC_SW_OTHER, mcpre_en);//en
|
||||
}
|
||||
|
||||
if ((di_pre_stru.di_mem_buf_dup_p == di_pre_stru.di_wr_buf) ||
|
||||
(di_pre_stru.di_chan2_buf_dup_p == di_pre_stru.di_wr_buf)) {
|
||||
pr_dbg("+++++++++++++++++++++++\n");
|
||||
@@ -5845,6 +5936,7 @@ static int process_post_vframe(void)
|
||||
int itmp;
|
||||
int ready_count = list_count(QUEUE_PRE_READY);
|
||||
bool check_drop = false;
|
||||
u32 di_afbc = false;
|
||||
|
||||
if (queue_empty(QUEUE_POST_FREE))
|
||||
return 0;
|
||||
@@ -5864,6 +5956,11 @@ static int process_post_vframe(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ready_di_buf->vframe->type & VIDTYPE_PRE_DI_AFBC) {
|
||||
di_afbc = 1;
|
||||
/*pr_info("di afbc mode 0x%x\n", ready_di_buf->vframe->type);*/
|
||||
}
|
||||
|
||||
if ((ready_di_buf->post_proc_flag) &&
|
||||
(ready_count >= buffer_keep_count)) {
|
||||
i = 0;
|
||||
@@ -5940,6 +6037,9 @@ static int process_post_vframe(void)
|
||||
VIDTYPE_VIU_SINGLE_PLANE |
|
||||
VIDTYPE_VIU_FIELD |
|
||||
VIDTYPE_PRE_INTERLACE;
|
||||
if (di_afbc)
|
||||
di_buf->vframe->type |=
|
||||
VIDTYPE_PRE_DI_AFBC;
|
||||
di_buf->vframe->width =
|
||||
di_buf->di_buf_dup_p[1]->width_bk;
|
||||
if (
|
||||
@@ -5966,6 +6066,10 @@ static int process_post_vframe(void)
|
||||
VIDTYPE_VIU_SINGLE_PLANE |
|
||||
VIDTYPE_VIU_FIELD |
|
||||
VIDTYPE_PRE_INTERLACE;
|
||||
if (di_afbc)
|
||||
di_buf->vframe->type |=
|
||||
VIDTYPE_PRE_DI_AFBC;
|
||||
|
||||
di_buf->vframe->height >>= 1;
|
||||
di_buf->vframe->canvas0Addr =
|
||||
di_buf->di_buf_dup_p[0]
|
||||
@@ -6113,6 +6217,10 @@ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
|
||||
|= VIDTYPE_VIU_FIELD;
|
||||
di_buf->vframe->type
|
||||
&= ~(VIDTYPE_TYPEMASK);
|
||||
if (di_afbc)
|
||||
di_buf->vframe->type |=
|
||||
VIDTYPE_PRE_DI_AFBC;
|
||||
|
||||
di_buf->vframe->process_fun
|
||||
= (post_wr_en && post_wr_support)?NULL:de_post_process;
|
||||
di_buf->process_fun_index
|
||||
@@ -6205,6 +6313,10 @@ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
|
||||
VIDTYPE_VIU_SINGLE_PLANE |
|
||||
VIDTYPE_VIU_FIELD |
|
||||
VIDTYPE_PRE_INTERLACE;
|
||||
if (di_afbc)
|
||||
di_buf->vframe->type |=
|
||||
VIDTYPE_PRE_DI_AFBC;
|
||||
|
||||
if (
|
||||
di_buf->di_buf_dup_p[0]->
|
||||
new_format_flag)
|
||||
@@ -6231,6 +6343,10 @@ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
|
||||
VIDTYPE_PROGRESSIVE |
|
||||
VIDTYPE_VIU_422 |
|
||||
VIDTYPE_VIU_SINGLE_PLANE;
|
||||
if (di_afbc)
|
||||
di_buf->vframe->type |=
|
||||
VIDTYPE_PRE_DI_AFBC;
|
||||
|
||||
if (
|
||||
(di_buf->di_buf_dup_p[0]->
|
||||
new_format_flag) ||
|
||||
@@ -6261,6 +6377,10 @@ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
|
||||
VIDTYPE_VIU_SINGLE_PLANE |
|
||||
VIDTYPE_VIU_FIELD |
|
||||
VIDTYPE_PRE_INTERLACE;
|
||||
if (di_afbc)
|
||||
di_buf->vframe->type |=
|
||||
VIDTYPE_PRE_DI_AFBC;
|
||||
|
||||
di_buf->vframe->height >>= 1;
|
||||
di_buf->vframe->width =
|
||||
di_buf->di_buf_dup_p[0]->width_bk;
|
||||
@@ -6910,6 +7030,8 @@ static void di_pre_trigger_work(struct di_pre_stru_s *pre_stru_p)
|
||||
Rd(DI_INTR_CTRL),
|
||||
(unsigned int)(cur_to_msecs() -
|
||||
di_pre_stru.irq_time[1]));
|
||||
pr_info("AFBCD0_MISC_CTRL=0x%x\n",
|
||||
RDMA_RD(VD1_AFBCD0_MISC_CTRL));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -7081,6 +7203,8 @@ static int di_receiver_event_fun(int type, void *data, void *arg)
|
||||
ddbg_mod_save(eDI_DBG_MOD_UNREGB, 0, 0);
|
||||
di_pre_stru.unreg_req_flag = 1;
|
||||
di_pre_stru.vdin_source = false;
|
||||
di_pre_stru.wait_afbc = false;
|
||||
/*di_requeset_afbc(false);*/
|
||||
trigger_pre_di_process(TRIGGER_PRE_BY_PROVERDER_UNREG);
|
||||
di_pre_stru.unreg_req_flag_cnt = 0;
|
||||
//wait 10ms:
|
||||
@@ -7453,6 +7577,7 @@ static vframe_t *di_vf_peek(void *arg)
|
||||
vframe_type_name[di_buf->type],
|
||||
di_buf->index, vframe_ret);
|
||||
#endif
|
||||
|
||||
return vframe_ret;
|
||||
}
|
||||
/*recycle the buffer for keeping buffer*/
|
||||
@@ -7585,6 +7710,7 @@ get_vframe:
|
||||
vframe_ret->early_process_fun(
|
||||
vframe_ret->private_data, vframe_ret);
|
||||
}
|
||||
|
||||
return vframe_ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -370,6 +370,8 @@ struct di_pre_stru_s {
|
||||
unsigned long irq_time[2];
|
||||
/* combing adaptive */
|
||||
struct combing_status_s *mtn_status;
|
||||
u64 afbc_rls_time;
|
||||
bool wait_afbc;
|
||||
};
|
||||
|
||||
struct di_post_stru_s {
|
||||
@@ -445,6 +447,8 @@ int get_di_video_peek_cnt(void);
|
||||
unsigned long get_di_reg_unreg_timeout_cnt(void);
|
||||
struct vframe_s **get_di_vframe_in(void);
|
||||
|
||||
extern s32 di_request_afbc_hw(u8 id, bool on);
|
||||
u32 di_requeset_afbc(u32 onoff);
|
||||
|
||||
/*---------------------*/
|
||||
|
||||
|
||||
@@ -870,7 +870,7 @@ const unsigned int reg_AFBC[AFBC_DEC_NUB][AFBC_REG_INDEX_NUB] = {
|
||||
|
||||
};
|
||||
|
||||
static enum eAFBC_DEC afbc_get_decnub(void)
|
||||
enum eAFBC_DEC afbc_get_decnub(void)
|
||||
{
|
||||
enum eAFBC_DEC sel_dec = eAFBC_DEC0;
|
||||
/* info from vlsi feijun
|
||||
@@ -1069,6 +1069,8 @@ u32 enable_afbc_input(struct vframe_s *vf)
|
||||
}
|
||||
RDMA_WR(reg[eAFBC_ENABLE], r);
|
||||
|
||||
/*pr_info("AFBC_ENABLE:0x%x\n", RDMA_RD(reg[eAFBC_ENABLE]));*/
|
||||
|
||||
r = 0x100;
|
||||
/* 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+
|
||||
@@ -1183,8 +1185,11 @@ static void afbcx_sw(bool on) /*g12a*/
|
||||
|
||||
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);
|
||||
RDMA_WR(reg_ctrl, tmp);
|
||||
/*0:vd1 to di 1:vd2 to di */
|
||||
@@ -1300,6 +1305,25 @@ void afbc_reg_sw(bool on)
|
||||
afbc_reg_unreg_flag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool afbc_is_free(void)
|
||||
{
|
||||
bool sts = 0;
|
||||
u32 afbc_num = afbc_get_decnub();
|
||||
|
||||
if (afbc_num == eAFBC_DEC0)
|
||||
sts = RDMA_RD_BITS(VD1_AFBCD0_MISC_CTRL, 8, 2);
|
||||
else
|
||||
sts = RDMA_RD_BITS(VD2_AFBCD1_MISC_CTRL, 8, 2);
|
||||
|
||||
if (sts)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void afbc_sw_trig(bool on)
|
||||
{
|
||||
|
||||
@@ -231,6 +231,8 @@ extern void di_patch_post_update_mc_sw(unsigned int cmd, bool on);
|
||||
extern void di_rst_protect(bool on);
|
||||
extern void di_pre_nr_wr_done_sel(bool on);
|
||||
extern void di_arb_sw(bool on);
|
||||
extern bool afbc_is_free(void);
|
||||
extern enum eAFBC_DEC afbc_get_decnub(void);
|
||||
|
||||
/*also see: dbg_mode_name*/
|
||||
enum eDI_DBG_MOD {
|
||||
|
||||
Reference in New Issue
Block a user