rkfb:support dual display for rk2928
authoryxj <yxj@rock-chips.com>
Fri, 7 Sep 2012 07:53:18 +0000 (15:53 +0800)
committeryxj <yxj@rock-chips.com>
Fri, 7 Sep 2012 07:54:25 +0000 (15:54 +0800)
drivers/video/rockchip/Kconfig
drivers/video/rockchip/rk_fb.c
include/linux/rk_fb.h
include/linux/rk_screen.h

index 49e959e9301e043b147a29cb4f647ec077dc22f2..a538dc8865c8886889223cc63cd901825f518e50 100755 (executable)
@@ -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"
index f25d6a1154225d60a870ec8a4bfa3436eb908288..8fede72179315921e68404e78212880775370e89 100644 (file)
@@ -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;
index 0a24b049e7f6ff5a375830444d400da276ed1301..6a646a24dd95d6f33a7ef20934cb4410c1e78a2f 100644 (file)
@@ -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;
 
        
index 072bd8d8561668b7c35869c7c7485b4053acee01..9535277db55dc3026f61892ed550f475bea0bdf0 100644 (file)
@@ -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;