diff --git a/drivers/amlogic/media/osd/osd.h b/drivers/amlogic/media/osd/osd.h index 828ff688d0af..58938e98fb78 100644 --- a/drivers/amlogic/media/osd/osd.h +++ b/drivers/amlogic/media/osd/osd.h @@ -93,6 +93,7 @@ enum color_index_e { #define FBIOPUT_OSD_ROTATE_ON 0x4516 #define FBIOPUT_OSD_ROTATE_ANGLE 0x4517 #define FBIOPUT_OSD_SYNC_ADD 0x4518 +#define FBIOPUT_OSD_SYNC_RENDER_ADD 0x4519 /* OSD color definition */ #define KEYCOLOR_FLAG_TARGET 1 @@ -240,6 +241,8 @@ struct fb_geometry_s { u32 height; u32 canvas_idx; u32 addr; + u32 xres; + u32 yres; }; struct osd_scale_s { @@ -273,8 +276,20 @@ struct osd_fence_map_s { s32 in_fd; s32 out_fd; u32 val; + u32 ext_addr; + u32 format; + u32 width; + u32 height; + u32 op; + u32 compose_type; + u32 dst_x; + u32 dst_y; + u32 dst_w; + u32 dst_h; + int byte_stride; + int pxiel_stride; + u32 reserve; struct sync_fence *in_fence; - struct files_struct *files; }; struct afbcd_data_s { @@ -295,9 +310,12 @@ struct hw_list_s { struct hw_para_s { struct pandata_s pandata[HW_OSD_COUNT]; struct pandata_s dispdata[HW_OSD_COUNT]; + struct pandata_s dispdata_backup[HW_OSD_COUNT]; struct pandata_s scaledata[HW_OSD_COUNT]; struct pandata_s free_src_data[HW_OSD_COUNT]; struct pandata_s free_dst_data[HW_OSD_COUNT]; + struct pandata_s free_src_data_backup[HW_OSD_COUNT]; + struct pandata_s free_dst_data_backup[HW_OSD_COUNT]; /* struct pandata_s rotation_pandata[HW_OSD_COUNT]; */ struct pandata_s cursor_dispdata[HW_OSD_COUNT]; @@ -311,9 +329,12 @@ struct hw_para_s { #endif struct osd_scale_s scale[HW_OSD_COUNT]; struct osd_scale_s free_scale[HW_OSD_COUNT]; + struct osd_scale_s free_scale_backup[HW_OSD_COUNT]; u32 free_scale_enable[HW_OSD_COUNT]; + u32 free_scale_enable_backup[HW_OSD_COUNT]; struct fb_geometry_s fb_gem[HW_OSD_COUNT]; const struct color_bit_define_s *color_info[HW_OSD_COUNT]; + const struct color_bit_define_s *color_backup[HW_OSD_COUNT]; u32 scan_mode; u32 order; struct osd_3d_mode_s mode_3d[HW_OSD_COUNT]; @@ -321,6 +342,7 @@ struct hw_para_s { /* u32 block_windows[HW_OSD_COUNT][HW_OSD_BLOCK_REG_COUNT]; */ u32 block_mode[HW_OSD_COUNT]; u32 free_scale_mode[HW_OSD_COUNT]; + u32 free_scale_mode_backup[HW_OSD_COUNT]; u32 osd_reverse[HW_OSD_COUNT]; /* struct osd_rotate_s rotate[HW_OSD_COUNT]; */ struct hw_list_s reg[HW_OSD_COUNT][HW_REG_INDEX_MAX]; @@ -334,6 +356,7 @@ struct hw_para_s { u32 hw_reset_flag; struct afbcd_data_s osd_afbcd[HW_OSD_COUNT]; u32 urgent[HW_OSD_COUNT]; + u32 osd_deband_enable; }; #endif /* _OSD_H_ */ diff --git a/drivers/amlogic/media/osd/osd_canvas.h b/drivers/amlogic/media/osd/osd_canvas.h index f35df041ba7c..460b377b454e 100644 --- a/drivers/amlogic/media/osd/osd_canvas.h +++ b/drivers/amlogic/media/osd/osd_canvas.h @@ -24,4 +24,6 @@ #define OSD4_CANVAS_INDEX 0x42 #define ALLOC_CANVAS_INDEX 0x44 +#define EXTERN1_CANVAS 0x41 +#define EXTERN2_CANVAS 0x42 #endif diff --git a/drivers/amlogic/media/osd/osd_debug.c b/drivers/amlogic/media/osd/osd_debug.c index 21fe8d89987c..6c08432c79a5 100644 --- a/drivers/amlogic/media/osd/osd_debug.c +++ b/drivers/amlogic/media/osd/osd_debug.c @@ -142,6 +142,10 @@ static void osd_debug_dump_register_all(void) osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); reg = VPP_OSD_SCO_V_START_END; osd_log_info("reg[0x%x]: 0x%08x\n\n", reg, osd_reg_read(reg)); + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX) { + reg = OSD_DB_FLT_CTRL; + osd_log_info("reg[0x%x]: 0x%08x\n\n", reg, osd_reg_read(reg)); + } for (index = 0; index < 2; index++) { if (index == 1) diff --git a/drivers/amlogic/media/osd/osd_fb.c b/drivers/amlogic/media/osd/osd_fb.c index 6ffa93094f44..0873ceb68353 100644 --- a/drivers/amlogic/media/osd/osd_fb.c +++ b/drivers/amlogic/media/osd/osd_fb.c @@ -379,7 +379,7 @@ static int osddev_setcolreg(unsigned int regno, u16 red, u16 green, u16 blue, mutex_lock(&fbdev->lock); osd_setpal_hw(fbdev->fb_info->node, regno, red, green, blue, transp); - mutex_lock(&fbdev->lock); + mutex_unlock(&fbdev->lock); } if (info->fix.visual == FB_VISUAL_TRUECOLOR) { u32 v, r, g, b, a; @@ -650,6 +650,7 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) unsigned long ret; u32 flush_rate; struct fb_sync_request_s sync_request; + struct fb_sync_request_render_s sync_request_render; struct fb_dmabuf_export dmaexp; switch (cmd) { @@ -669,6 +670,10 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) ret = copy_from_user(&sync_request, argp, sizeof(struct fb_sync_request_s)); break; + case FBIOPUT_OSD_SYNC_RENDER_ADD: + ret = copy_from_user(&sync_request_render, argp, + sizeof(struct fb_sync_request_render_s)); + break; case FBIO_WAITFORVSYNC: case FBIOGET_OSD_SCALE_AXIS: case FBIOPUT_OSD_ORDER: @@ -858,6 +863,47 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) info->var.yoffset = sync_request.yoffset; } break; + case FBIOPUT_OSD_SYNC_RENDER_ADD: + { + ion_phys_addr_t addr; + size_t len; + u32 phys_addr; + + if (sync_request_render.shared_fd >= 0) { + ret = meson_ion_share_fd_to_phys(fb_ion_client, + sync_request_render.shared_fd, + &addr, &len); + if (ret == 0) { + if (sync_request_render.type == + GE2D_COMPOSE_MODE) { + phys_addr = addr + + sync_request_render.yoffset + * info->fix.line_length; + } else + phys_addr = addr; + } else + phys_addr = 0; + } else + phys_addr = 0; + + sync_request_render.out_fen_fd = + osd_sync_request_render(info->node, + info->var.yres, + &sync_request_render, phys_addr); + ret = copy_to_user(argp, + &sync_request_render, + sizeof(struct fb_sync_request_render_s)); + if (sync_request_render.out_fen_fd < 0) { + /* fence create fail. */ + ret = -1; + } else { + info->var.xoffset = + sync_request_render.xoffset; + info->var.yoffset = + sync_request_render.yoffset; + } + } + break; case FBIOGET_OSD_DMABUF: #ifdef CONFIG_ION if (info->node == DEV_OSD0 && osd_get_afbc()) { @@ -967,6 +1013,9 @@ static int osd_open(struct fb_info *info, int arg) struct platform_device *pdev = NULL; fbdev = (struct osd_fb_dev_s *)info->par; + fbdev->open_count++; + osd_log_info("osd_open index=%d,open_count=%d\n", + fbdev->fb_index, fbdev->open_count); if (info->screen_base != NULL) return 0; pdev = fbdev->dev; @@ -1165,6 +1214,27 @@ static int osd_open(struct fb_info *info, int arg) return 0; } + +static int osd_release(struct fb_info *info, int arg) +{ + struct osd_fb_dev_s *fbdev; + int err = 0; + + fbdev = (struct osd_fb_dev_s *)info->par; + + if (!fbdev->open_count) { + err = -EINVAL; + osd_log_info("osd already released. index=%d\n", + fbdev->fb_index); + goto done; + } + osd_log_info("osd_release now.index=%d,open_count=%d\n", + fbdev->fb_index, fbdev->open_count); + + fbdev->open_count--; +done: + return err; +} static ssize_t osd_clear(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { @@ -1241,6 +1311,7 @@ static struct fb_ops osd_ops = { .fb_blank = osd_blank, .fb_pan_display = osd_pan_display, .fb_sync = osd_sync, + .fb_release = osd_release, }; static void set_default_display_axis(struct fb_var_screeninfo *var, @@ -2086,6 +2157,29 @@ static ssize_t free_scale_switch(struct device *device, return count; } +static ssize_t show_osd_deband(struct device *device, + struct device_attribute *attr, + char *buf) +{ + u32 osd_deband_enable; + + osd_get_deband(&osd_deband_enable); + return snprintf(buf, 40, "%d\n", + osd_deband_enable); +} + +static ssize_t store_osd_deband(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int res = 0; + int ret = 0; + + ret = kstrtoint(buf, 0, &res); + osd_set_deband(res); + + return count; +} static inline int str2lower(char *str) { while (*str != '\0') { @@ -2266,6 +2360,8 @@ static struct device_attribute osd_attrs[] = { show_reset_status, NULL), __ATTR(free_scale_switch, 0220, NULL, free_scale_switch), + __ATTR(osd_deband, 0644, + show_osd_deband, store_osd_deband), }; #ifdef CONFIG_PM diff --git a/drivers/amlogic/media/osd/osd_fb.h b/drivers/amlogic/media/osd/osd_fb.h index 620ad7b9f48a..4025018d701a 100644 --- a/drivers/amlogic/media/osd/osd_fb.h +++ b/drivers/amlogic/media/osd/osd_fb.h @@ -55,6 +55,7 @@ struct osd_fb_dev_s { u32 enable_key_flag; u32 color_key; u32 fb_index; + u32 open_count; bool dis_osd_mchange; }; diff --git a/drivers/amlogic/media/osd/osd_hw.c b/drivers/amlogic/media/osd/osd_hw.c index dca7fca42374..149facf8bf7a 100644 --- a/drivers/amlogic/media/osd/osd_hw.c +++ b/drivers/amlogic/media/osd/osd_hw.c @@ -101,6 +101,7 @@ static __nosavedata int use_h_filter_mode = -1; static __nosavedata int use_v_filter_mode = -1; static unsigned int osd_h_filter_mode = 1; +#define CANVAS_ALIGNED(x) (((x) + 31) & ~31) module_param(osd_h_filter_mode, uint, 0664); MODULE_PARM_DESC(osd_h_filter_mode, "osd_h_filter_mode"); @@ -303,8 +304,6 @@ static void osd_toggle_buffer(struct kthread_work *work) osd_pan_display_fence(data); if (data->in_fence) sync_fence_put(data->in_fence); - if (data->in_fd > 0) - __close_fd(data->files, data->in_fd); list_del(&data->list); kfree(data); } @@ -327,10 +326,10 @@ static int out_fence_create(int *release_fence_fd, u32 *val, u32 buf_num) cur_streamline_val = 1; if (timeline == NULL) return -1; - init_kthread_worker(&buffer_toggle_worker); + kthread_init_worker(&buffer_toggle_worker); buffer_toggle_thread = kthread_run(kthread_worker_fn, &buffer_toggle_worker, "aml_buf_toggle"); - init_kthread_work(&buffer_toggle_work, osd_toggle_buffer); + kthread_init_work(&buffer_toggle_work, osd_toggle_buffer); timeline_created = 1; } /* install fence map; first ,the simplest. */ @@ -363,13 +362,13 @@ int osd_sync_request(u32 index, u32 yres, u32 xoffset, u32 yoffset, int buf_num = 0; struct osd_fence_map_s *fence_map = kzalloc(sizeof(struct osd_fence_map_s), GFP_KERNEL); - buf_num = find_buf_num(yres, yoffset); if (!fence_map) { osd_log_err("could not allocate osd_fence_map\n"); return -ENOMEM; } mutex_lock(&post_fence_list_lock); + fence_map->op = 0xffffffff; fence_map->fb_index = index; fence_map->buf_num = buf_num; fence_map->yoffset = yoffset; @@ -377,13 +376,65 @@ int osd_sync_request(u32 index, u32 yres, u32 xoffset, u32 yoffset, fence_map->yres = yres; fence_map->in_fd = in_fence_fd; fence_map->in_fence = sync_fence_fdget(in_fence_fd); - fence_map->files = current->files; fence_map->out_fd = out_fence_create(&out_fence_fd, &fence_map->val, buf_num); list_add_tail(&fence_map->list, &post_fence_list); mutex_unlock(&post_fence_list_lock); - queue_kthread_work(&buffer_toggle_worker, &buffer_toggle_work); + kthread_queue_work(&buffer_toggle_worker, &buffer_toggle_work); + __close_fd(current->files, in_fence_fd); + return out_fence_fd; +} +int osd_sync_request_render(u32 index, u32 yres, + struct fb_sync_request_render_s *request, + u32 phys_addr) +{ + int out_fence_fd = -1; + int buf_num = 0; + u32 xoffset, yoffset; + s32 in_fence_fd; + struct osd_fence_map_s *fence_map = + kzalloc(sizeof(struct osd_fence_map_s), GFP_KERNEL); + + xoffset = request->xoffset; + yoffset = request->yoffset; + in_fence_fd = request->in_fen_fd; + buf_num = find_buf_num(yres, yoffset); + if (!fence_map) { + osd_log_err("could not allocate osd_fence_map\n"); + return -ENOMEM; + } + mutex_lock(&post_fence_list_lock); + fence_map->op = 0xffffffff; + fence_map->fb_index = index; + fence_map->buf_num = buf_num; + fence_map->yoffset = yoffset; + fence_map->xoffset = xoffset; + fence_map->yres = yres; + fence_map->in_fd = in_fence_fd; + fence_map->ext_addr = phys_addr; + if (fence_map->ext_addr) { + fence_map->format = request->format; + fence_map->width = request->width; + fence_map->height = request->height; + fence_map->dst_x = request->dst_x; + fence_map->dst_y = request->dst_y; + fence_map->dst_w = request->dst_w; + fence_map->dst_h = request->dst_h; + fence_map->byte_stride = request->byte_stride; + fence_map->pxiel_stride = request->pxiel_stride; + fence_map->reserve = request->reserve; + } + fence_map->compose_type = request->type; + fence_map->op = request->op; + fence_map->in_fence = sync_fence_fdget(in_fence_fd); + fence_map->out_fd = + out_fence_create(&out_fence_fd, &fence_map->val, buf_num); + list_add_tail(&fence_map->list, &post_fence_list); + mutex_unlock(&post_fence_list_lock); + kthread_queue_work(&buffer_toggle_worker, &buffer_toggle_work); + request->out_fen_fd = out_fence_fd; + __close_fd(current->files, in_fence_fd); return out_fence_fd; } @@ -420,6 +471,15 @@ int osd_sync_request(u32 index, u32 yres, u32 xoffset, u32 yoffset, osd_log_err("osd_sync_request not supported\n"); return -5566; } + + +int osd_sync_request_render(u32 index, u32 yres, + struct fb_sync_request_render_s *request, + u32 phys_addr) +{ + osd_log_err("osd_sync_request_render not supported\n"); + return -5566; +} #endif void osd_update_3d_mode(void) @@ -949,6 +1009,7 @@ void osd_set_color_mode(u32 index, const struct color_bit_define_s *color) { if (color != osd_hw.color_info[index]) { osd_hw.color_info[index] = color; + osd_hw.color_backup[index] = color; add_to_update_list(index, OSD_COLOR_MODE); } } @@ -988,6 +1049,8 @@ void osd_update_disp_axis_hw( /* if output mode change then reset pan ofFfset. */ memcpy(&osd_hw.pandata[index], &pan_data, sizeof(struct pandata_s)); memcpy(&osd_hw.dispdata[index], &disp_data, sizeof(struct pandata_s)); + memcpy(&osd_hw.dispdata_backup[index], + &disp_data, sizeof(struct pandata_s)); spin_lock_irqsave(&osd_lock, lock_flags); if (mode_change) /* modify pandata . */ osd_hw.reg[index][OSD_COLOR_MODE].update_func(); @@ -1081,6 +1144,8 @@ void osd_setup_hw(u32 index, else osd_hw.osd_afbcd[index].conv_lbuf_len = 1024; } + osd_hw.fb_gem[index].xres = xres; + osd_hw.fb_gem[index].yres = yres; osd_log_info("osd[%d] canvas.idx =0x%x\n", index, osd_hw.fb_gem[index].canvas_idx); osd_log_info("osd[%d] canvas.addr=0x%x\n", @@ -1090,9 +1155,9 @@ void osd_setup_hw(u32 index, osd_log_info("osd[%d] canvas.height=%d\n", index, osd_hw.fb_gem[index].height); osd_log_info("osd[%d] frame.width=%d\n", - index, xres); + index, osd_hw.fb_gem[index].xres); osd_log_info("osd[%d] frame.height=%d\n", - index, yres); + index, osd_hw.fb_gem[index].yres); #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS canvas_config(osd_hw.fb_gem[index].canvas_idx, osd_hw.fb_gem[index].addr, @@ -1106,6 +1171,7 @@ void osd_setup_hw(u32 index, if ((color != osd_hw.color_info[index]) || (index == OSD2)) { update_color_mode = 1; osd_hw.color_info[index] = color; + osd_hw.color_backup[index] = color; } /* osd blank only control by /sys/class/graphcis/fbx/blank */ #if 0 @@ -1124,6 +1190,8 @@ void osd_setup_hw(u32 index, sizeof(struct pandata_s)); memcpy(&osd_hw.dispdata[index], &disp_data, sizeof(struct pandata_s)); + memcpy(&osd_hw.dispdata_backup[index], &disp_data, + sizeof(struct pandata_s)); } spin_lock_irqsave(&osd_lock, lock_flags); if (update_color_mode) @@ -1150,8 +1218,15 @@ void osd_setpal_hw(u32 index, unsigned int transp ) { - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) - return; + int do_lut; + + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { + if ((get_cpu_type() == MESON_CPU_MAJOR_ID_TXLX) + && (index == OSD2)) { + do_lut = 1; + } else + return; + } if (regno < 256) { u32 pal; @@ -1193,7 +1268,10 @@ static void osd_set_free_scale_enable_mode1(u32 index, u32 enable) v_enable = (enable & 0xffff ? 1 : 0); osd_hw.free_scale[index].h_enable = h_enable; osd_hw.free_scale[index].v_enable = v_enable; + osd_hw.free_scale_backup[index].h_enable = h_enable; + osd_hw.free_scale_backup[index].v_enable = v_enable; osd_hw.free_scale_enable[index] = enable; + osd_hw.free_scale_enable_backup[index] = enable; if (osd_hw.free_scale_enable[index]) { ret = osd_set_scan_mode(index); spin_lock_irqsave(&osd_lock, lock_flags); @@ -1235,6 +1313,7 @@ void osd_get_free_scale_enable_hw(u32 index, u32 *free_scale_enable) void osd_set_free_scale_mode_hw(u32 index, u32 freescale_mode) { osd_hw.free_scale_mode[index] = freescale_mode; + osd_hw.free_scale_mode_backup[index] = freescale_mode; } void osd_get_free_scale_mode_hw(u32 index, u32 *freescale_mode) @@ -1249,22 +1328,22 @@ void osd_set_4k2k_fb_mode_hw(u32 fb_for_4k2k) void osd_get_free_scale_width_hw(u32 index, u32 *free_scale_width) { - *free_scale_width = osd_hw.free_src_data[index].x_end - - osd_hw.free_src_data[index].x_start + 1; + *free_scale_width = osd_hw.free_src_data_backup[index].x_end - + osd_hw.free_src_data_backup[index].x_start + 1; } void osd_get_free_scale_height_hw(u32 index, u32 *free_scale_height) { - *free_scale_height = osd_hw.free_src_data[index].y_end - - osd_hw.free_src_data[index].y_start + 1; + *free_scale_height = osd_hw.free_src_data_backup[index].y_end - + osd_hw.free_src_data_backup[index].y_start + 1; } void osd_get_free_scale_axis_hw(u32 index, s32 *x0, s32 *y0, s32 *x1, s32 *y1) { - *x0 = osd_hw.free_src_data[index].x_start; - *y0 = osd_hw.free_src_data[index].y_start; - *x1 = osd_hw.free_src_data[index].x_end; - *y1 = osd_hw.free_src_data[index].y_end; + *x0 = osd_hw.free_src_data_backup[index].x_start; + *y0 = osd_hw.free_src_data_backup[index].y_start; + *x1 = osd_hw.free_src_data_backup[index].x_end; + *y1 = osd_hw.free_src_data_backup[index].y_end; } void osd_set_free_scale_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1) @@ -1273,6 +1352,10 @@ void osd_set_free_scale_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1) osd_hw.free_src_data[index].y_start = y0; osd_hw.free_src_data[index].x_end = x1; osd_hw.free_src_data[index].y_end = y1; + osd_hw.free_src_data_backup[index].x_start = x0; + osd_hw.free_src_data_backup[index].y_start = y0; + osd_hw.free_src_data_backup[index].x_end = x1; + osd_hw.free_src_data_backup[index].y_end = y1; } void osd_get_scale_axis_hw(u32 index, s32 *x0, s32 *y0, s32 *x1, s32 *y1) @@ -1299,51 +1382,59 @@ void osd_get_window_axis_hw(u32 index, s32 *x0, s32 *y0, s32 *x1, s32 *y1) vinfo = get_current_vinfo(); if (vinfo) { if (is_interlaced(vinfo)) { - height = osd_hw.free_dst_data[index].y_end - - osd_hw.free_dst_data[index].y_start + 1; + height = osd_hw.free_dst_data_backup[index].y_end - + osd_hw.free_dst_data_backup[index].y_start + 1; height *= 2; - *y0 = osd_hw.free_dst_data[index].y_start * 2; + *y0 = osd_hw.free_dst_data_backup[index].y_start * 2; *y1 = height + *y0 - 1; } else { - *y0 = osd_hw.free_dst_data[index].y_start; - *y1 = osd_hw.free_dst_data[index].y_end; + *y0 = osd_hw.free_dst_data_backup[index].y_start; + *y1 = osd_hw.free_dst_data_backup[index].y_end; } } else { - *y0 = osd_hw.free_dst_data[index].y_start; - *y1 = osd_hw.free_dst_data[index].y_end; + *y0 = osd_hw.free_dst_data_backup[index].y_start; + *y1 = osd_hw.free_dst_data_backup[index].y_end; } - *x0 = osd_hw.free_dst_data[index].x_start; - *x1 = osd_hw.free_dst_data[index].x_end; + *x0 = osd_hw.free_dst_data_backup[index].x_start; + *x1 = osd_hw.free_dst_data_backup[index].x_end; } void osd_set_window_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1) { struct vinfo_s *vinfo; + s32 temp_y0, temp_y1; vinfo = get_current_vinfo(); mutex_lock(&osd_mutex); if (vinfo) { if (is_interlaced(vinfo)) { - osd_hw.free_dst_data[index].y_start = y0 / 2; - osd_hw.free_dst_data[index].y_end = y1 / 2; + temp_y0 = y0 / 2; + temp_y1 = y1 / 2; } else { - osd_hw.free_dst_data[index].y_start = y0; - osd_hw.free_dst_data[index].y_end = y1; + temp_y0 = y0; + temp_y1 = y1; } } else { - osd_hw.free_dst_data[index].y_start = y0; - osd_hw.free_dst_data[index].y_end = y1; + temp_y0 = y0; + temp_y1 = y1; } + osd_hw.free_dst_data[index].y_start = temp_y0; + osd_hw.free_dst_data[index].y_end = temp_y1; osd_hw.free_dst_data[index].x_start = x0; osd_hw.free_dst_data[index].x_end = x1; + osd_hw.free_dst_data_backup[index].y_start = temp_y0; + osd_hw.free_dst_data_backup[index].y_end = temp_y1; + osd_hw.free_dst_data_backup[index].x_start = x0; + osd_hw.free_dst_data_backup[index].x_end = x1; #if defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR) osd_hw.cursor_dispdata[index].x_start = x0; osd_hw.cursor_dispdata[index].x_end = x1; - osd_hw.cursor_dispdata[index].y_start = y0; - osd_hw.cursor_dispdata[index].y_end = y1; + osd_hw.cursor_dispdata[index].y_start = temp_y0; + osd_hw.cursor_dispdata[index].y_end = temp_y1; #endif if (osd_hw.free_dst_data[index].y_end >= 2159) { - if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM) + if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXM) + || (get_cpu_type() == MESON_CPU_MAJOR_ID_TXLX)) osd_reg_write(VPP_OSD_SC_DUMMY_DATA, 0x002020ff); else if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) @@ -1578,6 +1669,7 @@ void osd_set_clone_hw(u32 index, u32 clone) if (osd_hw.clone[index]) { if (osd_hw.angle[index]) { osd_hw.color_info[index] = osd_hw.color_info[OSD1]; + osd_hw.color_backup[index] = osd_hw.color_info[OSD1]; ret = osd_clone_task_start(); if (ret) osd_clone_pan(index, @@ -1647,6 +1739,12 @@ void osd_switch_free_scale( osd_hw.free_scale[pre_index].h_enable = h_enable; osd_hw.free_scale[pre_index].v_enable = v_enable; osd_hw.free_scale_enable[pre_index] = pre_scale; + osd_hw.free_scale_backup[pre_index].h_enable + = h_enable; + osd_hw.free_scale_backup[pre_index].v_enable + = v_enable; + osd_hw.free_scale_enable_backup[pre_index] + = pre_scale; osd_hw.enable[pre_index] = pre_enable; h_enable = (next_scale & 0xffff0000 ? 1 : 0); @@ -1654,6 +1752,9 @@ void osd_switch_free_scale( osd_hw.free_scale[next_index].h_enable = h_enable; osd_hw.free_scale[next_index].v_enable = v_enable; osd_hw.free_scale_enable[next_index] = next_scale; + osd_hw.free_scale_backup[next_index].h_enable = h_enable; + osd_hw.free_scale_backup[next_index].v_enable = v_enable; + osd_hw.free_scale_enable_backup[next_index] = next_scale; osd_hw.enable[next_index] = next_enable; osd_set_scan_mode(next_index); @@ -1702,7 +1803,230 @@ void osd_set_urgent(u32 index, u32 urgent) osd_wait_vsync_hw(); } +void osd_get_deband(u32 *osd_deband_enable) +{ + *osd_deband_enable = osd_hw.osd_deband_enable; +} + +void osd_set_deband(u32 osd_deband_enable) +{ + u32 data32; + + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX) { + if (osd_hw.free_scale_enable[OSD1] + || osd_hw.free_scale_enable[OSD2]) { + osd_hw.osd_deband_enable = osd_deband_enable; + + spin_lock_irqsave(&osd_lock, lock_flags); + + data32 = VSYNCOSD_RD_MPEG_REG(OSD_DB_FLT_CTRL); + if (osd_deband_enable) { + /* Bit 23 debanding registers of side + * lines, [0] for luma + * Bit 22 debanding registers of side + * lines, [1] for chroma + * Bit 5debanding registers,for luma + * Bit 4debanding registers,for chroma + */ + data32 |= 3 << 4; + data32 |= 3 << 22; + } else { + data32 |= 0 << 4; + data32 |= 0 << 22; + } + VSYNCOSD_WR_MPEG_REG(OSD_DB_FLT_CTRL, data32); + spin_unlock_irqrestore(&osd_lock, lock_flags); + osd_wait_vsync_hw(); + } + } +} #ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE +enum { + HAL_PIXEL_FORMAT_RGBA_8888 = 1, + HAL_PIXEL_FORMAT_RGBX_8888 = 2, + HAL_PIXEL_FORMAT_RGB_888 = 3, + HAL_PIXEL_FORMAT_RGB_565 = 4, + HAL_PIXEL_FORMAT_BGRA_8888 = 5, +}; + +static u32 extern_canvas[2] = {EXTERN1_CANVAS, EXTERN2_CANVAS}; +static int ext_canvas_id; +static bool use_ext; +const struct color_bit_define_s extern_color_format_array[] = { + /*32 bit color RGBA */ + { + COLOR_INDEX_32_ABGR, 2, 5, + 0, 8, 0, 8, 8, 0, 16, 8, 0, 24, 8, 0, + 0, 4 + }, + /*32 bit color RGBX */ + { + COLOR_INDEX_32_XBGR, 2, 5, + 0, 8, 0, 8, 8, 0, 16, 8, 0, 24, 0, 0, + 0, 4 + }, + /*24 bit color RGB */ + { + COLOR_INDEX_24_RGB, 5, 7, + 16, 8, 0, 8, 8, 0, 0, 8, 0, 0, 0, 0, + 0, 3 + }, + /*16 bit color BGR */ + { + COLOR_INDEX_16_565, 4, 4, + 11, 5, 0, 5, 6, 0, 0, 5, 0, 0, 0, 0, + 0, 2 + }, + /*32 bit color BGRA */ + { + COLOR_INDEX_32_ARGB, 1, 5, + 16, 8, 0, 8, 8, 0, 0, 8, 0, 24, 8, 0, + 0, 4 + }, +}; + +static const struct color_bit_define_s *convert_hal_format(u32 format) +{ + const struct color_bit_define_s *color = NULL; + + switch (format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_RGB_888: + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_BGRA_8888: + color = &extern_color_format_array[format - 1]; + break; + } + return color; +} + +static bool osd_ge2d_compose_pan_display(struct osd_fence_map_s *fence_map) +{ + u32 index = fence_map->fb_index; + bool free_scale_set = false; + + canvas_config(osd_hw.fb_gem[index].canvas_idx, + fence_map->ext_addr, + CANVAS_ALIGNED(fence_map->width * + osd_hw.color_info[index]->bpp), + fence_map->height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + + osd_hw.pandata[index].x_start = 0; + osd_hw.pandata[index].x_end = fence_map->width - 1; + osd_hw.pandata[index].y_start = 0; + osd_hw.pandata[index].y_end = fence_map->height - 1; + return free_scale_set; +} + +static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) +{ + u32 index = fence_map->fb_index; + u32 ext_addr = fence_map->ext_addr; + u32 width_src, width_dst, height_src, height_dst; + bool freescale_update = false; + + ext_addr = ext_addr + fence_map->byte_stride * fence_map->yoffset; + + canvas_config(osd_hw.fb_gem[index].canvas_idx, + ext_addr, + fence_map->byte_stride, + fence_map->height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + + width_dst = osd_hw.free_dst_data_backup[index].x_end - + osd_hw.free_dst_data_backup[index].x_start + 1; + width_src = osd_hw.free_src_data_backup[index].x_end - + osd_hw.free_src_data_backup[index].x_start + 1; + + height_dst = osd_hw.free_dst_data_backup[index].y_end - + osd_hw.free_dst_data_backup[index].y_start + 1; + height_src = osd_hw.free_src_data_backup[index].y_end - + osd_hw.free_src_data_backup[index].y_start + 1; + + if (osd_hw.free_scale_enable[index] || + (width_src != width_dst) || + (height_src != height_dst) || + (fence_map->width != fence_map->dst_w) || + (fence_map->height != fence_map->dst_h)) { + osd_hw.free_scale[index].h_enable = 1; + osd_hw.free_scale[index].v_enable = 1; + osd_hw.free_scale_enable[index] = 0x10001; + osd_hw.free_scale_mode[index] = 1; + + osd_hw.pandata[index].x_start = fence_map->xoffset; + osd_hw.pandata[index].x_end = + fence_map->xoffset + + fence_map->width - 1; + osd_hw.pandata[index].y_start = 0; + osd_hw.pandata[index].y_end = + fence_map->height - 1; + + osd_hw.dispdata[index].x_start = + osd_hw.dispdata_backup[index].x_start + + (fence_map->dst_x * width_dst) / + width_src; + osd_hw.dispdata[index].x_end = + osd_hw.dispdata_backup[index].x_start + + ((fence_map->dst_x + fence_map->dst_w) * + width_dst) / width_src - 1; + + osd_hw.dispdata[index].y_start = + osd_hw.dispdata_backup[index].y_start + + (fence_map->dst_y * height_dst) / + height_src; + osd_hw.dispdata[index].y_end = + osd_hw.dispdata_backup[index].y_start + + ((fence_map->dst_y + fence_map->dst_h) * + height_dst) / height_src - 1; + + if (((memcmp(&(osd_hw.free_src_data[index]), + &osd_hw.pandata[index], + sizeof(struct pandata_s)) != 0) || + (memcmp(&(osd_hw.free_dst_data[index]), + &osd_hw.dispdata[index], + sizeof(struct pandata_s)) != 0))) { + memcpy(&(osd_hw.free_src_data[index]), + &osd_hw.pandata[index], + sizeof(struct pandata_s)); + memcpy(&(osd_hw.free_dst_data[index]), + &osd_hw.dispdata[index], + sizeof(struct pandata_s)); + freescale_update = true; + osd_log_dbg("direct pandata x=%d,x_end=%d,y=%d,y_end=%d\n", + osd_hw.pandata[index].x_start, + osd_hw.pandata[index].x_end, + osd_hw.pandata[index].y_start, + osd_hw.pandata[index].y_end); + osd_log_dbg("fence_map:width=%d,height=%d\n", + fence_map->width, + fence_map->height); + osd_log_dbg("dst_w=%d,dst_h=%d,byte_stride=%d\n", + fence_map->dst_w, + fence_map->dst_h, + fence_map->byte_stride); + } + } else { + osd_hw.pandata[index].x_start = 0; + osd_hw.pandata[index].x_end = + fence_map->width - 1; + osd_hw.pandata[index].y_start = 0; + osd_hw.pandata[index].y_end = + fence_map->height - 1; + + osd_hw.dispdata[index].x_start = + fence_map->dst_x; + osd_hw.dispdata[index].x_end = + fence_map->dst_x + fence_map->dst_w - 1; + osd_hw.dispdata[index].y_start = + fence_map->dst_y; + osd_hw.dispdata[index].y_end = + fence_map->dst_y + fence_map->dst_h - 1; + } + fence_map->ext_addr = ext_addr; + return freescale_update; +} static void osd_pan_display_fence(struct osd_fence_map_s *fence_map) { s32 ret = 1; @@ -1710,7 +2034,11 @@ static void osd_pan_display_fence(struct osd_fence_map_s *fence_map) u32 index = fence_map->fb_index; u32 xoffset = fence_map->xoffset; u32 yoffset = fence_map->yoffset; - + const struct color_bit_define_s *color = NULL; + bool color_mode = false; + bool freescale_update = false; + u32 osd_enable = 0; + bool skip = false; if (index >= 2) return; if (timeline_created) { /* out fence created success. */ @@ -1719,15 +2047,122 @@ static void osd_pan_display_fence(struct osd_fence_map_s *fence_map) osd_log_dbg("fence wait ret %d\n", ret); } if (ret) { - if (xoffset != osd_hw.pandata[index].x_start - || yoffset != osd_hw.pandata[index].y_start) { + if (fence_map->op == 0xffffffff) + skip = true; + else + osd_enable = (fence_map->op & 1) ? DISABLE : ENABLE; + if (fence_map->ext_addr && fence_map->width + && fence_map->height && index == OSD1) { spin_lock_irqsave(&osd_lock, lock_flags); - diff_x = xoffset - osd_hw.pandata[index].x_start; - diff_y = yoffset - osd_hw.pandata[index].y_start; - osd_hw.pandata[index].x_start += diff_x; - osd_hw.pandata[index].x_end += diff_x; - osd_hw.pandata[index].y_start += diff_y; - osd_hw.pandata[index].y_end += diff_y; + use_ext = true; + osd_hw.fb_gem[index].canvas_idx = + extern_canvas[ext_canvas_id]; + ext_canvas_id ^= 1; + color = convert_hal_format(fence_map->format); + if (color) { + osd_hw.color_info[index] = color; + } else + osd_log_err("fence color format error %d\n", + fence_map->format); + + if (DIRECT_COMPOSE_MODE == + fence_map->compose_type) + freescale_update = + osd_direct_compose_pan_display(fence_map); + else if (GE2D_COMPOSE_MODE == + fence_map->compose_type) + freescale_update = + osd_ge2d_compose_pan_display(fence_map); + if (index == OSD1 && + osd_hw.osd_afbcd[index].enable == ENABLE) + osd_hw.osd_afbcd[index].phy_addr = + fence_map->ext_addr; + + osd_hw.reg[index][OSD_COLOR_MODE].update_func(); + osd_hw.reg[index][DISP_GEOMETRY].update_func(); + if ((osd_hw.free_scale_enable[index] + && osd_update_window_axis) + || freescale_update) { + osd_hw.reg[index][DISP_FREESCALE_ENABLE] + .update_func(); + osd_update_window_axis = false; + } + if ((osd_hw.osd_afbcd[index].enable == DISABLE) + && (osd_enable != osd_hw.enable[index]) + && skip == false) { + osd_hw.enable[index] = osd_enable; + osd_hw.reg[index][OSD_ENABLE].update_func(); + } + spin_unlock_irqrestore(&osd_lock, lock_flags); + osd_wait_vsync_hw(); + } else if (xoffset != osd_hw.pandata[index].x_start + || yoffset != osd_hw.pandata[index].y_start + || (use_ext && index == OSD1)) { + spin_lock_irqsave(&osd_lock, lock_flags); + if ((use_ext) && (index == OSD1)) { + osd_hw.fb_gem[index].canvas_idx = + OSD1_CANVAS_INDEX; + + osd_hw.pandata[index].x_start = xoffset; + osd_hw.pandata[index].x_end = xoffset + + osd_hw.fb_gem[index].xres - 1; + osd_hw.pandata[index].y_start = yoffset; + osd_hw.pandata[index].y_end = yoffset + + osd_hw.fb_gem[index].yres - 1; + + osd_hw.dispdata[index].x_start = + osd_hw.dispdata_backup[index].x_start; + osd_hw.dispdata[index].x_end = + osd_hw.dispdata_backup[index].x_end; + osd_hw.dispdata[index].y_start = + osd_hw.dispdata_backup[index].y_start; + osd_hw.dispdata[index].y_end = + osd_hw.dispdata_backup[index].y_end; + + /* restore free_scale info */ + osd_hw.free_scale[index].h_enable = + osd_hw.free_scale_backup[index].h_enable; + osd_hw.free_scale[index].v_enable = + osd_hw.free_scale_backup[index].v_enable; + osd_hw.free_scale_enable[index] = + osd_hw.free_scale_enable_backup[index]; + osd_hw.free_scale_mode[index] = + osd_hw.free_scale_mode_backup[index]; + + memcpy(&osd_hw.free_src_data[index], + &osd_hw.free_src_data_backup[index], + sizeof(struct pandata_s)); + memcpy(&osd_hw.free_dst_data[index], + &osd_hw.free_dst_data_backup[index], + sizeof(struct pandata_s)); + osd_log_dbg("switch back dispdata_backup x=%d,x_end=%d,y=%d,y_end=%d\n", + osd_hw.dispdata_backup[index].x_start, + osd_hw.dispdata_backup[index].x_end, + osd_hw.dispdata_backup[index].y_start, + osd_hw.dispdata_backup[index].y_end); + + osd_hw.color_info[index] = + osd_hw.color_backup[index]; + + canvas_config(osd_hw.fb_gem[0].canvas_idx, + osd_hw.fb_gem[0].addr, + osd_hw.fb_gem[0].width, + osd_hw.fb_gem[0].height, + CANVAS_ADDR_NOWRAP, + CANVAS_BLKMODE_LINEAR); + use_ext = false; + color_mode = true; + freescale_update = true; + } else { + diff_x = xoffset - + osd_hw.pandata[index].x_start; + diff_y = yoffset - + osd_hw.pandata[index].y_start; + osd_hw.pandata[index].x_start += diff_x; + osd_hw.pandata[index].x_end += diff_x; + osd_hw.pandata[index].y_start += diff_y; + osd_hw.pandata[index].y_end += diff_y; + } if (index == OSD1 && osd_hw.osd_afbcd[index].enable == ENABLE) { /* osd_hw.osd_afbcd[index].phy_addr = @@ -1743,13 +2178,32 @@ static void osd_pan_display_fence(struct osd_fence_map_s *fence_map) [osd_hw.pandata[index].y_start / osd_hw.osd_afbcd[index].frame_height]; } + if (color_mode) + osd_hw.reg[index][OSD_COLOR_MODE].update_func(); osd_hw.reg[index][DISP_GEOMETRY].update_func(); - if (osd_hw.free_scale_enable[index] - && osd_update_window_axis) { + if ((osd_hw.free_scale_enable[index] + && osd_update_window_axis) + || (osd_hw.free_scale_enable[index] + && freescale_update)) { osd_hw.reg[index][DISP_FREESCALE_ENABLE] .update_func(); osd_update_window_axis = false; } + if ((osd_hw.osd_afbcd[index].enable == DISABLE) + && (osd_enable != osd_hw.enable[index]) + && skip == false) { + osd_hw.enable[index] = osd_enable; + osd_hw.reg[index][OSD_ENABLE].update_func(); + } + spin_unlock_irqrestore(&osd_lock, lock_flags); + osd_wait_vsync_hw(); + } else if ((osd_enable != osd_hw.enable[index]) + && skip == false) { + spin_lock_irqsave(&osd_lock, lock_flags); + if (osd_hw.osd_afbcd[index].enable == DISABLE) { + osd_hw.enable[index] = osd_enable; + osd_hw.reg[index][OSD_ENABLE].update_func(); + } spin_unlock_irqrestore(&osd_lock, lock_flags); osd_wait_vsync_hw(); } @@ -3222,20 +3676,32 @@ void osd_init_hw(u32 logo_loaded) osd_hw.enable[OSD2] = osd_hw.enable[OSD1] = DISABLE; osd_hw.fb_gem[OSD1].canvas_idx = OSD1_CANVAS_INDEX; osd_hw.fb_gem[OSD2].canvas_idx = OSD2_CANVAS_INDEX; + osd_hw.fb_gem[OSD1].xres = 0; + osd_hw.fb_gem[OSD1].yres = 0; + osd_hw.fb_gem[OSD2].xres = 0; + osd_hw.fb_gem[OSD2].yres = 0; osd_hw.gbl_alpha[OSD1] = OSD_GLOBAL_ALPHA_DEF; osd_hw.gbl_alpha[OSD2] = OSD_GLOBAL_ALPHA_DEF; osd_hw.color_info[OSD1] = NULL; osd_hw.color_info[OSD2] = NULL; + osd_hw.color_backup[OSD1] = NULL; + osd_hw.color_backup[OSD2] = NULL; osd_hw.color_key[OSD1] = osd_hw.color_key[OSD2] = 0xffffffff; osd_hw.free_scale_enable[OSD1] = osd_hw.free_scale_enable[OSD2] = 0; osd_hw.scale[OSD1].h_enable = osd_hw.scale[OSD1].v_enable = 0; osd_hw.scale[OSD2].h_enable = osd_hw.scale[OSD2].v_enable = 0; + osd_hw.free_scale_enable_backup[OSD1] = 0; + osd_hw.free_scale_enable_backup[OSD2] = 0; osd_hw.mode_3d[OSD2].enable = osd_hw.mode_3d[OSD1].enable = 0; osd_hw.block_mode[OSD1] = osd_hw.block_mode[OSD2] = 0; osd_hw.free_scale[OSD1].h_enable = 0; osd_hw.free_scale[OSD1].h_enable = 0; osd_hw.free_scale[OSD2].v_enable = 0; osd_hw.free_scale[OSD2].v_enable = 0; + osd_hw.free_scale_backup[OSD1].h_enable = 0; + osd_hw.free_scale_backup[OSD1].h_enable = 0; + osd_hw.free_scale_backup[OSD2].v_enable = 0; + osd_hw.free_scale_backup[OSD2].v_enable = 0; osd_hw.osd_reverse[OSD1] = REVERSE_FALSE; osd_hw.osd_reverse[OSD2] = REVERSE_FALSE; /* @@ -3245,6 +3711,7 @@ void osd_init_hw(u32 logo_loaded) * osd_hw.rotation_pandata[OSD2].y_start = 0; */ osd_hw.antiflicker_mode = 0; + osd_hw.osd_deband_enable = 1; osd_hw.color_key_enable[OSD1] = 0; osd_hw.color_key_enable[OSD2] = 0; osd_hw.free_src_data[OSD1].x_start = 0; @@ -3255,15 +3722,25 @@ void osd_init_hw(u32 logo_loaded) osd_hw.free_src_data[OSD2].x_end = 0; osd_hw.free_src_data[OSD2].y_start = 0; osd_hw.free_src_data[OSD2].y_end = 0; + osd_hw.free_src_data_backup[OSD1].x_start = 0; + osd_hw.free_src_data_backup[OSD1].x_end = 0; + osd_hw.free_src_data_backup[OSD1].y_start = 0; + osd_hw.free_src_data_backup[OSD1].y_end = 0; + osd_hw.free_src_data_backup[OSD2].x_start = 0; + osd_hw.free_src_data_backup[OSD2].x_end = 0; + osd_hw.free_src_data_backup[OSD2].y_start = 0; + osd_hw.free_src_data_backup[OSD2].y_end = 0; osd_hw.free_scale_mode[OSD1] = 0; osd_hw.free_scale_mode[OSD2] = 1; - if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM) + if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXM) + || (get_cpu_type() == MESON_CPU_MAJOR_ID_TXLX)) osd_reg_write(VPP_OSD_SC_DUMMY_DATA, 0x002020ff); else if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) osd_reg_write(VPP_OSD_SC_DUMMY_DATA, 0xff); else osd_reg_write(VPP_OSD_SC_DUMMY_DATA, 0x008080ff); + osd_set_deband(osd_hw.osd_deband_enable); /* osd_hw.osd_afbcd[OSD1].enable = 0; * osd_hw.osd_afbcd[OSD2].enable = 0; */ @@ -3321,29 +3798,11 @@ void osd_cursor_hw(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, u32 osd_w, && (osd_hw.scaledata[OSD2].x_end > 0)) { x = x * osd_hw.scaledata[OSD2].x_end / osd_hw.scaledata[OSD2].x_start; - if (osd_hw.scaledata[OSD2].x_end > - osd_hw.scaledata[OSD2].x_start) { - disp_tmp.x_start = osd_hw.dispdata[OSD1].x_start * - osd_hw.scaledata[OSD2].x_end / - osd_hw.scaledata[OSD2].x_start; - disp_tmp.x_end = osd_hw.dispdata[OSD1].x_end * - osd_hw.scaledata[OSD2].x_end / - osd_hw.scaledata[OSD2].x_start; - } } if (osd_hw.scale[OSD2].v_enable && (osd_hw.scaledata[OSD2].y_start > 0) && (osd_hw.scaledata[OSD2].y_end > 0)) { y = y * osd_hw.scaledata[OSD2].y_end / osd_hw.scaledata[OSD2].y_start; - if (osd_hw.scaledata[OSD2].y_end > - osd_hw.scaledata[OSD2].y_start) { - disp_tmp.y_start = osd_hw.dispdata[OSD1].y_start * - osd_hw.scaledata[OSD2].y_end / - osd_hw.scaledata[OSD2].y_start; - disp_tmp.y_end = osd_hw.dispdata[OSD1].y_end * - osd_hw.scaledata[OSD2].y_end / - osd_hw.scaledata[OSD2].y_start; - } } x += xstart; y += ystart; diff --git a/drivers/amlogic/media/osd/osd_hw.h b/drivers/amlogic/media/osd/osd_hw.h index 7f198e93123f..3b25980f094e 100644 --- a/drivers/amlogic/media/osd/osd_hw.h +++ b/drivers/amlogic/media/osd/osd_hw.h @@ -20,6 +20,7 @@ #include #include "osd.h" +#include "osd_sync.h" #define REG_OFFSET (0x20) #define OSD_RELATIVE_BITS 0x33330 @@ -112,6 +113,9 @@ extern void osd_pan_display_hw(u32 index, unsigned int xoffset, unsigned int yoffset); extern int osd_sync_request(u32 index, u32 yres, u32 xoffset, u32 yoffset, s32 in_fence_fd); +extern int osd_sync_request_render(u32 index, u32 yres, + struct fb_sync_request_render_s *request, + u32 phys_addr); extern s32 osd_wait_vsync_event(void); #if defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR) extern void osd_cursor_hw(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, @@ -145,6 +149,8 @@ extern void osd_switch_free_scale( u32 next_index, u32 next_enable, u32 next_scale); 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); int logo_work_init(void); void set_logo_loaded(void); int set_osd_logo_freescaler(void); diff --git a/drivers/amlogic/media/osd/osd_reg.h b/drivers/amlogic/media/osd/osd_reg.h index 98f5bfa3a413..5e22245aa848 100644 --- a/drivers/amlogic/media/osd/osd_reg.h +++ b/drivers/amlogic/media/osd/osd_reg.h @@ -280,6 +280,27 @@ #define VIU_OSD1_MATRIX_COEF22_30 0x1a9d #define VIU_OSD1_MATRIX_COEF31_32 0x1a9e #define VIU_OSD1_MATRIX_COEF40_41 0x1a9f + +#define VIU_OSD_BLENDO_H_START_END 0x1aa9 +#define VIU_OSD_BLENDO_V_START_END 0x1aaa +#define VIU_OSD_BLEND_GEN_CTRL0 0x1aab +#define VIU_OSD_BLEND_GEN_CTRL1 0x1aac +#define VIU_OSD_BLEND_DUMMY_DATA 0x1aad +#define VIU_OSD_BLEND_CURRENT_XY 0x1aae + +#define VIU_OSD2_MATRIX_CTRL 0x1ab0 +#define VIU_OSD2_MATRIX_COEF00_01 0x1ab1 +#define VIU_OSD2_MATRIX_COEF02_10 0x1ab2 +#define VIU_OSD2_MATRIX_COEF11_12 0x1ab3 +#define VIU_OSD2_MATRIX_COEF20_21 0x1ab4 +#define VIU_OSD2_MATRIX_COEF22 0x1ab5 +#define VIU_OSD2_MATRIX_OFFSET0_1 0x1ab6 +#define VIU_OSD2_MATRIX_OFFSET2 0x1ab7 +#define VIU_OSD2_MATRIX_PRE_OFFSET0_1 0x1ab8 +#define VIU_OSD2_MATRIX_PRE_OFFSET2 0x1ab9 +#define VIU_OSD2_MATRIX_PROBE_COLOR 0x1aba +#define VIU_OSD2_MATRIX_HL_COLOR 0x1abb +#define VIU_OSD2_MATRIX_PROBE_POS 0x1abc #define VIU_OSD1_EOTF_CTL 0x1ad4 #define VIU_OSD1_EOTF_COEF00_01 0x1ad5 #define VIU_OSD1_EOTF_COEF02_10 0x1ad6 @@ -1351,6 +1372,7 @@ #define OSDSR_UK_GRAD2DADJA_TH_RATE 0x313d #define OSDSR_UK_GRAD2DADJA_LIMIT 0x313e #define OSDSR_UK_BST_GAIN 0x313f +#if 0 #define OSDSR_HVBLEND_TH 0x3140 #define OSDSR_DEMO_WIND_TB 0x3141 #define OSDSR_DEMO_WIND_LR 0x3142 @@ -1362,6 +1384,19 @@ #define OSDSR_ABIC_VCOEF0 0x3148 #define OSDSR_YBIC_VCOEF0 0x3149 #define OSDSR_CBIC_VCOEF0 0x314a +#endif +#define OSD_DB_FLT_CTRL 0x3140 +#define OSD_DB_FLT_CTRL1 0x3141 +#define OSD_DB_FLT_LUMA_THRD 0x3142 +#define OSD_DB_FLT_CHRM_THRD 0x3143 +#define OSD_DB_FLT_RANDLUT 0x3144 +#define OSD_DB_FLT_PXI_THRD 0x3145 +#define OSD_DB_FLT_SEED_Y 0x3146 +#define OSD_DB_FLT_SEED_U 0x3147 +#define OSD_DB_FLT_SEED_V 0x3148 +#define OSD_DB_FLT_SEED3 0x3149 +#define OSD_DB_FLT_SEED4 0x314a +#define OSD_DB_FLT_SEED5 0x314b /* osd afbcd on gxtvbb */ #define OSD1_AFBCD_ENABLE 0x31a0 diff --git a/drivers/amlogic/media/osd/osd_sync.h b/drivers/amlogic/media/osd/osd_sync.h index 4855f38c4265..3ac28857f2ca 100644 --- a/drivers/amlogic/media/osd/osd_sync.h +++ b/drivers/amlogic/media/osd/osd_sync.h @@ -18,7 +18,11 @@ #ifndef _OSD_SYNC_H_ #define _OSD_SYNC_H_ - +enum { + GLES_COMPOSE_MODE = 0, + DIRECT_COMPOSE_MODE = 1, + GE2D_COMPOSE_MODE = 2, +}; struct fb_sync_request_s { unsigned int xoffset; @@ -27,4 +31,23 @@ struct fb_sync_request_s { int out_fen_fd; }; +struct fb_sync_request_render_s { + unsigned int xoffset; + unsigned int yoffset; + int in_fen_fd; + int out_fen_fd; + int width; + int height; + int format; + int shared_fd; + unsigned int op; + unsigned int type; /*direct render or ge2d*/ + unsigned int dst_x; + unsigned int dst_y; + unsigned int dst_w; + unsigned int dst_h; + int byte_stride; + int pxiel_stride; + unsigned int reserve; +}; #endif