From 54ef4b2fe0e3a8ade787720a16f541f094421ca5 Mon Sep 17 00:00:00 2001 From: Brian Zhu Date: Wed, 29 Aug 2018 23:36:55 +0800 Subject: [PATCH] osd: add the position check to avoid refresh logo when mode changed PD#171930: add the position check to avoid refresh logo when mode changed Change-Id: I6760a70736209d89d6edeba40c6772d5f794208d Signed-off-by: Brian Zhu --- drivers/amlogic/media/osd/osd_hw.c | 87 ++++++++++++++++++++++++++++++++++++ drivers/amlogic/media/osd/osd_hw.h | 6 +++ drivers/amlogic/media/osd/osd_logo.c | 55 ++++++++++++++++++----- 3 files changed, 138 insertions(+), 10 deletions(-) diff --git a/drivers/amlogic/media/osd/osd_hw.c b/drivers/amlogic/media/osd/osd_hw.c index 1caeeb5..faf2f28 100644 --- a/drivers/amlogic/media/osd/osd_hw.c +++ b/drivers/amlogic/media/osd/osd_hw.c @@ -2436,6 +2436,93 @@ void osd_set_window_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1) mutex_unlock(&osd_mutex); } + +s32 osd_get_position_from_reg( + u32 index, + s32 *src_x_start, s32 *src_x_end, + s32 *src_y_start, s32 *src_y_end, + s32 *dst_x_start, s32 *dst_x_end, + s32 *dst_y_start, s32 *dst_y_end) +{ + struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index]; + u32 data32 = 0x0; + + if (index >= OSD4) + return -1; + + if (!src_x_start || !src_x_end || !src_y_start || !src_y_end + || !dst_y_start || !dst_x_end || !dst_y_start || !dst_y_end) + return -1; + + data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w1); + *src_x_start = data32 & 0x1fff; + *src_x_end = (data32 >> 16) & 0x1fff; + + data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w2); + *src_y_start = data32 & 0x1fff; + *src_y_end = (data32 >> 16) & 0x1fff; + + if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) { + data32 = osd_reg_read(osd_reg->osd_sc_ctrl0); + if ((data32 & 0xc) == 0xc) { + data32 = osd_reg_read(osd_reg->osd_sco_h_start_end); + *dst_x_end = data32 & 0x1fff; + *dst_x_start = (data32 >> 16) & 0x1fff; + + data32 = osd_reg_read(osd_reg->osd_sco_v_start_end); + *dst_y_end = data32 & 0x1fff; + *dst_y_start = (data32 >> 16) & 0x1fff; + } else { + data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w3); + *dst_x_start = data32 & 0x1fff; + *dst_x_end = (data32 >> 16) & 0x1fff; + + data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w4); + *dst_y_start = data32 & 0x1fff; + *dst_y_end = (data32 >> 16) & 0x1fff; + } + } else if (osd_hw.osd_meson_dev.osd_ver == OSD_NORMAL) { + s32 scaler_index = -1; + + osd_reg = &hw_osd_reg_array[0]; + data32 = osd_reg_read(osd_reg->osd_sc_ctrl0); + + if ((data32 & 3) == 0) + scaler_index = 0; + else if ((data32 & 3) == 1) + scaler_index = 1; + + if (((data32 & 0xc) == 0xc) && ((u32)scaler_index == index)) { + data32 = osd_reg_read(osd_reg->osd_sco_h_start_end); + *dst_x_end = data32 & 0x1fff; + *dst_x_start = (data32 >> 16) & 0x1fff; + + data32 = osd_reg_read(osd_reg->osd_sco_v_start_end); + *dst_y_end = data32 & 0x1fff; + *dst_y_start = (data32 >> 16) & 0x1fff; + } else { + osd_reg = &hw_osd_reg_array[index]; + data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w3); + *dst_x_start = data32 & 0x1fff; + *dst_x_end = (data32 >> 16) & 0x1fff; + + data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w4); + *dst_y_start = data32 & 0x1fff; + *dst_y_end = (data32 >> 16) & 0x1fff; + } + } else if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) { + osd_reg = &hw_osd_reg_array[0]; + data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w3); + *dst_x_start = data32 & 0x1fff; + *dst_x_end = (data32 >> 16) & 0x1fff; + + data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w4); + *dst_y_start = data32 & 0x1fff; + *dst_y_end = (data32 >> 16) & 0x1fff; + } + return 0; +} + void osd_get_block_windows_hw(u32 index, u32 *windows) { /* diff --git a/drivers/amlogic/media/osd/osd_hw.h b/drivers/amlogic/media/osd/osd_hw.h index 8999cde..c3da6fa 100644 --- a/drivers/amlogic/media/osd/osd_hw.h +++ b/drivers/amlogic/media/osd/osd_hw.h @@ -88,6 +88,12 @@ extern void osd_get_window_axis_hw(u32 index, s32 *x0, s32 *y0, s32 *x1, s32 *y1); extern void osd_set_window_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1); extern void osd_set_scale_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1); +extern s32 osd_get_position_from_reg( + u32 index, + s32 *src_x_start, s32 *src_x_end, + s32 *src_y_start, s32 *src_y_end, + s32 *dst_x_start, s32 *dst_x_end, + s32 *dst_y_start, s32 *dst_y_end); extern void osd_get_block_windows_hw(u32 index, u32 *windows); extern void osd_set_block_windows_hw(u32 index, u32 *windows); extern void osd_get_block_mode_hw(u32 index, u32 *mode); diff --git a/drivers/amlogic/media/osd/osd_logo.c b/drivers/amlogic/media/osd/osd_logo.c index 49fc819..3bff38c 100644 --- a/drivers/amlogic/media/osd/osd_logo.c +++ b/drivers/amlogic/media/osd/osd_logo.c @@ -184,32 +184,67 @@ int set_osd_logo_freescaler(void) { const struct vinfo_s *vinfo; u32 index = logo_info.index; + s32 src_x_start = 0, src_x_end = 0; + s32 src_y_start = 0, src_y_end = 0; + s32 dst_x_start = 0, dst_x_end = 0; + s32 dst_y_start = 0, dst_y_end = 0; + s32 target_x_end = 0, target_y_end = 0; if (logo_info.loaded == 0) return 0; + if (osd_get_logo_index() != logo_info.index) { pr_info("logo changed, return!\n"); return -1; } + if ((osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) && (index >= 1)) return -1; + if (osd_get_position_from_reg( + index, + &src_x_start, &src_x_end, + &src_y_start, &src_y_end, + &dst_x_start, &dst_x_end, + &dst_y_start, &dst_y_end)) + return -1; + + vinfo = get_current_vinfo(); + if (vinfo) { + target_x_end = vinfo->width - 1; + target_y_end = vinfo->height - 1; + } else { + target_x_end = 1919; + target_y_end = 1079; + } + if ((src_x_start == 0) + && (src_x_end == (logo_info.fb_width - 1)) + && (src_y_start == 0) + && (src_y_end == (logo_info.fb_height - 1)) + && (dst_x_start == 0) + && (dst_x_end == target_x_end) + && (dst_y_start == 0) + && (dst_y_end == target_y_end)) + return 0; + + if (vinfo) + pr_info("outputmode changed to %s, reset osd%d, (%d, %d, %d, %d) -> (%d, %d, %d, %d)\n", + vinfo->name, index, + dst_x_start, dst_y_start, dst_x_end, dst_y_end, + 0, 0, target_x_end, target_y_end); + else + pr_info("outputmode changed to NULL, reset osd%d, (%d, %d, %d, %d) -> (%d, %d, %d, %d)\n", + index, + dst_x_start, dst_y_start, dst_x_end, dst_y_end, + 0, 0, target_x_end, target_y_end); + osd_set_free_scale_mode_hw(index, 1); osd_set_free_scale_enable_hw(index, 0); - osd_set_free_scale_axis_hw(index, 0, 0, logo_info.fb_width - 1, logo_info.fb_height - 1); osd_update_disp_axis_hw(index, 0, logo_info.fb_width - 1, 0, logo_info.fb_height - 1, 0, 0, 0); - vinfo = get_current_vinfo(); - if (vinfo) { - pr_info("outputmode changed to %s, reset osd%d scaler\n", - vinfo->name, index); - osd_set_window_axis_hw(index, 0, 0, - (vinfo->width - 1), (vinfo->height - 1)); - } else { - osd_set_window_axis_hw(index, 0, 0, 1919, 1079); - } + osd_set_window_axis_hw(index, 0, 0, target_x_end, target_y_end); osd_set_free_scale_enable_hw(index, 0x10001); osd_enable_hw(index, 1); return 0; -- 2.7.4