mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
osd: rdma write miss caused afbc mosaic [1/1]
PD#SWPL-4502 Problem: afbc mosaic when bandwidth is high, root cause is rdma write regs missed. Solution: 1. add vsync line detected, if rdma write nearly vsync, wait vsync needed 2. add rdma write detected, if rdma write missed wait vsync needed 3. add tl1/g12b afbc backup Verify: Locally on tl1 Change-Id: If4fd303c3808525fa44e1118742a3e26830323f5 Signed-off-by: Pengcheng Chen <pengcheng.chen@amlogic.com>
This commit is contained in:
committed by
Jianxin Pan
parent
62288af515
commit
616354015e
@@ -108,7 +108,7 @@ static int osd_afbc_dec_enable;
|
||||
static int ext_canvas_id[HW_OSD_COUNT];
|
||||
static int osd_extra_idx[HW_OSD_COUNT][2];
|
||||
static bool suspend_flag;
|
||||
|
||||
static u32 rdma_dt_cnt;
|
||||
static void osd_clone_pan(u32 index, u32 yoffset, int debug_flag);
|
||||
static void osd_set_dummy_data(u32 index, u32 alpha);
|
||||
|
||||
@@ -604,12 +604,15 @@ module_param(enable_vd_zorder, uint, 0664);
|
||||
static int vsync_enter_line_max;
|
||||
static int vsync_exit_line_max;
|
||||
static int vsync_line_threshold = 950;
|
||||
static int line_threshold = 90;
|
||||
MODULE_PARM_DESC(vsync_enter_line_max, "\n vsync_enter_line_max\n");
|
||||
module_param(vsync_enter_line_max, uint, 0664);
|
||||
MODULE_PARM_DESC(vsync_exit_line_max, "\n vsync_exit_line_max\n");
|
||||
module_param(vsync_exit_line_max, uint, 0664);
|
||||
MODULE_PARM_DESC(vsync_line_threshold, "\n vsync_line_threshold\n");
|
||||
module_param(vsync_line_threshold, uint, 0664);
|
||||
MODULE_PARM_DESC(line_threshold, "\n line_threshold\n");
|
||||
module_param(line_threshold, uint, 0664);
|
||||
|
||||
static unsigned int osd_filter_coefs_bicubic_sharp[] = {
|
||||
0x01fa008c, 0x01fa0100, 0xff7f0200, 0xfe7f0300,
|
||||
@@ -842,26 +845,37 @@ static void f2v_get_vertical_phase(
|
||||
static bool osd_hdr_on;
|
||||
#endif
|
||||
|
||||
static int cnt;
|
||||
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
|
||||
static int get_encp_line(void)
|
||||
{
|
||||
int enc_line = 0;
|
||||
int active_line_begin = 0;
|
||||
unsigned int reg = 0;
|
||||
|
||||
switch (osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3) {
|
||||
case 0:
|
||||
enc_line = (osd_reg_read(ENCL_INFO_READ) >> 16) & 0x1fff;
|
||||
reg = osd_reg_read(ENCL_INFO_READ);
|
||||
active_line_begin =
|
||||
osd_reg_read(ENCL_VIDEO_VAVON_BLINE);
|
||||
break;
|
||||
case 1:
|
||||
enc_line = (osd_reg_read(ENCI_INFO_READ) >> 16) & 0x1fff;
|
||||
reg = osd_reg_read(ENCI_INFO_READ);
|
||||
active_line_begin =
|
||||
osd_reg_read(ENCI_VFIFO2VD_LINE_TOP_START);
|
||||
break;
|
||||
case 2:
|
||||
enc_line = (osd_reg_read(ENCP_INFO_READ) >> 16) & 0x1fff;
|
||||
reg = osd_reg_read(ENCP_INFO_READ);
|
||||
active_line_begin =
|
||||
osd_reg_read(ENCP_VIDEO_VAVON_BLINE);
|
||||
break;
|
||||
case 3:
|
||||
enc_line = (osd_reg_read(ENCT_INFO_READ) >> 16) & 0x1fff;
|
||||
reg = osd_reg_read(ENCT_INFO_READ);
|
||||
active_line_begin =
|
||||
osd_reg_read(ENCT_VIDEO_VAVON_BLINE);
|
||||
break;
|
||||
}
|
||||
enc_line = (reg >> 16) & 0x1fff;
|
||||
enc_line -= active_line_begin;
|
||||
return enc_line;
|
||||
}
|
||||
#endif
|
||||
@@ -870,20 +884,7 @@ static int get_enter_encp_line(void)
|
||||
{
|
||||
int enc_line = 0;
|
||||
|
||||
switch (osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3) {
|
||||
case 0:
|
||||
enc_line = (osd_reg_read(ENCL_INFO_READ) >> 16) & 0x1fff;
|
||||
break;
|
||||
case 1:
|
||||
enc_line = (osd_reg_read(ENCI_INFO_READ) >> 16) & 0x1fff;
|
||||
break;
|
||||
case 2:
|
||||
enc_line = (osd_reg_read(ENCP_INFO_READ) >> 16) & 0x1fff;
|
||||
break;
|
||||
case 3:
|
||||
enc_line = (osd_reg_read(ENCT_INFO_READ) >> 16) & 0x1fff;
|
||||
break;
|
||||
}
|
||||
enc_line = get_encp_line();
|
||||
if (enc_line > vsync_enter_line_max)
|
||||
vsync_enter_line_max = enc_line;
|
||||
return enc_line;
|
||||
@@ -893,20 +894,7 @@ static int get_exit_encp_line(void)
|
||||
{
|
||||
int enc_line = 0;
|
||||
|
||||
switch (osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3) {
|
||||
case 0:
|
||||
enc_line = (osd_reg_read(ENCL_INFO_READ) >> 16) & 0x1fff;
|
||||
break;
|
||||
case 1:
|
||||
enc_line = (osd_reg_read(ENCI_INFO_READ) >> 16) & 0x1fff;
|
||||
break;
|
||||
case 2:
|
||||
enc_line = (osd_reg_read(ENCP_INFO_READ) >> 16) & 0x1fff;
|
||||
break;
|
||||
case 3:
|
||||
enc_line = (osd_reg_read(ENCT_INFO_READ) >> 16) & 0x1fff;
|
||||
break;
|
||||
}
|
||||
enc_line = get_encp_line();
|
||||
if (enc_line > vsync_exit_line_max)
|
||||
vsync_exit_line_max = enc_line;
|
||||
return enc_line;
|
||||
@@ -1268,11 +1256,10 @@ int osd_sync_request_render(u32 index, u32 yres,
|
||||
{
|
||||
int line;
|
||||
|
||||
cnt++;
|
||||
line = get_encp_line();
|
||||
osd_log_dbg2(MODULE_RENDER,
|
||||
"enter osd_sync_request_render:cnt=%d,encp line=%d\n",
|
||||
cnt, line);
|
||||
"enter osd_sync_request_render:encp line=%d\n",
|
||||
line);
|
||||
if (request->magic == FB_SYNC_REQUEST_RENDER_MAGIC_V1)
|
||||
osd_hw.hwc_enable = 0;
|
||||
else if (request->magic == FB_SYNC_REQUEST_RENDER_MAGIC_V2)
|
||||
@@ -1294,8 +1281,8 @@ int osd_sync_do_hwc(struct do_hwc_cmd_s *hwc_cmd)
|
||||
|
||||
line = get_encp_line();
|
||||
osd_log_dbg2(MODULE_RENDER,
|
||||
"enter osd_sync_do_hwc:cnt=%d,encp line=%d\n",
|
||||
cnt, line);
|
||||
"enter osd_sync_do_hwc:encp line=%d\n",
|
||||
line);
|
||||
fence_map = kzalloc(
|
||||
sizeof(struct osd_layers_fence_map_s), GFP_KERNEL);
|
||||
if (!fence_map)
|
||||
@@ -7575,6 +7562,7 @@ static void adjust_dst_position(void)
|
||||
|
||||
static int osd_setting_order(void)
|
||||
{
|
||||
#define RDMA_DETECT_REG VIU_OSD2_TCOLOR_AG2
|
||||
int i;
|
||||
struct layer_blend_reg_s *blend_reg;
|
||||
struct hw_osd_blending_s *blending;
|
||||
@@ -7583,6 +7571,7 @@ static int osd_setting_order(void)
|
||||
int line1;
|
||||
int line2;
|
||||
int vinfo_height;
|
||||
u32 val;
|
||||
|
||||
blending = &osd_blending;
|
||||
blend_reg = &(blending->blend_reg);
|
||||
@@ -7618,10 +7607,11 @@ static int osd_setting_order(void)
|
||||
line1 = get_enter_encp_line();
|
||||
vinfo_height = osd_hw.field_out_en ?
|
||||
(osd_hw.vinfo_height * 2) : osd_hw.vinfo_height;
|
||||
if (line1 >= vinfo_height) {
|
||||
/* if nearly vsync signal, wait vsync here */
|
||||
if (line1 >= vinfo_height * line_threshold / 100) {
|
||||
osd_log_dbg(MODULE_RENDER,
|
||||
"enter osd_setting_order:cnt=%d,encp line=%d\n",
|
||||
cnt, line1);
|
||||
"enter osd_setting_order:encp line=%d\n",
|
||||
line1);
|
||||
osd_wait_vsync_hw();
|
||||
line1 = get_enter_encp_line();
|
||||
}
|
||||
@@ -7692,14 +7682,21 @@ static int osd_setting_order(void)
|
||||
|
||||
set_blend_reg(blend_reg);
|
||||
save_blend_reg(blend_reg);
|
||||
/* append RDMA_DETECT_REG at last and detect if rdma missed some regs */
|
||||
rdma_dt_cnt++;
|
||||
VSYNCOSD_WR_MPEG_REG(RDMA_DETECT_REG, rdma_dt_cnt);
|
||||
spin_unlock_irqrestore(&osd_lock, lock_flags);
|
||||
line2 = get_exit_encp_line();
|
||||
osd_log_dbg2(MODULE_RENDER,
|
||||
"enter osd_setting_order:cnt=%d,encp line=%d\n",
|
||||
cnt, line2);
|
||||
if (line2 < line1)
|
||||
osd_log_info("osd line %d,%d\n", line1, line2);
|
||||
"enter osd_setting_order:encp line=%d\n",
|
||||
line2);
|
||||
osd_wait_vsync_hw();
|
||||
val = osd_reg_read(RDMA_DETECT_REG);
|
||||
/* if missed, need wait vsync */
|
||||
if (/*(line2 < line1) || */(val != rdma_dt_cnt)) {
|
||||
osd_wait_vsync_hw();
|
||||
osd_log_dbg(MODULE_RENDER, "osd line %d,%d\n", line1, line2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -8682,7 +8679,7 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe,
|
||||
osd_hw.afbc_regs_backup = 1;
|
||||
} else {
|
||||
osd_hw.afbc_force_reset = 1;
|
||||
osd_hw.afbc_regs_backup = 0;
|
||||
osd_hw.afbc_regs_backup = 1;
|
||||
data32 = osd_reg_read(MALI_AFBCD_TOP_CTRL);
|
||||
osd_reg_write(MALI_AFBCD_TOP_CTRL,
|
||||
data32 | 0x800000);
|
||||
|
||||
Reference in New Issue
Block a user