From: 黄涛 Date: Mon, 28 Jul 2014 08:09:07 +0000 (+0800) Subject: Merge remote-tracking branch 'origin/develop-3.10' into develop-3.10-next X-Git-Tag: firefly_0821_release~4916^2~142 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b5d61451d6b04fbf8d470030fa4bf96235c921f9;p=firefly-linux-kernel-4.4.55.git Merge remote-tracking branch 'origin/develop-3.10' into develop-3.10-next --- b5d61451d6b04fbf8d470030fa4bf96235c921f9 diff --cc drivers/video/rockchip/rk_fb.c index 62f42ef0dca2,5f181a2056d7..2573ab9d3e1e --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@@ -1452,8 -1432,192 +1436,191 @@@ static void rk_fb_update_driver(struct win->z_order = -1; */ } - } + static int rk_fb_update_hdmi_win(struct rk_lcdc_win *ext_win, + struct rk_lcdc_win *win) + { + struct rk_fb *rk_fb = platform_get_drvdata(fb_pdev); + struct rk_lcdc_driver *dev_drv = rk_get_prmry_lcdc_drv(); + struct rk_lcdc_driver *ext_dev_drv = rk_get_extend_lcdc_drv(); + struct rk_screen *screen; + struct rk_screen *ext_screen; + int hdmi_xsize; + int hdmi_ysize; + int pixel_width, vir_width_bit, y_stride; + struct rk_lcdc_win *last_win; + bool is_yuv = false; + static u8 fb_index = 0; + + if ((rk_fb->disp_mode != DUAL) || + (hdmi_get_hotplug() != HDMI_HPD_ACTIVED) || + (!hdmi_switch_complete)) { + printk(KERN_INFO "%s: hdmi is disconnect!\n", __func__); + return -1; + } + + if (unlikely(!dev_drv) || unlikely(!ext_dev_drv)) + return -1; + + screen = dev_drv->cur_screen; + ext_screen = ext_dev_drv->cur_screen; + hdmi_xsize = ext_screen->xsize; + hdmi_ysize = ext_screen->ysize; + + ext_win->state = win->state; + ext_win->id = win->id; + if (win->area[0].smem_start == 0) + ext_win->state = 0; + if (ext_win->state == 0) + return 0; + + ext_win->area_num = win->area_num; + ext_win->format = win->format; + ext_win->z_order = win->z_order; + ext_win->alpha_en = win->alpha_en; + ext_win->alpha_mode = win->alpha_mode; + ext_win->g_alpha_val = win->g_alpha_val; + + /* win0 and win1 have only one area and support scale + * but win2 and win3 don't support scale + * so hdmi only use win0 or win1 + */ + ext_win->area[0].state = win->area[0].state; + + switch (ext_win->format) { + case YUV422: + case YUV420: + case YUV444: + case YUV422_A: + case YUV420_A: + case YUV444_A: + is_yuv = true; + break; + default: + is_yuv = false; + break; + } + + if (ext_dev_drv->rotate_mode == ROTATE_90 || + ext_dev_drv->rotate_mode == ROTATE_270) { + if (ext_win->id == 0) { + ext_win->area[0].smem_start = + rk_fb->fb[rk_fb->num_fb >> 1]->fix.smem_start; + ext_win->area[0].y_offset = (get_rotate_fb_size() >> 1) * fb_index; + if ((++fb_index) > 1) + fb_index = 0; + } else { + ext_win->area[0].y_offset = 0; + last_win = ext_dev_drv->win[ext_win->id - 1]; + if (last_win->area[0].cbr_start) + ext_win->area[0].smem_start = + last_win->area[0].cbr_start + + last_win->area[0].c_offset + + last_win->area[0].xvir * last_win->area[0].yvir; + else + ext_win->area[0].smem_start = + last_win->area[0].smem_start + + last_win->area[0].y_offset + + last_win->area[0].xvir * last_win->area[0].yvir; + } + + ext_win->area[0].xact = win->area[0].yact; + ext_win->area[0].yact = win->area[0].xact; + ext_win->area[0].xvir = win->area[0].yact; + ext_win->area[0].yvir = win->area[0].xact; + pixel_width = rk_fb_pixel_width(ext_win->format); + vir_width_bit = pixel_width * ext_win->area[0].xvir; + y_stride = ALIGN_N_TIMES(vir_width_bit, 32) / 8; + ext_win->area[0].y_vir_stride = y_stride >> 2; + } else { + ext_win->area[0].smem_start = win->area[0].smem_start; + ext_win->area[0].y_offset = win->area[0].y_offset; + ext_win->area[0].xact = win->area[0].xact; + ext_win->area[0].yact = win->area[0].yact; + ext_win->area[0].xvir = win->area[0].xvir; + ext_win->area[0].yvir = win->area[0].yvir; + ext_win->area[0].y_vir_stride = win->area[0].y_vir_stride; + } + + if (win->area[0].xpos != 0 || win->area[0].ypos != 0) { + if (ext_dev_drv->rotate_mode == ROTATE_270) { + int xbom_pos = 0, ybom_pos = 0; + int xtop_pos = 0, ytop_pos = 0; + + ext_win->area[0].xsize = hdmi_xsize * + win->area[0].ysize / + screen->mode.yres; + ext_win->area[0].ysize = hdmi_ysize * + win->area[0].xsize / + screen->mode.xres; + xbom_pos = hdmi_xsize * win->area[0].ypos / screen->mode.yres; + ybom_pos = hdmi_ysize * win->area[0].xpos / screen->mode.xres; + xtop_pos = hdmi_xsize - ext_win->area[0].xsize - xbom_pos; + ytop_pos = hdmi_ysize - ext_win->area[0].ysize - ybom_pos; + ext_win->area[0].xpos = + ((ext_screen->mode.xres - hdmi_xsize) >> 1) + xtop_pos; + ext_win->area[0].ypos = + ((ext_screen->mode.yres - hdmi_ysize) >> 1) + ytop_pos; + } else if (ext_dev_drv->rotate_mode == ROTATE_90) { + ext_win->area[0].xsize = hdmi_xsize * + win->area[0].ysize / + screen->mode.yres; + ext_win->area[0].ysize = hdmi_ysize * + win->area[0].xsize / + screen->mode.xres; + ext_win->area[0].xpos = + ((ext_screen->mode.xres - hdmi_xsize) >> 1) + + hdmi_xsize * win->area[0].ypos / screen->mode.yres; + ext_win->area[0].ypos = + ((ext_screen->mode.yres - hdmi_ysize) >> 1) + + hdmi_ysize * win->area[0].xpos / screen->mode.xres; + } else { + ext_win->area[0].xsize = hdmi_xsize * + win->area[0].xsize / + screen->mode.xres; + ext_win->area[0].ysize = hdmi_ysize * + win->area[0].ysize / + screen->mode.yres; + ext_win->area[0].xpos = + ((ext_screen->mode.xres - hdmi_xsize) >> 1) + + hdmi_xsize * win->area[0].xpos / screen->mode.xres; + ext_win->area[0].ypos = + ((ext_screen->mode.yres - hdmi_ysize) >> 1) + + hdmi_ysize * win->area[0].ypos / screen->mode.yres; + } + } else { + ext_win->area[0].xsize = hdmi_xsize; + ext_win->area[0].ysize = hdmi_ysize; + ext_win->area[0].xpos = + (ext_screen->mode.xres - hdmi_xsize) >> 1; + ext_win->area[0].ypos = + (ext_screen->mode.yres - hdmi_ysize) >> 1; + } + + if (!is_yuv) { + ext_win->area[0].uv_vir_stride = 0; + ext_win->area[0].cbr_start = 0; + ext_win->area[0].c_offset = 0; + return 0; + } + + if (ext_dev_drv->rotate_mode == ROTATE_90 || + ext_dev_drv->rotate_mode == ROTATE_270) { + ext_win->area[0].uv_vir_stride = ext_win->area[0].y_vir_stride; + ext_win->area[0].cbr_start = ext_win->area[0].smem_start + + ext_win->area[0].y_offset + + ext_win->area[0].xvir * ext_win->area[0].yvir; + ext_win->area[0].c_offset = win->area[0].c_offset; + } else { + ext_win->area[0].uv_vir_stride = win->area[0].uv_vir_stride; + ext_win->area[0].cbr_start = win->area[0].cbr_start; + ext_win->area[0].c_offset = win->area[0].c_offset; + } + + return 0; + } + static struct rk_fb_reg_win_data *rk_fb_get_win_data(struct rk_fb_reg_data *regs, int win_id) {