From ef6f19b23c93553f46750d9ccc597e74fd85610d Mon Sep 17 00:00:00 2001 From: yxj Date: Fri, 7 Sep 2012 15:53:18 +0800 Subject: [PATCH] rkfb:support dual display for rk2928 --- drivers/video/rockchip/Kconfig | 32 +++++++++++++---------- drivers/video/rockchip/rk_fb.c | 47 ++++++++++++++++++++-------------- include/linux/rk_fb.h | 2 +- include/linux/rk_screen.h | 5 ++-- 4 files changed, 51 insertions(+), 35 deletions(-) diff --git a/drivers/video/rockchip/Kconfig b/drivers/video/rockchip/Kconfig index 49e959e9301e..a538dc8865c8 100755 --- a/drivers/video/rockchip/Kconfig +++ b/drivers/video/rockchip/Kconfig @@ -7,6 +7,25 @@ config FB_ROCKCHIP ---help--- Framebuffer driver for rockchip based platform +config DUAL_DISP_IN_KERNEL + bool "implement dual display in kernel" + depends on FB_ROCKCHIP + default y if HDMI_RK30 + help + select y will implement dual screen display in kernel +config ONE_LCDC_DUAL_OUTPUT_INF + bool "one lcdc dual output display interface support" + depends on FB_ROCKCHIP + default y if ARCH_RK2928 + help + select y if on platform like rk2928 which have one lcdc but two output interface +config THREE_FB_BUFFER + bool "Three fb buffer support" + depends on FB_ROCKCHIP + default y + help + select y if android support three buffer,like Jelly Bean + config FB_WIMO bool "WiMO support" depends on FB_ROCKCHIP @@ -60,19 +79,6 @@ config LCDC1_RK31 help Support lcdc1 if you say y here -config DUAL_DISP_IN_KERNEL - bool "implement dual display in kernel" - depends on FB_ROCKCHIP - default y if HDMI_RK30 - help - select y will implement dual screen display in kernel - -config THREE_FB_BUFFER - bool "Three fb buffer support" - depends on FB_ROCKCHIP - default y - help - select y if android support three buffer,like Jelly Bean source "drivers/video/rockchip/hdmi/Kconfig" source "drivers/video/rockchip/rga/Kconfig" source "drivers/video/rockchip/lvds/Kconfig" diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index f25d6a115422..8fede7217931 100644 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -399,8 +399,8 @@ static int rk_fb_set_par(struct fb_info *info) ysize = screen->y_res; } - if(screen->lcdc_id == 0) //this is for device like rk2928 ,whic have one lcdc but two display outputs - { + if(screen->screen_id == 0) //this is for device like rk2928 ,whic have one lcdc but two display outputs + { //save parameter set by android dev_drv->screen0->xsize = xsize; dev_drv->screen0->ysize = ysize; dev_drv->screen0->xpos = xpos; @@ -559,19 +559,19 @@ static struct fb_ops fb_ops = { static struct fb_var_screeninfo def_var = { - .red = {11,5,0},//default set to rgb565,the boot logo is rgb565 - .green = {5,6,0}, - .blue = {0,5,0}, - .transp = {0,0,0}, - #ifdef CONFIG_LOGO_LINUX_BMP + .red = {11,5,0},//default set to rgb565,the boot logo is rgb565 + .green = {5,6,0}, + .blue = {0,5,0}, + .transp = {0,0,0}, +#ifdef CONFIG_LOGO_LINUX_BMP .nonstd = HAL_PIXEL_FORMAT_RGBA_8888, - #else - .nonstd = HAL_PIXEL_FORMAT_RGB_565, //(ypos<<20+xpos<<8+format) format - #endif - .grayscale = 0, //(ysize<<20+xsize<<8) - .activate = FB_ACTIVATE_NOW, - .accel_flags = 0, - .vmode = FB_VMODE_NONINTERLACED, +#else + .nonstd = HAL_PIXEL_FORMAT_RGB_565, //(ypos<<20+xpos<<8+format) format +#endif + .grayscale = 0, //(ysize<<20+xsize<<8) + .activate = FB_ACTIVATE_NOW, + .accel_flags = 0, + .vmode = FB_VMODE_NONINTERLACED, }; static struct fb_fix_screeninfo def_fix = { @@ -623,7 +623,7 @@ int rk_fb_switch_screen(rk_screen *screen ,int enable ,int lcdc_id) int layer_id; sprintf(name, "lcdc%d",lcdc_id); - for(i = 0; i < inf->num_lcdc; i++) + for(i = 0; i < inf->num_lcdc; i++) //find the driver the display device connected to { if(!strcmp(inf->lcdc_dev_drv[i]->name,name)) { @@ -646,7 +646,7 @@ int rk_fb_switch_screen(rk_screen *screen ,int enable ,int lcdc_id) } else if((lcdc_id == 1)&&(inf->num_lcdc == 2)) { - info = inf->fb[2]; + info = inf->fb[dev_drv->num_layer]; //the main fb of lcdc2 } if(dev_drv->screen1) //device like rk2928 ,have only one lcdc but two outputs @@ -654,12 +654,21 @@ int rk_fb_switch_screen(rk_screen *screen ,int enable ,int lcdc_id) if(enable) { memcpy(dev_drv->screen1,screen,sizeof(rk_screen )); - dev_drv->screen1->lcdc_id = 1; + dev_drv->screen1->lcdc_id = 0; //connect screen1 to output interface 0 + dev_drv->screen1->screen_id = 1; + dev_drv->screen0->lcdc_id = 1; //connect screen0 to output interface 1 dev_drv->cur_screen = dev_drv->screen1; + dev_drv->screen0->sscreen_get(dev_drv->screen0,dev_drv->cur_screen->hdmi_resolution); + } else { + dev_drv->screen1->lcdc_id = 1; //connect screen1 to output interface 1 + dev_drv->screen0->lcdc_id = 0; //connect screen0 to output interface 0 dev_drv->cur_screen = dev_drv->screen0; + dev_drv->screen_ctr_info->set_screen_info(dev_drv->cur_screen, + dev_drv->screen_ctr_info->lcd_info); + } } @@ -735,7 +744,7 @@ int rk_fb_disp_scale(u8 scale_x, u8 scale_y,u8 lcdc_id) char name[6]; int i; - printk("scale_x:%x>>scale_y:%d\n",scale_x,scale_y); + printk("%s>>scale_x:%x>>scale_y:%d\n",__func__,scale_x,scale_y); sprintf(name, "lcdc%d",lcdc_id); for(i = 0; i < inf->num_lcdc; i++) { @@ -759,7 +768,7 @@ int rk_fb_disp_scale(u8 scale_x, u8 scale_y,u8 lcdc_id) } else if( (inf->num_lcdc == 2)&&(lcdc_id == 1)) { - info = inf->fb[2]; + info = inf->fb[dev_drv->num_layer]; } var = &info->var; diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h index 0a24b049e7f6..6a646a24dd95 100644 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -205,7 +205,7 @@ struct rk_lcdc_device_driver{ int fb_index_base; //the first fb index of the lcdc device rk_screen *screen0; //some platform have only one lcdc,but extend rk_screen *screen1; //two display devices for dual display,such as rk2918,rk2928 - rk_screen *cur_screen; + rk_screen *cur_screen; //screen0 is primary screen ,like lcd panel,screen1 is extend screen,like hdmi u32 pixclock; diff --git a/include/linux/rk_screen.h b/include/linux/rk_screen.h index 072bd8d85616..9535277db55d 100644 --- a/include/linux/rk_screen.h +++ b/include/linux/rk_screen.h @@ -103,7 +103,8 @@ typedef struct rk29fb_screen { u16 type; u16 hw_format; u16 face; - u8 lcdc_id;//which lcdc the screeen connect to + u8 lcdc_id; //which output interface the screeen connect to + u8 screen_id; //screen number /* Screen size */ u16 x_res; @@ -122,7 +123,7 @@ typedef struct rk29fb_screen { u16 vsync_len; u8 ft; //the time need to display one frame,in ms int *dsp_lut; //display lut -#ifdef CONFIG_HDMI_DUAL_DISP +#if defined(CONFIG_HDMI_DUAL_DISP) || defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF) /* Scaler mode Timing */ u32 s_pixclock; u16 s_left_margin; -- 2.34.1