Subject: glamo_fix_improper_xrandr_geometry_setting.patch
authorBalaji Rao <balajirrao@openmoko.org>
Thu, 29 Jan 2009 18:25:32 +0000 (18:25 +0000)
committerAndy Green <agreen@octopus.localdomain>
Thu, 29 Jan 2009 18:25:32 +0000 (18:25 +0000)
X-Git-Url: http://git.openmoko.org/?p=kernel.git;a=commitdiff_plain;h=3b09161ffa5f29870d1f2cab1442f79ff2017b69

glamo_fix_improper_xrandr_geometry_setting.patch

Switching to xrandr -o 3 from xrandr -o 1 caused the screen to look crazy
because of the way lcd geometry is set in glamo. This patch fixes it.

Signed-off-by: Balaji Rao <balajirrao@openmoko.org>

drivers/mfd/glamo/glamo-fb.c

index 3e4a307..19dcd71 100644 (file)
@@ -75,6 +75,7 @@ struct glamofb_handle {
        int cursor_on;
        u_int32_t pseudo_pal[16];
        spinlock_t lock_cmd;
+       int angle;      /* Current rotation angle */
 };
 
 /* 'sibling' spi device for lcm init */
@@ -255,11 +256,6 @@ static void reg_set_bit_mask(struct glamofb_handle *glamo,
 #define GLAMO_LCD_HV_RETR_DISP_START_MASK 0x03FF
 #define GLAMO_LCD_HV_RETR_DISP_END_MASK 0x03FF
 
-enum orientation {
-    ORIENTATION_PORTRAIT,
-    ORIENTATION_LANDSCAPE
-};
-
 
 /* the caller has to enxure lock_cmd is held and we are in cmd mode */
 static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation)
@@ -275,17 +271,22 @@ static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation)
        switch (rotation) {
                case FB_ROTATE_UR:
                        glamo_rot = GLAMO_LCD_ROT_MODE_0;
+                       glamo->angle = 0;
                        break;
                case FB_ROTATE_CW:
                        glamo_rot = GLAMO_LCD_ROT_MODE_90;
+                       glamo->angle = 90;
                        break;
                case FB_ROTATE_UD:
                        glamo_rot = GLAMO_LCD_ROT_MODE_180;
+                       glamo->angle = 180;
                        break;
                case FB_ROTATE_CCW:
                        glamo_rot = GLAMO_LCD_ROT_MODE_270;
+                       glamo->angle = 270;
                        break;
                default:
+                       glamo->angle = 0;
                        glamo_rot = GLAMO_LCD_ROT_MODE_0;
                        break;
        }
@@ -301,38 +302,12 @@ static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation)
                                 GLAMO_LCD_MODE1_ROTATE_EN : 0);
 }
 
-static enum orientation get_orientation(struct fb_var_screeninfo *var)
-{
-       if (var->xres <= var->yres)
-               return ORIENTATION_PORTRAIT;
-
-       return ORIENTATION_LANDSCAPE;
-}
-
-static int will_orientation_change(struct fb_var_screeninfo *var)
-{
-       enum orientation orient = get_orientation(var);
-
-       switch (orient) {
-               case ORIENTATION_LANDSCAPE:
-                       if (var->rotate == FB_ROTATE_UR ||
-                           var->rotate == FB_ROTATE_UD)
-                               return 1;
-                       break;
-               case ORIENTATION_PORTRAIT:
-                       if (var->rotate == FB_ROTATE_CW ||
-                           var->rotate == FB_ROTATE_CCW)
-                               return 1;
-                       break;
-       }
-       return 0;
-}
-
 static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
                                          struct fb_var_screeninfo *var)
 {
-       int sync, bp, disp, fp, total, xres, yres, pitch, orientation_changing;
+       int sync, bp, disp, fp, total, pitch;
        unsigned long flags;
+       int width, height;
 
        if (!glamo || !var)
                return;
@@ -355,31 +330,52 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
                                     GLAMO_ENGINE_LCD,
                                     var->pixclock);
 
-       xres = var->xres;
-       yres = var->yres;
+       if (glamo->angle == 90 || glamo->angle == 270) {
+               /* 
+                * But if we are going back to portrait mode from here,
+                * we get inverted values from Xglamo 
+                */ 
+               if (!(var->rotate == FB_ROTATE_UR ||
+                               var->rotate == FB_ROTATE_UD)) {
+                       width = var->yres;
+                       height = var->xres;
+               } else {
+                       width = var->xres;
+                       height = var->yres;
+               }
 
-       /* figure out if orientation is going to change */
-       orientation_changing = will_orientation_change(var);
+       } else {
+               width = var->xres;
+               height = var->yres;
+       }
 
-       /* adjust the pitch according to new orientation to come */
+       /* Portrait ? */
+       if (var->rotate == FB_ROTATE_UR || var->rotate == FB_ROTATE_UD) {
+               /* We don't need to set xres and yres in this particular case
+                * because Xglamo does it for us */
+               if (!(glamo->angle == 90 || glamo->angle == 270)) {
+                       var->xres = width;var->yres = height;
+               }
 
-       if (orientation_changing) {
-               pitch = var->yres * var->bits_per_pixel / 8;
-        } else {
-               pitch = var->xres * var->bits_per_pixel / 8;
-        }
+               var->xres_virtual = width * 2;
+               var->yres_virtual = height;
+               pitch = width * var->bits_per_pixel / 8;
+       } else {
+               var->xres = height;
+               var->yres = width;
+               var->xres_virtual = height;
+               var->yres_virtual = width * 2;
+               pitch = height * var->bits_per_pixel / 8;
+       }
 
-       /*
-        * set the desired LCD geometry
-        */
        reg_set_bit_mask(glamo,
                         GLAMO_REG_LCD_WIDTH,
                         GLAMO_LCD_WIDTH_MASK,
-                        xres);
+                        width);
        reg_set_bit_mask(glamo,
                         GLAMO_REG_LCD_HEIGHT,
                         GLAMO_LCD_HEIGHT_MASK,
-                        yres);
+                        height);
        reg_set_bit_mask(glamo,
                         GLAMO_REG_LCD_PITCH,
                         GLAMO_LCD_PITCH_MASK,
@@ -388,22 +384,11 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
        /* honour the rotation request */
        __rotate_lcd(glamo, var->rotate);
 
-       /* update the reported geometry of the framebuffer. */
-       if (orientation_changing) {
-               var->xres_virtual = var->xres = yres;
-               var->xres_virtual *= 2;
-               var->yres_virtual = var->yres = xres;
-       } else {
-               var->xres_virtual = var->xres = xres;
-               var->yres_virtual = var->yres = yres;
-               var->yres_virtual *= 2;
-       }
-
        /* update scannout timings */
        sync = 0;
        bp = sync + var->hsync_len;
        disp = bp + var->left_margin;
-       fp = disp + xres;
+       fp = disp + width;
        total = fp + var->right_margin;
 
        reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_TOTAL,
@@ -420,7 +405,7 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
        sync = 0;
        bp = sync + var->vsync_len;
        disp = bp + var->upper_margin;
-       fp = disp + yres;
+       fp = disp + height;
        total = fp + var->lower_margin;
 
        reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_TOTAL,
@@ -836,6 +821,8 @@ static int __init glamofb_probe(struct platform_device *pdev)
        glamofb->fb = fbinfo;
        glamofb->dev = &pdev->dev;
 
+       glamofb->angle = 0;
+
        strcpy(fbinfo->fix.id, "SMedia Glamo");
 
        glamofb->reg = platform_get_resource_byname(pdev, IORESOURCE_MEM,