pxafb: move parallel LCD timing setup into dedicate function
authorEric Miao <eric.miao@marvell.com>
Wed, 30 Apr 2008 07:52:25 +0000 (00:52 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 30 Apr 2008 15:29:32 +0000 (08:29 -0700)
the new_regs stuff has been removed, and all the setup (modification to those
fbi->reg_*) is protected with IRQ disabled

   * disable IRQ is too heavy here, provided that no IRQ context will
     touch the fbi->reg_* and the only possible contending place is
     in the CPUFREQ_POSTCHANGE (task context), a mutex will be better,
     leave this for future improvement

Signed-off-by: eric miao <eric.miao@marvell.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/video/pxafb.c
drivers/video/pxafb.h

index a4ee722..d11ea78 100644 (file)
@@ -594,6 +594,43 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,
        return 0;
 }
 
+static void setup_parallel_timing(struct pxafb_info *fbi,
+                                 struct fb_var_screeninfo *var)
+{
+       unsigned int lines_per_panel, pcd = get_pcd(fbi, var->pixclock);
+
+       fbi->reg_lccr1 =
+               LCCR1_DisWdth(var->xres) +
+               LCCR1_HorSnchWdth(var->hsync_len) +
+               LCCR1_BegLnDel(var->left_margin) +
+               LCCR1_EndLnDel(var->right_margin);
+
+       /*
+        * If we have a dual scan LCD, we need to halve
+        * the YRES parameter.
+        */
+       lines_per_panel = var->yres;
+       if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual)
+               lines_per_panel /= 2;
+
+       fbi->reg_lccr2 =
+               LCCR2_DisHght(lines_per_panel) +
+               LCCR2_VrtSnchWdth(var->vsync_len) +
+               LCCR2_BegFrmDel(var->upper_margin) +
+               LCCR2_EndFrmDel(var->lower_margin);
+
+       fbi->reg_lccr3 = fbi->lccr3 |
+               (var->sync & FB_SYNC_HOR_HIGH_ACT ?
+                LCCR3_HorSnchH : LCCR3_HorSnchL) |
+               (var->sync & FB_SYNC_VERT_HIGH_ACT ?
+                LCCR3_VrtSnchH : LCCR3_VrtSnchL);
+
+       if (pcd) {
+               fbi->reg_lccr3 |= LCCR3_PixClkDiv(pcd);
+               set_hsync_time(fbi, pcd);
+       }
+}
+
 /*
  * pxafb_activate_var():
  *     Configures LCD Controller based on entries in var parameter.
@@ -602,9 +639,7 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,
 static int pxafb_activate_var(struct fb_var_screeninfo *var,
                              struct pxafb_info *fbi)
 {
-       struct pxafb_lcd_reg new_regs;
        u_long flags;
-       u_int lines_per_panel, pcd = get_pcd(fbi, var->pixclock);
        size_t nbytes;
 
 #if DEBUG_VAR
@@ -645,61 +680,31 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
                printk(KERN_ERR "%s: invalid lower_margin %d\n",
                        fbi->fb.fix.id, var->lower_margin);
 #endif
+       /* Update shadow copy atomically */
+       local_irq_save(flags);
+
+       setup_parallel_timing(fbi, var);
 
-       new_regs.lccr0 = fbi->lccr0 |
+       fbi->reg_lccr0 = fbi->lccr0 |
                (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM |
                 LCCR0_QDM | LCCR0_BM  | LCCR0_OUM);
 
-       new_regs.lccr1 =
-               LCCR1_DisWdth(var->xres) +
-               LCCR1_HorSnchWdth(var->hsync_len) +
-               LCCR1_BegLnDel(var->left_margin) +
-               LCCR1_EndLnDel(var->right_margin);
-
-       /*
-        * If we have a dual scan LCD, we need to halve
-        * the YRES parameter.
-        */
-       lines_per_panel = var->yres;
-       if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual)
-               lines_per_panel /= 2;
-
-       new_regs.lccr2 =
-               LCCR2_DisHght(lines_per_panel) +
-               LCCR2_VrtSnchWdth(var->vsync_len) +
-               LCCR2_BegFrmDel(var->upper_margin) +
-               LCCR2_EndFrmDel(var->lower_margin);
+       fbi->reg_lccr3 |= pxafb_bpp_to_lccr3(var);
 
-       new_regs.lccr3 = fbi->lccr3 |
-               pxafb_bpp_to_lccr3(var) |
-               (var->sync & FB_SYNC_HOR_HIGH_ACT ?
-                LCCR3_HorSnchH : LCCR3_HorSnchL) |
-               (var->sync & FB_SYNC_VERT_HIGH_ACT ?
-                LCCR3_VrtSnchH : LCCR3_VrtSnchL);
+       nbytes = var->yres * fbi->fb.fix.line_length;
 
-       if (pcd)
-               new_regs.lccr3 |= LCCR3_PixClkDiv(pcd);
-
-       /* Update shadow copy atomically */
-       local_irq_save(flags);
-
-       nbytes = lines_per_panel * fbi->fb.fix.line_length;
-
-       if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual)
+       if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual) {
+               nbytes = nbytes / 2;
                setup_frame_dma(fbi, DMA_LOWER, PAL_NONE, nbytes, nbytes);
+       }
 
        if (var->bits_per_pixel >= 16)
                setup_frame_dma(fbi, DMA_BASE, PAL_NONE, 0, nbytes);
        else
                setup_frame_dma(fbi, DMA_BASE, PAL_BASE, 0, nbytes);
 
-       fbi->reg_lccr0 = new_regs.lccr0;
-       fbi->reg_lccr1 = new_regs.lccr1;
-       fbi->reg_lccr2 = new_regs.lccr2;
-       fbi->reg_lccr3 = new_regs.lccr3;
        fbi->reg_lccr4 = lcd_readl(fbi, LCCR4) & ~LCCR4_PAL_FOR_MASK;
        fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK);
-       set_hsync_time(fbi, pcd);
        local_irq_restore(flags);
 
        /*
index f47f139..c627b83 100644 (file)
  * for more details.
  */
 
-/* Shadows for LCD controller registers */
-struct pxafb_lcd_reg {
-       unsigned int lccr0;
-       unsigned int lccr1;
-       unsigned int lccr2;
-       unsigned int lccr3;
-};
-
 /* PXA LCD DMA descriptor */
 struct pxafb_dma_descriptor {
        unsigned int fdadr;