From ffc48c38038b01e76e47d05556d97d582a8cfd26 Mon Sep 17 00:00:00 2001 From: pengcheng chen Date: Tue, 20 Nov 2018 09:42:44 +0800 Subject: [PATCH] osd: add viu2 support for tl1 [1/1] PD#172587 Problem: add viu2 support for tl1. Solution: add viu2 support for tl1. Verify: verified by x301 Change-Id: Ie728f6ee7e0c4c4062e5e12e3d80515d99d020f8 Signed-off-by: pengcheng chen ff60d15 osd: calc osd parameters used num/den replace left/right shift [1/1] 481d4f2 osd: set hdr size according osd blend0 out size [1/1] 42b54ce osd: afbc decode error when loop viu1 to vdin [1/1] 91bda20 osd: fix afbc decoder error caused flicker in display [1/1] 799ba4c osd: fix hotplug hdmi causes system crash [1/1] e9fadfe5 osd: fix osd afbc can't display on android5.1 [1/1] 1f8aa33 osd: frame just display on half screen [1/1] 7bcfa18 osd: set osd1 scaler before osd blend [1/1] 6913eaa osd: osd display color abnormal when run drm [1/1] 6862fb2 osd: add viu2 fence support [1/1] f59b7a6 drm: a113d support drm issue [1/1] 50557a1 osd: reset afbcd flag when convert format value [1/1] cfbcb3d osd: fix buidroot compile error issue [1/1] 6163540 osd: rdma write miss caused afbc mosaic [1/1] 032a712 osd: fix display frame offset caused osd display abnormal [1/1] 2c1269e osd: osd: recovey mode always blank [1/1] 3be570b osd: osd: reserve vs_ctrl bit for VPP [1/1] 40bfe97 osd: add viu2 support for tl1 [1/1] osd: osd: reserve vs_ctrl bit for VPP [1/1] PD#172587 Problem: reserve vs_ctrl bit for VPP Solution: Avoid operating VPP_OFIFO_SIZE bit19 on OSD code Verify: verified on t962x2_x301 Change-Id: Ic450d6f64e2349d97d02f0802058b4031564fea4 Signed-off-by: Jian Cao osd: osd: recovey mode always blank [1/1] PD#TV-1287 Problem: recovey mode always blank Solution: set right condition to enable free_scale Verify: verified on P321 board Change-Id: I2f70b9c5436b30156f157a3297a11a2ef1cfec67 Signed-off-by: Jian Cao osd: fix display frame offset caused osd display abnormal [1/1] PD#OTT-1663 Problem: display frame offset caused osd display abnormal Solution: remove unnecessary blend dst_data adjust Verify: Locally on raven Change-Id: I38b97f6da750f5edea97416b4d7fc0172dea7466 Signed-off-by: Pengcheng Chen 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 osd: fix buidroot compile error issue [1/1] PD#SWPL-4502 Problem: buidlroot compile error Solution: fix buidroot compile error issue Verify: buildroot make linux-build Change-Id: I0277c2b3f439946ab680f4c34f30c16e31ea6034 Signed-off-by: Pengcheng Chen osd: reset afbcd flag when convert format value [1/1] PD#SWPL-5185 Problem: "fence color format error 28" when test weston-simple-egl Solution: reset afbcd flag when convert format value Verify: Locally on g12b_w400 Change-Id: I81a9394288026bc596f6b3438cec72ceaad7749f Signed-off-by: Jian Cao drm: a113d support drm issue [1/1] PD#SH-397 Problem: use modetest to test A113D DRM function, displaying is incorrect Solution: add linear addr config for a113d drm mode Verify: verified on s400 Change-Id: Id6a2c6ad94bc0148815076561d9dc2ae8ded6884 Signed-off-by: Dezhi Kong osd: add viu2 fence support [1/1] PD#SWPL-6384 Problem: viu2 not support fence Solution: add viu2 fence support. Verify: test pass on tl1 Change-Id: I94a5e483c88cace79b7386bb918c203ada6b8274 Signed-off-by: Pengcheng Chen osd: osd display color abnormal when run drm [1/1] PD#SWPL-6867 Problem: osd dispaly color abnormal because osd enable not update. Solution: update osd enalbe flag in drm process. Verify: Verified u212 Change-Id: I1c2e8b62d9d5af203c95d3d0ac940fb512dd8e5e Signed-off-by: Pengcheng Chen osd: set osd1 scaler before osd blend [1/1] PD#SWPL-6596 Problem: bring up osd for TM2 Solution: set osd1 scaler before osd blend Verify: Verified on T962e2_ab319 Change-Id: I9e7d5fa83b2edc8e9359371695ea46fa3b39e09c Signed-off-by: Pengcheng Chen osd: frame just display on half screen [1/1] PD#SWPL-7039 Problem: bring up osd for TM2 frame just display on half screen Solution: fix field_out_en value from array Verify: Verified on T962e2_ab319 Change-Id: Id07f3d813242f031125fcac11d3fa05205895448 Signed-off-by: Jian Cao osd: fix osd afbc can't display on android5.1 [1/1] PD#SWPL-6869 Problem: afbc can't display with android5.1, because blank enable called before afbc set, which make osd enable not updated and afbc not enable when hwc post frame Solution: if mali afbc enable, call osd enable. Verify: verified on x301 Change-Id: I1d727a586a66c6e7848d09dfb5c5b74ff7a2e3e6 Signed-off-by: Shuide Chen osd: fix hotplug hdmi causes system crash [1/1] PD#SWPL-7009 Problem: hotplug hdmi causes system crash when unplug hdmi display mode is null, hwc hasn't received event and post frame normal but osd vsync lost, which caused wait hw vsync timeout(1s), and fd leak. Solution: when process every frame, if display mode is null, exit frame process just process fence. Verify: verified on Raven, franklin Change-Id: Icbe7cd76776e46a6ed79c6cee3ea05772cc5f9d2 Signed-off-by: Pengcheng Chen osd: fix afbc decoder error caused flicker in display [1/1] PD#OTT-3000 Problem: afbc decoder error caused flicker in display. Solution: close osd prefetch. Verify: Verified with raven Change-Id: I44356c028b41e251f7a98b5e931b2cbd583b0829 Signed-off-by: Pengcheng Chen osd: afbc decode error when loop viu1 to vdin [1/1] PD#TV-5024 Problem: afbc decode error when loop viu1 to vdin. Solution: set osd hold line to max if vinfo is dummy_panel Verify: Tl1 X301 Change-Id: I0ebb312d381accb1890233164f071a095310d2f1 Signed-off-by: Pengcheng Chen osd: set hdr size according osd blend0 out size [1/1] PD#IPTV-2395 Problem: osd last line have abnormal data Solution: set hdr size according osd blend0 out size Verify: Verfied on u212 Change-Id: Iad738b16fce066270c78213f1b696a802e1b8da6 Signed-off-by: Pengcheng Chen osd: calc osd parameters used num/den replace left/right shift [1/1] PD#OTT-3615 Problem: a line on the right displayed Solution: calc osd parameters used num/den replace left/right shift Verify: Verfied on u212 Change-Id: If59d9de0bb3c525d2b67d05ec449d458fbbcdfe2 Signed-off-by: Pengcheng Chen --- drivers/amlogic/media/osd/osd.h | 28 +- drivers/amlogic/media/osd/osd_debug.c | 6 +- drivers/amlogic/media/osd/osd_drm.c | 12 +- drivers/amlogic/media/osd/osd_fb.c | 202 +-- drivers/amlogic/media/osd/osd_hw.c | 2752 +++++++++++++++++++++------------ drivers/amlogic/media/osd/osd_hw.h | 30 +- drivers/amlogic/media/osd/osd_reg.h | 2 +- 7 files changed, 1868 insertions(+), 1164 deletions(-) diff --git a/drivers/amlogic/media/osd/osd.h b/drivers/amlogic/media/osd/osd.h index 8003c51..b5fdc53 100644 --- a/drivers/amlogic/media/osd/osd.h +++ b/drivers/amlogic/media/osd/osd.h @@ -106,7 +106,6 @@ enum color_index_e { #define FBIOPUT_OSD_CURSOR \ _IOWR(FB_IOC_MAGIC, 0x0, struct fb_cursor_user) - /* OSD color definition */ #define KEYCOLOR_FLAG_TARGET 1 #define KEYCOLOR_FLAG_ONHOLD 2 @@ -114,6 +113,8 @@ enum color_index_e { #define HW_OSD_COUNT 4 #define OSD_BLEND_LAYERS 4 +#define VIU_COUNT 2 + /* OSD block definition */ #define HW_OSD_BLOCK_COUNT 4 #define HW_OSD_BLOCK_REG_COUNT (HW_OSD_BLOCK_COUNT*2) @@ -509,6 +510,7 @@ struct osd_device_data_s { u32 vpp_fifo_len; u32 dummy_data; u32 has_viu2; + u32 osd0_sc_independ; u32 viu1_osd_count; u32 viu2_index; struct clk *vpu_clkc; @@ -611,8 +613,10 @@ struct hw_osd_blending_s { bool osd1_freescale_disable; u32 vinfo_width; u32 vinfo_height; - u32 screen_ratio_w; - u32 screen_ratio_h; + u32 screen_ratio_w_num; + u32 screen_ratio_w_den; + u32 screen_ratio_h_num; + u32 screen_ratio_h_den; struct dispdata_s dst_data; struct layer_blend_reg_s blend_reg; struct layer_blend_s layer_blend; @@ -707,7 +711,7 @@ struct hw_para_s { u32 scan_mode[HW_OSD_COUNT]; u32 order[HW_OSD_COUNT]; u32 premult_en[HW_OSD_COUNT]; - struct display_flip_info_s disp_info; + struct display_flip_info_s disp_info[VIU_COUNT]; struct osd_3d_mode_s mode_3d[HW_OSD_COUNT]; u32 updated[HW_OSD_COUNT]; /* u32 block_windows[HW_OSD_COUNT][HW_OSD_BLOCK_REG_COUNT]; */ @@ -722,7 +726,7 @@ struct hw_para_s { int use_h_filter_mode[HW_OSD_COUNT]; int use_v_filter_mode[HW_OSD_COUNT]; struct hw_list_s reg[HW_REG_INDEX_MAX]; - u32 field_out_en; + u32 field_out_en[VIU_COUNT]; u32 scale_workaround; u32 fb_for_4k2k; u32 antiflicker_mode; @@ -734,21 +738,21 @@ struct hw_para_s { struct osd_device_data_s osd_meson_dev; u32 urgent[HW_OSD_COUNT]; u32 osd_deband_enable; - u32 osd_fps; - u32 osd_fps_start; + u32 osd_fps[VIU_COUNT]; + u32 osd_fps_start[VIU_COUNT]; u32 osd_display_debug; ulong screen_base[HW_OSD_COUNT]; ulong screen_size[HW_OSD_COUNT]; ulong screen_base_backup[HW_OSD_COUNT]; ulong screen_size_backup[HW_OSD_COUNT]; - u32 vinfo_width; - u32 vinfo_height; + u32 vinfo_width[VIU_COUNT]; + u32 vinfo_height[VIU_COUNT]; u32 fb_drvier_probe; u32 afbc_force_reset; u32 afbc_regs_backup; u32 afbc_status_err_reset; u32 afbc_use_latch; - u32 hwc_enable; + u32 hwc_enable[VIU_COUNT]; u32 osd_use_latch[HW_OSD_COUNT]; u32 hw_cursor_en; u32 hw_rdma_en; @@ -761,8 +765,8 @@ struct hw_para_s { u32 viu_type; u32 line_n_rdma; struct hw_debug_s osd_debug; - int out_fence_fd; + int out_fence_fd[VIU_COUNT]; int in_fd[HW_OSD_COUNT]; - struct osd_fence_fun_s osd_fence[2]; + struct osd_fence_fun_s osd_fence[VIU_COUNT][2]; }; #endif /* _OSD_H_ */ diff --git a/drivers/amlogic/media/osd/osd_debug.c b/drivers/amlogic/media/osd/osd_debug.c index 701da24..eb1dd8d 100644 --- a/drivers/amlogic/media/osd/osd_debug.c +++ b/drivers/amlogic/media/osd/osd_debug.c @@ -66,7 +66,9 @@ static void osd_debug_dump_value(void) osd_log_info("--- OSD ---\n"); osd_log_info("bot_type: %d\n", hwpara->bot_type); - osd_log_info("field_out_en: %d\n", hwpara->field_out_en); + osd_log_info("field_out_en: %d\n", hwpara->field_out_en[VIU1]); + if (osd_hw.osd_meson_dev.has_viu2) + osd_log_info("field_out_en: %d\n", hwpara->field_out_en[VIU2]); if (hwpara->osd_meson_dev.osd_ver == OSD_HIGH_ONE) { struct hw_osd_blending_s *blend_para = NULL; @@ -345,7 +347,7 @@ static void osd_debug_dump_register_all(void) if (osd_hw.osd_meson_dev.cpu_id >= __MESON_CPU_MAJOR_ID_G12B) { if (osd_hw.osd_meson_dev.has_viu2 && - osd_hw.powered[OSD4]) { + osd_hw.powered[osd_hw.osd_meson_dev.viu2_index]) { reg = VPP2_MISC; osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); diff --git a/drivers/amlogic/media/osd/osd_drm.c b/drivers/amlogic/media/osd/osd_drm.c index d2cb627..3732b20 100644 --- a/drivers/amlogic/media/osd/osd_drm.c +++ b/drivers/amlogic/media/osd/osd_drm.c @@ -563,11 +563,13 @@ static ssize_t osd_hwc_enable_read_file(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { + struct seq_file *s = file->private_data; + int osd_id = *(int *)s; char buf[128]; ssize_t len; unsigned int hwc_enable = 0; - osd_get_hwc_enable(&hwc_enable); + osd_get_hwc_enable(osd_id, &hwc_enable); len = snprintf(buf, 128, "%d\n", hwc_enable); return simple_read_from_buffer(userbuf, count, ppos, buf, len); } @@ -576,6 +578,8 @@ static ssize_t osd_hwc_enable_write_file(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos) { + struct seq_file *s = file->private_data; + int osd_id = *(int *)s; char buf[128]; unsigned int hwc_enable = 0; int ret = 0; @@ -586,7 +590,7 @@ static ssize_t osd_hwc_enable_write_file(struct file *file, buf[count] = 0; ret = kstrtoint(buf, 0, &hwc_enable); osd_log_info("hwc enable: %d\n", hwc_enable); - osd_set_hwc_enable(hwc_enable); + osd_set_hwc_enable(osd_id, hwc_enable); return count; } @@ -594,6 +598,8 @@ static ssize_t osd_do_hwc_write_file(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos) { + struct seq_file *s = file->private_data; + int osd_id = *(int *)s; char buf[128]; unsigned int do_hwc = 0; int ret = 0; @@ -605,7 +611,7 @@ static ssize_t osd_do_hwc_write_file(struct file *file, ret = kstrtoint(buf, 0, &do_hwc); osd_log_info("do_hwc: %d\n", do_hwc); if (do_hwc) - osd_do_hwc(); + osd_do_hwc(osd_id); return count; } diff --git a/drivers/amlogic/media/osd/osd_fb.c b/drivers/amlogic/media/osd/osd_fb.c index 71a881e2..81c3648 100644 --- a/drivers/amlogic/media/osd/osd_fb.c +++ b/drivers/amlogic/media/osd/osd_fb.c @@ -684,19 +684,24 @@ static int osd_check_var(struct fb_var_screeninfo *var, struct fb_info *info) static int osd_set_par(struct fb_info *info) { - const struct vinfo_s *vinfo; + const struct vinfo_s *vinfo = NULL; struct osd_fb_dev_s *fbdev = (struct osd_fb_dev_s *)info->par; struct osd_ctl_s *osd_ctrl = &fbdev->osd_ctl; u32 virt_end_x, virt_end_y; + u32 output_index; + + output_index = get_output_device_id(fbdev->fb_index); - if (fbdev->fb_index <= OSD3) { + if (fbdev->fb_index < osd_hw.osd_meson_dev.viu1_osd_count) { vinfo = get_current_vinfo(); if (!vinfo) { osd_log_err("current vinfo NULL\n"); return -1; } } else { +#ifdef CONFIG_AMLOGIC_VOUT2_SERVE vinfo = get_current_vinfo2(); +#endif if (!vinfo) { osd_log_err("current vinfo NULL\n"); return -1; @@ -888,7 +893,7 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) arg & 0xffff ? 1 : 0); break; case FBIOGET_OSD_FLUSH_RATE: - osd_get_flush_rate_hw(&flush_rate); + osd_get_flush_rate_hw(info->node, &flush_rate); if (copy_to_user(argp, &flush_rate, sizeof(u32))) return -EFAULT; break; @@ -1098,12 +1103,12 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) #endif break; case FBIOPUT_OSD_HWC_ENABLE: - osd_set_hwc_enable(hwc_enable); + osd_set_hwc_enable(info->node, hwc_enable); ret = 0; break; case FBIOPUT_OSD_DO_HWC: do_hwc_cmd.out_fen_fd = - osd_sync_do_hwc(&do_hwc_cmd); + osd_sync_do_hwc(info->node, &do_hwc_cmd); ret = copy_to_user(argp, &do_hwc_cmd, sizeof(struct do_hwc_cmd_s)); @@ -1500,7 +1505,7 @@ static int osd_open(struct fb_info *info, int arg) fb_index = fbdev->fb_index; if ((osd_meson_dev.has_viu2) - && (fb_index == OSD4)) { + && (fb_index == osd_meson_dev.viu2_index)) { int vpu_clkc_rate; /* select mux0, if select mux1, mux0 must be set */ @@ -1893,13 +1898,14 @@ static int osd_cursor(struct fb_info *fbi, struct fb_cursor *var) { s16 startx = 0, starty = 0; struct osd_fb_dev_s *fb_dev = gp_fbdev_list[1]; + u32 output_index; if (fb_dev) { startx = fb_dev->osd_ctl.disp_start_x; starty = fb_dev->osd_ctl.disp_start_y; } - - if (osd_hw.hwc_enable) + output_index = get_output_device_id(fbi->node); + if (osd_hw.hwc_enable[output_index]) 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); @@ -1991,18 +1997,22 @@ int osd_notify_callback(struct notifier_block *block, unsigned long cmd, if ((!strcmp(vinfo->name, "invalid")) || (!strcmp(vinfo->name, "null"))) return -1; - osd_hw.vinfo_width = vinfo->width; - osd_hw.vinfo_height = vinfo->field_height; - osd_hw.field_out_en = is_interlaced(vinfo); + osd_hw.vinfo_width[VIU1] = vinfo->width; + osd_hw.vinfo_height[VIU1] = vinfo->field_height; + osd_hw.field_out_en[VIU1] = is_interlaced(vinfo); switch (cmd) { case VOUT_EVENT_MODE_CHANGE: set_osd_logo_freescaler(); + if (!strcmp(vinfo->name, "dummy_panel")) + osd_set_hold_line(MAX_HOLD_LINE); + else + osd_set_hold_line(DEFAULT_HOLD_LINE); if (osd_hw.osd_meson_dev.cpu_id == __MESON_CPU_MAJOR_ID_G12B && is_meson_rev_b()) set_reset_rdma_trigger_line(); if ((osd_meson_dev.osd_ver == OSD_NORMAL) || (osd_meson_dev.osd_ver == OSD_SIMPLE) - || (osd_hw.hwc_enable == 0)) { + || (osd_hw.hwc_enable[VIU1] == 0)) { for (i = 0; i < osd_meson_dev.viu1_osd_count; i++) { fb_dev = gp_fbdev_list[i]; if (fb_dev == NULL) @@ -2033,7 +2043,7 @@ int osd_notify_callback(struct notifier_block *block, unsigned long cmd, case VOUT_EVENT_OSD_DISP_AXIS: if ((osd_meson_dev.osd_ver == OSD_NORMAL) || (osd_meson_dev.osd_ver == OSD_SIMPLE) - || (osd_hw.hwc_enable == 0)) { + || (osd_hw.hwc_enable[VIU1] == 0)) { disp_rect = (struct disp_rect_s *)para; for (i = 0; i < osd_meson_dev.viu1_osd_count; i++) { @@ -2084,111 +2094,6 @@ int osd_notify_callback(struct notifier_block *block, unsigned long cmd, return 0; } -#if 0 -int osd_notify_callback(struct notifier_block *block, unsigned long cmd, - void *para) -{ - struct vinfo_s *vinfo; - struct osd_fb_dev_s *fb_dev; - int i, blank; - struct disp_rect_s *disp_rect; - - vinfo = get_current_vinfo(); - if (!vinfo) { - osd_log_err("current vinfo NULL\n"); - return -1; - } - osd_log_info("current vmode=%s, cmd: 0x%lx\n", - vinfo->name, cmd); - if ((!strcmp(vinfo->name, "invalid")) || - (!strcmp(vinfo->name, "null"))) - return -1; - osd_hw.vinfo_width = vinfo->width; - osd_hw.vinfo_height = vinfo->field_height; - osd_hw.field_out_en = is_interlaced(vinfo); - switch (cmd) { - case VOUT_EVENT_MODE_CHANGE: - set_osd_logo_freescaler(); - for (i = 0; i < osd_meson_dev.viu1_osd_count; i++) { - fb_dev = gp_fbdev_list[i]; - if (fb_dev == NULL) - continue; - set_default_display_axis(&fb_dev->fb_info->var, - &fb_dev->osd_ctl, vinfo); - console_lock(); - osddev_update_disp_axis(fb_dev, 1); - if ((osd_meson_dev.osd_ver == OSD_NORMAL) - || (osd_meson_dev.osd_ver == OSD_SIMPLE)) - osd_set_antiflicker_hw(DEV_OSD1, vinfo, - gp_fbdev_list - [DEV_OSD1]->fb_info->var.yres); - else if (osd_meson_dev.osd_ver == OSD_HIGH_ONE) - osd_set_antiflicker_hw(i, vinfo, - gp_fbdev_list[i]->fb_info->var.yres); - osd_reg_write(VPP_POSTBLEND_H_SIZE, vinfo->width); - console_unlock(); - } - break; - case VOUT_EVENT_OSD_BLANK: - blank = *(int *)para; - for (i = 0; i < osd_meson_dev.viu1_osd_count; i++) { - fb_dev = gp_fbdev_list[i]; - if (fb_dev == NULL) - continue; - console_lock(); - osd_blank(blank, fb_dev->fb_info); - console_unlock(); - } - break; - case VOUT_EVENT_OSD_DISP_AXIS: - disp_rect = (struct disp_rect_s *)para; - for (i = 0; i < osd_meson_dev.viu1_osd_count; i++) { - if (!disp_rect) - break; - - /* vout serve send only two layer axis */ - if (i >= 2) - break; - - fb_dev = gp_fbdev_list[i]; - /* - * if osd layer preblend, - * it's position is controlled by vpp. - if (fb_dev->preblend_enable) - break; - */ - fb_dev->osd_ctl.disp_start_x = disp_rect->x; - fb_dev->osd_ctl.disp_start_y = disp_rect->y; - osd_log_dbg("set disp axis: x:%d y:%d w:%d h:%d\n", - disp_rect->x, disp_rect->y, - disp_rect->w, disp_rect->h); - if (disp_rect->x + disp_rect->w > vinfo->width) - fb_dev->osd_ctl.disp_end_x = vinfo->width - 1; - else - fb_dev->osd_ctl.disp_end_x = - fb_dev->osd_ctl.disp_start_x + - disp_rect->w - 1; - if (disp_rect->y + disp_rect->h > vinfo->height) - fb_dev->osd_ctl.disp_end_y = vinfo->height - 1; - else - fb_dev->osd_ctl.disp_end_y = - fb_dev->osd_ctl.disp_start_y + - disp_rect->h - 1; - disp_rect++; - osd_log_dbg("new disp axis: x0:%d y0:%d x1:%d y1:%d\n", - fb_dev->osd_ctl.disp_start_x, - fb_dev->osd_ctl.disp_start_y, - fb_dev->osd_ctl.disp_end_x, - fb_dev->osd_ctl.disp_end_y); - console_lock(); - osddev_update_disp_axis(fb_dev, 0); - console_unlock(); - } - break; - } - return 0; -} -#endif int osd_notify_callback_viu2(struct notifier_block *block, unsigned long cmd, void *para) { @@ -2209,6 +2114,8 @@ int osd_notify_callback_viu2(struct notifier_block *block, unsigned long cmd, vinfo->name, cmd); if (!strcmp(vinfo->name, "invalid")) return -1; + osd_hw.vinfo_width[VIU2] = vinfo->width; + osd_hw.vinfo_height[VIU2] = vinfo->field_height; i = osd_meson_dev.viu2_index; switch (cmd) { case VOUT_EVENT_MODE_CHANGE: @@ -2843,9 +2750,10 @@ static ssize_t show_flush_rate(struct device *device, struct device_attribute *attr, char *buf) { + struct fb_info *fb_info = dev_get_drvdata(device); u32 flush_rate = 0; - osd_get_flush_rate_hw(&flush_rate); + osd_get_flush_rate_hw(fb_info->node, &flush_rate); return snprintf(buf, PAGE_SIZE, "flush_rate:[%d]\n", flush_rate); } @@ -2897,15 +2805,22 @@ static ssize_t store_antiflicker(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { - struct vinfo_s *vinfo; + struct vinfo_s *vinfo = NULL; unsigned int osd_antiflicker = 0; struct fb_info *fb_info = dev_get_drvdata(device); int res = 0; int ret = 0; + u32 output_index; ret = kstrtoint(buf, 0, &res); osd_antiflicker = res; - vinfo = get_current_vinfo(); + output_index = get_output_device_id(fb_info->node); + if (output_index == VIU1) + vinfo = get_current_vinfo(); +#ifdef CONFIG_AMLOGIC_VOUT2_SERVE + else if (output_index == VIU2) + vinfo = get_current_vinfo2(); +#endif if (!vinfo) { osd_log_err("get current vinfo NULL\n"); return 0; @@ -3021,9 +2936,10 @@ static ssize_t show_osd_fps(struct device *device, struct device_attribute *attr, char *buf) { + struct fb_info *fb_info = dev_get_drvdata(device); u32 osd_fps; - osd_get_fps(&osd_fps); + osd_get_fps(fb_info->node, &osd_fps); return snprintf(buf, 40, "%d\n", osd_fps); } @@ -3032,11 +2948,12 @@ static ssize_t store_osd_fps(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { + struct fb_info *fb_info = dev_get_drvdata(device); int res = 0; int ret = 0; ret = kstrtoint(buf, 0, &res); - osd_set_fps(res); + osd_set_fps(fb_info->node, res); return count; } @@ -3123,9 +3040,10 @@ static ssize_t show_osd_background_size(struct device *device, struct device_attribute *attr, char *buf) { + struct fb_info *fb_info = dev_get_drvdata(device); struct display_flip_info_s disp_info; - osd_get_background_size(&disp_info); + osd_get_background_size(fb_info->node, &disp_info); return snprintf(buf, 80, "%d %d %d %d %d %d %d %d\n", disp_info.background_w, disp_info.background_h, @@ -3141,12 +3059,14 @@ static ssize_t store_osd_background_size(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { + struct fb_info *fb_info = dev_get_drvdata(device); int parsed[8]; - if (likely(parse_para(buf, 8, parsed) == 8)) { + if (likely(parse_para(buf, 8, parsed) == 8)) osd_set_background_size( + fb_info->node, (struct display_flip_info_s *)&parsed); - } else + else osd_log_err("set background size error\n"); return count; @@ -3209,9 +3129,10 @@ static ssize_t show_osd_hwc_enalbe(struct device *device, struct device_attribute *attr, char *buf) { + struct fb_info *fb_info = dev_get_drvdata(device); u32 hwc_enalbe; - osd_get_hwc_enable(&hwc_enalbe); + osd_get_hwc_enable(fb_info->node, &hwc_enalbe); return snprintf(buf, 40, "%d\n", hwc_enalbe); } @@ -3220,13 +3141,14 @@ static ssize_t store_osd_hwc_enalbe(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { + struct fb_info *fb_info = dev_get_drvdata(device); int res = 0; int ret = 0; ret = kstrtoint(buf, 0, &res); if (ret < 0) return -EINVAL; - osd_set_hwc_enable(res); + osd_set_hwc_enable(fb_info->node, res); return count; } @@ -3235,6 +3157,7 @@ static ssize_t store_do_hwc(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { + struct fb_info *fb_info = dev_get_drvdata(device); int res = 0; int ret = 0; @@ -3242,7 +3165,7 @@ static ssize_t store_do_hwc(struct device *device, if (ret < 0) return -EINVAL; if (res) - osd_do_hwc(); + osd_do_hwc(fb_info->node); return count; } @@ -3276,13 +3199,14 @@ static ssize_t store_osd_single_step_mode(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { + struct fb_info *fb_info = dev_get_drvdata(device); int res = 0; int ret = 0; ret = kstrtoint(buf, 0, &res); if (ret < 0) return -EINVAL; - osd_set_single_step_mode(res); + osd_set_single_step_mode(fb_info->node, res); return count; } @@ -3291,13 +3215,14 @@ static ssize_t store_osd_single_step(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { + struct fb_info *fb_info = dev_get_drvdata(device); int res = 0; int ret = 0; ret = kstrtoint(buf, 0, &res); if (ret < 0) return -EINVAL; - osd_set_single_step(res); + osd_set_single_step(fb_info->node, res); return count; } @@ -3866,6 +3791,7 @@ static struct osd_device_data_s osd_gxbb = { .vpp_fifo_len = 0x77f, .dummy_data = 0x00808000, .has_viu2 = 0, + .osd0_sc_independ = 0, }; static struct osd_device_data_s osd_gxtvbb = { @@ -3881,6 +3807,7 @@ static struct osd_device_data_s osd_gxtvbb = { .vpp_fifo_len = 0xfff, .dummy_data = 0x0, .has_viu2 = 0, + .osd0_sc_independ = 0, }; static struct osd_device_data_s osd_gxl = { @@ -3896,6 +3823,7 @@ static struct osd_device_data_s osd_gxl = { .vpp_fifo_len = 0x77f, .dummy_data = 0x00808000, .has_viu2 = 0, + .osd0_sc_independ = 0, }; static struct osd_device_data_s osd_gxm = { @@ -3911,6 +3839,7 @@ static struct osd_device_data_s osd_gxm = { .vpp_fifo_len = 0xfff, .dummy_data = 0x00202000,/* dummy data is different */ .has_viu2 = 0, + .osd0_sc_independ = 0, }; static struct osd_device_data_s osd_txl = { @@ -3926,6 +3855,7 @@ static struct osd_device_data_s osd_txl = { .vpp_fifo_len = 0x77f, .dummy_data = 0x00808000, .has_viu2 = 0, + .osd0_sc_independ = 0, }; static struct osd_device_data_s osd_txlx = { @@ -3941,6 +3871,7 @@ static struct osd_device_data_s osd_txlx = { .vpp_fifo_len = 0x77f, .dummy_data = 0x00808000, .has_viu2 = 0, + .osd0_sc_independ = 0, }; static struct osd_device_data_s osd_axg = { @@ -3957,6 +3888,7 @@ static struct osd_device_data_s osd_axg = { .vpp_fifo_len = 0x400, .dummy_data = 0x00808000, .has_viu2 = 0, + .osd0_sc_independ = 0, }; static struct osd_device_data_s osd_g12a = { @@ -3972,6 +3904,7 @@ static struct osd_device_data_s osd_g12a = { .vpp_fifo_len = 0xfff,/* 2048 */ .dummy_data = 0x00808000, .has_viu2 = 1, + .osd0_sc_independ = 0, }; static struct osd_device_data_s osd_g12b = { @@ -3987,6 +3920,7 @@ static struct osd_device_data_s osd_g12b = { .vpp_fifo_len = 0xfff,/* 2048 */ .dummy_data = 0x00808000, .has_viu2 = 1, + .osd0_sc_independ = 0, }; static struct osd_device_data_s osd_tl1 = { @@ -4002,6 +3936,7 @@ static struct osd_device_data_s osd_tl1 = { .vpp_fifo_len = 0xfff,/* 2048 */ .dummy_data = 0x00808000, .has_viu2 = 1, + .osd0_sc_independ = 0, }; static struct osd_device_data_s osd_sm1 = { @@ -4017,6 +3952,7 @@ static struct osd_device_data_s osd_sm1 = { .vpp_fifo_len = 0xfff,/* 2048 */ .dummy_data = 0x00808000, .has_viu2 = 1, + .osd0_sc_independ = 0, }; static struct osd_device_data_s osd_tm2 = { @@ -4027,11 +3963,12 @@ static struct osd_device_data_s osd_tm2 = { .has_deband = 1, .has_lut = 1, .has_rdma = 1, - .has_dolby_vision = 1, + .has_dolby_vision = 0, .osd_fifo_len = 64, /* fifo len 64*8 = 512 */ .vpp_fifo_len = 0xfff,/* 2048 */ .dummy_data = 0x00808000, .has_viu2 = 1, + .osd0_sc_independ = 1, }; static const struct of_device_id meson_fb_dt_match[] = { @@ -4129,7 +4066,6 @@ static int osd_probe(struct platform_device *pdev) return -ENODEV; } } - /* get interrupt resource */ int_viu_vsync = platform_get_irq_byname(pdev, "viu-vsync"); if (int_viu_vsync == -ENXIO) { diff --git a/drivers/amlogic/media/osd/osd_hw.c b/drivers/amlogic/media/osd/osd_hw.c index c145728..c032403 100644 --- a/drivers/amlogic/media/osd/osd_hw.c +++ b/drivers/amlogic/media/osd/osd_hw.c @@ -75,7 +75,6 @@ #include "osd_hw_def.h" #include "osd_fb.h" -#define OSD_BLEND_SHIFT_WORKAROUND #ifdef CONFIG_AMLOGIC_VSYNC_FIQ_ENABLE #define FIQ_VSYNC #endif @@ -95,7 +94,6 @@ #define osd_tprintk(...) -#define OSD_CALC 14 #define FREE_SCALE_MAX_WIDTH 1920 struct hw_para_s osd_hw; static DEFINE_MUTEX(osd_mutex); @@ -108,11 +106,13 @@ 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); -struct hw_osd_reg_s hw_osd_reg_array[HW_OSD_COUNT] = { +struct hw_osd_reg_s hw_osd_reg_array[HW_OSD_COUNT]; + +struct hw_osd_reg_s hw_osd_reg_array_g12a[HW_OSD_COUNT] = { { VIU_OSD1_CTRL_STAT, VIU_OSD1_CTRL_STAT2, @@ -134,8 +134,6 @@ struct hw_osd_reg_s hw_osd_reg_array[HW_OSD_COUNT] = { VIU_OSD1_PROT_CTRL, VIU_OSD1_MALI_UNPACK_CTRL, VIU_OSD1_DIMM_CTRL, - //VIU_OSD_BLEND_DIN0_SCOPE_H, - //VIU_OSD_BLEND_DIN0_SCOPE_V, VPP_OSD_SCALE_COEF_IDX, VPP_OSD_SCALE_COEF, @@ -187,8 +185,6 @@ struct hw_osd_reg_s hw_osd_reg_array[HW_OSD_COUNT] = { VIU_OSD2_PROT_CTRL, VIU_OSD2_MALI_UNPACK_CTRL, VIU_OSD2_DIMM_CTRL, - //VIU_OSD_BLEND_DIN2_SCOPE_H, - //VIU_OSD_BLEND_DIN2_SCOPE_V, OSD2_SCALE_COEF_IDX, OSD2_SCALE_COEF, @@ -239,8 +235,6 @@ struct hw_osd_reg_s hw_osd_reg_array[HW_OSD_COUNT] = { VIU_OSD3_PROT_CTRL, VIU_OSD3_MALI_UNPACK_CTRL, VIU_OSD3_DIMM_CTRL, - //VIU_OSD_BLEND_DIN3_SCOPE_H, - //VIU_OSD_BLEND_DIN3_SCOPE_V, OSD34_SCALE_COEF_IDX, OSD34_SCALE_COEF, @@ -319,66 +313,226 @@ struct hw_osd_reg_s hw_osd_reg_array[HW_OSD_COUNT] = { VIU2_OSD1_UNSUPPORT, } }; + +struct hw_osd_reg_s hw_osd_reg_array_tl1[HW_OSD_COUNT] = { + { + VIU_OSD1_CTRL_STAT, + VIU_OSD1_CTRL_STAT2, + VIU_OSD1_COLOR_ADDR, + VIU_OSD1_COLOR, + VIU_OSD1_TCOLOR_AG0, + VIU_OSD1_TCOLOR_AG1, + VIU_OSD1_TCOLOR_AG2, + VIU_OSD1_TCOLOR_AG3, + VIU_OSD1_BLK0_CFG_W0, + VIU_OSD1_BLK0_CFG_W1, + VIU_OSD1_BLK0_CFG_W2, + VIU_OSD1_BLK0_CFG_W3, + VIU_OSD1_BLK0_CFG_W4, + VIU_OSD1_BLK1_CFG_W4, + VIU_OSD1_BLK2_CFG_W4, + VIU_OSD1_FIFO_CTRL_STAT, + VIU_OSD1_TEST_RDDATA, + VIU_OSD1_PROT_CTRL, + VIU_OSD1_MALI_UNPACK_CTRL, + VIU_OSD1_DIMM_CTRL, + + VPP_OSD_SCALE_COEF_IDX, + VPP_OSD_SCALE_COEF, + VPP_OSD_VSC_PHASE_STEP, + VPP_OSD_VSC_INI_PHASE, + VPP_OSD_VSC_CTRL0, + VPP_OSD_HSC_PHASE_STEP, + VPP_OSD_HSC_INI_PHASE, + VPP_OSD_HSC_CTRL0, + VPP_OSD_SC_DUMMY_DATA, + VPP_OSD_SC_CTRL0, + VPP_OSD_SCI_WH_M1, + VPP_OSD_SCO_H_START_END, + VPP_OSD_SCO_V_START_END, + VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0, + VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0, + VPU_MAFBC_FORMAT_SPECIFIER_S0, + VPU_MAFBC_BUFFER_WIDTH_S0, + VPU_MAFBC_BUFFER_HEIGHT_S0, + VPU_MAFBC_BOUNDING_BOX_X_START_S0, + VPU_MAFBC_BOUNDING_BOX_X_END_S0, + VPU_MAFBC_BOUNDING_BOX_Y_START_S0, + VPU_MAFBC_BOUNDING_BOX_Y_END_S0, + VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0, + VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0, + VPU_MAFBC_OUTPUT_BUF_STRIDE_S0, + VPU_MAFBC_PREFETCH_CFG_S0, + + + }, + { + VIU_OSD2_CTRL_STAT, + VIU_OSD2_CTRL_STAT2, + VIU_OSD2_COLOR_ADDR, + VIU_OSD2_COLOR, + VIU_OSD2_TCOLOR_AG0, + VIU_OSD2_TCOLOR_AG1, + VIU_OSD2_TCOLOR_AG2, + VIU_OSD2_TCOLOR_AG3, + VIU_OSD2_BLK0_CFG_W0, + VIU_OSD2_BLK0_CFG_W1, + VIU_OSD2_BLK0_CFG_W2, + VIU_OSD2_BLK0_CFG_W3, + VIU_OSD2_BLK0_CFG_W4, + VIU_OSD2_BLK1_CFG_W4, + VIU_OSD2_BLK2_CFG_W4, + VIU_OSD2_FIFO_CTRL_STAT, + VIU_OSD2_TEST_RDDATA, + VIU_OSD2_PROT_CTRL, + VIU_OSD2_MALI_UNPACK_CTRL, + VIU_OSD2_DIMM_CTRL, + + OSD2_SCALE_COEF_IDX, + OSD2_SCALE_COEF, + OSD2_VSC_PHASE_STEP, + OSD2_VSC_INI_PHASE, + OSD2_VSC_CTRL0, + OSD2_HSC_PHASE_STEP, + OSD2_HSC_INI_PHASE, + OSD2_HSC_CTRL0, + OSD2_SC_DUMMY_DATA, + OSD2_SC_CTRL0, + OSD2_SCI_WH_M1, + OSD2_SCO_H_START_END, + OSD2_SCO_V_START_END, + VPU_MAFBC_HEADER_BUF_ADDR_LOW_S1, + VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S1, + VPU_MAFBC_FORMAT_SPECIFIER_S1, + VPU_MAFBC_BUFFER_WIDTH_S1, + VPU_MAFBC_BUFFER_HEIGHT_S1, + VPU_MAFBC_BOUNDING_BOX_X_START_S1, + VPU_MAFBC_BOUNDING_BOX_X_END_S1, + VPU_MAFBC_BOUNDING_BOX_Y_START_S1, + VPU_MAFBC_BOUNDING_BOX_Y_END_S1, + VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S1, + VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S1, + VPU_MAFBC_OUTPUT_BUF_STRIDE_S1, + VPU_MAFBC_PREFETCH_CFG_S1, + + }, + { + VIU2_OSD1_CTRL_STAT, + VIU2_OSD1_CTRL_STAT2, + VIU2_OSD1_COLOR_ADDR, + VIU2_OSD1_COLOR, + VIU2_OSD1_TCOLOR_AG0, + VIU2_OSD1_TCOLOR_AG1, + VIU2_OSD1_TCOLOR_AG2, + VIU2_OSD1_TCOLOR_AG3, + VIU2_OSD1_BLK0_CFG_W0, + VIU2_OSD1_BLK0_CFG_W1, + VIU2_OSD1_BLK0_CFG_W2, + VIU2_OSD1_BLK0_CFG_W3, + VIU2_OSD1_BLK0_CFG_W4, + VIU2_OSD1_BLK1_CFG_W4, + VIU2_OSD1_BLK2_CFG_W4, + VIU2_OSD1_FIFO_CTRL_STAT, + VIU2_OSD1_TEST_RDDATA, + VIU2_OSD1_PROT_CTRL, + VIU2_OSD1_MALI_UNPACK_CTRL, + VIU2_OSD1_DIMM_CTRL, + + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + VIU2_OSD1_UNSUPPORT, + } +}; + static int osd_setting_blending_scope(u32 index); static int vpp_blend_setting_default(u32 index); #ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE /* sync fence relative varible. */ -static int timeline_created; -static void *osd_timeline; -static u32 cur_streamline_val; +static int timeline_created[VIU_COUNT]; +static void *osd_timeline[VIU_COUNT]; +static u32 cur_streamline_val[VIU_COUNT]; /* thread control part */ -struct kthread_worker buffer_toggle_worker; -struct task_struct *buffer_toggle_thread; -struct kthread_work buffer_toggle_work; -struct list_head post_fence_list; -struct mutex post_fence_list_lock; -struct osd_layers_fence_map_s map_layers; +struct kthread_worker buffer_toggle_worker[VIU_COUNT]; +struct task_struct *buffer_toggle_thread[VIU_COUNT]; +struct kthread_work buffer_toggle_work[VIU_COUNT]; +struct list_head post_fence_list[VIU_COUNT]; +struct mutex post_fence_list_lock[VIU_COUNT]; /*post fence mutex*/ +struct osd_layers_fence_map_s map_layers[VIU_COUNT]; struct file *displayed_bufs[HW_OSD_COUNT]; static void osd_pan_display_single_fence( struct osd_fence_map_s *fence_map); static void osd_pan_display_layers_fence( struct osd_layers_fence_map_s *fence_map); +static void osd_pan_display_single_fence_viu2( + struct osd_fence_map_s *fence_map); +static void osd_pan_display_layers_fence_viu2( + struct osd_layers_fence_map_s *fence_map); -static void *osd_timeline_create(void) +static void *osd_timeline_create(u32 output_index) { - const char *tlName = "osd_timeline"; + char tlname[32] = {}; - if (osd_timeline == NULL) { - if (osd_hw.hwc_enable) + sprintf(tlname, "osd_timeline_%d", output_index); + if (!osd_timeline[output_index]) { + if (osd_hw.hwc_enable[output_index]) /* present fence */ - cur_streamline_val = 0; + cur_streamline_val[output_index] = 0; else - cur_streamline_val = 1; - osd_timeline = aml_sync_create_timeline(tlName); + cur_streamline_val[output_index] = 1; + osd_timeline[output_index] = aml_sync_create_timeline(tlname); osd_tprintk("osd timeline create\n"); } - - return osd_timeline; + return osd_timeline[output_index]; } -static int osd_timeline_create_fence(void) +static int osd_timeline_create_fence(u32 output_index) { int out_fence_fd = -1; u32 pt_val = 0; - pt_val = cur_streamline_val + 1; - out_fence_fd = aml_sync_create_fence(osd_timeline, pt_val); + pt_val = cur_streamline_val[output_index] + 1; + out_fence_fd = aml_sync_create_fence + (osd_timeline[output_index], pt_val); osd_tprintk("osd created out pt:%d, fence_fd:%d\n", pt_val, out_fence_fd); if (out_fence_fd >= 0) - cur_streamline_val++; + cur_streamline_val[output_index]++; else pr_info("create fence returned %d", out_fence_fd); return out_fence_fd; } -static void osd_timeline_increase(void) +static void osd_timeline_increase(u32 output_index) { - aml_sync_inc_timeline(osd_timeline, 1); - osd_tprintk("osd out timeline inc\n"); + aml_sync_inc_timeline(osd_timeline[output_index], 1); + osd_tprintk("osd out timeline %d inc\n", output_index); + } static struct fence *osd_get_fenceobj(int fencefd) @@ -454,12 +608,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, @@ -692,48 +849,44 @@ 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 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; @@ -743,20 +896,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; @@ -809,12 +949,40 @@ static void osd_vpu_power_on_viu2(void) #endif } -static int get_osd_hwc_type(void) +u32 get_output_device_id(u32 index) +{ + u32 output_index = VIU1; + + if (osd_hw.osd_meson_dev.has_viu2) { + switch (osd_hw.osd_meson_dev.cpu_id) { + case __MESON_CPU_MAJOR_ID_G12A: + case __MESON_CPU_MAJOR_ID_G12B: + if (index == osd_hw.osd_meson_dev.viu2_index) + output_index = VIU2; + else + output_index = VIU1; + break; + case __MESON_CPU_MAJOR_ID_TL1: + if (index == osd_hw.osd_meson_dev.viu2_index) + output_index = VIU2; + else + output_index = VIU1; + break; + default: + break; + } + } + return output_index; +} + +static int get_osd_hwc_type(u32 index) { int ret = 0; + u32 output_index; + output_index = get_output_device_id(index); /* new hwcomposer enable */ - if (osd_hw.hwc_enable) { + if (osd_hw.hwc_enable[output_index]) { if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) ret = OSD_G12A_NEW_HWC; else @@ -844,10 +1012,10 @@ static void osd_toggle_buffer_single(struct kthread_work *work) struct osd_fence_map_s *data, *next; struct list_head saved_list; - mutex_lock(&post_fence_list_lock); - saved_list = post_fence_list; - list_replace_init(&post_fence_list, &saved_list); - mutex_unlock(&post_fence_list_lock); + mutex_lock(&post_fence_list_lock[VIU1]); + saved_list = post_fence_list[VIU1]; + list_replace_init(&post_fence_list[VIU1], &saved_list); + mutex_unlock(&post_fence_list_lock[VIU1]); list_for_each_entry_safe(data, next, &saved_list, list) { osd_pan_display_single_fence(data); list_del(&data->list); @@ -860,10 +1028,10 @@ static void osd_toggle_buffer_layers(struct kthread_work *work) struct osd_layers_fence_map_s *data, *next; struct list_head saved_list; - mutex_lock(&post_fence_list_lock); - saved_list = post_fence_list; - list_replace_init(&post_fence_list, &saved_list); - mutex_unlock(&post_fence_list_lock); + mutex_lock(&post_fence_list_lock[VIU1]); + saved_list = post_fence_list[VIU1]; + list_replace_init(&post_fence_list[VIU1], &saved_list); + mutex_unlock(&post_fence_list_lock[VIU1]); list_for_each_entry_safe(data, next, &saved_list, list) { osd_pan_display_layers_fence(data); list_del(&data->list); @@ -874,38 +1042,94 @@ static void osd_toggle_buffer_layers(struct kthread_work *work) static void osd_toggle_buffer(struct kthread_work *work) { - osd_hw.osd_fence[osd_hw.hwc_enable]. - toggle_buffer_handler(work); + u32 hwc_enable; + + hwc_enable = osd_hw.hwc_enable[VIU1]; + if (osd_hw.osd_fence[VIU1][hwc_enable].toggle_buffer_handler) + osd_hw.osd_fence[VIU1][hwc_enable] + .toggle_buffer_handler(work); +} + +static void osd_toggle_buffer_single_viu2(struct kthread_work *work) +{ + struct osd_fence_map_s *data, *next; + struct list_head saved_list; + + mutex_lock(&post_fence_list_lock[VIU2]); + saved_list = post_fence_list[VIU2]; + list_replace_init(&post_fence_list[VIU2], &saved_list); + mutex_unlock(&post_fence_list_lock[VIU2]); + list_for_each_entry_safe(data, next, &saved_list, list) { + osd_pan_display_single_fence_viu2(data); + list_del(&data->list); + kfree(data); + } +} + +static void osd_toggle_buffer_layers_viu2(struct kthread_work *work) +{ + struct osd_layers_fence_map_s *data, *next; + struct list_head saved_list; + + mutex_lock(&post_fence_list_lock[VIU2]); + saved_list = post_fence_list[VIU2]; + list_replace_init(&post_fence_list[VIU2], &saved_list); + mutex_unlock(&post_fence_list_lock[VIU2]); + list_for_each_entry_safe(data, next, &saved_list, list) { + osd_pan_display_layers_fence_viu2(data); + list_del(&data->list); + kfree(data); + } +} + +static void osd_toggle_buffer_viu2(struct kthread_work *work) +{ + u32 hwc_enable; + + hwc_enable = osd_hw.hwc_enable[VIU2]; + if (osd_hw.osd_fence[VIU2][hwc_enable].toggle_buffer_handler) + osd_hw.osd_fence[VIU2][hwc_enable] + .toggle_buffer_handler(work); } -static int out_fence_create(int *release_fence_fd) +static int out_fence_create(u32 output_index, int *release_fence_fd) { int out_fence_fd = -1; struct sched_param param = {.sched_priority = 2}; + char toggle_thread_name[32] = {}; - if (!timeline_created) { + if (!timeline_created[output_index]) { /* timeline has not been created */ - if (osd_timeline_create()) { - kthread_init_worker(&buffer_toggle_worker); - buffer_toggle_thread = kthread_run( + if (osd_timeline_create(output_index)) { + kthread_init_worker + (&buffer_toggle_worker[output_index]); + sprintf(toggle_thread_name, + "aml_buf_toggle_%d", output_index); + buffer_toggle_thread[output_index] = kthread_run( kthread_worker_fn, - &buffer_toggle_worker, - "aml_buf_toggle"); - if (IS_ERR(buffer_toggle_thread)) { + &buffer_toggle_worker[output_index], + toggle_thread_name); + if (IS_ERR(buffer_toggle_thread[output_index])) { osd_log_err("create osd toggle kthread failed"); return -1; } - sched_setscheduler(buffer_toggle_thread, - SCHED_FIFO, ¶m); - kthread_init_work( - &buffer_toggle_work, osd_toggle_buffer); - timeline_created = 1; + sched_setscheduler(buffer_toggle_thread[output_index], + SCHED_FIFO, ¶m); + if (output_index == VIU1) + kthread_init_work( + &buffer_toggle_work[output_index], + osd_toggle_buffer); + else if (output_index == VIU2) + kthread_init_work( + &buffer_toggle_work[output_index], + osd_toggle_buffer_viu2); + timeline_created[output_index] = 1; } } /* hwc_enable disable create fence every time */ - if (!osd_hw.hwc_enable) { - out_fence_fd = osd_timeline_create_fence(); + if (!osd_hw.hwc_enable[output_index]) { + out_fence_fd = osd_timeline_create_fence(output_index); if (out_fence_fd < 0) { osd_log_err("fence obj create fail\n"); out_fence_fd = -1; @@ -914,15 +1138,16 @@ static int out_fence_create(int *release_fence_fd) /* hwc_enable enable create fence * when first sync request called */ - if (osd_hw.out_fence_fd == -1) { - out_fence_fd = osd_timeline_create_fence(); + if (osd_hw.out_fence_fd[output_index] == -1) { + out_fence_fd = osd_timeline_create_fence(output_index); if (out_fence_fd < 0) { osd_log_err("fence obj create fail\n"); out_fence_fd = -1; } - osd_hw.out_fence_fd = out_fence_fd; - } else - out_fence_fd = osd_hw.out_fence_fd; + osd_hw.out_fence_fd[output_index] = out_fence_fd; + } else { + out_fence_fd = osd_hw.out_fence_fd[output_index]; + } } if (release_fence_fd) *release_fence_fd = out_fence_fd; @@ -934,17 +1159,19 @@ int osd_sync_request(u32 index, u32 yres, struct fb_sync_request_s *request) int out_fence_fd = -1; int buf_num = 0; int in_fence_fd = -1; + u32 output_index = 0; struct osd_fence_map_s *fence_map = kzalloc(sizeof(struct osd_fence_map_s), GFP_KERNEL); - osd_hw.hwc_enable = 0; + output_index = get_output_device_id(index); + osd_hw.hwc_enable[output_index] = 0; if (request->sync_req.magic == FB_SYNC_REQUEST_MAGIC) { buf_num = find_buf_num(yres, request->sync_req.yoffset); if (!fence_map) { osd_log_err("could not allocate osd_fence_map\n"); return -ENOMEM; } - mutex_lock(&post_fence_list_lock); + mutex_lock(&post_fence_list_lock[output_index]); fence_map->op = 0xffffffff; fence_map->fb_index = index; fence_map->buf_num = buf_num; @@ -958,14 +1185,14 @@ int osd_sync_request(u32 index, u32 yres, struct fb_sync_request_s *request) fence_map->in_fence = osd_get_fenceobj( request->sync_req.in_fen_fd); fence_map->out_fd = - out_fence_create(&out_fence_fd); + out_fence_create(output_index, &out_fence_fd); } else { buf_num = find_buf_num(yres, request->sync_req_old.yoffset); if (!fence_map) { osd_log_err("could not allocate osd_fence_map\n"); return -ENOMEM; } - mutex_lock(&post_fence_list_lock); + mutex_lock(&post_fence_list_lock[output_index]); fence_map->op = 0xffffffff; fence_map->fb_index = index; fence_map->buf_num = buf_num; @@ -978,11 +1205,12 @@ int osd_sync_request(u32 index, u32 yres, struct fb_sync_request_s *request) fence_map->in_fence = osd_get_fenceobj( request->sync_req_old.in_fen_fd); fence_map->out_fd = - out_fence_create(&out_fence_fd); + out_fence_create(output_index, &out_fence_fd); } - list_add_tail(&fence_map->list, &post_fence_list); - mutex_unlock(&post_fence_list_lock); - kthread_queue_work(&buffer_toggle_worker, &buffer_toggle_work); + list_add_tail(&fence_map->list, &post_fence_list[output_index]); + mutex_unlock(&post_fence_list_lock[output_index]); + kthread_queue_work(&buffer_toggle_worker[output_index], + &buffer_toggle_work[output_index]); if (in_fence_fd >= 0) __close_fd(current->files, in_fence_fd); return out_fence_fd; @@ -997,6 +1225,7 @@ static int sync_render_single_fence(u32 index, u32 yres, int out_fence_fd = -1; int buf_num = 0; u32 xoffset, yoffset; + u32 output_index = 0; struct osd_fence_map_s *fence_map = NULL; if (index > OSD1) @@ -1009,7 +1238,8 @@ static int sync_render_single_fence(u32 index, u32 yres, osd_log_err("could not allocate osd_fence_map\n"); return -ENOMEM; } - mutex_lock(&post_fence_list_lock); + output_index = get_output_device_id(index); + mutex_lock(&post_fence_list_lock[output_index]); fence_map->op = 0xffffffff; fence_map->fb_index = index; fence_map->buf_num = buf_num; @@ -1037,13 +1267,15 @@ static int sync_render_single_fence(u32 index, u32 yres, osd_tprintk("direct render fence fd:%d\n", fence_map->in_fd); fence_map->in_fence = osd_get_fenceobj(fence_map->in_fd); fence_map->out_fd = - out_fence_create(&out_fence_fd); + out_fence_create(output_index, &out_fence_fd); /* Todo: */ - list_add_tail(&fence_map->list, &post_fence_list); - mutex_unlock(&post_fence_list_lock); - kthread_queue_work(&buffer_toggle_worker, &buffer_toggle_work); + list_add_tail(&fence_map->list, &post_fence_list[output_index]); + mutex_unlock(&post_fence_list_lock[output_index]); + kthread_queue_work(&buffer_toggle_worker[output_index], + &buffer_toggle_work[output_index]); request->out_fen_fd = out_fence_fd; - __close_fd(current->files, request->in_fen_fd); + if (request->in_fen_fd >= 0) + __close_fd(current->files, request->in_fen_fd); return out_fence_fd; } @@ -1054,13 +1286,15 @@ static int sync_render_layers_fence(u32 index, u32 yres, { int out_fence_fd = -1; s32 in_fence_fd; + u32 output_index = 0; struct osd_layers_fence_map_s *fence_map = NULL; if (index > OSD_MAX) return -1; + output_index = get_output_device_id(index); in_fence_fd = request->in_fen_fd; - mutex_lock(&post_fence_list_lock); - fence_map = &map_layers; + mutex_lock(&post_fence_list_lock[output_index]); + fence_map = &map_layers[output_index]; fence_map->cmd = LAYER_SYNC; fence_map->layer_map[index].fb_index = index; /* layer_map[index].enable will update if have blank ioctl */ @@ -1101,15 +1335,17 @@ static int sync_render_layers_fence(u32 index, u32 yres, /* no longer put list, will put them via do_hwc */ fence_map->layer_map[index].in_fence = osd_get_fenceobj(in_fence_fd); fence_map->layer_map[index].out_fd = - out_fence_create(&out_fence_fd); - mutex_unlock(&post_fence_list_lock); + out_fence_create(output_index, &out_fence_fd); + mutex_unlock(&post_fence_list_lock[output_index]); osd_log_dbg(MODULE_FENCE, "sync_render_layers_fence:osd%d: ind_fd=%d,out_fd=%d\n", fence_map->layer_map[index].fb_index, fence_map->layer_map[index].in_fd, fence_map->layer_map[index].out_fd); request->out_fen_fd = out_fence_fd; - __close_fd(current->files, in_fence_fd); - __close_fd(current->files, request->shared_fd); + if (in_fence_fd >= 0) + __close_fd(current->files, in_fence_fd); + if (request->shared_fd >= 0) + __close_fd(current->files, request->shared_fd); return out_fence_fd; } @@ -1118,49 +1354,53 @@ int osd_sync_request_render(u32 index, u32 yres, u32 phys_addr, size_t len) { - int line; + int line, hwc_enable; + u32 output_index = 0; - cnt++; line = get_encp_line(); + output_index = get_output_device_id(index); 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; + osd_hw.hwc_enable[output_index] = 0; else if (request->magic == FB_SYNC_REQUEST_RENDER_MAGIC_V2) - osd_hw.hwc_enable = 1; - if (index == OSD4) - osd_hw.viu_type = VIU2; - else - osd_hw.viu_type = VIU1; - osd_hw.osd_fence[osd_hw.hwc_enable].sync_fence_handler( - index, yres, request, phys_addr, len); + osd_hw.hwc_enable[output_index] = 1; + output_index = get_output_device_id(index); + hwc_enable = osd_hw.hwc_enable[output_index]; + + if (osd_hw.osd_fence[output_index][hwc_enable].sync_fence_handler) + osd_hw.osd_fence[output_index][hwc_enable] + .sync_fence_handler(index, yres, + request, phys_addr, len); return request->out_fen_fd; } -int osd_sync_do_hwc(struct do_hwc_cmd_s *hwc_cmd) +int osd_sync_do_hwc(u32 index, struct do_hwc_cmd_s *hwc_cmd) { int out_fence_fd = -1; struct osd_layers_fence_map_s *fence_map = NULL; int line; + u32 output_index = 0; + output_index = get_output_device_id(index); 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) return -ENOMEM; - osd_hw.hwc_enable = 1; - mutex_lock(&post_fence_list_lock); - memcpy(fence_map, &map_layers, - sizeof(struct osd_layers_fence_map_s)); + osd_hw.hwc_enable[output_index] = 1; + mutex_lock(&post_fence_list_lock[output_index]); + memcpy(fence_map, &map_layers[output_index], + sizeof(struct osd_layers_fence_map_s)); /* clear map_layers, need alloc next add_sync ioctl */ - memset(&map_layers, 0, - sizeof(struct osd_layers_fence_map_s)); + memset(&map_layers[output_index], 0, + sizeof(struct osd_layers_fence_map_s)); fence_map->out_fd = - out_fence_create(&out_fence_fd); + out_fence_create(output_index, &out_fence_fd); fence_map->disp_info.background_w = hwc_cmd->disp_info.background_w; fence_map->disp_info.background_h = @@ -1179,12 +1419,14 @@ int osd_sync_do_hwc(struct do_hwc_cmd_s *hwc_cmd) hwc_cmd->disp_info.position_h; fence_map->hdr_mode = hwc_cmd->hdr_mode; /* other info set via add_sync and blank ioctl */ - list_add_tail(&fence_map->list, &post_fence_list); + list_add_tail(&fence_map->list, &post_fence_list[output_index]); /* after do_hwc, clear osd_hw.out_fence_fd */ - if (timeline_created && osd_hw.out_fence_fd) - osd_hw.out_fence_fd = -1; - mutex_unlock(&post_fence_list_lock); - kthread_queue_work(&buffer_toggle_worker, &buffer_toggle_work); + if (timeline_created[output_index] && + osd_hw.out_fence_fd[output_index]) + osd_hw.out_fence_fd[output_index] = -1; + mutex_unlock(&post_fence_list_lock[output_index]); + kthread_queue_work(&buffer_toggle_worker[output_index], + &buffer_toggle_work[output_index]); if (get_logo_loaded()) { int logo_index; @@ -1258,7 +1500,7 @@ int osd_sync_request_render(u32 index, u32 yres, return -5566; } -int osd_sync_do_hwc(struct do_hwc_cmd_s *hwc_cmd) +int osd_sync_do_hwc(u32 output_index, struct do_hwc_cmd_s *hwc_cmd) { osd_log_err("osd_do_hwc not supported\n"); return -5566; @@ -1268,7 +1510,10 @@ int osd_sync_do_hwc(struct do_hwc_cmd_s *hwc_cmd) void osd_set_enable_hw(u32 index, u32 enable) { - if (osd_hw.hwc_enable) { + u32 output_index = 0; + + output_index = get_output_device_id(index); + if (osd_hw.hwc_enable[output_index]) { if (index > OSD_MAX) return; if ((osd_hw.osd_meson_dev.osd_ver < OSD_HIGH_ONE) @@ -1276,11 +1521,13 @@ void osd_set_enable_hw(u32 index, u32 enable) osd_enable_hw(index, enable); else { #ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE - mutex_lock(&post_fence_list_lock); - map_layers.layer_map[index].fb_index = index; - map_layers.layer_map[index].enable = enable; - map_layers.cmd = BLANK_CMD; - mutex_unlock(&post_fence_list_lock); + mutex_lock(&post_fence_list_lock[output_index]); + map_layers[output_index].layer_map[index] + .fb_index = index; + map_layers[output_index].layer_map[index] + .enable = enable; + map_layers[output_index].cmd = BLANK_CMD; + mutex_unlock(&post_fence_list_lock[output_index]); osd_log_dbg(MODULE_BASE, "osd_set_enable_hw: osd%d,enable=%d\n", index, enable); #endif @@ -1441,7 +1688,6 @@ static void osd_update_interlace_mode(int index) { /* only called by vsync irq or rdma irq */ unsigned int fb0_cfg_w0 = 0, fb1_cfg_w0 = 0; - unsigned int fb3_cfg_w0 = 0; unsigned int scan_line_number = 0; unsigned int odd_even; @@ -1494,35 +1740,17 @@ static void osd_update_interlace_mode(int index) if ((index & (1 << OSD1)) == (1 << OSD1)) { VSYNCOSD_IRQ_WR_MPEG_REG( hw_osd_reg_array[OSD1].osd_blk0_cfg_w0, fb0_cfg_w0); - if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) - VSYNCOSD_IRQ_WR_MPEG_REG( - hw_osd_reg_array[OSD3].osd_blk0_cfg_w0, fb0_cfg_w0); + if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) { + if ((osd_hw.osd_meson_dev.viu1_osd_count - 1) == OSD3) + VSYNCOSD_IRQ_WR_MPEG_REG( + hw_osd_reg_array[OSD3].osd_blk0_cfg_w0, + fb0_cfg_w0); + } } if ((index & (1 << OSD2)) == (1 << OSD2)) VSYNCOSD_IRQ_WR_MPEG_REG( hw_osd_reg_array[OSD2].osd_blk0_cfg_w0, fb1_cfg_w0); - if (osd_hw.powered[OSD4]) { - if (osd_hw.powered[OSD4]) - fb3_cfg_w0 = VSYNCOSD_RD_MPEG_REG( - hw_osd_reg_array[OSD4].osd_blk0_cfg_w0); - if (osd_hw.scan_mode[OSD4] == SCAN_MODE_INTERLACE) { - if ((osd_hw.pandata[OSD4].y_start % 2) == 1) { - odd_even = (osd_reg_read(ENCI_INFO_READ) & - (1 << 29)) ? OSD_TYPE_TOP_FIELD : - OSD_TYPE_BOT_FIELD; - } else { - odd_even = (osd_reg_read(ENCI_INFO_READ) - & (1 << 29)) ? OSD_TYPE_BOT_FIELD : - OSD_TYPE_TOP_FIELD; - } - } - fb3_cfg_w0 &= ~1; - fb3_cfg_w0 |= odd_even; - if ((index & (1 << OSD4)) == (1 << OSD4)) - VSYNCOSD_IRQ_WR_MPEG_REG( - hw_osd_reg_array[OSD4].osd_blk0_cfg_w0, fb3_cfg_w0); - } spin_unlock_irqrestore(&osd_lock, lock_flags); } @@ -1531,18 +1759,26 @@ void osd_update_scan_mode(void) /* only called by vsync irq or rdma irq */ unsigned int output_type = 0; int index = 0; + int viu2_index = osd_hw.osd_meson_dev.viu2_index; + int osd_count = osd_hw.osd_meson_dev.viu1_osd_count; + int has_osd3 = 0; + if ((osd_count - 1) == OSD3) + has_osd3 = 1; + //todo: Karry output_type = osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3; osd_hw.scan_mode[OSD1] = SCAN_MODE_PROGRESSIVE; osd_hw.scan_mode[OSD2] = SCAN_MODE_PROGRESSIVE; - osd_hw.scan_mode[OSD3] = SCAN_MODE_PROGRESSIVE; - osd_hw.scan_mode[OSD4] = SCAN_MODE_PROGRESSIVE; + if (has_osd3) + osd_hw.scan_mode[OSD3] = SCAN_MODE_PROGRESSIVE; + osd_hw.scan_mode[viu2_index] = SCAN_MODE_PROGRESSIVE; switch (output_type) { case VOUT_ENCP: if (osd_reg_read(ENCP_VIDEO_MODE) & (1 << 12)) { /* 1080i */ osd_hw.scan_mode[OSD1] = SCAN_MODE_INTERLACE; osd_hw.scan_mode[OSD2] = SCAN_MODE_INTERLACE; + if (has_osd3) osd_hw.scan_mode[OSD3] = SCAN_MODE_INTERLACE; } break; @@ -1550,25 +1786,11 @@ void osd_update_scan_mode(void) if (osd_reg_read(ENCI_VIDEO_EN) & 1) { osd_hw.scan_mode[OSD1] = SCAN_MODE_INTERLACE; osd_hw.scan_mode[OSD2] = SCAN_MODE_INTERLACE; + if (has_osd3) osd_hw.scan_mode[OSD3] = SCAN_MODE_INTERLACE; } break; } - if (osd_hw.powered[OSD4]) { - output_type = (osd_reg_read(VPU_VIU_VENC_MUX_CTRL) >> 2) & 0x3; - switch (output_type) { - case VOUT_ENCP: - if (osd_reg_read(ENCP_VIDEO_MODE) & (1 << 12)) - /* 1080i */ - osd_hw.scan_mode[OSD4] = SCAN_MODE_INTERLACE; - break; - case VOUT_ENCI: - if (osd_reg_read(ENCI_VIDEO_EN) & 1) - osd_hw.scan_mode[OSD4] = SCAN_MODE_INTERLACE; - break; - } - - } if (osd_hw.hw_cursor_en) { /* 3 layers osd don't support osd2 cursor */ if (osd_hw.free_scale_enable[OSD1]) @@ -1593,11 +1815,72 @@ void osd_update_scan_mode(void) } } if ((osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE) - || (osd_hw.scan_mode[OSD2] == SCAN_MODE_INTERLACE) - || (osd_hw.scan_mode[OSD4] == SCAN_MODE_INTERLACE)) + || (osd_hw.scan_mode[OSD2] == SCAN_MODE_INTERLACE)) osd_update_interlace_mode(index); } +static void osd_update_interlace_mode_viu2(void) +{ + /* only called by vsync irq or rdma irq */ + unsigned int fb3_cfg_w0 = 0; + unsigned int odd_even = 0; + u32 viu2_index; + + spin_lock_irqsave(&osd_lock, lock_flags); + viu2_index = osd_hw.osd_meson_dev.viu2_index; + if (osd_hw.powered[viu2_index]) { + fb3_cfg_w0 = VSYNCOSD_RD_MPEG_REG( + hw_osd_reg_array[viu2_index].osd_blk0_cfg_w0); + if (osd_hw.scan_mode[viu2_index] == SCAN_MODE_INTERLACE) { + if ((osd_hw.pandata[viu2_index].y_start % 2) == 1) { + odd_even = (osd_reg_read(ENCI_INFO_READ) & + (1 << 29)) ? OSD_TYPE_TOP_FIELD : + OSD_TYPE_BOT_FIELD; + } else { + odd_even = (osd_reg_read(ENCI_INFO_READ) + & (1 << 29)) ? OSD_TYPE_BOT_FIELD : + OSD_TYPE_TOP_FIELD; + } + } + fb3_cfg_w0 &= ~1; + fb3_cfg_w0 |= odd_even; + VSYNCOSD_IRQ_WR_MPEG_REG( + hw_osd_reg_array[viu2_index].osd_blk0_cfg_w0, + fb3_cfg_w0); + } + spin_unlock_irqrestore(&osd_lock, lock_flags); +} + +void osd_update_scan_mode_viu2(void) +{ + /* only called by vsync irq or rdma irq */ + unsigned int output_type = 0; + int viu2_index = osd_hw.osd_meson_dev.viu2_index; + + output_type = osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3; + osd_hw.scan_mode[viu2_index] = SCAN_MODE_PROGRESSIVE; + if (osd_hw.powered[viu2_index]) { + output_type = (osd_reg_read(VPU_VIU_VENC_MUX_CTRL) + >> 2) & 0x3; + switch (output_type) { + case VOUT_ENCP: + if (osd_reg_read(ENCP_VIDEO_MODE) & (1 << 12)) + /* 1080i */ + osd_hw.scan_mode[viu2_index] = + SCAN_MODE_INTERLACE; + break; + case VOUT_ENCI: + if (osd_reg_read(ENCI_VIDEO_EN) & 1) + osd_hw.scan_mode[viu2_index] = + SCAN_MODE_INTERLACE; + break; + } + + } + if (osd_hw.scan_mode[viu2_index] == SCAN_MODE_INTERLACE) + osd_update_interlace_mode_viu2(); +} + //not rdma will call update func; void walk_through_update_list(void) { @@ -1624,7 +1907,8 @@ static bool mali_afbc_get_error(void) status = VSYNCOSD_RD_MPEG_REG(VPU_MAFBC_IRQ_RAW_STATUS); if (status & 0x3c) { - osd_log_dbg(MODULE_BASE, "afbc error happened\n"); + osd_log_dbg(MODULE_BASE, + "afbc error happened,status=0x%x\n", status); osd_hw.afbc_err_cnt++; error = true; } @@ -1852,6 +2136,7 @@ static void osd_viu2_fiq_isr(void) static irqreturn_t vsync_viu2_isr(int irq, void *dev_id) #endif { + osd_update_scan_mode_viu2(); #ifndef FIQ_VSYNC return IRQ_HANDLED; #endif @@ -1902,8 +2187,16 @@ void osd_wait_vsync_hw(void) if (pxp_mode) timeout = msecs_to_jiffies(50); - else - timeout = msecs_to_jiffies(1000); + else { + struct vinfo_s *vinfo; + + vinfo = get_current_vinfo(); + if (vinfo && (!strcmp(vinfo->name, "invalid") || + !strcmp(vinfo->name, "null"))) { + timeout = msecs_to_jiffies(1); + } else + timeout = msecs_to_jiffies(1000); + } wait_event_interruptible_timeout( osd_vsync_wq, vsync_hit, timeout); } @@ -1928,6 +2221,8 @@ s64 osd_wait_vsync_event(void) int is_interlaced(struct vinfo_s *vinfo) { + if (!vinfo) + return 0; if (vinfo->mode == VMODE_CVBS) return 1; if (vinfo->height != vinfo->field_height) @@ -1938,12 +2233,19 @@ int is_interlaced(struct vinfo_s *vinfo) int osd_set_scan_mode(u32 index) { - struct vinfo_s *vinfo; + struct vinfo_s *vinfo = NULL; u32 data32 = 0x0; s32 y_end = 0; + u32 output_index; + output_index = get_output_device_id(index); osd_hw.scan_mode[index] = SCAN_MODE_PROGRESSIVE; - vinfo = get_current_vinfo(); + if (output_index == VIU1) + vinfo = get_current_vinfo(); +#ifdef CONFIG_AMLOGIC_VOUT2_SERVE + else if (output_index == VIU2) + vinfo = get_current_vinfo2(); +#endif if (vinfo && (strcmp(vinfo->name, "invalid") && strcmp(vinfo->name, "null"))) { osd_hw.scale_workaround = 0; @@ -1959,7 +2261,7 @@ int osd_set_scan_mode(u32 index) if ((vinfo->width == 720) && (vinfo->height == 480)) { if (osd_hw.free_scale_mode[index]) { - osd_hw.field_out_en = 1; + osd_hw.field_out_en[output_index] = 1; switch (y_end) { case 719: osd_hw.bot_type = 2; @@ -1979,7 +2281,7 @@ int osd_set_scan_mode(u32 index) } else if ((vinfo->width == 720) && (vinfo->height == 576)) { if (osd_hw.free_scale_mode[index]) { - osd_hw.field_out_en = 1; + osd_hw.field_out_en[output_index] = 1; switch (y_end) { case 719: osd_hw.bot_type = 2; @@ -2000,7 +2302,7 @@ int osd_set_scan_mode(u32 index) } else if ((vinfo->width == 1920) && (vinfo->height == 1080)) { if (osd_hw.free_scale_mode[index]) { - osd_hw.field_out_en = 1; + osd_hw.field_out_en[output_index] = 1; switch (y_end) { case 719: osd_hw.bot_type = 1; @@ -2023,7 +2325,7 @@ int osd_set_scan_mode(u32 index) && (osd_hw.free_scale_enable[index])) if (!(osd_hw.osd_meson_dev.afbc_type)) osd_hw.scale_workaround = 1; - osd_hw.field_out_en = 0; + osd_hw.field_out_en[output_index] = 0; } else if (((vinfo->width == 720) && (vinfo->height == 480)) || ((vinfo->width == 720) @@ -2033,10 +2335,10 @@ int osd_set_scan_mode(u32 index) osd_v_filter_mode = 6; } if (osd_hw.free_scale_mode[index]) - osd_hw.field_out_en = 0; + osd_hw.field_out_en[output_index] = 0; } else { if (osd_hw.free_scale_mode[index]) - osd_hw.field_out_en = 0; + osd_hw.field_out_en[output_index] = 0; } } } @@ -2457,7 +2759,10 @@ static void osd_set_free_scale_enable_mode1(u32 index, u32 enable) void osd_set_free_scale_enable_hw(u32 index, u32 enable) { - if (osd_hw.free_scale_mode[index] && (index != OSD4)) { + if (osd_hw.free_scale_mode[index] + && (osd_hw.osd_meson_dev.has_viu2 ? + ((index != osd_hw.osd_meson_dev.viu2_index) ? + 1 : 0) : 1)) { osd_set_free_scale_enable_mode1(index, enable); if (osd_hw.osd_meson_dev.osd_ver == OSD_NORMAL) { u32 height_dst, height_src; @@ -2552,11 +2857,18 @@ void osd_set_scale_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1) void osd_get_window_axis_hw(u32 index, s32 *x0, s32 *y0, s32 *x1, s32 *y1) { - struct vinfo_s *vinfo; + struct vinfo_s *vinfo = NULL; s32 height; + u32 output_index; + output_index = get_output_device_id(index); if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { - vinfo = get_current_vinfo(); + if (output_index == VIU1) + vinfo = get_current_vinfo(); +#ifdef CONFIG_AMLOGIC_VOUT2_SERVE + else if (output_index == VIU2) + vinfo = get_current_vinfo2(); +#endif if (vinfo && (strcmp(vinfo->name, "invalid") && strcmp(vinfo->name, "null"))) { if (is_interlaced(vinfo)) { @@ -2592,15 +2904,17 @@ void osd_get_window_axis_hw(u32 index, s32 *x0, s32 *y0, s32 *x1, s32 *y1) void osd_set_window_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1) { - struct vinfo_s *vinfo; + struct vinfo_s *vinfo = NULL; s32 temp_y0, temp_y1; + u32 output_index; - #if 0 - if (osd_hw.hwc_enable && - (osd_hw.osd_display_debug != OSD_DISP_DEBUG)) - return; - #endif - vinfo = get_current_vinfo(); + output_index = get_output_device_id(index); + if (output_index == VIU1) + vinfo = get_current_vinfo(); +#ifdef CONFIG_AMLOGIC_VOUT2_SERVE + else if (output_index == VIU2) + vinfo = get_current_vinfo2(); +#endif mutex_lock(&osd_mutex); if (vinfo && (strcmp(vinfo->name, "invalid") && strcmp(vinfo->name, "null"))) { @@ -2637,13 +2951,12 @@ void osd_set_window_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1) if (osd_hw.free_dst_data[index].y_end >= 2159) osd_set_dummy_data(index, 0xff); osd_update_window_axis = true; - if (osd_hw.hwc_enable && - (osd_hw.osd_display_debug == OSD_DISP_DEBUG)) - osd_setting_blend(); + if (osd_hw.hwc_enable[output_index] && + (osd_hw.osd_display_debug == OSD_DISP_DEBUG)) + osd_setting_blend(output_index); mutex_unlock(&osd_mutex); } - s32 osd_get_position_from_reg( u32 index, s32 *src_x_start, s32 *src_x_end, @@ -2654,7 +2967,7 @@ s32 osd_get_position_from_reg( struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index]; u32 data32 = 0x0; - if (index >= OSD4) + if (index >= OSD_MAX) return -1; if (!src_x_start || !src_x_end || !src_y_start || !src_y_end @@ -2789,6 +3102,7 @@ void osd_enable_hw(u32 index, u32 enable) { int i = 0; int count = (pxp_mode == 1)?3:WAIT_AFBC_READY_COUNT; + u32 output_index; if (index == 0) { osd_log_info("osd[%d] enable: %d (%s)\n", @@ -2800,8 +3114,8 @@ void osd_enable_hw(u32 index, u32 enable) /* reset viu 31bit ?? */ if (!osd_hw.enable[index] && - osd_hw.osd_afbcd[index].enable && enable - && (get_osd_hwc_type() != OSD_G12A_NEW_HWC)) { + osd_hw.osd_afbcd[index].enable && enable && + (get_osd_hwc_type(index) != OSD_G12A_NEW_HWC)) { spin_lock_irqsave(&osd_lock, lock_flags); if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) { osd_reg_write(VIU_SW_RESET, 0x80000000); @@ -2829,11 +3143,13 @@ void osd_enable_hw(u32 index, u32 enable) } osd_hw.enable[index] = enable; - if (get_osd_hwc_type() != OSD_G12A_NEW_HWC) { + output_index = get_output_device_id(index); + if (get_osd_hwc_type(index) != OSD_G12A_NEW_HWC) { add_to_update_list(index, OSD_ENABLE); osd_wait_vsync_hw(); - } else if (osd_hw.hwc_enable && osd_hw.osd_display_debug) - osd_setting_blend(); + } else if (osd_hw.hwc_enable[output_index] && + osd_hw.osd_display_debug) + osd_setting_blend(output_index); } void osd_set_2x_scale_hw(u32 index, u16 h_scale_enable, u16 v_scale_enable) @@ -2862,11 +3178,20 @@ void osd_set_2x_scale_hw(u32 index, u16 h_scale_enable, u16 v_scale_enable) osd_wait_vsync_hw(); } -void osd_get_flush_rate_hw(u32 *break_rate) +void osd_get_flush_rate_hw(u32 index, u32 *break_rate) { - const struct vinfo_s *vinfo; + const struct vinfo_s *vinfo = NULL; + u32 output_index; - vinfo = get_current_vinfo(); + output_index = get_output_device_id(index); + if (output_index == VIU1) + vinfo = get_current_vinfo(); +#ifdef CONFIG_AMLOGIC_VOUT2_SERVE + else if (output_index == VIU2) + vinfo = get_current_vinfo2(); +#endif + if (!vinfo) + return; *break_rate = vinfo->sync_duration_num / vinfo->sync_duration_den; } @@ -3151,26 +3476,33 @@ void osd_set_deband(u32 osd_deband_enable) } -void osd_get_fps(u32 *osd_fps) +void osd_get_fps(u32 index, u32 *osd_fps) { - *osd_fps = osd_hw.osd_fps; + u32 output_index; + + output_index = get_output_device_id(index); + *osd_fps = osd_hw.osd_fps[output_index]; + } -void osd_set_fps(u32 osd_fps_start) +void osd_set_fps(u32 index, u32 osd_fps_start) { static int stime, etime; + u32 output_index; - osd_hw.osd_fps_start = osd_fps_start; + output_index = get_output_device_id(index); + osd_hw.osd_fps_start[output_index] = osd_fps_start; if (osd_fps_start) { /* start to calc fps */ stime = ktime_to_us(ktime_get()); - osd_hw.osd_fps = 0; + osd_hw.osd_fps[output_index] = 0; } else { /* stop to calc fps */ etime = ktime_to_us(ktime_get()); - osd_hw.osd_fps = (osd_hw.osd_fps * 1000000) + osd_hw.osd_fps[output_index] = + (osd_hw.osd_fps[output_index] * 1000000) / (etime - stime); - osd_log_info("osd fps:=%d\n", osd_hw.osd_fps); + osd_log_info("osd fps:=%d\n", osd_hw.osd_fps[output_index]); } } @@ -3184,16 +3516,22 @@ void osd_set_display_debug(u32 osd_display_debug_enable) osd_hw.osd_display_debug = osd_display_debug_enable; } -void osd_get_background_size(struct display_flip_info_s *disp_info) +void osd_get_background_size(u32 index, struct display_flip_info_s *disp_info) { - memcpy(disp_info, &osd_hw.disp_info, - sizeof(struct display_flip_info_s)); + u32 output_index; + + output_index = get_output_device_id(index); + memcpy(disp_info, &osd_hw.disp_info[output_index], + sizeof(struct display_flip_info_s)); } -void osd_set_background_size(struct display_flip_info_s *disp_info) +void osd_set_background_size(u32 index, struct display_flip_info_s *disp_info) { - memcpy(&osd_hw.disp_info, disp_info, - sizeof(struct display_flip_info_s)); + u32 output_index; + + output_index = get_output_device_id(index); + memcpy(&osd_hw.disp_info[output_index], disp_info, + sizeof(struct display_flip_info_s)); } void osd_get_hdr_used(u32 *val) @@ -3218,22 +3556,31 @@ void osd_set_afbc_format(u32 index, u32 format, u32 inter_format) osd_hw.osd_afbcd[index].inter_format = inter_format; } -void osd_get_hwc_enable(u32 *hwc_enable) +void osd_get_hwc_enable(u32 index, u32 *hwc_enable) { - *hwc_enable = osd_hw.hwc_enable; + u32 output_index; + + output_index = get_output_device_id(index); + *hwc_enable = osd_hw.hwc_enable[output_index]; } -void osd_set_hwc_enable(u32 hwc_enable) +void osd_set_hwc_enable(u32 index, u32 hwc_enable) { - osd_hw.hwc_enable = hwc_enable; + u32 output_index; + + output_index = get_output_device_id(index); + osd_hw.hwc_enable[output_index] = hwc_enable; /* setting default hwc path */ if (!hwc_enable) - osd_setting_blend(); + osd_setting_blend(OSD1); } -void osd_do_hwc(void) +void osd_do_hwc(u32 index) { - osd_setting_blend(); + u32 output_index; + + output_index = get_output_device_id(index); + osd_setting_blend(output_index); } static void osd_set_two_ports(bool set) @@ -3273,26 +3620,36 @@ void osd_set_urgent_info(u32 ports, u32 basic_urgent) osd_set_two_ports(osd_hw.two_ports); } -void osd_set_single_step_mode(u32 osd_single_step_mode) +void osd_set_single_step_mode(u32 index, u32 osd_single_step_mode) { + u32 output_index; + + output_index = get_output_device_id(index); + if (output_index != VIU1) + return; osd_hw.osd_debug.osd_single_step_mode = osd_single_step_mode; if ((osd_hw.osd_debug.wait_fence_release) && (osd_hw.osd_debug.osd_single_step_mode == 0)) { #ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE - osd_timeline_increase(); + osd_timeline_increase(output_index); #endif osd_hw.osd_debug.wait_fence_release = false; } } -void osd_set_single_step(u32 osd_single_step) +void osd_set_single_step(u32 index, u32 osd_single_step) { + u32 output_index; + + output_index = get_output_device_id(index); + if (output_index != VIU1) + return; osd_hw.osd_debug.osd_single_step = osd_single_step; if ((osd_hw.osd_debug.wait_fence_release) && (osd_hw.osd_debug.osd_single_step > 0)) { #ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE - osd_timeline_increase(); + osd_timeline_increase(output_index); #endif osd_hw.osd_debug.wait_fence_release = false; } @@ -3305,7 +3662,7 @@ void osd_get_rotate(u32 index, u32 *osd_rotate) void osd_set_rotate(u32 index, u32 osd_rotate) { - if (index != OSD4) + if (index != osd_hw.osd_meson_dev.viu2_index) osd_log_err("osd%d not support rotate\n", index); osd_hw.osd_rotate[index] = osd_rotate; add_to_update_list(index, DISP_OSD_ROTATE); @@ -3329,6 +3686,25 @@ void osd_set_dimm_info(u32 index, u32 osd_dimm_layer, u32 osd_dimm_color) osd_hw.dim_color[index] = osd_dimm_color; } +void osd_set_hold_line(int hold_line) +{ + int i; + unsigned int data32 = 0, val = 0; + + for (i = 0; i <= osd_hw.osd_meson_dev.viu1_osd_count; i++) { + if (osd_hw.powered[i]) { + data32 = VSYNCOSD_RD_MPEG_REG + (hw_osd_reg_array[i].osd_fifo_ctrl_stat); + val = (data32 >> 5) & 0x1f; + if (val != hold_line) { + VSYNCOSD_WR_MPEG_REG_BITS + (hw_osd_reg_array[i].osd_fifo_ctrl_stat, + hold_line & 0x1f, 5, 5); + } + } + } +} + int osd_get_capbility(u32 index) { u32 capbility = 0; @@ -3338,10 +3714,10 @@ int osd_get_capbility(u32 index) capbility |= OSD_LAYER_ENABLE | OSD_FREESCALE | OSD_UBOOT_LOGO | OSD_ZORDER | OSD_VIU1 | OSD_PRIMARY; - else if ((index == OSD2) || (index == OSD3)) + else if (index < osd_hw.osd_meson_dev.viu1_osd_count) capbility |= OSD_LAYER_ENABLE | OSD_FREESCALE | OSD_ZORDER | OSD_VIU1; - else if (index == OSD4) + else if (index == osd_hw.osd_meson_dev.viu2_index) capbility |= OSD_LAYER_ENABLE | OSD_VIU2; } else if (osd_hw.osd_meson_dev.osd_ver == OSD_NORMAL) { if (index == OSD1) @@ -3735,30 +4111,30 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) height_dst) / height_src - 1; if (osd_hw.osd_reverse[index] == REVERSE_TRUE) { - x_start = osd_hw.vinfo_width + x_start = osd_hw.vinfo_width[VIU1] - freescale_dst[index].x_end - 1; - y_start = osd_hw.vinfo_height + y_start = osd_hw.vinfo_height[VIU1] - freescale_dst[index].y_end - 1; - x_end = osd_hw.vinfo_width + x_end = osd_hw.vinfo_width[VIU1] - freescale_dst[index].x_start - 1; - y_end = osd_hw.vinfo_height + y_end = osd_hw.vinfo_height[VIU1] - freescale_dst[index].y_start - 1; freescale_dst[index].x_start = x_start; freescale_dst[index].y_start = y_start; freescale_dst[index].x_end = x_end; freescale_dst[index].y_end = y_end; } else if (osd_hw.osd_reverse[index] == REVERSE_X) { - x_start = osd_hw.vinfo_width + x_start = osd_hw.vinfo_width[VIU1] - freescale_dst[index].x_end - 1; - x_end = osd_hw.vinfo_width + x_end = osd_hw.vinfo_width[VIU1] - freescale_dst[index].x_start - 1; freescale_dst[index].x_start = x_start; freescale_dst[index].x_end = x_end; } else if (osd_hw.osd_reverse[index] == REVERSE_Y) { - y_start = osd_hw.vinfo_height + y_start = osd_hw.vinfo_height[VIU1] - freescale_dst[index].y_end - 1; - y_end = osd_hw.vinfo_height + y_end = osd_hw.vinfo_height[VIU1] - freescale_dst[index].y_start - 1; freescale_dst[index].y_start = y_start; freescale_dst[index].y_end = y_end; @@ -3815,30 +4191,30 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) osd_hw.dispdata[index].y_end = fence_map->dst_y + fence_map->dst_h - 1; if (osd_hw.osd_reverse[index] == REVERSE_TRUE) { - x_start = osd_hw.vinfo_width + x_start = osd_hw.vinfo_width[VIU1] - osd_hw.dispdata[index].x_end - 1; - y_start = osd_hw.vinfo_height + y_start = osd_hw.vinfo_height[VIU1] - osd_hw.dispdata[index].y_end - 1; - x_end = osd_hw.vinfo_width + x_end = osd_hw.vinfo_width[VIU1] - osd_hw.dispdata[index].x_start - 1; - y_end = osd_hw.vinfo_height + y_end = osd_hw.vinfo_height[VIU1] - osd_hw.dispdata[index].y_start - 1; osd_hw.dispdata[index].x_start = x_start; osd_hw.dispdata[index].y_start = y_start; osd_hw.dispdata[index].x_end = x_end; osd_hw.dispdata[index].y_end = y_end; } else if (osd_hw.osd_reverse[index] == REVERSE_X) { - x_start = osd_hw.vinfo_width + x_start = osd_hw.vinfo_width[VIU1] - osd_hw.dispdata[index].x_end - 1; - x_end = osd_hw.vinfo_width + x_end = osd_hw.vinfo_width[VIU1] - osd_hw.dispdata[index].x_start - 1; osd_hw.dispdata[index].x_start = x_start; osd_hw.dispdata[index].x_end = x_end; } else if (osd_hw.osd_reverse[index] == REVERSE_Y) { - y_start = osd_hw.vinfo_height + y_start = osd_hw.vinfo_height[VIU1] - osd_hw.dispdata[index].y_end - 1; - y_end = osd_hw.vinfo_height + y_end = osd_hw.vinfo_height[VIU1] - osd_hw.dispdata[index].y_start - 1; osd_hw.dispdata[index].y_start = y_start; osd_hw.dispdata[index].y_end = y_end; @@ -3861,19 +4237,27 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map) u32 osd_enable = 0; bool skip = false; const struct vinfo_s *vinfo; - + u32 output_index = VIU1; if (index >= OSD2) goto out; - if (timeline_created) { /* out fence created success. */ + vinfo = get_current_vinfo(); + if (!vinfo || (!strcmp(vinfo->name, "invalid") || + !strcmp(vinfo->name, "null"))) + goto out; + + osd_hw.vinfo_width[output_index] = vinfo->width; + osd_hw.vinfo_height[output_index] = vinfo->height; + + if (timeline_created[output_index]) { /* out fence created success. */ ret = osd_wait_buf_ready(fence_map); if (ret < 0) osd_log_dbg(MODULE_BASE, "fence wait ret %d\n", ret); } if (ret) { osd_hw.buffer_alloc[index] = 1; - if (osd_hw.osd_fps_start) - osd_hw.osd_fps++; + if (osd_hw.osd_fps_start[output_index]) + osd_hw.osd_fps[output_index]++; if (fence_map->op == 0xffffffff) skip = true; else @@ -3886,14 +4270,6 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map) AFBC_EN | BLOCK_SPLIT | YUV_TRANSFORM | SUPER_BLOCK_ASPECT; } - vinfo = get_current_vinfo(); - if (vinfo) { - if ((strcmp(vinfo->name, "invalid")) && - (strcmp(vinfo->name, "null"))) { - osd_hw.vinfo_width = vinfo->width; - osd_hw.vinfo_height = vinfo->height; - } - } /* Todo: */ if (fence_map->ext_addr && fence_map->width && fence_map->height) { @@ -3939,7 +4315,10 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map) .update_func(index); osd_update_window_axis = false; } - if ((osd_enable != osd_hw.enable[index]) + if ((osd_enable != osd_hw.enable[index] || + (osd_hw.osd_meson_dev.afbc_type + == MALI_AFBC && + osd_hw.osd_afbcd[index].enable)) && (skip == false) && (suspend_flag == false)) { osd_hw.enable[index] = osd_enable; @@ -4060,7 +4439,10 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map) .update_func(index); osd_update_window_axis = false; } - if ((osd_enable != osd_hw.enable[index]) + if ((osd_enable != osd_hw.enable[index] || + (osd_hw.osd_meson_dev.afbc_type + == MALI_AFBC && + osd_hw.osd_afbcd[index].enable)) && (skip == false) && (suspend_flag == false)) { osd_hw.enable[index] = osd_enable; @@ -4072,7 +4454,9 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map) osd_mali_afbc_start(); spin_unlock_irqrestore(&osd_lock, lock_flags); osd_wait_vsync_hw(); - } else if ((osd_enable != osd_hw.enable[index]) + } else if ((osd_enable != osd_hw.enable[index] || + (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC && + osd_hw.osd_afbcd[index].enable)) && (skip == false)) { spin_lock_irqsave(&osd_lock, lock_flags); if (suspend_flag == false) { @@ -4087,20 +4471,24 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map) osd_wait_vsync_hw(); } } - if (timeline_created) { +#ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT + if (ret) + osd_ext_clone_pan(index); +#endif +out: + if (timeline_created[output_index]) { if (ret) - osd_timeline_increase(); + osd_timeline_increase(output_index); else osd_log_err("------NOT signal out_fence ERROR\n"); } -#ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT - if (ret) - osd_ext_clone_pan(index); -#endif -out: if (fence_map->in_fence) osd_put_fenceobj(fence_map->in_fence); +} +static void osd_pan_display_single_fence_viu2(struct osd_fence_map_s *fence_map) +{ + osd_log_err("osd hwc version not support viu2\n"); } static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map) @@ -4109,6 +4497,7 @@ static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map) const struct color_bit_define_s *color = NULL; u32 ext_addr = 0; u32 format = 0; + u32 output_index = 0; if (index > OSD_MAX) return; @@ -4272,7 +4661,8 @@ static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map) layer_map->dst_x + layer_map->dst_w - 1; osd_hw.free_dst_data[index].y_end = layer_map->dst_y + layer_map->dst_h - 1; - if (osd_hw.field_out_en) { + output_index = get_output_device_id(index); + if (osd_hw.field_out_en[output_index]) { osd_hw.free_dst_data[index].y_start /= 2; osd_hw.free_dst_data[index].y_end /= 2; } @@ -4284,31 +4674,49 @@ static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map) #endif } -static void osd_pan_display_layers_fence( +static void _osd_pan_display_layers_fence( + u32 output_index, + struct vinfo_s *vinfo, struct osd_layers_fence_map_s *fence_map) { int i = 0; int ret; - int osd_count = osd_hw.osd_meson_dev.osd_count - 1; + int start_index = 0; + int backup_en = 0; + int osd_count = 0; /* osd_count need -1 when VIU2 enable */ struct layer_fence_map_s *layer_map = NULL; - struct vinfo_s *vinfo; - if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) - osd_count = 1; - vinfo = get_current_vinfo(); - if (vinfo && (strcmp(vinfo->name, "invalid") && - strcmp(vinfo->name, "null"))) { - osd_hw.vinfo_width = vinfo->width; - osd_hw.vinfo_height = vinfo->field_height; + if (!vinfo || (!strcmp(vinfo->name, "invalid") || + !strcmp(vinfo->name, "null"))) + /* vout is null, release fence */ + goto out; + + osd_hw.vinfo_width[output_index] = vinfo->width; + osd_hw.vinfo_height[output_index] = vinfo->field_height; + memcpy(&osd_hw.disp_info[output_index], &fence_map->disp_info, + sizeof(struct display_flip_info_s)); + if (output_index == VIU1) { + osd_count = osd_hw.osd_meson_dev.viu1_osd_count; + if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) + osd_count = 1; + start_index = 0; + backup_en = 1; + } else if (output_index == VIU2) { + start_index = osd_hw.osd_meson_dev.viu2_index; + osd_count = start_index + 1; + backup_en = 0; + } else { + osd_log_err("invald output_index=%d\n", output_index); + return; } - osd_set_background_size(&(fence_map->disp_info)); - if (osd_hw.osd_fps_start) - osd_hw.osd_fps++; - clear_backup_info(); + if (osd_hw.osd_fps_start[output_index]) + osd_hw.osd_fps[output_index]++; + if (backup_en) + clear_backup_info(); osd_hw.hdr_used = fence_map->hdr_mode; - for (i = 0; i < osd_count; i++) { + for (i = start_index; i < osd_count; i++) { layer_map = &fence_map->layer_map[i]; if (i != layer_map->fb_index) { osd_hw.screen_base[i] = 0; @@ -4317,7 +4725,7 @@ static void osd_pan_display_layers_fence( continue; } /* wait in fence */ - if (timeline_created && layer_map->enable + if (timeline_created[output_index] && layer_map->enable && (fence_map->cmd == LAYER_SYNC)) { ret = osd_wait_buf_ready_combine(layer_map); if (ret < 0) @@ -4325,23 +4733,25 @@ static void osd_pan_display_layers_fence( "fence wait ret %d\n", ret); } osd_pan_display_update_info(layer_map); - save_layer_info(layer_map); + if (backup_en) + save_layer_info(layer_map); } /* set hw regs */ if (osd_hw.osd_display_debug != OSD_DISP_DEBUG) - osd_setting_blend(); + osd_setting_blend(output_index); +out: /* signal out fence */ - if (timeline_created) { + if (timeline_created[output_index]) { if (osd_hw.osd_debug.osd_single_step_mode) { /* single step mode */ if (osd_hw.osd_debug.osd_single_step > 0) { - osd_timeline_increase(); + osd_timeline_increase(output_index); osd_log_dbg(MODULE_FENCE, "signal out fence\n"); osd_hw.osd_debug.osd_single_step--; } else osd_hw.osd_debug.wait_fence_release = true; } else - osd_timeline_increase(); + osd_timeline_increase(output_index); } /*clear last displayed buffer.*/ for (i = 0; i < HW_OSD_COUNT; i++) { @@ -4351,7 +4761,7 @@ static void osd_pan_display_layers_fence( } } /* clear osd layer's order */ - for (i = 0; i < osd_count; i++) { + for (i = start_index; i < osd_count; i++) { layer_map = &fence_map->layer_map[i]; if (layer_map->buf_file) displayed_bufs[i] = layer_map->buf_file; @@ -4360,14 +4770,42 @@ static void osd_pan_display_layers_fence( osd_hw.order[i] = 0; } } + +static void osd_pan_display_layers_fence( + struct osd_layers_fence_map_s *fence_map) +{ + u32 output_index = VIU1; + struct vinfo_s *vinfo = NULL; + + vinfo = get_current_vinfo(); + + _osd_pan_display_layers_fence(output_index, + vinfo, fence_map); +} + +static void osd_pan_display_layers_fence_viu2( + struct osd_layers_fence_map_s *fence_map) +{ + u32 output_index = VIU2; + struct vinfo_s *vinfo = NULL; + +#ifdef CONFIG_AMLOGIC_VOUT2_SERVE + vinfo = get_current_vinfo2(); +#endif + + _osd_pan_display_layers_fence(output_index, + vinfo, fence_map); +} #endif void osd_pan_display_hw(u32 index, unsigned int xoffset, unsigned int yoffset) { long diff_x, diff_y; + u32 output_index; if (index >= HW_OSD_COUNT) return; + output_index = get_output_device_id(index); if (xoffset != osd_hw.pandata[index].x_start || yoffset != osd_hw.pandata[index].y_start) { diff_x = xoffset - osd_hw.pandata[index].x_start; @@ -4383,8 +4821,8 @@ void osd_pan_display_hw(u32 index, unsigned int xoffset, unsigned int yoffset) osd_hw.src_data[index].h = osd_hw.pandata[index].y_end - osd_hw.pandata[index].y_start + 1; add_to_update_list(index, DISP_GEOMETRY); - if (osd_hw.osd_fps_start) - osd_hw.osd_fps++; + if (osd_hw.osd_fps_start[output_index]) + osd_hw.osd_fps[output_index]++; /* osd_wait_vsync_hw(); */ } #ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT @@ -4458,6 +4896,7 @@ static void osd_update_disp_freescale_enable(u32 index) struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index]; u32 data32 = 0x0; u32 shift_workaround = 0; + u32 output_index = 0; if (osd_hw.osd_meson_dev.osd_ver != OSD_HIGH_ONE) osd_reg = &hw_osd_reg_array[0]; @@ -4467,7 +4906,8 @@ static void osd_update_disp_freescale_enable(u32 index) else vf_bank_len = 4; - if (osd_hw.hwc_enable && (index == OSD1)) + output_index = get_output_device_id(index); + if (osd_hw.hwc_enable[output_index] && (index == OSD1)) shift_workaround = osd_hw.workaround_line; #ifndef NEW_PPS_PHASE @@ -4525,7 +4965,7 @@ static void osd_update_disp_freescale_enable(u32 index) vf_phase_step = (src_h << 20) / dst_h; #ifdef NEW_PPS_PHASE - if (osd_hw.field_out_en) { + if (osd_hw.field_out_en[output_index]) { struct osd_f2v_vphase_s vphase; f2v_get_vertical_phase( @@ -4556,7 +4996,7 @@ static void osd_update_disp_freescale_enable(u32 index) bot_ini_phase = 0; } #else - if (osd_hw.field_out_en) /* interface output */ + if (osd_hw.field_out_en[output_index]) /* interface output */ bot_ini_phase = ((vf_phase_step / 2) >> 4); else bot_ini_phase = 0; @@ -4568,7 +5008,7 @@ static void osd_update_disp_freescale_enable(u32 index) data32 = 0x0; if (shift_workaround) { vsc_ini_rcv_num++; - if (osd_hw.field_out_en) + if (osd_hw.field_out_en[output_index]) vsc_bot_rcv_num++; } @@ -4590,7 +5030,7 @@ static void osd_update_disp_freescale_enable(u32 index) data32 |= (vf_bank_len & 0x7) | ((vsc_ini_rcv_num & 0xf) << 3) | ((vsc_ini_rpt_p0_num & 0x3) << 8); - if (osd_hw.field_out_en) + if (osd_hw.field_out_en[output_index]) data32 |= ((vsc_bot_rcv_num & 0xf) << 11) | ((vsc_bot_rpt_p0_num & 0x3) << 16) | (1 << 23); @@ -4625,8 +5065,8 @@ static void osd_update_disp_freescale_enable(u32 index) VSYNCOSD_WR_MPEG_REG( osd_reg->osd_vsc_init_phase, data32); } - if ((osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) - && (!osd_hw.hwc_enable)) { + if ((osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) && + (!osd_hw.hwc_enable[output_index])) { osd_setting_blending_scope(index); vpp_blend_setting_default(index); } @@ -4927,8 +5367,10 @@ static void osd_update_enable(u32 index) notify_to_amvideo(); VSYNCOSD_CLR_MPEG_REG_MASK(VPP_MISC, temp_val); } - VSYNCOSD_CLR_MPEG_REG_MASK( - osd_reg->osd_ctrl_stat, 1 << 0); + if (!(osd_hw.osd_meson_dev.cpu_id == + __MESON_CPU_MAJOR_ID_G12B)) + VSYNCOSD_CLR_MPEG_REG_MASK( + osd_reg->osd_ctrl_stat, 1 << 0); } if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) { if ((osd_hw.osd_afbcd[index].enable == ENABLE) @@ -5053,7 +5495,7 @@ static void osd_update_disp_osd_rotate(u32 index) u32 data32; enum color_index_e idx; struct dispdata_s src_data; - const struct vinfo_s *vinfo; + const struct vinfo_s *vinfo = NULL; int out_y_crop_start, out_y_crop_end; if (osd_hw.osd_meson_dev.cpu_id != __MESON_CPU_MAJOR_ID_G12B) @@ -5063,11 +5505,14 @@ static void osd_update_disp_osd_rotate(u32 index) src_data.y = 0; src_data.w = osd_hw.fb_gem[index].xres; src_data.h = osd_hw.fb_gem[index].yres; + src_data.h = osd_hw.fb_gem[index].yres; +#ifdef CONFIG_AMLOGIC_VOUT2_SERVE vinfo = get_current_vinfo2(); if (!vinfo) { osd_log_err("current vinfo NULL\n"); return; } +#endif out_y_crop_start = 0; out_y_crop_end = vinfo->height; src_width = src_data.w; @@ -5331,13 +5776,12 @@ static u32 blend_din_to_osd( osd_index = blending->osd_to_bdin_table[blend_din_index]; - if (osd_index > OSD3) + if (osd_index >= osd_hw.osd_meson_dev.viu1_osd_count) return OSD_MAX; else return osd_index; } -#ifdef OSD_BLEND_SHIFT_WORKAROUND static u32 get_max_order(u32 order1, u32 order2) { u32 max_order = 0; @@ -5627,179 +6071,30 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending) blending->din_reoder_sel; } -#else -static void generate_blend_din_table(struct hw_osd_blending_s *blending) +static bool is_freescale_para_changed(u32 index) { - int i = 0; - int osd_count = osd_hw.osd_meson_dev.osd_count - 1; - - /* reorder[i] = osd[i]'s display layer */ - for (i = 0; i < OSD_BLEND_LAYERS; i++) - blending->osd_to_bdin_table[i] = -1; - blending->din_reoder_sel = 0; - switch (blending->layer_cnt) { - case 0: - break; - case 1: - for (i = 0; i < osd_count; i++) { - if (blending->reorder[i] != LAYER_UNSUPPORT) { - /* blend_din1 */ - blending->din_reoder_sel |= (i + 1) << 0; - /* blend_din1 -- osdx */ - blending->osd_to_bdin_table[0] = i; - break; - } - } - break; - case 2: - { - int temp_index[2] = {0}; - int j = 0; + static int first[HW_OSD_COUNT - 1] = {1}; + bool freescale_update = false; - for (i = 0; i < osd_count; i++) { - if (blending->reorder[i] != LAYER_UNSUPPORT) { - /* save the osd index */ - temp_index[j] = i; - j++; - } - } - osd_log_dbg(MODULE_BLEND, "blend_din4==%d\n", - blending->reorder[temp_index[0]]); - osd_log_dbg(MODULE_BLEND, "blend_din1==%d\n", - blending->reorder[temp_index[1]]); - /* mode A_C */ - if (blending->osd_blend_mode == OSD_BLEND_A_C) { - /* blend_din1 */ - blending->din_reoder_sel |= (temp_index[0] + 1) << 0; - /* blend_din1 -- osdx */ - blending->osd_to_bdin_table[0] = temp_index[0]; - /* blend_din3 */ - blending->din_reoder_sel |= (temp_index[1] + 1) << 12; - /* blend_din3 -- osdx */ - blending->osd_to_bdin_table[3] = temp_index[1]; - /* exchane vpp osd blend in order */ - if (blending->reorder[temp_index[0]] < - blending->reorder[temp_index[1]]) { - blending->b_exchange_blend_in = true; - osd_log_dbg(MODULE_BLEND, "need exchange vpp order\n"); - } - } else { - if (blending->reorder[temp_index[0]] < - blending->reorder[temp_index[1]]) { - /* blend_din4 */ - blending->din_reoder_sel |= - (temp_index[0] + 1) << 12; - /* blend_din3 -- osdx */ - blending->osd_to_bdin_table[3] = temp_index[0]; - /* blend_din1 */ - blending->din_reoder_sel |= - (temp_index[1] + 1) << 0; - /* blend_din1 -- osdx */ - blending->osd_to_bdin_table[0] = temp_index[1]; - blending->b_exchange_din = true; - osd_log_dbg(MODULE_BLEND, "need exchange osd din order\n"); - } else { - /* blend_din1 */ - blending->din_reoder_sel |= - (temp_index[0] + 1) << 0; - /* blend_din1 -- osdx */ - blending->osd_to_bdin_table[0] = temp_index[0]; - /* blend_din3 */ - blending->din_reoder_sel |= - (temp_index[1] + 1) << 12; - /* blend_din3 -- osdx */ - blending->osd_to_bdin_table[3] = temp_index[1]; - } - } - break; + if (memcmp(&(osd_hw.free_src_data[index]), + &osd_hw.free_src_data_backup[index], + sizeof(struct pandata_s)) != 0 || + memcmp(&(osd_hw.free_dst_data[index]), + &osd_hw.free_dst_data_backup[index], + sizeof(struct pandata_s)) != 0) { + memcpy(&(osd_hw.free_src_data_backup[index]), + &osd_hw.free_src_data[index], + sizeof(struct pandata_s)); + memcpy(&(osd_hw.free_dst_data_backup[index]), + &osd_hw.free_dst_data[index], + sizeof(struct pandata_s)); + freescale_update = true; } - case 3: - /* blend_din1 is bottom, blend_din4 is top layer */ - /* mode A_BC */ - /* osd0 always used blend_din1 */ - /* blend_din1 */ - blending->din_reoder_sel |= 1 << 0; - /* blend_din1 -- osd1 */ - blending->osd_to_bdin_table[0] = OSD1; - if (blending->reorder[OSD2] > blending->reorder[OSD3]) { - /* blend_din4 */ - blending->din_reoder_sel |= (OSD3 + 1) << 12; - /* blend_din4 -- osd3 */ - blending->osd_to_bdin_table[3] = OSD3; - - /* blend_din3 */ - blending->din_reoder_sel |= (OSD2 + 1) << 8; - /* blend_din3 -- osd2 */ - blending->osd_to_bdin_table[2] = OSD2; - } else { - /* blend_din3 */ - blending->din_reoder_sel |= (OSD2 + 1) << 12; - /* blend_din3 -- osd2 */ - blending->osd_to_bdin_table[3] = OSD2; - - /* blend_din3 */ - blending->din_reoder_sel |= (OSD3 + 1) << 8; - /* blend_din3 -- osd2 */ - blending->osd_to_bdin_table[2] = OSD3; - - } - if (blending->reorder[OSD1] < blending->reorder[OSD3]) { - if (blending->osd_blend_mode == OSD_BLEND_A_BC) { - blending->b_exchange_blend_in = true; - osd_log_dbg(MODULE_BLEND, "need exchange vpp order\n"); - } else { - u32 temp1, temp2; - - blending->b_exchange_din = true; - osd_log_dbg(MODULE_BLEND, "need exchange osd din order\n"); - temp1 = blending->osd_to_bdin_table[2]; - temp2 = blending->osd_to_bdin_table[3]; - blending->osd_to_bdin_table[3] = - blending->osd_to_bdin_table[0]; - blending->osd_to_bdin_table[2] = temp2; - blending->osd_to_bdin_table[0] = temp1; - temp1 = blending->din_reoder_sel & 0xf000; - temp2 = blending->din_reoder_sel & 0x0f00; - blending->din_reoder_sel = (1 << 12); - blending->din_reoder_sel |= temp1 >> 4; - blending->din_reoder_sel |= temp2 >> 8; - } - } - break; - } - osd_log_dbg(MODULE_BLEND, "osd_to_bdin_table[i]=[%x,%x,%x,%x]\n", - blending->osd_to_bdin_table[0], - blending->osd_to_bdin_table[1], - blending->osd_to_bdin_table[2], - blending->osd_to_bdin_table[3]); - blending->blend_reg.din_reoder_sel = - blending->din_reoder_sel; -} -#endif -static bool is_freescale_para_changed(u32 index) -{ - static int first[HW_OSD_COUNT - 1] = {1}; - bool freescale_update = false; - - if (memcmp(&(osd_hw.free_src_data[index]), - &osd_hw.free_src_data_backup[index], - sizeof(struct pandata_s)) != 0 || - memcmp(&(osd_hw.free_dst_data[index]), - &osd_hw.free_dst_data_backup[index], - sizeof(struct pandata_s)) != 0) { - memcpy(&(osd_hw.free_src_data_backup[index]), - &osd_hw.free_src_data[index], - sizeof(struct pandata_s)); - memcpy(&(osd_hw.free_dst_data_backup[index]), - &osd_hw.free_dst_data[index], - sizeof(struct pandata_s)); - freescale_update = true; - } - if (first[index]) - freescale_update = true; - first[index] = 0; - return freescale_update; -} + if (first[index]) + freescale_update = true; + first[index] = 0; + return freescale_update; +} static int osd_setting_blending_scope(u32 index) { @@ -5807,7 +6102,7 @@ static int osd_setting_blending_scope(u32 index) u32 bld_osd_v_start, bld_osd_v_end; u32 reg_offset = 2; - if (index > OSD3) { + if (index >= osd_hw.osd_meson_dev.viu1_osd_count) { osd_log_err("error osd index=%d\n", index); return -1; } @@ -5854,7 +6149,7 @@ static int vpp_blend_setting_default(u32 index) osd_log_dbg(MODULE_BASE, "vpp_blend_setting_default\n"); - if (index > OSD3) { + if (index >= osd_hw.osd_meson_dev.viu1_osd_count) { osd_log_err("error osd index=%d\n", index); return -1; } @@ -5877,8 +6172,6 @@ static int vpp_blend_setting_default(u32 index) osd1_v_start = osd_hw.dispdata[index].y_start; osd1_v_end = osd_hw.dispdata[index].y_end; } - VSYNCOSD_WR_MPEG_REG(VPP_OSD1_IN_SIZE, - osd1_dst_h | osd1_dst_v << 16); /* setting blend scope */ VSYNCOSD_WR_MPEG_REG(VPP_OSD1_BLD_H_SCOPE, @@ -5934,13 +6227,9 @@ static void set_blend_order(struct hw_osd_blending_s *blending) static void set_blend_din(struct hw_osd_blending_s *blending) { int i = 0, osd_index; -#ifdef OSD_BLEND_SHIFT_WORKAROUND /* workaround for shift issue */ /* blend_din_en must equal 5 */ u32 blend_din_en = 0x5; -#else - u32 blend_din_en = 0x9; -#endif if (!blending) return; @@ -5961,7 +6250,6 @@ static void set_blend_din(struct hw_osd_blending_s *blending) static void set_blend_mode(struct hw_osd_blending_s *blending) { u8 osd_blend_mode = OSD_BLEND_NONE; - //u32 osd_index; if (!blending) return; @@ -5985,11 +6273,7 @@ static void set_blend_mode(struct hw_osd_blending_s *blending) if (osd_hw.hdr_used) osd_blend_mode = OSD_BLEND_ABC; else -#ifdef OSD_BLEND_SHIFT_WORKAROUND osd_blend_mode = OSD_BLEND_AB_C; -#else - osd_blend_mode = OSD_BLEND_A_BC; -#endif break; } blending->osd_blend_mode = osd_blend_mode; @@ -6133,19 +6417,9 @@ static void osd_setting_blend1(struct hw_osd_blending_s *blending) } layer_blend = &(blending->layer_blend); blend_reg = &(blending->blend_reg); -#ifdef OSD_BLEND_SHIFT_WORKAROUND /* blend1_dout to blend2 */ blend_reg->din2_osd_sel = 0; -#else - /* input1 default route to blend1 */ - if (layer_blend->input1 & BYPASS_DIN) { - /* blend1_dout to dout1 */ - blend_reg->din2_osd_sel = 1; - layer_blend->input1 &= ~BYPASS_DIN; - } else - /* blend1_dout to blend2 */ - blend_reg->din2_osd_sel = 0; -#endif + if (layer_blend->input2 & BYPASS_DIN) { /* blend1_din3 bypass to dout1 */ blend_reg->din3_osd_sel = 1; @@ -6209,7 +6483,6 @@ static void osd_setting_blend1(struct hw_osd_blending_s *blending) } if (blend_reg->din3_osd_sel || layer_blend->input1 == BLEND_NO_DIN) { /* blend din3 bypass,output == input */ -#ifdef OSD_BLEND_SHIFT_WORKAROUND if (layer_blend->input2 == BLEND_NO_DIN) { memcpy(&layer_blend->output_data, &layer_blend->input1_data, @@ -6220,16 +6493,7 @@ static void osd_setting_blend1(struct hw_osd_blending_s *blending) sizeof(struct dispdata_s)); } layer_blend->output_data.h += workaround_line; -#else - layer_blend->output_data.x = 0; - layer_blend->output_data.y = 0; - layer_blend->output_data.w = - layer_blend->input2_data.x + - layer_blend->input2_data.w; - layer_blend->output_data.h = - layer_blend->input2_data.y + - layer_blend->input2_data.h; -#endif + } else calc_max_output(blending); blend_hsize = layer_blend->output_data.w; @@ -6262,7 +6526,6 @@ static void osd_setting_blend2(struct hw_osd_blending_s *blending) /* osd_blend_blend0_size share with blend2_size*/ blend_reg->osd_blend_blend0_size = blend_vsize << 16 | blend_hsize; -#ifdef OSD_BLEND_SHIFT_WORKAROUND switch (layer_blend->input2) { case BLEND1_DIN: blend1_input = 0; @@ -6272,19 +6535,7 @@ static void osd_setting_blend2(struct hw_osd_blending_s *blending) blend1_input = 1; break; } -#else - switch (layer_blend->input2) { - case BLEND1_DIN: - /* blend1_dout to blend2 */ - blend_reg->din2_osd_sel = 0; - break; - default: - /* blend1_dout to dout1 */ - blend_reg->din2_osd_sel = 1; - break; - } - blend1_input = blend_reg->din2_osd_sel; -#endif + /* premult set */ blend_reg->blend2_premult_en = 3; if (blend1_input) @@ -6296,11 +6547,9 @@ static void osd_setting_blend2(struct hw_osd_blending_s *blending) blend_vsize = layer_blend->output_data.h; blend_reg->osd_blend_blend0_size = blend_vsize << 16 | blend_hsize; -#ifdef OSD_BLEND_SHIFT_WORKAROUND /* blend 0 and blend1 size need same */ blend_reg->osd_blend_blend1_size = blend_reg->osd_blend_blend0_size; -#endif } osd_log_dbg2(MODULE_BLEND, "layer_blend2->output_data:%d,%d,%d,%d\n", layer_blend->output_data.x, @@ -6339,11 +6588,7 @@ static void vpp_setting_blend(struct hw_osd_blending_s *blending) switch (layer_blend->input1) { case BLEND1_DIN: blend_reg->postbld_src3_sel = POSTBLD_OSD2; -#ifdef OSD_BLEND_SHIFT_WORKAROUND if (layer_blend->blend_core1_bypass) -#else - if (blend_reg->din3_osd_sel) -#endif blend_reg->postbld_osd1_premult = 0; else blend_reg->postbld_osd1_premult = 1; @@ -6372,11 +6617,7 @@ static void vpp_setting_blend(struct hw_osd_blending_s *blending) switch (layer_blend->input2) { case BLEND1_DIN: blend_reg->postbld_src4_sel = POSTBLD_OSD2; -#ifdef OSD_BLEND_SHIFT_WORKAROUND if (layer_blend->blend_core1_bypass) -#else - if (blend_reg->din3_osd_sel) -#endif blend_reg->postbld_osd2_premult = 0; else blend_reg->postbld_osd2_premult = 1; @@ -6411,7 +6652,6 @@ static void vpp_setting_blend(struct hw_osd_blending_s *blending) blend_reg->vpp_osd2_blend_v_scope); } -/* input w, h is background */ static void osd_set_freescale(u32 index, struct hw_osd_blending_s *blending) @@ -6421,10 +6661,11 @@ static void osd_set_freescale(u32 index, u32 width, height; u32 src_height; u32 workaround_line = osd_hw.workaround_line; + u32 output_index = 0; layer_blend = &(blending->layer_blend); blend_reg = &(blending->blend_reg); - if (index > OSD3) { + if (index >= osd_hw.osd_meson_dev.viu1_osd_count) { osd_log_err("error osd index=%d\n", index); return; } @@ -6432,6 +6673,7 @@ static void osd_set_freescale(u32 index, osd_hw.free_scale[index].h_enable = 1; osd_hw.free_scale[index].v_enable = 1; osd_hw.free_scale_mode[index] = 1; + output_index = get_output_device_id(index); if (index == OSD1) { osd_hw.free_src_data[index].x_start = @@ -6447,11 +6689,13 @@ static void osd_set_freescale(u32 index, osd_hw.free_dst_data[index].x_start = 0; osd_hw.free_dst_data[index].y_start = 0; - width = layer_blend->output_data.w - * blending->screen_ratio_w >> OSD_CALC; - height = (layer_blend->output_data.h - workaround_line) - * blending->screen_ratio_h >> OSD_CALC; - if (osd_hw.field_out_en) + width = layer_blend->output_data.w * + blending->screen_ratio_w_num / + blending->screen_ratio_w_den; + height = (layer_blend->output_data.h - workaround_line) * + blending->screen_ratio_h_num / + blending->screen_ratio_h_den; + if (osd_hw.field_out_en[output_index]) height = height >> 1; } else { osd_hw.free_src_data[index].x_start = @@ -6469,15 +6713,19 @@ static void osd_set_freescale(u32 index, (blending->osd_blend_mode == OSD_BLEND_ABC)) { /* combine mode, need uniformization */ osd_hw.free_dst_data[index].x_start = - (osd_hw.dst_data[index].x << OSD_CALC) / - blending->screen_ratio_w; + osd_hw.dst_data[index].x * + blending->screen_ratio_w_den / + blending->screen_ratio_w_num; osd_hw.free_dst_data[index].y_start = - (osd_hw.dst_data[index].y << OSD_CALC) / - blending->screen_ratio_h; - width = (osd_hw.dst_data[index].w << OSD_CALC) / - blending->screen_ratio_w; - height = (osd_hw.dst_data[index].h << OSD_CALC) / - blending->screen_ratio_h; + osd_hw.dst_data[index].y * + blending->screen_ratio_h_den / + blending->screen_ratio_h_num; + width = osd_hw.dst_data[index].w * + blending->screen_ratio_w_den / + blending->screen_ratio_w_num; + height = osd_hw.dst_data[index].h * + blending->screen_ratio_h_den / + blending->screen_ratio_h_num; if (width > FREE_SCALE_MAX_WIDTH) width = FREE_SCALE_MAX_WIDTH; } else if (blending->osd_blend_mode == OSD_BLEND_AB_C) { @@ -6486,17 +6734,19 @@ static void osd_set_freescale(u32 index, if (blending->blend_din != BLEND_DIN4) { /* combine mode, need uniformization */ osd_hw.free_dst_data[index].x_start = - (osd_hw.dst_data[index].x << OSD_CALC) / - blending->screen_ratio_w; + osd_hw.dst_data[index].x * + blending->screen_ratio_w_den / + blending->screen_ratio_w_num; osd_hw.free_dst_data[index].y_start = - (osd_hw.dst_data[index].y << OSD_CALC) / - blending->screen_ratio_h; - width = (osd_hw.dst_data[index].w - << OSD_CALC) / - blending->screen_ratio_w; - height = (osd_hw.dst_data[index].h - << OSD_CALC) / - blending->screen_ratio_h; + osd_hw.dst_data[index].y * + blending->screen_ratio_h_den / + blending->screen_ratio_h_num; + width = osd_hw.dst_data[index].w * + blending->screen_ratio_w_den / + blending->screen_ratio_w_num; + height = osd_hw.dst_data[index].h * + blending->screen_ratio_h_den / + blending->screen_ratio_h_num; } else { /* direct used dst as freescale dst */ osd_hw.free_dst_data[index].x_start = @@ -6506,7 +6756,7 @@ static void osd_set_freescale(u32 index, width = osd_hw.dst_data[index].w; height = osd_hw.dst_data[index].h; /* interleaced case */ - if (osd_hw.field_out_en) { + if (osd_hw.field_out_en[output_index]) { height = height >> 1; osd_hw.free_dst_data[index].y_start >>= 1; @@ -6520,7 +6770,7 @@ static void osd_set_freescale(u32 index, osd_hw.dst_data[index].y; width = osd_hw.dst_data[index].w; height = osd_hw.dst_data[index].h; - if (osd_hw.field_out_en) { + if (osd_hw.field_out_en[output_index]) { height = height >> 1; osd_hw.free_dst_data[index].y_start >>= 1; } @@ -6650,7 +6900,6 @@ static void osd_setting_blend1_input(u32 index, layer_blend->output_data.h); } -/* every output is next path input */ static void set_blend_path(struct hw_osd_blending_s *blending) { struct layer_blend_s *layer_blend; @@ -6658,14 +6907,14 @@ static void set_blend_path(struct hw_osd_blending_s *blending) struct dispdata_s output1_data; u32 index = 0; u8 input1 = 0, input2 = 0; + u32 output_index; if (!blending) return; + output_index = get_output_device_id(index); layer_blend = &(blending->layer_blend); blend_reg = &(blending->blend_reg); -#ifdef OSD_BLEND_SHIFT_WORKAROUND layer_blend->blend_core1_bypass = 0; -#endif switch (blending->osd_blend_mode) { case OSD_BLEND_NONE: blend_reg->postbld_osd1_premult = 0; @@ -6706,13 +6955,13 @@ static void set_blend_path(struct hw_osd_blending_s *blending) layer_blend->input1_data.x = osd_hw.free_dst_data[index].x_start + - osd_hw.disp_info.position_x; + osd_hw.disp_info[output_index].position_x; layer_blend->input1_data.w = osd_hw.free_dst_data[index].x_end - osd_hw.free_dst_data[index].x_start + 1; layer_blend->input1_data.y = osd_hw.free_dst_data[index].y_start + - osd_hw.disp_info.position_y; + osd_hw.disp_info[output_index].position_y; layer_blend->input1_data.h = osd_hw.free_dst_data[index].y_end - osd_hw.free_dst_data[index].y_start + 1; @@ -6721,13 +6970,13 @@ static void set_blend_path(struct hw_osd_blending_s *blending) "first: set osd%d freescale\n", index); osd_set_freescale(index, blending); osd_hw.free_dst_data[index].x_start += - osd_hw.disp_info.position_x; + osd_hw.disp_info[output_index].position_x; osd_hw.free_dst_data[index].x_end += - osd_hw.disp_info.position_x; + osd_hw.disp_info[output_index].position_x; osd_hw.free_dst_data[index].y_start += - osd_hw.disp_info.position_y; + osd_hw.disp_info[output_index].position_y; osd_hw.free_dst_data[index].y_end += - osd_hw.disp_info.position_y; + osd_hw.disp_info[output_index].position_y; osd_setting_blend0_input(index, blending); osd_setting_blend0(blending); @@ -6773,9 +7022,6 @@ static void set_blend_path(struct hw_osd_blending_s *blending) index = blend_din_to_osd(input1, blending); if (index >= OSD_MAX) return; -#ifndef OSD_BLEND_SHIFT_WORKAROUND - osd_setting_blend0_input(index, blending); -#endif if (index != OSD1) { /* here used freescale osd1/osd2 */ osd_log_dbg2(MODULE_BLEND, @@ -6783,9 +7029,7 @@ static void set_blend_path(struct hw_osd_blending_s *blending) index); osd_set_freescale(index, blending); } -#ifdef OSD_BLEND_SHIFT_WORKAROUND osd_setting_blend0_input(index, blending); -#endif osd_setting_blend0(blending); memcpy(&output1_data, &(layer_blend->output_data), sizeof(struct dispdata_s)); @@ -6801,22 +7045,7 @@ static void set_blend_path(struct hw_osd_blending_s *blending) } layer_blend->input1 = BLEND_NO_DIN; layer_blend->input2 = input2; -#ifndef OSD_BLEND_SHIFT_WORKAROUND - if (osd_hw.blend_bypass) - layer_blend->input2 |= BYPASS_DIN; -#endif -#if 0 - layer_blend->input2_data.x = - osd_hw.free_dst_data[index].x_start; - layer_blend->input2_data.w = - osd_hw.free_dst_data[index].x_end - - osd_hw.free_dst_data[index].x_start + 1; - layer_blend->input2_data.y = - osd_hw.free_dst_data[index].y_start; - layer_blend->input2_data.h = - osd_hw.free_dst_data[index].y_end - - osd_hw.free_dst_data[index].y_start + 1; -#endif + osd_setting_blend1_input(index, blending); memcpy(&layer_blend->input2_data, &layer_blend->output_data, @@ -6838,13 +7067,13 @@ static void set_blend_path(struct hw_osd_blending_s *blending) layer_blend->input2 = BLEND_NO_DIN; layer_blend->input1_data.x = osd_hw.free_dst_data[OSD1].x_start + - osd_hw.disp_info.position_x; + osd_hw.disp_info[output_index].position_x; layer_blend->input1_data.w = osd_hw.free_dst_data[OSD1].x_end - osd_hw.free_dst_data[OSD1].x_start + 1; layer_blend->input1_data.y = osd_hw.free_dst_data[OSD1].y_start + - osd_hw.disp_info.position_y; + osd_hw.disp_info[output_index].position_y; layer_blend->input1_data.h = osd_hw.free_dst_data[OSD1].y_end - osd_hw.free_dst_data[OSD1].y_start + 1; @@ -6882,20 +7111,20 @@ static void set_blend_path(struct hw_osd_blending_s *blending) /* save freescale output */ output1_data.x = osd_hw.free_dst_data[index].x_start + - osd_hw.disp_info.position_x; + osd_hw.disp_info[output_index].position_x; output1_data.w = osd_hw.free_dst_data[index].x_end - osd_hw.free_dst_data[index].x_start + 1; output1_data.y = osd_hw.free_dst_data[index].y_start + - osd_hw.disp_info.position_y; + osd_hw.disp_info[output_index].position_y; output1_data.h = osd_hw.free_dst_data[index].y_end - osd_hw.free_dst_data[index].y_start + 1; osd_log_dbg2(MODULE_BLEND, "position_x=%d, y=%d\n", - osd_hw.disp_info.position_x, - osd_hw.disp_info.position_y); + osd_hw.disp_info[output_index].position_x, + osd_hw.disp_info[output_index].position_y); index = blend_din_to_osd(BLEND_DIN4, blending); if (index >= OSD_MAX) @@ -6904,41 +7133,19 @@ static void set_blend_path(struct hw_osd_blending_s *blending) osd_log_dbg2(MODULE_BLEND, "before blend1: set osd%d freescale\n", index); osd_set_freescale(index, blending); -#ifdef OSD_BLEND_SHIFT_WORKAROUND layer_blend->input1 = BLEND_NO_DIN; /* must bypass for shift workaround */ layer_blend->input2 = BLEND_DIN4 | BYPASS_DIN; layer_blend->blend_core1_bypass = 1; -#else - /* always route(bypass) to dout1 */ - layer_blend->input1 = BLEND_NO_DIN | BYPASS_DIN; - layer_blend->input2 = BLEND_DIN4; - if (osd_hw.blend_bypass) - layer_blend->input2 |= BYPASS_DIN; -#endif - #if 0 - layer_blend->input2_data.x = - osd_hw.free_dst_data[index].x_start + - osd_hw.disp_info.position_x; - layer_blend->input2_data.w = - osd_hw.free_dst_data[index].x_end - - osd_hw.free_dst_data[index].x_start + 1; - layer_blend->input2_data.y = - osd_hw.free_dst_data[index].y_start + - osd_hw.disp_info.position_y; - layer_blend->input2_data.h = - osd_hw.free_dst_data[index].y_end - - osd_hw.free_dst_data[index].y_start + 1; - #endif osd_setting_blend1_input(index, blending); memcpy(&layer_blend->input2_data, &layer_blend->output_data, sizeof(struct dispdata_s)); /* adjust offset*/ layer_blend->input2_data.x += - osd_hw.disp_info.position_x; + osd_hw.disp_info[output_index].position_x; layer_blend->input2_data.y += - osd_hw.disp_info.position_y; + osd_hw.disp_info[output_index].position_y; osd_setting_blend1(blending); @@ -7014,10 +7221,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) layer_blend->input2 = BLEND1_DIN; memcpy(&layer_blend->input1_data, &output1_data, sizeof(struct dispdata_s)); -#ifdef OSD_BLEND_SHIFT_WORKAROUND memcpy(&layer_blend->input2_data, &layer_blend->output_data, sizeof(struct dispdata_s)); -#endif osd_setting_blend2(blending); /* used osd0 freescale */ osd_set_freescale(OSD1, blending); @@ -7026,21 +7231,600 @@ static void set_blend_path(struct hw_osd_blending_s *blending) layer_blend->input2 = BLEND_NO_DIN; layer_blend->input1_data.x = osd_hw.free_dst_data[OSD1].x_start + - osd_hw.disp_info.position_x; + osd_hw.disp_info[output_index].position_x; layer_blend->input1_data.w = osd_hw.free_dst_data[OSD1].x_end - osd_hw.free_dst_data[OSD1].x_start + 1; layer_blend->input1_data.y = osd_hw.free_dst_data[OSD1].y_start + - osd_hw.disp_info.position_y; + osd_hw.disp_info[output_index].position_y; layer_blend->input1_data.h = osd_hw.free_dst_data[OSD1].y_end - osd_hw.free_dst_data[OSD1].y_start + 1; vpp_setting_blend(blending); break; - case OSD_BLEND_A_BC: - /* blend0 -->blend2-->sc->vpp_osd1 */ - /* 2input-->sc-->blend1 -->vpp_osd2 */ + case OSD_BLEND_A_BC: + /* blend0 -->blend2-->sc->vpp_osd1 */ + /* 2input-->sc-->blend1 -->vpp_osd2 */ + layer_blend->input1 = BLEND_DIN1; + if (osd_hw.blend_bypass) + layer_blend->input1 |= BYPASS_DIN; + layer_blend->input2 = BLEND_NO_DIN; + index = blend_din_to_osd(BLEND_DIN1, blending); + if (index >= OSD_MAX) + return; + osd_setting_blend0_input(index, blending); + osd_setting_blend0(blending); + + if (!blend_reg->din0_byp_blend) { + layer_blend->input1 = BLEND0_DIN; + layer_blend->input2 = BLEND_NO_DIN; + memcpy(&layer_blend->input1_data, + &layer_blend->output_data, + sizeof(struct dispdata_s)); + /* background is same with blend0's background */ + osd_setting_blend2(blending); + } + + osd_log_dbg(MODULE_BLEND, + "after blend2: set osd%d freescale\n", index); + osd_set_freescale(index, blending); + /* save freescale output */ + output1_data.x = + osd_hw.free_dst_data[index].x_start + + osd_hw.disp_info[output_index].position_x; + output1_data.w = + osd_hw.free_dst_data[index].x_end - + osd_hw.free_dst_data[index].x_start + 1; + output1_data.y = + osd_hw.free_dst_data[index].y_start + + osd_hw.disp_info[output_index].position_y; + output1_data.h = + osd_hw.free_dst_data[index].y_end - + osd_hw.free_dst_data[index].y_start + 1; + index = blend_din_to_osd(BLEND_DIN3, blending); + if (index >= OSD_MAX) + return; + osd_log_dbg2(MODULE_BLEND, + "before blend1: set osd%d freescale\n", index); + osd_set_freescale(index, blending); + layer_blend->input1_data.x = + osd_hw.free_dst_data[index].x_start + + osd_hw.disp_info[output_index].position_x; + layer_blend->input1_data.w = + osd_hw.free_dst_data[index].x_end - + osd_hw.free_dst_data[index].x_start + 1; + layer_blend->input1_data.y = + osd_hw.free_dst_data[index].y_start + + osd_hw.disp_info[output_index].position_y; + layer_blend->input1_data.h = + osd_hw.free_dst_data[index].y_end - + osd_hw.free_dst_data[index].y_start + 1; + + index = blend_din_to_osd(BLEND_DIN4, blending); + if (index >= OSD_MAX) + return; + osd_log_dbg2(MODULE_BLEND, + "before blend1: set osd%d freescale\n", index); + osd_set_freescale(index, blending); + layer_blend->input2_data.x = + osd_hw.free_dst_data[index].x_start + + osd_hw.disp_info[output_index].position_x; + layer_blend->input2_data.w = + osd_hw.free_dst_data[index].x_end - + osd_hw.free_dst_data[index].x_start + 1; + layer_blend->input2_data.y = + osd_hw.free_dst_data[index].y_start + + osd_hw.disp_info[output_index].position_y; + layer_blend->input2_data.h = + osd_hw.free_dst_data[index].y_end - + osd_hw.free_dst_data[index].y_start + 1; + + /* always route(bypass) to dout1 */ + layer_blend->input1 = BLEND_DIN3 | BYPASS_DIN; + layer_blend->input2 = BLEND_DIN4; + + osd_setting_blend1(blending); + + if (!blending->b_exchange_blend_in) { + layer_blend->input1 = BLEND2_DIN; + layer_blend->input2 = BLEND1_DIN; + memcpy(&layer_blend->input1_data, &output1_data, + sizeof(struct dispdata_s)); + memcpy(&layer_blend->input2_data, + &layer_blend->output_data, + sizeof(struct dispdata_s)); + } else { + layer_blend->input1 = BLEND1_DIN; + layer_blend->input2 = BLEND2_DIN; + memcpy(&layer_blend->input1_data, + &layer_blend->output_data, + sizeof(struct dispdata_s)); + memcpy(&layer_blend->input2_data, + &output1_data, + sizeof(struct dispdata_s)); + } + vpp_setting_blend(blending); + break; + case OSD_BLEND_AB_C: + /* blend0 -->blend2-->sc->vpp_osd1 */ + /* sc-->blend1-->blend2-->sc-->vpp_osd1 */ + /* sc -->vpp_osd2 */ + layer_blend->input1 = BLEND_DIN1; + layer_blend->input2 = BLEND_NO_DIN; + blending->blend_din = BLEND_DIN1; + index = blend_din_to_osd(BLEND_DIN1, blending); + if (index != OSD1) { + osd_log_info("index=%d, need set freescale\n", index); + osd_set_freescale(index, blending); + } + osd_setting_blend0_input(index, blending); + osd_setting_blend0(blending); + /* save blend0 output */ + memcpy(&output1_data, &(layer_blend->output_data), + sizeof(struct dispdata_s)); + + /* din3 input to blend1 */ + layer_blend->input1 = BLEND_DIN3; + layer_blend->input2 = BLEND_NO_DIN | BYPASS_DIN; + layer_blend->blend_core1_bypass = 1; + blending->blend_din = BLEND_DIN3; + index = blend_din_to_osd(BLEND_DIN3, blending); + if (index != OSD1) { + osd_log_dbg2(MODULE_BLEND, + "before blend1: set osd%d freescale\n", + index); + osd_set_freescale(index, blending); + } + osd_setting_blend1_input(index, blending); + memcpy(&layer_blend->input1_data, + &layer_blend->output_data, + sizeof(struct dispdata_s)); + osd_setting_blend1(blending); + + /* din1=>blend0 & din3-> blend1 ==> blend2 */ + layer_blend->input1 = BLEND0_DIN; + layer_blend->input2 = BLEND1_DIN; + memcpy(&layer_blend->input1_data, &output1_data, + sizeof(struct dispdata_s)); + memcpy(&layer_blend->input2_data, &layer_blend->output_data, + sizeof(struct dispdata_s)); + osd_setting_blend2(blending); + + /* blend2 ==> osd0 freescale */ + osd_set_freescale(OSD1, blending); + output1_data.x = + osd_hw.free_dst_data[OSD1].x_start + + osd_hw.disp_info[output_index].position_x; + output1_data.w = + osd_hw.free_dst_data[OSD1].x_end - + osd_hw.free_dst_data[OSD1].x_start + 1; + output1_data.y = + osd_hw.free_dst_data[OSD1].y_start + + osd_hw.disp_info[output_index].position_y; + output1_data.h = + osd_hw.free_dst_data[OSD1].y_end - + osd_hw.free_dst_data[OSD1].y_start + 1; + osd_log_dbg2(MODULE_BLEND, "output1_data:%d,%d,%d,%d\n", + output1_data.x, + output1_data.w, + output1_data.y, + output1_data.h); + + + /* din4 ==> vpp */ + index = blend_din_to_osd(BLEND_DIN4, blending); + blending->blend_din = BLEND_DIN4; + osd_log_dbg2(MODULE_BLEND, + "bypass blend1: set osd%d freescale\n", index); + osd_set_freescale(index, blending); + + layer_blend->input2_data.x = + osd_hw.free_dst_data[index].x_start + + osd_hw.disp_info[output_index].position_x; + layer_blend->input2_data.w = + osd_hw.free_dst_data[index].x_end - + osd_hw.free_dst_data[index].x_start + 1; + layer_blend->input2_data.y = + osd_hw.free_dst_data[index].y_start + + osd_hw.disp_info[output_index].position_y; + layer_blend->input2_data.h = + osd_hw.free_dst_data[index].y_end - + osd_hw.free_dst_data[index].y_start + 1; + + /* 2vpp input */ + if (!blending->b_exchange_blend_in) { + layer_blend->input1 = BLEND2_DIN; + layer_blend->input2 = BLEND1_DIN; + memcpy(&layer_blend->input1_data, &output1_data, + sizeof(struct dispdata_s)); + } else { + layer_blend->input1 = BLEND1_DIN; + layer_blend->input2 = BLEND2_DIN; + memcpy(&layer_blend->input1_data, + &layer_blend->input2_data, + sizeof(struct dispdata_s)); + memcpy(&layer_blend->input2_data, + &output1_data, + sizeof(struct dispdata_s)); + } + vpp_setting_blend(blending); + break; + } +} + +static void osd_setting_blend0_new(struct hw_osd_blending_s *blending) +{ + struct layer_blend_reg_s *blend_reg; + struct layer_blend_s *layer_blend; + u32 index = 0; + u32 bld_osd_h_start = 0, bld_osd_h_end = 0; + u32 bld_osd_v_start = 0, bld_osd_v_end = 0; + + if (!blending) + return; + layer_blend = &(blending->layer_blend); + blend_reg = &(blending->blend_reg); + /* blend0 only accept input1 */ + if (layer_blend->input1 & BYPASS_DIN) { + blend_reg->din0_byp_blend = 1; + layer_blend->input1 &= ~BYPASS_DIN; + } else + blend_reg->din0_byp_blend = 0; + if (layer_blend->input1 != BLEND_NO_DIN) { + /* calculate osd blend din scope */ + index = blend_din_to_osd(layer_blend->input1, blending); + if (index >= OSD_MAX) + return; + layer_blend->input1_data.x = + osd_hw.free_dst_data[index].x_start; + layer_blend->input1_data.y = + osd_hw.free_dst_data[index].y_start; + layer_blend->input1_data.w = + osd_hw.free_dst_data[index].x_end - + osd_hw.free_dst_data[index].x_start + 1; + layer_blend->input1_data.h = + osd_hw.free_dst_data[index].y_end - + osd_hw.free_dst_data[index].y_start + 1; + + bld_osd_h_start = + layer_blend->input1_data.x; + bld_osd_h_end = + layer_blend->input1_data.x + + layer_blend->input1_data.w - 1; + bld_osd_v_start = + layer_blend->input1_data.y; + bld_osd_v_end = + layer_blend->input1_data.y + + layer_blend->input1_data.h - 1; + blend_reg->osd_blend_din_scope_h[index] = + bld_osd_h_end << 16 | bld_osd_h_start; + blend_reg->osd_blend_din_scope_v[index] = + bld_osd_v_end << 16 | bld_osd_v_start; + } + layer_blend->output_data.x = 0; + layer_blend->output_data.y = 0; + layer_blend->output_data.w = layer_blend->input1_data.x + + layer_blend->input1_data.w; + layer_blend->output_data.h = layer_blend->input1_data.y + + layer_blend->input1_data.h; + osd_log_dbg2(MODULE_BLEND, + "blend0:input1_data[osd%d]:%d,%d,%d,%d\n", + index, + layer_blend->input1_data.x, + layer_blend->input1_data.y, + layer_blend->input1_data.w, + layer_blend->input1_data.h); + osd_log_dbg2(MODULE_BLEND, + "blend0:layer_blend->output_data:%d,%d,%d,%d\n", + layer_blend->output_data.x, + layer_blend->output_data.y, + layer_blend->output_data.w, + layer_blend->output_data.h); +} + +static void osd_setting_blend1_new(struct hw_osd_blending_s *blending) +{ + struct layer_blend_s *layer_blend; + struct layer_blend_reg_s *blend_reg; + u32 index = 0; + u32 blend_hsize, blend_vsize; + u32 bld_osd_h_start = 0, bld_osd_h_end = 0; + u32 bld_osd_v_start = 0, bld_osd_v_end = 0; + /* for g12a blend shift issue */ + + if (!blending) + return; + layer_blend = &(blending->layer_blend); + blend_reg = &(blending->blend_reg); + /* blend1_dout to blend2 */ + blend_reg->din2_osd_sel = 0; + + if (layer_blend->input2 & BYPASS_DIN) { + /* blend1_din3 bypass to dout1 */ + blend_reg->din3_osd_sel = 1; + layer_blend->input2 &= ~BYPASS_DIN; + } else + /* blend1_din3 input to blend1 */ + blend_reg->din3_osd_sel = 0; + + if (layer_blend->input1 != BLEND_NO_DIN) { + index = blend_din_to_osd(layer_blend->input1, blending); + if (index >= OSD_MAX) + return; + layer_blend->input1_data.x = + osd_hw.free_dst_data[index].x_start; + layer_blend->input1_data.y = + osd_hw.free_dst_data[index].y_start; + layer_blend->input1_data.w = + osd_hw.free_dst_data[index].x_end - + osd_hw.free_dst_data[index].x_start + 1; + layer_blend->input1_data.h = + osd_hw.free_dst_data[index].y_end - + osd_hw.free_dst_data[index].y_start + 1; + + /* calculate osd blend din scope */ + bld_osd_h_start = + layer_blend->input1_data.x; + bld_osd_h_end = + layer_blend->input1_data.x + + layer_blend->input1_data.w - 1; + bld_osd_v_start = + layer_blend->input1_data.y; + bld_osd_v_end = + layer_blend->input1_data.y + + layer_blend->input1_data.h - 1; + blend_reg->osd_blend_din_scope_h[index] = + bld_osd_h_end << 16 | bld_osd_h_start; + blend_reg->osd_blend_din_scope_v[index] = + bld_osd_v_end << 16 | bld_osd_v_start; + osd_log_dbg2(MODULE_BLEND, + "blend1:input1_data(osd%d):%d,%d,%d,%d\n", + index, + layer_blend->input1_data.x, + layer_blend->input1_data.y, + layer_blend->input1_data.w, + layer_blend->input1_data.h); + } + if (layer_blend->input2 != BLEND_NO_DIN) { + index = blend_din_to_osd(layer_blend->input2, blending); + if (index >= OSD_MAX) + return; + layer_blend->input2_data.x = + osd_hw.free_dst_data[index].x_start; + layer_blend->input2_data.y = + osd_hw.free_dst_data[index].y_start; + layer_blend->input2_data.w = + osd_hw.free_dst_data[index].x_end - + osd_hw.free_dst_data[index].x_start + 1; + layer_blend->input2_data.h = + osd_hw.free_dst_data[index].y_end - + osd_hw.free_dst_data[index].y_start + 1; + /* calculate osd blend din scope */ + bld_osd_h_start = + layer_blend->input2_data.x; + bld_osd_h_end = + layer_blend->input2_data.x + + layer_blend->input2_data.w - 1; + bld_osd_v_start = + layer_blend->input2_data.y; + bld_osd_v_end = + layer_blend->input2_data.y + + layer_blend->input2_data.h - 1; + blend_reg->osd_blend_din_scope_h[index] = + bld_osd_h_end << 16 | bld_osd_h_start; + blend_reg->osd_blend_din_scope_v[index] = + bld_osd_v_end << 16 | bld_osd_v_start; + osd_log_dbg2(MODULE_BLEND, + "layer_blend->input2_data:%d,%d,%d,%d\n", + layer_blend->input2_data.x, + layer_blend->input2_data.y, + layer_blend->input2_data.w, + layer_blend->input2_data.h); + } + if (blend_reg->din3_osd_sel || layer_blend->input1 == BLEND_NO_DIN) { + /* blend din3 bypass,output == input */ + if (layer_blend->input2 == BLEND_NO_DIN) { + memcpy(&layer_blend->output_data, + &layer_blend->input1_data, + sizeof(struct dispdata_s)); + } else { + memcpy(&layer_blend->output_data, + &layer_blend->input2_data, + sizeof(struct dispdata_s)); + } + } else + calc_max_output(blending); + blend_hsize = layer_blend->output_data.w; + blend_vsize = layer_blend->output_data.h; + blend_reg->osd_blend_blend1_size = + blend_vsize << 16 | blend_hsize; + + osd_log_dbg2(MODULE_BLEND, "layer_blend1->output_data:%d,%d,%d,%d\n", + layer_blend->output_data.x, + layer_blend->output_data.y, + layer_blend->output_data.w, + layer_blend->output_data.h); +} + +/* input w, h is background */ +static void osd_set_freescale_new(u32 index, + struct hw_osd_blending_s *blending) + +{ + struct layer_blend_s *layer_blend; + struct layer_blend_reg_s *blend_reg; + u32 width, height; + u32 src_height; + u32 output_index; + + layer_blend = &(blending->layer_blend); + blend_reg = &(blending->blend_reg); + if (index >= osd_hw.osd_meson_dev.viu1_osd_count) { + osd_log_err("error osd index=%d\n", index); + return; + } + output_index = get_output_device_id(index); + osd_hw.free_scale_enable[index] = 0x10001; + osd_hw.free_scale[index].h_enable = 1; + osd_hw.free_scale[index].v_enable = 1; + osd_hw.free_scale_mode[index] = 1; + + osd_hw.free_src_data[index].x_start = + osd_hw.src_data[index].x; + osd_hw.free_src_data[index].x_end = + osd_hw.src_data[index].x + + osd_hw.src_data[index].w - 1; + osd_hw.free_src_data[index].y_start = + osd_hw.src_data[index].y; + osd_hw.free_src_data[index].y_end = + osd_hw.src_data[index].y + + osd_hw.src_data[index].h - 1; + + /* direct used dst as freescale dst */ + osd_hw.free_dst_data[index].x_start = + osd_hw.dst_data[index].x; + osd_hw.free_dst_data[index].y_start = + osd_hw.dst_data[index].y; + width = osd_hw.dst_data[index].w; + height = osd_hw.dst_data[index].h; + if (osd_hw.field_out_en[output_index]) { + height = height >> 1; + osd_hw.free_dst_data[index].y_start >>= 1; + } + osd_hw.free_dst_data[index].x_end = + osd_hw.free_dst_data[index].x_start + + width - 1; + osd_hw.free_dst_data[index].y_end = + osd_hw.free_dst_data[index].y_start + + height - 1; + + src_height = osd_hw.free_src_data[index].x_end - + osd_hw.free_src_data[index].x_start + 1; + osd_set_dummy_data(index, 0xff); + osd_log_dbg2(MODULE_BLEND, "osd%d:free_src_data:%d,%d,%d,%d\n", + index, + osd_hw.free_src_data[index].x_start, + osd_hw.free_src_data[index].y_start, + osd_hw.free_src_data[index].x_end, + osd_hw.free_src_data[index].y_end); + osd_log_dbg2(MODULE_BLEND, "osd%d:free_dst_data:%d,%d,%d,%d\n", + index, + osd_hw.free_dst_data[index].x_start, + osd_hw.free_dst_data[index].y_start, + osd_hw.free_dst_data[index].x_end, + osd_hw.free_dst_data[index].y_end); +} + +/* every output is next path input */ +static void set_blend_path_new(struct hw_osd_blending_s *blending) +{ + struct layer_blend_s *layer_blend; + struct layer_blend_reg_s *blend_reg; + struct dispdata_s output1_data; + u32 index = 0; + u8 input1 = 0, input2 = 0; + u32 output_index; + + if (!blending) + return; + output_index = get_output_device_id(index); + + layer_blend = &(blending->layer_blend); + blend_reg = &(blending->blend_reg); + layer_blend->blend_core1_bypass = 0; + switch (blending->osd_blend_mode) { + case OSD_BLEND_NONE: + blend_reg->postbld_osd1_premult = 0; + blend_reg->postbld_src4_sel = POSTBLD_CLOSE; + blend_reg->postbld_src3_sel = POSTBLD_CLOSE; + blend_reg->postbld_osd2_premult = 0; + break; + case OSD_BLEND_A: + /* sc-->blend0-->blend2-->vpp_osd1 */ + layer_blend->input1 = BLEND_DIN1; + if (osd_hw.blend_bypass) + layer_blend->input1 |= BYPASS_DIN; + layer_blend->input2 = BLEND_NO_DIN; + index = blend_din_to_osd(BLEND_DIN1, blending); + if (index >= OSD_MAX) + return; + osd_set_freescale_new(index, blending); + osd_setting_blend0_new(blending); + if (!blend_reg->din0_byp_blend) { + layer_blend->input1 = BLEND0_DIN; + layer_blend->input2 = BLEND_NO_DIN; + memcpy(&layer_blend->input1_data, + &layer_blend->output_data, + sizeof(struct dispdata_s)); + /* same with blend0's background */ + osd_setting_blend2(blending); + } + layer_blend->input1 = BLEND2_DIN; + layer_blend->input2 = BLEND_NO_DIN; + memcpy(&(layer_blend->input1_data), + &(layer_blend->output_data), + sizeof(struct dispdata_s)); + layer_blend->input1_data.x += + osd_hw.disp_info[output_index].position_x; + layer_blend->input1_data.y += + osd_hw.disp_info[output_index].position_y; + vpp_setting_blend(blending); + break; + case OSD_BLEND_AC: + /* sc-->blend0 -->blend1-->blend2-->vpp_osd1 */ + /* sc-->blend0 & blend1-->blend2-->vpp_osd1 */ + if (!blending->b_exchange_din) { + input1 = BLEND_DIN1; + input2 = BLEND_DIN4; + } else { + input1 = BLEND_DIN4; + input2 = BLEND_DIN1; + } + layer_blend->input1 = input1; + layer_blend->input2 = BLEND_NO_DIN; + index = blend_din_to_osd(input1, blending); + if (index >= OSD_MAX) + return; + osd_set_freescale_new(index, blending); + osd_setting_blend0_new(blending); + /* save blend0 output */ + memcpy(&output1_data, &(layer_blend->output_data), + sizeof(struct dispdata_s)); + + index = blend_din_to_osd(input2, blending); + if (index >= OSD_MAX) + return; + osd_set_freescale_new(index, blending); + layer_blend->input1 = BLEND_NO_DIN; + layer_blend->input2 = input2; + osd_setting_blend1_new(blending); + + layer_blend->input1 = BLEND0_DIN; + layer_blend->input2 = BLEND1_DIN; + + /* blend0 output-> blend2 input1 */ + memcpy(&layer_blend->input1_data, &output1_data, + sizeof(struct dispdata_s)); + /* blend1 output-> blend2 input2 */ + memcpy(&layer_blend->input2_data, &layer_blend->output_data, + sizeof(struct dispdata_s)); + osd_setting_blend2(blending); + + layer_blend->input1 = BLEND2_DIN; + layer_blend->input2 = BLEND_NO_DIN; + memcpy(&(layer_blend->input1_data), + &(layer_blend->output_data), + sizeof(struct dispdata_s)); + layer_blend->input1_data.x += + osd_hw.disp_info[output_index].position_x; + layer_blend->input1_data.y += + osd_hw.disp_info[output_index].position_y; + vpp_setting_blend(blending); + break; + case OSD_BLEND_A_C: + /* sc-->blend0 -->blend2->vpp_osd1 */ + /* sc-->blend1 -->vpp_osd2 */ layer_blend->input1 = BLEND_DIN1; if (osd_hw.blend_bypass) layer_blend->input1 |= BYPASS_DIN; @@ -7048,9 +7832,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) index = blend_din_to_osd(BLEND_DIN1, blending); if (index >= OSD_MAX) return; - osd_setting_blend0_input(index, blending); - osd_setting_blend0(blending); - + osd_set_freescale_new(index, blending); + osd_setting_blend0_new(blending); if (!blend_reg->din0_byp_blend) { layer_blend->input1 = BLEND0_DIN; layer_blend->input2 = BLEND_NO_DIN; @@ -7060,66 +7843,28 @@ static void set_blend_path(struct hw_osd_blending_s *blending) /* background is same with blend0's background */ osd_setting_blend2(blending); } - - osd_log_dbg(MODULE_BLEND, - "after blend2: set osd%d freescale\n", index); - osd_set_freescale(index, blending); - /* save freescale output */ - output1_data.x = - osd_hw.free_dst_data[index].x_start + - osd_hw.disp_info.position_x; - output1_data.w = - osd_hw.free_dst_data[index].x_end - - osd_hw.free_dst_data[index].x_start + 1; - output1_data.y = - osd_hw.free_dst_data[index].y_start + - osd_hw.disp_info.position_y; - output1_data.h = - osd_hw.free_dst_data[index].y_end - - osd_hw.free_dst_data[index].y_start + 1; - index = blend_din_to_osd(BLEND_DIN3, blending); - if (index >= OSD_MAX) - return; - osd_log_dbg2(MODULE_BLEND, - "before blend1: set osd%d freescale\n", index); - osd_set_freescale(index, blending); - layer_blend->input1_data.x = - osd_hw.free_dst_data[index].x_start + - osd_hw.disp_info.position_x; - layer_blend->input1_data.w = - osd_hw.free_dst_data[index].x_end - - osd_hw.free_dst_data[index].x_start + 1; - layer_blend->input1_data.y = - osd_hw.free_dst_data[index].y_start + - osd_hw.disp_info.position_y; - layer_blend->input1_data.h = - osd_hw.free_dst_data[index].y_end - - osd_hw.free_dst_data[index].y_start + 1; + /* save blend0/blend2 output */ + memcpy(&output1_data, &(layer_blend->output_data), + sizeof(struct dispdata_s)); + /* adjust input 1 offset*/ + output1_data.x += + osd_hw.disp_info[output_index].position_x; + output1_data.y += + osd_hw.disp_info[output_index].position_y; index = blend_din_to_osd(BLEND_DIN4, blending); if (index >= OSD_MAX) return; - osd_log_dbg2(MODULE_BLEND, - "before blend1: set osd%d freescale\n", index); - osd_set_freescale(index, blending); - layer_blend->input2_data.x = - osd_hw.free_dst_data[index].x_start + - osd_hw.disp_info.position_x; - layer_blend->input2_data.w = - osd_hw.free_dst_data[index].x_end - - osd_hw.free_dst_data[index].x_start + 1; - layer_blend->input2_data.y = - osd_hw.free_dst_data[index].y_start + - osd_hw.disp_info.position_y; - layer_blend->input2_data.h = - osd_hw.free_dst_data[index].y_end - - osd_hw.free_dst_data[index].y_start + 1; - - /* always route(bypass) to dout1 */ - layer_blend->input1 = BLEND_DIN3 | BYPASS_DIN; - layer_blend->input2 = BLEND_DIN4; - - osd_setting_blend1(blending); + osd_set_freescale_new(index, blending); + layer_blend->input1 = BLEND_NO_DIN; + layer_blend->input2 = BLEND_DIN4 | BYPASS_DIN; + layer_blend->blend_core1_bypass = 1; + osd_setting_blend1_new(blending); + /* adjust input 2 offset*/ + layer_blend->output_data.x += + osd_hw.disp_info[output_index].position_x; + layer_blend->output_data.y += + osd_hw.disp_info[output_index].position_y; if (!blending->b_exchange_blend_in) { layer_blend->input1 = BLEND2_DIN; @@ -7135,27 +7880,66 @@ static void set_blend_path(struct hw_osd_blending_s *blending) memcpy(&layer_blend->input1_data, &layer_blend->output_data, sizeof(struct dispdata_s)); - memcpy(&layer_blend->input2_data, - &output1_data, + memcpy(&layer_blend->input2_data, &output1_data, sizeof(struct dispdata_s)); } vpp_setting_blend(blending); break; -#ifdef OSD_BLEND_SHIFT_WORKAROUND + case OSD_BLEND_ABC: + /* sc->blend0 -->blend2-->vpp_osd1 */ + /* sc-->blend1 -->blend2 */ + input1 = BLEND_DIN1; + input2 = BLEND_DIN4; + layer_blend->input1 = input1; + layer_blend->input2 = BLEND_NO_DIN; + index = blend_din_to_osd(input1, blending); + if (index >= OSD_MAX) + return; + osd_set_freescale_new(index, blending); + osd_setting_blend0_new(blending); + /* save blend0 output */ + memcpy(&output1_data, &(layer_blend->output_data), + sizeof(struct dispdata_s)); + + layer_blend->input1 = BLEND_DIN3; + layer_blend->input2 = input2; + index = blend_din_to_osd(layer_blend->input1, blending); + osd_set_freescale_new(index, blending); + index = blend_din_to_osd(layer_blend->input2, blending); + osd_set_freescale_new(index, blending); + osd_setting_blend1_new(blending); + + layer_blend->input1 = BLEND0_DIN; + layer_blend->input2 = BLEND1_DIN; + memcpy(&layer_blend->input1_data, &output1_data, + sizeof(struct dispdata_s)); + memcpy(&layer_blend->input2_data, &layer_blend->output_data, + sizeof(struct dispdata_s)); + osd_setting_blend2(blending); + + layer_blend->input1 = BLEND2_DIN; + layer_blend->input2 = BLEND_NO_DIN; + memcpy(&(layer_blend->input1_data), + &(layer_blend->output_data), + sizeof(struct dispdata_s)); + layer_blend->input1_data.x += + osd_hw.disp_info[output_index].position_x; + layer_blend->input1_data.y += + osd_hw.disp_info[output_index].position_y; + vpp_setting_blend(blending); + break; case OSD_BLEND_AB_C: - /* blend0 -->blend2-->sc->vpp_osd1 */ - /* sc-->blend1-->blend2-->sc-->vpp_osd1 */ + /* sc-->blend0 -->blend2->vpp_osd1 */ + /* sc-->blend1-->blend2-->vpp_osd1 */ /* sc -->vpp_osd2 */ layer_blend->input1 = BLEND_DIN1; layer_blend->input2 = BLEND_NO_DIN; blending->blend_din = BLEND_DIN1; index = blend_din_to_osd(BLEND_DIN1, blending); - if (index != OSD1) { - osd_log_info("index=%d, need set freescale\n", index); - osd_set_freescale(index, blending); - } - osd_setting_blend0_input(index, blending); - osd_setting_blend0(blending); + if (index >= OSD_MAX) + return; + osd_set_freescale_new(index, blending); + osd_setting_blend0_new(blending); /* save blend0 output */ memcpy(&output1_data, &(layer_blend->output_data), sizeof(struct dispdata_s)); @@ -7166,17 +7950,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) layer_blend->blend_core1_bypass = 1; blending->blend_din = BLEND_DIN3; index = blend_din_to_osd(BLEND_DIN3, blending); - if (index != OSD1) { - osd_log_dbg2(MODULE_BLEND, - "before blend1: set osd%d freescale\n", - index); - osd_set_freescale(index, blending); - } - osd_setting_blend1_input(index, blending); - memcpy(&layer_blend->input1_data, - &layer_blend->output_data, - sizeof(struct dispdata_s)); - osd_setting_blend1(blending); + osd_set_freescale_new(index, blending); + osd_setting_blend1_new(blending); /* din1=>blend0 & din3-> blend1 ==> blend2 */ layer_blend->input1 = BLEND0_DIN; @@ -7186,21 +7961,12 @@ static void set_blend_path(struct hw_osd_blending_s *blending) memcpy(&layer_blend->input2_data, &layer_blend->output_data, sizeof(struct dispdata_s)); osd_setting_blend2(blending); - - /* blend2 ==> osd0 freescale */ - osd_set_freescale(OSD1, blending); - output1_data.x = - osd_hw.free_dst_data[OSD1].x_start + - osd_hw.disp_info.position_x; - output1_data.w = - osd_hw.free_dst_data[OSD1].x_end - - osd_hw.free_dst_data[OSD1].x_start + 1; - output1_data.y = - osd_hw.free_dst_data[OSD1].y_start + - osd_hw.disp_info.position_y; - output1_data.h = - osd_hw.free_dst_data[OSD1].y_end - - osd_hw.free_dst_data[OSD1].y_start + 1; + memcpy(&output1_data, &(layer_blend->output_data), + sizeof(struct dispdata_s)); + output1_data.x += + osd_hw.disp_info[output_index].position_x; + output1_data.y += + osd_hw.disp_info[output_index].position_y; osd_log_dbg2(MODULE_BLEND, "output1_data:%d,%d,%d,%d\n", output1_data.x, output1_data.w, @@ -7211,19 +7977,16 @@ static void set_blend_path(struct hw_osd_blending_s *blending) /* din4 ==> vpp */ index = blend_din_to_osd(BLEND_DIN4, blending); blending->blend_din = BLEND_DIN4; - osd_log_dbg2(MODULE_BLEND, - "bypass blend1: set osd%d freescale\n", index); - osd_set_freescale(index, blending); - + osd_set_freescale_new(index, blending); layer_blend->input2_data.x = osd_hw.free_dst_data[index].x_start + - osd_hw.disp_info.position_x; + osd_hw.disp_info[output_index].position_x; layer_blend->input2_data.w = osd_hw.free_dst_data[index].x_end - osd_hw.free_dst_data[index].x_start + 1; layer_blend->input2_data.y = osd_hw.free_dst_data[index].y_start + - osd_hw.disp_info.position_y; + osd_hw.disp_info[output_index].position_y; layer_blend->input2_data.h = osd_hw.free_dst_data[index].y_end - osd_hw.free_dst_data[index].y_start + 1; @@ -7246,7 +8009,6 @@ static void set_blend_path(struct hw_osd_blending_s *blending) } vpp_setting_blend(blending); break; -#endif } } @@ -7255,16 +8017,16 @@ static void set_blend_reg(struct layer_blend_reg_s *blend_reg) int i; u32 reg_offset = 2; u32 osd1_alpha_div = 0, osd2_alpha_div = 0; -#ifdef OSD_BLEND_SHIFT_WORKAROUND u32 osd_count = OSD_BLEND_LAYERS; -#else - u32 osd_count = osd_hw.osd_meson_dev.viu1_osd_count; -#endif u32 dv_core2_hsize; u32 dv_core2_vsize; if (!blend_reg) return; + /* osd0 scale position before osd blend */ + if (osd_hw.osd_meson_dev.osd0_sc_independ) + VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCALE_CTRL, 0x01); + /* osd blend ctrl */ VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_CTRL, 4 << 29| @@ -7305,6 +8067,10 @@ static void set_blend_reg(struct layer_blend_reg_s *blend_reg) VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND0_SIZE, blend_reg->osd_blend_blend0_size); + /* hdr input size should set to osd blend0 output size */ + VSYNCOSD_WR_MPEG_REG(VPP_OSD1_IN_SIZE, + blend_reg->osd_blend_blend0_size); + VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND1_SIZE, blend_reg->osd_blend_blend1_size); @@ -7326,7 +8092,6 @@ static void set_blend_reg(struct layer_blend_reg_s *blend_reg) VIU_OSD_BLEND_DIN0_SCOPE_V + reg_offset * i, blend_reg->osd_blend_din_scope_v[i]); } -#ifdef OSD_BLEND_SHIFT_WORKAROUND else { if ((blend_reg->osd_blend_din_scope_v[i] & 0xffff) == 0) blend_reg->osd_blend_din_scope_v[i] = 0x43a0439; @@ -7334,7 +8099,6 @@ static void set_blend_reg(struct layer_blend_reg_s *blend_reg) VIU_OSD_BLEND_DIN0_SCOPE_V + reg_offset * i, blend_reg->osd_blend_din_scope_v[i]); } -#endif } dv_core2_vsize = (blend_reg->osd_blend_blend0_size >> 16) & 0xfff; @@ -7358,25 +8122,18 @@ static void set_blend_reg(struct layer_blend_reg_s *blend_reg) static void uniformization_fb(u32 index, struct hw_osd_blending_s *blending) { - blending->dst_data.x = (osd_hw.dst_data[index].x << OSD_CALC) / - blending->screen_ratio_w; - blending->dst_data.y = (osd_hw.dst_data[index].y << OSD_CALC) / - blending->screen_ratio_h; - blending->dst_data.w = (osd_hw.dst_data[index].w << OSD_CALC) / - blending->screen_ratio_w; - blending->dst_data.h = (osd_hw.dst_data[index].h << OSD_CALC) / - blending->screen_ratio_h; - if (osd_hw.dst_data[index].w < osd_hw.disp_info.position_w) - osd_log_err("base dispframe w(%d) must >= position_w(%d)\n", - osd_hw.dst_data[index].w, osd_hw.disp_info.position_w); - if ((blending->dst_data.w + blending->dst_data.x) > - osd_hw.disp_info.background_w) { - blending->dst_data.w = osd_hw.disp_info.background_w - - blending->dst_data.x; - osd_log_info("blending w(%d) must < base fb w(%d)\n", - blending->dst_data.w + blending->dst_data.x, - osd_hw.disp_info.background_w); - } + blending->dst_data.x = osd_hw.dst_data[index].x * + blending->screen_ratio_w_den / + blending->screen_ratio_w_num; + blending->dst_data.y = osd_hw.dst_data[index].y * + blending->screen_ratio_h_den / + blending->screen_ratio_h_num; + blending->dst_data.w = osd_hw.dst_data[index].w * + blending->screen_ratio_w_den / + blending->screen_ratio_w_num; + blending->dst_data.h = osd_hw.dst_data[index].h * + blending->screen_ratio_h_den / + blending->screen_ratio_h_num; osd_log_dbg2(MODULE_BLEND, "uniformization:osd%d:dst_data:%d,%d,%d,%d\n", index, @@ -7386,17 +8143,29 @@ static void uniformization_fb(u32 index, blending->dst_data.h); } -static void adjust_dst_position(void) +static void adjust_dst_position(u32 output_index) { int i = 0; - int osd_count = osd_hw.osd_meson_dev.viu1_osd_count; + int osd_count = 0; + int start_index = 0; + + if (output_index == VIU1) { + osd_count = osd_hw.osd_meson_dev.viu1_osd_count; + start_index = 0; + } else if (output_index == VIU2) { + start_index = osd_hw.osd_meson_dev.viu2_index; + osd_count = start_index + 1; + } else { + osd_log_err("invald output_index=%d\n", output_index); + return; + } for (i = 0; i < osd_count; i++) { if (osd_hw.enable[i]) { osd_hw.dst_data[i].x -= - osd_hw.disp_info.position_x; + osd_hw.disp_info[output_index].position_x; osd_hw.dst_data[i].y -= - osd_hw.disp_info.position_y; + osd_hw.disp_info[output_index].position_y; if (osd_hw.dst_data[i].x < 0) osd_hw.dst_data[i].x = 0; if (osd_hw.dst_data[i].y < 0) @@ -7410,12 +8179,13 @@ static void adjust_dst_position(void) osd_hw.dst_data[i].h); } } - if (osd_hw.field_out_en) - osd_hw.disp_info.position_y /= 2; + if (osd_hw.field_out_en[output_index]) + osd_hw.disp_info[output_index].position_y /= 2; } -static int osd_setting_order(void) +static int osd_setting_order(u32 output_index) { +#define RDMA_DETECT_REG VIU_OSD2_TCOLOR_AG2 int i; struct layer_blend_reg_s *blend_reg; struct hw_osd_blending_s *blending; @@ -7424,18 +8194,21 @@ static int osd_setting_order(void) int line1; int line2; int vinfo_height; + u32 val; blending = &osd_blending; blend_reg = &(blending->blend_reg); - blending->vinfo_width = osd_hw.vinfo_width; - blending->vinfo_height = osd_hw.vinfo_height; - blending->screen_ratio_w = - (osd_hw.disp_info.position_w << OSD_CALC) - / osd_hw.disp_info.background_w; - blending->screen_ratio_h = - (osd_hw.disp_info.position_h << OSD_CALC) - / osd_hw.disp_info.background_h; + blending->vinfo_width = osd_hw.vinfo_width[output_index]; + blending->vinfo_height = osd_hw.vinfo_height[output_index]; + blending->screen_ratio_w_num = + osd_hw.disp_info[output_index].position_w; + blending->screen_ratio_w_den = + osd_hw.disp_info[output_index].background_w; + blending->screen_ratio_h_num = + osd_hw.disp_info[output_index].position_h; + blending->screen_ratio_h_den = + osd_hw.disp_info[output_index].background_h; blending->layer_cnt = get_available_layers(); set_blend_order(blending); @@ -7445,8 +8218,9 @@ static int osd_setting_order(void) blending->b_exchange_din = false; blending->b_exchange_blend_in = false; blending->osd1_freescale_disable = false; - adjust_dst_position(); - uniformization_fb(OSD1, blending); + adjust_dst_position(output_index); + if (!osd_hw.osd_meson_dev.osd0_sc_independ) + uniformization_fb(OSD1, blending); /* set blend mode */ set_blend_mode(blending); @@ -7455,14 +8229,19 @@ static int osd_setting_order(void) set_blend_din(blending); /* set blend path */ - set_blend_path(blending); + if (osd_hw.osd_meson_dev.osd0_sc_independ) + set_blend_path_new(blending); + else + set_blend_path(blending); 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) { + vinfo_height = osd_hw.field_out_en[output_index] ? + (osd_hw.vinfo_height[output_index] * 2) : + osd_hw.vinfo_height[output_index]; + /* 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(); } @@ -7533,14 +8312,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; } @@ -7606,8 +8392,8 @@ static void osd_setting_default_hwc(void) 0x0 << 11 | 0x0); - blend_hsize = osd_hw.disp_info.background_w; - blend_vsize = osd_hw.disp_info.background_h; + blend_hsize = osd_hw.disp_info[VIU1].background_w; + blend_vsize = osd_hw.disp_info[VIU1].background_h; VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND0_SIZE, blend_vsize << 16 | @@ -7615,6 +8401,10 @@ static void osd_setting_default_hwc(void) VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND1_SIZE, blend_vsize << 16 | blend_hsize); + /* hdr input size should set to osd blend0 output size */ + VSYNCOSD_WR_MPEG_REG(VPP_OSD1_IN_SIZE, + blend_vsize << 16 | + blend_hsize); VSYNCOSD_WR_MPEG_REG_BITS(DOLBY_PATH_CTRL, 0x3, 2, 2); } @@ -7624,29 +8414,29 @@ static bool set_old_hwc_freescale(u32 index) u32 x_start, x_end, y_start, y_end, height_dst, height_src; if (osd_hw.osd_reverse[index] == REVERSE_TRUE) { - x_start = osd_hw.vinfo_width + x_start = osd_hw.vinfo_width[VIU1] - osd_hw.free_dst_data[index].x_end - 1; - y_start = osd_hw.vinfo_height + y_start = osd_hw.vinfo_height[VIU1] - osd_hw.free_dst_data[index].y_end - 1; - x_end = osd_hw.vinfo_width + x_end = osd_hw.vinfo_width[VIU1] - osd_hw.free_dst_data[index].x_start - 1; - y_end = osd_hw.vinfo_height + y_end = osd_hw.vinfo_height[VIU1] - osd_hw.free_dst_data[index].y_start - 1; osd_hw.free_dst_data[index].x_start = x_start; osd_hw.free_dst_data[index].y_start = y_start; osd_hw.free_dst_data[index].x_end = x_end; osd_hw.free_dst_data[index].y_end = y_end; } else if (osd_hw.osd_reverse[index] == REVERSE_X) { - x_start = osd_hw.vinfo_width + x_start = osd_hw.vinfo_width[VIU1] - osd_hw.free_dst_data[index].x_end - 1; - x_end = osd_hw.vinfo_width + x_end = osd_hw.vinfo_width[VIU1] - osd_hw.free_dst_data[index].x_start - 1; osd_hw.free_dst_data[index].x_start = x_start; osd_hw.free_dst_data[index].x_end = x_end; } else if (osd_hw.osd_reverse[index] == REVERSE_Y) { - y_start = osd_hw.vinfo_height + y_start = osd_hw.vinfo_height[VIU1] - osd_hw.free_dst_data[index].y_end - 1; - y_end = osd_hw.vinfo_height + y_end = osd_hw.vinfo_height[VIU1] - osd_hw.free_dst_data[index].y_start - 1; osd_hw.free_dst_data[index].y_start = y_start; osd_hw.free_dst_data[index].y_end = y_end; @@ -7678,101 +8468,6 @@ static bool set_old_hwc_freescale(u32 index) return false; } -#if 0 -static bool set_old_hwc_freescale(u32 index) -{ - u32 x_start, x_end, y_start, y_end; - u32 width_src = 0, width_dst = 0, height_src = 0, height_dst = 0; - u32 width, height; - u32 screen_ratio_w, screen_ratio_h; - - width_src = osd_hw.disp_info.background_w; - height_src = osd_hw.disp_info.background_h; - - width_dst = osd_hw.vinfo_width; - height_dst = osd_hw.vinfo_height; - screen_ratio_w = (osd_hw.disp_info.position_w << OSD_CALC) - / osd_hw.disp_info.background_w; - screen_ratio_h = (osd_hw.disp_info.position_h << OSD_CALC) - / osd_hw.disp_info.background_h; - osd_log_dbg("width_src:%d,%d\n", - width_src, height_src); - osd_log_dbg("width_src:%d,%d\n", - width_dst, height_dst); - - width = osd_hw.free_dst_data[index].x_end - - osd_hw.free_dst_data[index].x_start; - height = osd_hw.free_dst_data[index].y_end - - osd_hw.free_dst_data[index].y_start; - osd_hw.free_dst_data[index].x_start = - (osd_hw.free_dst_data[index].x_start - * screen_ratio_w >> OSD_CALC); - osd_hw.free_dst_data[index].y_start = - (osd_hw.free_dst_data[index].y_start - * screen_ratio_h >> OSD_CALC); - width = (width * screen_ratio_w >> OSD_CALC); - height = (height * screen_ratio_h >> OSD_CALC); - - osd_hw.free_dst_data[index].x_start += - osd_hw.disp_info.position_x; - osd_hw.free_dst_data[index].x_end = - osd_hw.free_dst_data[index].x_start + width; - osd_hw.free_dst_data[index].y_start += - osd_hw.disp_info.position_y; - osd_hw.free_dst_data[index].y_end = - osd_hw.free_dst_data[index].y_start + height; - - if (osd_hw.osd_reverse[index] == REVERSE_TRUE) { - x_start = osd_hw.vinfo_width - - osd_hw.free_dst_data[index].x_end - 1; - y_start = osd_hw.vinfo_height - - osd_hw.free_dst_data[index].y_end - 1; - x_end = osd_hw.vinfo_width - - osd_hw.free_dst_data[index].x_start - 1; - y_end = osd_hw.vinfo_height - - osd_hw.free_dst_data[index].y_start - 1; - osd_hw.free_dst_data[index].x_start = x_start; - osd_hw.free_dst_data[index].y_start = y_start; - osd_hw.free_dst_data[index].x_end = x_end; - osd_hw.free_dst_data[index].y_end = y_end; - } else if (osd_hw.osd_reverse[index] == REVERSE_X) { - x_start = osd_hw.vinfo_width - - osd_hw.free_dst_data[index].x_end - 1; - x_end = osd_hw.vinfo_width - - osd_hw.free_dst_data[index].x_start - 1; - osd_hw.free_dst_data[index].x_start = x_start; - osd_hw.free_dst_data[index].x_end = x_end; - } else if (osd_hw.osd_reverse[index] == REVERSE_Y) { - y_start = osd_hw.vinfo_height - - osd_hw.free_dst_data[index].y_end - 1; - y_end = osd_hw.vinfo_height - - osd_hw.free_dst_data[index].y_start - 1; - osd_hw.free_dst_data[index].y_start = y_start; - osd_hw.free_dst_data[index].y_end = y_end; - } - osd_log_dbg("free_dst_data: %x,%x,%x,%x\n", - osd_hw.free_dst_data[index].x_start, - osd_hw.free_dst_data[index].x_end, - osd_hw.free_dst_data[index].y_start, - osd_hw.free_dst_data[index].y_end); - if ((memcmp(&(osd_hw.free_src_data[index]), - &osd_hw.free_src_data_backup[index], - sizeof(struct pandata_s)) != 0) || - (memcmp(&(osd_hw.free_dst_data[index]), - &osd_hw.free_dst_data_backup[index], - sizeof(struct pandata_s)) != 0)) { - memcpy(&osd_hw.free_src_data_backup[index], - &osd_hw.free_src_data[index], - sizeof(struct pandata_s)); - memcpy(&osd_hw.free_dst_data_backup[index], - &osd_hw.free_dst_data[index], - sizeof(struct pandata_s)); - return true; - } else - return false; -} -#endif - static void osd_setting_old_hwc(void) { int index = OSD1; @@ -7817,7 +8512,7 @@ static void osd_setting_old_hwc(void) static void osd_setting_viu2(void) { - int index = OSD4; + int index = osd_hw.osd_meson_dev.viu2_index; if (!osd_hw.osd_afbcd[index].enable) canvas_config(osd_hw.fb_gem[index].canvas_idx, @@ -7833,25 +8528,28 @@ static void osd_setting_viu2(void) if (!osd_hw.osd_display_debug) osd_hw.reg[OSD_ENABLE] .update_func(index); + osd_wait_vsync_hw(); } -int osd_setting_blend(void) +int osd_setting_blend(u32 output_index) { int ret; if (osd_hw.osd_meson_dev.osd_ver < OSD_HIGH_ONE) osd_setting_old_hwc(); else { - if (osd_hw.hwc_enable) { - if (osd_hw.viu_type == VIU1) { - ret = osd_setting_order(); + if (osd_hw.hwc_enable[output_index]) { + if (output_index == VIU1) { + ret = osd_setting_order(output_index); if (ret < 0) return -1; - } else if (osd_hw.viu_type == VIU2) + } else if (output_index == VIU2) { osd_setting_viu2(); - } else + } + } else { osd_setting_default_hwc(); + } } return 0; } @@ -8275,7 +8973,10 @@ static void osd_update_fifo(u32 index) { u32 data32; - data32 = osd_hw.urgent[index] & 1; + data32 = VSYNCOSD_RD_MPEG_REG( + hw_osd_reg_array[index].osd_fifo_ctrl_stat); + data32 |= osd_hw.urgent[index] & 1; + #if 0 data32 |= 4 << 5; /* hold_fifo_lines */ /* burst_len_sel: 3=64, g12a = 5 */ @@ -8298,6 +8999,7 @@ static void osd_update_fifo(u32 index) data32 |= 2 << 22; /* bit 28:24, fifo_lim */ data32 |= 2 << 24; + #endif VSYNCOSD_WR_MPEG_REG( hw_osd_reg_array[index].osd_fifo_ctrl_stat, data32); remove_from_update_list(index, OSD_FIFO); @@ -8364,6 +9066,17 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe, sizeof(struct osd_device_data_s)); osd_vpu_power_on(); + if (osd_meson->cpu_id == __MESON_CPU_MAJOR_ID_TL1) { + /* VIU1 2 OSD + 1 VIU2 1 OSD*/ + memcpy(&hw_osd_reg_array[0], &hw_osd_reg_array_tl1[0], + sizeof(struct hw_osd_reg_s) * + osd_hw.osd_meson_dev.osd_count); + } else { + /* VIU1 3 OSD + 1 VIU2 1 OSD or VIU1 2 OSD*/ + memcpy(&hw_osd_reg_array[0], &hw_osd_reg_array_g12a[0], + sizeof(struct hw_osd_reg_s) * + osd_hw.osd_meson_dev.osd_count); + } if (osd_meson->cpu_id == __MESON_CPU_MAJOR_ID_GXTVBB) backup_regs_init(HW_RESET_AFBCD_REGS); else if (osd_meson->cpu_id == __MESON_CPU_MAJOR_ID_GXM) @@ -8385,7 +9098,8 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe, osd_hdr_on = false; #endif osd_hw.hw_reset_flag = HW_RESET_NONE; - osd_hw.hwc_enable = 0; + osd_hw.hwc_enable[VIU1] = 0; + osd_hw.hwc_enable[VIU2] = 0; if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { osd_hw.hw_cursor_en = 1; if (osd_hw.osd_meson_dev.has_rdma) @@ -8402,7 +9116,7 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe, /* init vpu fifo control register */ data32 = osd_reg_read(VPP_OFIFO_SIZE); if (osd_hw.osd_meson_dev.osd_ver >= OSD_HIGH_ONE) { - data32 = 0; /* reset value 0xfff0fff */ + data32 &= ~((0xfff << 20) | 0x3fff); data32 |= (osd_hw.osd_meson_dev.vpp_fifo_len) << 20; data32 |= osd_hw.osd_meson_dev.vpp_fifo_len + 1; } else @@ -8480,18 +9194,18 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe, osd_hw.order[OSD1] = LAYER_1; osd_hw.order[OSD2] = LAYER_2; osd_hw.order[OSD3] = LAYER_3; - //osd_hw.osd_blend_mode = OSD_BLEND_NONE; - osd_hw.disp_info.background_w = 1920; - osd_hw.disp_info.background_h = 1080; - osd_hw.disp_info.fullscreen_w = 1920; - osd_hw.disp_info.fullscreen_h = 1080; - osd_hw.disp_info.position_x = 0; - osd_hw.disp_info.position_y = 0; - osd_hw.disp_info.position_w = 1920; - osd_hw.disp_info.position_h = 1080; - osd_hw.vinfo_width = 1920; - osd_hw.vinfo_height = 1080; - osd_hw.workaround_line = 0; + for (idx = 0; idx < VIU_COUNT; idx++) { + osd_hw.disp_info[idx].background_w = 1920; + osd_hw.disp_info[idx].background_h = 1080; + osd_hw.disp_info[idx].fullscreen_w = 1920; + osd_hw.disp_info[idx].fullscreen_h = 1080; + osd_hw.disp_info[idx].position_x = 0; + osd_hw.disp_info[idx].position_y = 0; + osd_hw.disp_info[idx].position_w = 1920; + osd_hw.disp_info[idx].background_h = 1080; + osd_hw.vinfo_width[idx] = 1920; + osd_hw.vinfo_height[idx] = 1080; + } if ((osd_hw.osd_meson_dev.cpu_id == __MESON_CPU_MAJOR_ID_G12A) || ((osd_hw.osd_meson_dev.cpu_id == @@ -8513,7 +9227,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); @@ -8529,13 +9243,11 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe, osd_reg_set_bits( hw_osd_reg_array[idx].osd_fifo_ctrl_stat, 1, 10, 2); - /* TODO: temp set at here, - * need check for logo - */ - if (idx > 0) - osd_reg_set_bits( - hw_osd_reg_array[idx].osd_ctrl_stat, - 0, 0, 1); + if (osd_hw.osd_meson_dev.cpu_id == + __MESON_CPU_MAJOR_ID_G12B) + osd_reg_set_bits + (hw_osd_reg_array[idx].osd_ctrl_stat, + 1, 0, 1); osd_reg_set_bits( hw_osd_reg_array[idx].osd_ctrl_stat, 0, 31, 1); @@ -8619,26 +9331,39 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe, } /* hwc_enable == 0 handler */ #ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE - osd_hw.osd_fence[DISABLE].sync_fence_handler = + osd_hw.osd_fence[VIU1][DISABLE].sync_fence_handler = sync_render_single_fence; - osd_hw.osd_fence[DISABLE].toggle_buffer_handler = + osd_hw.osd_fence[VIU1][DISABLE].toggle_buffer_handler = osd_toggle_buffer_single; /* hwc_enable == 1 handler */ - osd_hw.osd_fence[ENABLE].sync_fence_handler = + osd_hw.osd_fence[VIU1][ENABLE].sync_fence_handler = sync_render_layers_fence; - osd_hw.osd_fence[ENABLE].toggle_buffer_handler = + osd_hw.osd_fence[VIU1][ENABLE].toggle_buffer_handler = osd_toggle_buffer_layers; + if (osd_hw.osd_meson_dev.has_viu2) { + osd_hw.osd_fence[VIU2][DISABLE].sync_fence_handler = + sync_render_single_fence; + osd_hw.osd_fence[VIU2][DISABLE].toggle_buffer_handler = + osd_toggle_buffer_single_viu2; + /* hwc_enable == 1 handler */ + osd_hw.osd_fence[VIU2][ENABLE].sync_fence_handler = + sync_render_layers_fence; + osd_hw.osd_fence[VIU2][ENABLE].toggle_buffer_handler = + osd_toggle_buffer_layers_viu2; + } #endif osd_hw.fb_gem[OSD1].canvas_idx = OSD1_CANVAS_INDEX; osd_hw.fb_gem[OSD2].canvas_idx = OSD2_CANVAS_INDEX; if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) { osd_hw.fb_gem[OSD3].canvas_idx = OSD3_CANVAS_INDEX; + if (osd_hw.osd_meson_dev.osd_count == 4) osd_hw.fb_gem[OSD4].canvas_idx = OSD4_CANVAS_INDEX; } osd_extra_canvas_alloc(); osd_hw.antiflicker_mode = 0; osd_hw.osd_deband_enable = 1; - osd_hw.out_fence_fd = -1; + osd_hw.out_fence_fd[VIU1] = -1; + osd_hw.out_fence_fd[VIU2] = -1; osd_hw.blend_bypass = 0; osd_hw.afbc_err_cnt = 0; if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) { @@ -8653,8 +9378,10 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe, osd_set_deband(osd_hw.osd_deband_enable); if (osd_hw.fb_drvier_probe) { #ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE - INIT_LIST_HEAD(&post_fence_list); - mutex_init(&post_fence_list_lock); + INIT_LIST_HEAD(&post_fence_list[VIU1]); + mutex_init(&post_fence_list_lock[VIU1]); + INIT_LIST_HEAD(&post_fence_list[VIU2]); + mutex_init(&post_fence_list_lock[VIU2]); #endif #ifdef FIQ_VSYNC osd_hw.fiq_handle_item.handle = vsync_isr; @@ -8690,6 +9417,7 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe, void osd_init_viu2(void) { u32 idx, data32; + struct vinfo_s *vinfo; set_viu2_rgb2yuv(1); @@ -8702,7 +9430,11 @@ void osd_init_viu2(void) * set DDR request priority to be urgent */ data32 = 1; - data32 |= 4 << 5; /* hold_fifo_lines */ + vinfo = get_current_vinfo2(); + if (vinfo && (!strcmp(vinfo->name, "dummy_panel"))) { + data32 |= MAX_HOLD_LINE << 5; /* hold_fifo_lines */ + } else + data32 |= DEFAULT_HOLD_LINE << 5; /* hold_fifo_lines */ /* burst_len_sel: 3=64, g12a = 5 */ if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) { data32 |= 1 << 10; @@ -8934,7 +9666,7 @@ void osd_cursor_hw_no_scale(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, memcpy(&disp_tmp, &osd_hw.dispdata[OSD1], sizeof(struct pandata_s)); - if (osd_hw.field_out_en) { + if (osd_hw.field_out_en[VIU1]) { disp_tmp.y_start *= 2; disp_tmp.y_end *= 2; } @@ -9040,7 +9772,7 @@ void osd_cursor_hw_no_scale(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, } } - if (osd_hw.field_out_en) + if (osd_hw.field_out_en[VIU1]) osd_hw.dispdata[OSD2].y_start /= 2; osd_hw.dispdata[OSD2].x_end = osd_hw.dispdata[OSD2].x_start + @@ -9519,6 +10251,7 @@ static const struct color_bit_define_s *convert_panel_format(u32 format) { const struct color_bit_define_s *color = NULL; + format &= ~AFBC_EN; switch (format) { case COLOR_INDEX_02_PAL4: case COLOR_INDEX_04_PAL16: @@ -9560,19 +10293,27 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) u32 x_start, x_end, y_start, y_end; bool freescale_update = false; struct pandata_s freescale_dst[HW_OSD_COUNT]; + u32 output_index; + output_index = get_output_device_id(index); phy_addr = phy_addr + plane_map->byte_stride * plane_map->src_y; osd_hw.screen_base[index] = phy_addr; osd_hw.screen_size[index] = plane_map->byte_stride * plane_map->src_h; osd_log_dbg(MODULE_RENDER, "canvas_id=%x, phy_addr=%x\n", osd_hw.fb_gem[index].canvas_idx, phy_addr); - canvas_config(osd_hw.fb_gem[index].canvas_idx, - phy_addr, - plane_map->byte_stride, - plane_map->src_h, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - if (osd_hw.hwc_enable) { + if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) { + osd_hw.fb_gem[index].addr = phy_addr; + osd_hw.fb_gem[index].width = plane_map->byte_stride; + osd_update_phy_addr(0); + } else { + canvas_config(osd_hw.fb_gem[index].canvas_idx, + phy_addr, + plane_map->byte_stride, + plane_map->src_h, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + } + if (osd_hw.hwc_enable[output_index]) { /* just get para, need update via do_hwc */ osd_hw.order[index] = plane_map->zorder; switch (plane_map->blend_mode) { @@ -9664,30 +10405,30 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) ((plane_map->dst_y + plane_map->dst_h) * height_dst) / height_src - 1; if (osd_hw.osd_reverse[index] == REVERSE_TRUE) { - x_start = osd_hw.vinfo_width + x_start = osd_hw.vinfo_width[output_index] - freescale_dst[index].x_end - 1; - y_start = osd_hw.vinfo_height + y_start = osd_hw.vinfo_height[output_index] - freescale_dst[index].y_end - 1; - x_end = osd_hw.vinfo_width + x_end = osd_hw.vinfo_width[output_index] - freescale_dst[index].x_start - 1; - y_end = osd_hw.vinfo_height + y_end = osd_hw.vinfo_height[output_index] - freescale_dst[index].y_start - 1; freescale_dst[index].x_start = x_start; freescale_dst[index].y_start = y_start; freescale_dst[index].x_end = x_end; freescale_dst[index].y_end = y_end; } else if (osd_hw.osd_reverse[index] == REVERSE_X) { - x_start = osd_hw.vinfo_width + x_start = osd_hw.vinfo_width[output_index] - freescale_dst[index].x_end - 1; - x_end = osd_hw.vinfo_width + x_end = osd_hw.vinfo_width[output_index] - freescale_dst[index].x_start - 1; freescale_dst[index].x_start = x_start; freescale_dst[index].x_end = x_end; } else if (osd_hw.osd_reverse[index] == REVERSE_Y) { - y_start = osd_hw.vinfo_height + y_start = osd_hw.vinfo_height[output_index] - freescale_dst[index].y_end - 1; - y_end = osd_hw.vinfo_height + y_end = osd_hw.vinfo_height[output_index] - freescale_dst[index].y_start - 1; freescale_dst[index].y_start = y_start; freescale_dst[index].y_end = y_end; @@ -9753,30 +10494,30 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) osd_hw.dispdata[index].y_end = plane_map->dst_y + plane_map->dst_h - 1; if (osd_hw.osd_reverse[index] == REVERSE_TRUE) { - x_start = osd_hw.vinfo_width + x_start = osd_hw.vinfo_width[output_index] - osd_hw.dispdata[index].x_end - 1; - y_start = osd_hw.vinfo_height + y_start = osd_hw.vinfo_height[output_index] - osd_hw.dispdata[index].y_end - 1; - x_end = osd_hw.vinfo_width + x_end = osd_hw.vinfo_width[output_index] - osd_hw.dispdata[index].x_start - 1; - y_end = osd_hw.vinfo_height + y_end = osd_hw.vinfo_height[output_index] - osd_hw.dispdata[index].y_start - 1; osd_hw.dispdata[index].x_start = x_start; osd_hw.dispdata[index].y_start = y_start; osd_hw.dispdata[index].x_end = x_end; osd_hw.dispdata[index].y_end = y_end; } else if (osd_hw.osd_reverse[index] == REVERSE_X) { - x_start = osd_hw.vinfo_width + x_start = osd_hw.vinfo_width[output_index] - osd_hw.dispdata[index].x_end - 1; - x_end = osd_hw.vinfo_width + x_end = osd_hw.vinfo_width[output_index] - osd_hw.dispdata[index].x_start - 1; osd_hw.dispdata[index].x_start = x_start; osd_hw.dispdata[index].x_end = x_end; } else if (osd_hw.osd_reverse[index] == REVERSE_Y) { - y_start = osd_hw.vinfo_height + y_start = osd_hw.vinfo_height[output_index] - osd_hw.dispdata[index].y_end - 1; - y_end = osd_hw.vinfo_height + y_end = osd_hw.vinfo_height[output_index] - osd_hw.dispdata[index].y_start - 1; osd_hw.dispdata[index].y_start = y_start; osd_hw.dispdata[index].y_end = y_end; @@ -9804,9 +10545,11 @@ static void osd_cursor_move(struct osd_plane_map_s *plane_map) u32 x, y; struct pandata_s disp_tmp; struct pandata_s free_dst_data_backup; + u32 output_index; if (index != OSD2) return; + output_index = get_output_device_id(index); phy_addr = phy_addr + plane_map->byte_stride * plane_map->src_y; osd_hw.screen_base[index] = phy_addr; osd_hw.screen_size[index] = @@ -9904,29 +10647,29 @@ static void osd_cursor_move(struct osd_plane_map_s *plane_map) osd_hw.pandata[OSD2].y_end - osd_hw.pandata[OSD2].y_start; if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) { - x_start = osd_hw.vinfo_width + x_start = osd_hw.vinfo_width[output_index] - osd_hw.dispdata[index].x_end - 1; - y_start = osd_hw.vinfo_height + y_start = osd_hw.vinfo_height[output_index] - osd_hw.dispdata[index].y_end - 1; - x_end = osd_hw.vinfo_width + x_end = osd_hw.vinfo_width[output_index] - osd_hw.dispdata[index].x_start - 1; - y_end = osd_hw.vinfo_height + y_end = osd_hw.vinfo_height[output_index] - osd_hw.dispdata[index].y_start - 1; osd_hw.dispdata[index].x_start = x_start; osd_hw.dispdata[index].y_start = y_start; osd_hw.dispdata[index].x_end = x_end; osd_hw.dispdata[index].y_end = y_end; } else if (osd_hw.osd_reverse[OSD2] == REVERSE_X) { - x_start = osd_hw.vinfo_width + x_start = osd_hw.vinfo_width[output_index] - osd_hw.dispdata[index].x_end - 1; - x_end = osd_hw.vinfo_width + x_end = osd_hw.vinfo_width[output_index] - osd_hw.dispdata[index].x_start - 1; osd_hw.dispdata[index].x_start = x_start; osd_hw.dispdata[index].x_end = x_end; } else if (osd_hw.osd_reverse[OSD2] == REVERSE_Y) { - y_start = osd_hw.vinfo_height + y_start = osd_hw.vinfo_height[output_index] - osd_hw.dispdata[index].y_end - 1; - y_end = osd_hw.vinfo_height + y_end = osd_hw.vinfo_height[output_index] - osd_hw.dispdata[index].y_start - 1; osd_hw.dispdata[index].y_start = y_start; osd_hw.dispdata[index].y_end = y_end; @@ -9964,9 +10707,11 @@ void osd_page_flip(struct osd_plane_map_s *plane_map) bool freescale_update = false; u32 osd_enable = 0; u32 format = 0; - const struct vinfo_s *vinfo; + const struct vinfo_s *vinfo = NULL; + u32 output_index; - if (!osd_hw.hwc_enable) { + output_index = get_output_device_id(index); + if (!osd_hw.hwc_enable[output_index]) { if (index >= OSD2) return; } else { @@ -9975,16 +10720,23 @@ void osd_page_flip(struct osd_plane_map_s *plane_map) } osd_hw.buffer_alloc[index] = 1; - if (osd_hw.osd_fps_start) - osd_hw.osd_fps++; - + if (osd_hw.osd_fps_start[output_index]) + osd_hw.osd_fps[output_index]++; osd_enable = (plane_map->enable & 1) ? ENABLE : DISABLE; - vinfo = get_current_vinfo(); - if (vinfo && (strcmp(vinfo->name, "invalid") && - strcmp(vinfo->name, "null"))) { - osd_hw.vinfo_width = vinfo->width; - osd_hw.vinfo_height = vinfo->height; + + if (output_index == VIU1) + vinfo = get_current_vinfo(); +#ifdef CONFIG_AMLOGIC_VOUT2_SERVE + else if (output_index == VIU2) + vinfo = get_current_vinfo2(); +#endif + if (!vinfo || (!strcmp(vinfo->name, "invalid") || + !strcmp(vinfo->name, "null"))) { + return; } + osd_hw.vinfo_width[output_index] = vinfo->width; + osd_hw.vinfo_height[output_index] = vinfo->height; + osd_hw.osd_afbcd[index].enable = (plane_map->afbc_inter_format & AFBC_EN) >> 31; if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { @@ -10079,7 +10831,7 @@ void osd_page_flip(struct osd_plane_map_s *plane_map) osd_hw.osd_afbcd[index].phy_addr = plane_map->phy_addr; osd_hw.reg[OSD_COLOR_MODE].update_func(index); - if (!osd_hw.hwc_enable) { + if (!osd_hw.hwc_enable[output_index]) { osd_hw.reg[DISP_GEOMETRY].update_func(index); osd_hw.reg[DISP_OSD_REVERSE].update_func(index); if ((osd_hw.free_scale_enable[index] diff --git a/drivers/amlogic/media/osd/osd_hw.h b/drivers/amlogic/media/osd/osd_hw.h index ce8ec87..2e1217e 100644 --- a/drivers/amlogic/media/osd/osd_hw.h +++ b/drivers/amlogic/media/osd/osd_hw.h @@ -23,6 +23,8 @@ #include "osd_sync.h" #include "osd_drm.h" +#define MAX_HOLD_LINE 0x1f +#define DEFAULT_HOLD_LINE 0x04 //#define REG_OFFSET (0x20) #define OSD_RELATIVE_BITS 0x33330 #include "osd_rdma.h" @@ -102,7 +104,7 @@ extern void osd_set_block_mode_hw(u32 index, u32 mode); extern void osd_enable_3d_mode_hw(u32 index, u32 enable); extern void osd_set_2x_scale_hw(u32 index, u16 h_scale_enable, u16 v_scale_enable); -extern void osd_get_flush_rate_hw(u32 *break_rate); +extern void osd_get_flush_rate_hw(u32 index, u32 *break_rate); extern void osd_set_reverse_hw(u32 index, u32 reverse, u32 update); extern void osd_get_reverse_hw(u32 index, u32 *reverse); extern void osd_set_antiflicker_hw(u32 index, struct vinfo_s *vinfo, u32 yres); @@ -126,7 +128,7 @@ extern int osd_sync_request_render(u32 index, u32 yres, struct sync_req_render_s *request, u32 phys_addr, size_t len); -extern int osd_sync_do_hwc(struct do_hwc_cmd_s *hwc_cmd); +int osd_sync_do_hwc(u32 output_index, 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); @@ -165,8 +167,8 @@ extern void osd_get_urgent(u32 index, u32 *urgent); extern void osd_set_urgent(u32 index, u32 urgent); void osd_get_deband(u32 *osd_deband_enable); void osd_set_deband(u32 osd_deband_enable); -void osd_get_fps(u32 *osd_fps); -void osd_set_fps(u32 osd_fps_start); +void osd_get_fps(u32 index, u32 *osd_fps); +void osd_set_fps(u32 index, u32 osd_fps_start); extern void osd_get_info(u32 index, u32 *addr, u32 *width, u32 *height); void osd_update_scan_mode(void); void osd_update_3d_mode(void); @@ -180,15 +182,15 @@ int set_osd_logo_freescaler(void); int is_interlaced(struct vinfo_s *vinfo); void osd_get_display_debug(u32 *osd_display_debug_enable); void osd_set_display_debug(u32 osd_display_debug_enable); -void osd_get_background_size(struct display_flip_info_s *disp_info); -void osd_set_background_size(struct display_flip_info_s *disp_info); +void osd_get_background_size(u32 index, struct display_flip_info_s *disp_info); +void osd_set_background_size(u32 index, struct display_flip_info_s *disp_info); void osd_get_hdr_used(u32 *val); void osd_set_hdr_used(u32 val); void osd_get_afbc_format(u32 index, u32 *format, u32 *inter_format); void osd_set_afbc_format(u32 index, u32 format, u32 inter_format); -void osd_get_hwc_enable(u32 *hwc_enable); -void osd_set_hwc_enable(u32 hwc_enable); -void osd_do_hwc(void); +void osd_get_hwc_enable(u32 index, u32 *hwc_enable); +void osd_set_hwc_enable(u32 index, u32 hwc_enable); +void osd_do_hwc(u32 index); int osd_get_capbility(u32 index); void osd_backup_screen_info( u32 index, @@ -204,12 +206,12 @@ ssize_t dd_vmap_write(u32 index, const char __user *buf, int osd_set_clear(u32 index); void osd_page_flip(struct osd_plane_map_s *plane_map); void walk_through_update_list(void); -int osd_setting_blend(void); -void osd_set_hwc_enable(u32 hwc_enable); +int osd_setting_blend(u32 output_index); +void osd_set_hwc_enable(u32 index, u32 hwc_enable); void osd_set_urgent_info(u32 ports, u32 basic_urgent); void osd_get_urgent_info(u32 *ports, u32 *basic_urgent); -void osd_set_single_step_mode(u32 osd_single_step_mode); -void osd_set_single_step(u32 osd_single_step); +void osd_set_single_step_mode(u32 index, u32 osd_single_step_mode); +void osd_set_single_step(u32 index, u32 osd_single_step); void output_save_info(void); void osd_get_rotate(u32 index, u32 *osd_rotate); void osd_set_rotate(u32 index, u32 osd_rotate); @@ -218,4 +220,6 @@ void osd_get_dimm_info(u32 index, u32 *osd_dimm_layer, u32 *osd_dimm_color); void osd_set_dimm_info(u32 index, u32 osd_dimm_layer, u32 osd_dimm_color); u32 osd_get_line_n_rdma(void); void osd_set_line_n_rdma(u32 line_n_rdma); +u32 get_output_device_id(u32 index); +void osd_set_hold_line(int hold_line); #endif diff --git a/drivers/amlogic/media/osd/osd_reg.h b/drivers/amlogic/media/osd/osd_reg.h index 8821d24a..eee86b8 100644 --- a/drivers/amlogic/media/osd/osd_reg.h +++ b/drivers/amlogic/media/osd/osd_reg.h @@ -392,7 +392,7 @@ #define VPP_OSD_SCALE_COEF_IDX 0x1dcc #define VPP_OSD_SCALE_COEF 0x1dcd #define VPP_INT_LINE_NUM 0x1dce - +#define VPP_OSD_SCALE_CTRL 0x1dff /* osd2 scaler */ #define OSD2_VSC_PHASE_STEP 0x3d00 #define OSD2_VSC_INI_PHASE 0x3d01 -- 2.7.4