From 6862fb2e9687118824254506e94af63561a89422 Mon Sep 17 00:00:00 2001 From: Pengcheng Chen Date: Fri, 15 Feb 2019 16:52:52 +0800 Subject: [PATCH] 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 --- drivers/amlogic/media/osd/osd.h | 21 +- drivers/amlogic/media/osd/osd_debug.c | 4 +- drivers/amlogic/media/osd/osd_drm.c | 12 +- drivers/amlogic/media/osd/osd_fb.c | 179 ++--- drivers/amlogic/media/osd/osd_hw.c | 1024 +++++++++++++++---------- drivers/amlogic/media/osd/osd_hw.h | 27 +- 6 files changed, 689 insertions(+), 578 deletions(-) diff --git a/drivers/amlogic/media/osd/osd.h b/drivers/amlogic/media/osd/osd.h index bead47117592..ae45075dc345 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) @@ -706,7 +707,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]; */ @@ -721,7 +722,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; @@ -733,21 +734,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; @@ -760,8 +761,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 e5caf5f14e8c..eb1dd8d14b86 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; diff --git a/drivers/amlogic/media/osd/osd_drm.c b/drivers/amlogic/media/osd/osd_drm.c index d2cb62783e21..3732b201d41d 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 9d53c74522ed..c13fabee4e0d 100644 --- a/drivers/amlogic/media/osd/osd_fb.c +++ b/drivers/amlogic/media/osd/osd_fb.c @@ -652,10 +652,13 @@ 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 < osd_hw.osd_meson_dev.viu1_osd_count) { vinfo = get_current_vinfo(); @@ -664,7 +667,9 @@ static int osd_set_par(struct fb_info *info) return -1; } } else { +#ifdef CONFIG_AMLOGIC_VOUT2_SERVE vinfo = get_current_vinfo2(); +#endif if (!vinfo) { osd_log_err("current vinfo NULL\n"); return -1; @@ -849,7 +854,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; @@ -1059,12 +1064,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)); @@ -1853,13 +1858,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); @@ -1944,9 +1950,9 @@ 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(); @@ -1955,7 +1961,7 @@ int osd_notify_callback(struct notifier_block *block, unsigned long cmd, 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) @@ -1986,7 +1992,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++) { @@ -2037,111 +2043,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) { @@ -2162,6 +2063,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: @@ -2796,9 +2699,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); } @@ -2850,15 +2754,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; @@ -2974,9 +2885,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); } @@ -2985,11 +2897,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; } @@ -3076,9 +2989,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, @@ -3094,12 +3008,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; @@ -3162,9 +3078,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); } @@ -3173,13 +3090,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; } @@ -3188,6 +3106,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; @@ -3195,7 +3114,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; } @@ -3229,13 +3148,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; } @@ -3244,13 +3164,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; } diff --git a/drivers/amlogic/media/osd/osd_hw.c b/drivers/amlogic/media/osd/osd_hw.c index 4c055a29c68e..8a9e641e0d6b 100644 --- a/drivers/amlogic/media/osd/osd_hw.c +++ b/drivers/amlogic/media/osd/osd_hw.c @@ -474,61 +474,67 @@ 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) @@ -945,12 +951,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 @@ -980,10 +1014,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); @@ -996,10 +1030,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); @@ -1010,38 +1044,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 int out_fence_create(int *release_fence_fd) +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(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; @@ -1050,15 +1140,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; @@ -1070,17 +1161,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; @@ -1094,14 +1187,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; @@ -1114,11 +1207,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; @@ -1133,6 +1227,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) @@ -1145,7 +1240,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; @@ -1173,11 +1269,12 @@ 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); return out_fence_fd; @@ -1190,13 +1287,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 */ @@ -1237,8 +1336,8 @@ 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, @@ -1254,31 +1353,36 @@ 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; line = get_encp_line(); + output_index = get_output_device_id(index); osd_log_dbg2(MODULE_RENDER, "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 == osd_hw.osd_meson_dev.viu2_index) - 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:encp line=%d\n", @@ -1287,15 +1391,15 @@ int osd_sync_do_hwc(struct do_hwc_cmd_s *hwc_cmd) 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 = @@ -1314,12 +1418,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; @@ -1393,7 +1499,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; @@ -1403,7 +1509,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) @@ -1411,11 +1520,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 @@ -2099,6 +2210,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) @@ -2109,12 +2222,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; @@ -2130,7 +2250,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; @@ -2150,7 +2270,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; @@ -2171,7 +2291,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; @@ -2194,7 +2314,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) @@ -2204,10 +2324,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; } } } @@ -2726,11 +2846,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)) { @@ -2766,15 +2893,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"))) { @@ -2811,13 +2940,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); } -//todo: Karry s32 osd_get_position_from_reg( u32 index, s32 *src_x_start, s32 *src_x_end, @@ -2963,6 +3091,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", @@ -2974,8 +3103,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); @@ -3003,11 +3132,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) @@ -3036,11 +3167,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; } @@ -3325,26 +3465,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]); } } @@ -3358,16 +3505,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) @@ -3392,22 +3545,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) @@ -3447,26 +3609,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; } @@ -3909,30 +4081,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; @@ -3989,30 +4161,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; @@ -4035,19 +4207,19 @@ 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. */ + 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 @@ -4064,8 +4236,9 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map) if (vinfo) { if ((strcmp(vinfo->name, "invalid")) && (strcmp(vinfo->name, "null"))) { - osd_hw.vinfo_width = vinfo->width; - osd_hw.vinfo_height = vinfo->height; + osd_hw.vinfo_width[output_index] = vinfo->width; + osd_hw.vinfo_height[output_index] = + vinfo->height; } } /* Todo: */ @@ -4261,9 +4434,9 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map) osd_wait_vsync_hw(); } } - if (timeline_created) { + 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"); } @@ -4274,7 +4447,11 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map) 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) @@ -4283,6 +4460,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; @@ -4446,7 +4624,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; } @@ -4458,31 +4637,47 @@ 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; /* 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; + 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; @@ -4491,7 +4686,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) @@ -4499,23 +4694,24 @@ 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); /* 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++) { @@ -4525,7 +4721,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; @@ -4534,14 +4730,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; @@ -4557,8 +4781,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 @@ -4632,6 +4856,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]; @@ -4698,8 +4923,9 @@ static void osd_update_disp_freescale_enable(u32 index) else vf_phase_step = (src_h << 20) / dst_h; + output_index = get_output_device_id(index); #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( @@ -4730,7 +4956,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; @@ -4742,7 +4968,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++; } @@ -4764,7 +4990,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); @@ -4799,8 +5025,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); } @@ -5227,7 +5453,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 || @@ -5238,11 +5464,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; @@ -6596,6 +6825,7 @@ 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); @@ -6607,6 +6837,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 = @@ -6626,7 +6857,7 @@ static void osd_set_freescale(u32 index, * 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) + if (osd_hw.field_out_en[output_index]) height = height >> 1; } else { osd_hw.free_src_data[index].x_start = @@ -6681,7 +6912,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; @@ -6695,7 +6926,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; } @@ -6833,9 +7064,11 @@ 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 @@ -6881,13 +7114,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; @@ -6896,13 +7129,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); @@ -7013,13 +7246,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; @@ -7057,20 +7290,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) @@ -7111,9 +7344,9 @@ static void set_blend_path(struct hw_osd_blending_s *blending) 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); @@ -7201,13 +7434,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; @@ -7242,13 +7475,13 @@ 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; @@ -7260,13 +7493,13 @@ static void set_blend_path(struct hw_osd_blending_s *blending) osd_set_freescale(index, 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; @@ -7279,13 +7512,13 @@ static void set_blend_path(struct hw_osd_blending_s *blending) osd_set_freescale(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; @@ -7366,13 +7599,13 @@ static void set_blend_path(struct hw_osd_blending_s *blending) osd_set_freescale(OSD1, blending); output1_data.x = osd_hw.free_dst_data[OSD1].x_start + - osd_hw.disp_info.position_x; + 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.position_y; + 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; @@ -7392,13 +7625,13 @@ static void set_blend_path(struct hw_osd_blending_s *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; @@ -7550,17 +7783,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) @@ -7574,11 +7819,11 @@ 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; @@ -7594,14 +7839,14 @@ static int osd_setting_order(void) blending = &osd_blending; blend_reg = &(blending->blend_reg); - blending->vinfo_width = osd_hw.vinfo_width; - blending->vinfo_height = osd_hw.vinfo_height; + blending->vinfo_width = osd_hw.vinfo_width[output_index]; + blending->vinfo_height = osd_hw.vinfo_height[output_index]; blending->screen_ratio_w = - (osd_hw.disp_info.position_w << OSD_CALC) - / osd_hw.disp_info.background_w; + (osd_hw.disp_info[output_index].position_w << OSD_CALC) + / osd_hw.disp_info[output_index].background_w; blending->screen_ratio_h = - (osd_hw.disp_info.position_h << OSD_CALC) - / osd_hw.disp_info.background_h; + (osd_hw.disp_info[output_index].position_h << OSD_CALC) + / osd_hw.disp_info[output_index].background_h; blending->layer_cnt = get_available_layers(); set_blend_order(blending); @@ -7611,7 +7856,7 @@ 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(); + adjust_dst_position(output_index); uniformization_fb(OSD1, blending); /* set blend mode */ @@ -7623,8 +7868,9 @@ static int osd_setting_order(void) /* set blend path */ 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; + 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, @@ -7780,8 +8026,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 | @@ -7798,29 +8044,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; @@ -7852,101 +8098,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; @@ -8007,25 +8158,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; } @@ -8570,7 +8724,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) @@ -8665,18 +8820,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 == @@ -8804,15 +8959,26 @@ 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; @@ -8824,7 +8990,8 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe, 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) { @@ -8839,8 +9006,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; @@ -9120,7 +9289,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; } @@ -9226,7 +9395,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 + @@ -9747,7 +9916,9 @@ 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] = @@ -9765,7 +9936,7 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) plane_map->src_h, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); } - if (osd_hw.hwc_enable) { + 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) { @@ -9857,30 +10028,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; @@ -9946,30 +10117,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; @@ -9997,9 +10168,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] = @@ -10097,29 +10270,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; @@ -10157,9 +10330,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 { @@ -10168,15 +10343,20 @@ 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]++; + + if (output_index == VIU1) + vinfo = get_current_vinfo(); +#ifdef CONFIG_AMLOGIC_VOUT2_SERVE + else if (output_index == VIU2) + vinfo = get_current_vinfo2(); +#endif - 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; + 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; @@ -10272,7 +10452,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 ce8ec8705f3c..f86f0b29b2f2 100644 --- a/drivers/amlogic/media/osd/osd_hw.h +++ b/drivers/amlogic/media/osd/osd_hw.h @@ -102,7 +102,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 +126,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 +165,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 +180,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 +204,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 +218,5 @@ 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); #endif