From d431ee6246cfdae84c8904ab08b873ca678ceb72 Mon Sep 17 00:00:00 2001 From: Jian Cao Date: Wed, 5 Dec 2018 15:31:30 +0800 Subject: [PATCH] osd: range of mouse is wrong under 4K mode [1/2] PD#SWPL-2551 Problem: range of mouse is wrong under 4K mode Solution: new cursor coordinate paras without using scale add osd_cursor_hw_no_scale() to deal with it. Verify: verified on P212 Change-Id: I1748df569b96522eb58dc00af862983bca17815a Signed-off-by: Jian Cao --- drivers/amlogic/media/osd/osd_fb.c | 12 ++- drivers/amlogic/media/osd/osd_hw.c | 145 +++++++++++++++++++++++++++++++++++++ drivers/amlogic/media/osd/osd_hw.h | 2 + 3 files changed, 157 insertions(+), 2 deletions(-) diff --git a/drivers/amlogic/media/osd/osd_fb.c b/drivers/amlogic/media/osd/osd_fb.c index 96768bd..ed2eebbc 100644 --- a/drivers/amlogic/media/osd/osd_fb.c +++ b/drivers/amlogic/media/osd/osd_fb.c @@ -1597,8 +1597,16 @@ static int osd_cursor(struct fb_info *fbi, struct fb_cursor *var) startx = fb_dev->osd_ctl.disp_start_x; starty = fb_dev->osd_ctl.disp_start_y; } - osd_cursor_hw(fbi->node, (s16)var->hot.x, (s16)var->hot.y, (s16)startx, - (s16)starty, fbi->var.xres, fbi->var.yres); + + if (osd_hw.hwc_enable) + osd_cursor_hw_no_scale(fbi->node, (s16)var->hot.x, + (s16)var->hot.y, (s16)startx, (s16)starty, + fbi->var.xres, fbi->var.yres); + else + osd_cursor_hw(fbi->node, (s16)var->hot.x, + (s16)var->hot.y, (s16)startx, (s16)starty, + fbi->var.xres, fbi->var.yres); + return 0; } diff --git a/drivers/amlogic/media/osd/osd_hw.c b/drivers/amlogic/media/osd/osd_hw.c index c3e4a1c..1d10d04 100644 --- a/drivers/amlogic/media/osd/osd_hw.c +++ b/drivers/amlogic/media/osd/osd_hw.c @@ -8791,6 +8791,151 @@ void osd_cursor_hw(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, u32 osd_w, osd_hw.dispdata[OSD2].y_start, osd_hw.dispdata[OSD2].y_end); } +void osd_cursor_hw_no_scale(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, + u32 osd_w, u32 osd_h) +{ + struct pandata_s disp_tmp; + struct vinfo_s *vinfo = NULL; + int w = 0, h = 0; + int w_diff = 0; + + if (index != 1) + return; + + osd_log_dbg2("cursor: x=%d, y=%d, x0=%d, y0=%d, w=%d, h=%d\n", + x, y, xstart, ystart, osd_w, osd_h); + + if (osd_hw.free_scale_mode[OSD1]) { + if (osd_hw.free_scale_enable[OSD1]) + memcpy(&disp_tmp, &osd_hw.cursor_dispdata[OSD1], + sizeof(struct pandata_s)); + else + memcpy(&disp_tmp, &osd_hw.dispdata[OSD1], + sizeof(struct pandata_s)); + } else + memcpy(&disp_tmp, &osd_hw.dispdata[OSD1], + sizeof(struct pandata_s)); + + if (osd_hw.field_out_en) { + disp_tmp.y_start *= 2; + disp_tmp.y_end *= 2; + } + + if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) { + vinfo = get_current_vinfo(); + + if ((vinfo == NULL) || (vinfo->mode == VMODE_INIT_NULL)) + return; + + w = vinfo->width; + h = vinfo->height; + + x = w - x; + y = h - y; + } + + x += xstart; + y += ystart; + + if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) { + if (osd_w >= osd_h) + w_diff = osd_w - osd_h; + else + w_diff = 0; + osd_hw.pandata[OSD2].x_start = w_diff; + osd_hw.pandata[OSD2].x_end = osd_w - 1; + osd_hw.pandata[OSD2].y_start = 0; + osd_hw.pandata[OSD2].y_end = osd_h - 1; + x -= osd_w; + y -= osd_h; + osd_log_dbg2("x=%d,y=%d\n", x, y); + } + + + /* + * Use pandata to show a partial cursor when it is at the edge because + * the registers can't have negative values and because we need to + * manually clip the cursor when it is past the edge. The edge is + * hardcoded to the OSD0 area. + */ + osd_hw.dispdata[OSD2].x_start = x; + osd_hw.dispdata[OSD2].y_start = y; + if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) { + if (x < disp_tmp.x_start) { + /* if negative position, set osd x pan. */ + if ((disp_tmp.x_start - x) < osd_w) { + osd_hw.pandata[OSD2].x_start = + w_diff; + osd_hw.pandata[OSD2].x_end = + osd_w - 1 - (disp_tmp.x_start - x); + } + /* set osd x to disp_tmp.x_start */ + osd_hw.dispdata[OSD2].x_start = disp_tmp.x_start; + } + if (y < disp_tmp.y_start) { + /* if negative position, set osd y pan. */ + if ((disp_tmp.y_start - y) < osd_h) { + osd_hw.pandata[OSD2].y_start = 0; + osd_hw.pandata[OSD2].y_end = + osd_h - 1 - (disp_tmp.y_start - y); + } + /* set osd y to disp_tmp.y_start */ + osd_hw.dispdata[OSD2].y_start = disp_tmp.y_start; + } + } else { + if (x < disp_tmp.x_start) { + /* if negative position, set osd to 0,y and pan. */ + if ((disp_tmp.x_start - x) < osd_w) { + osd_hw.pandata[OSD2].x_start = + disp_tmp.x_start - x; + osd_hw.pandata[OSD2].x_end = osd_w - 1; + } + osd_hw.dispdata[OSD2].x_start = 0; + } else { + osd_hw.pandata[OSD2].x_start = 0; + if (x + osd_w > disp_tmp.x_end) { + /* + * if past positive edge, + * set osd to inside of the edge and pan. + */ + if (x < disp_tmp.x_end) + osd_hw.pandata[OSD2].x_end = + disp_tmp.x_end - x; + } else + osd_hw.pandata[OSD2].x_end = osd_w - 1; + } + if (y < disp_tmp.y_start) { + if ((disp_tmp.y_start - y) < osd_h) { + osd_hw.pandata[OSD2].y_start = + disp_tmp.y_start - y; + osd_hw.pandata[OSD2].y_end = osd_h - 1; + } + osd_hw.dispdata[OSD2].y_start = 0; + } else { + osd_hw.pandata[OSD2].y_start = 0; + if (y + osd_h > disp_tmp.y_end) { + if (y < disp_tmp.y_end) + osd_hw.pandata[OSD2].y_end = + disp_tmp.y_end - y; + } else + osd_hw.pandata[OSD2].y_end = osd_h - 1; + } + } + + if (osd_hw.field_out_en) + osd_hw.dispdata[OSD2].y_start /= 2; + + osd_hw.dispdata[OSD2].x_end = osd_hw.dispdata[OSD2].x_start + + osd_hw.pandata[OSD2].x_end - osd_hw.pandata[OSD2].x_start; + osd_hw.dispdata[OSD2].y_end = osd_hw.dispdata[OSD2].y_start + + osd_hw.pandata[OSD2].y_end - osd_hw.pandata[OSD2].y_start; + add_to_update_list(OSD2, OSD_COLOR_MODE); + add_to_update_list(OSD2, DISP_GEOMETRY); + osd_log_dbg2("dispdata: %d,%d,%d,%d\n", + osd_hw.dispdata[OSD2].x_start, osd_hw.dispdata[OSD2].x_end, + osd_hw.dispdata[OSD2].y_start, osd_hw.dispdata[OSD2].y_end); +} + void osd_suspend_hw(void) { if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { diff --git a/drivers/amlogic/media/osd/osd_hw.h b/drivers/amlogic/media/osd/osd_hw.h index 4b2680f..ee15fcb 100644 --- a/drivers/amlogic/media/osd/osd_hw.h +++ b/drivers/amlogic/media/osd/osd_hw.h @@ -128,6 +128,8 @@ extern int osd_sync_do_hwc(struct do_hwc_cmd_s *hwc_cmd); extern s64 osd_wait_vsync_event(void); extern void osd_cursor_hw(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, u32 osd_w, u32 osd_h); +extern void osd_cursor_hw_no_scale(u32 index, s16 x, s16 y, s16 xstart, + s16 ystart, u32 osd_w, u32 osd_h); extern void osd_init_scan_mode(void); extern void osd_suspend_hw(void); extern void osd_resume_hw(void); -- 2.7.4