osd: add the position check to avoid refresh logo when mode changed
authorBrian Zhu <brian.zhu@amlogic.com>
Wed, 29 Aug 2018 15:36:55 +0000 (23:36 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Fri, 31 Aug 2018 15:03:18 +0000 (08:03 -0700)
PD#171930: add the position check to avoid refresh logo when mode changed

Change-Id: I6760a70736209d89d6edeba40c6772d5f794208d
Signed-off-by: Brian Zhu <brian.zhu@amlogic.com>
drivers/amlogic/media/osd/osd_hw.c
drivers/amlogic/media/osd/osd_hw.h
drivers/amlogic/media/osd/osd_logo.c

index 1caeeb5..faf2f28 100644 (file)
@@ -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)
 {
        /*
index 8999cde..c3da6fa 100644 (file)
@@ -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);
index 49fc819..3bff38c 100644 (file)
@@ -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;