]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
[ARM] pxafb: add support for FBIOPAN_DISPLAY by dma braching
authorEric Miao <ycmiao@ycmiao-hp520.(none)>
Wed, 17 Dec 2008 08:50:43 +0000 (16:50 +0800)
committerEric Miao <eric.miao@marvell.com>
Mon, 29 Dec 2008 09:59:17 +0000 (17:59 +0800)
dma branching is enabled by extending the current setup_frame_dma()
function to allow a 2nd set of frame/palette dma descriptors to be
used.

As a result, pxafb_dma_buff.dma_desc[], pxafb_dma_buff.pal_desc[]
and pxafb_info.fdadr[] are doubled.

This allows maximum re-use of the current dma setup code, although
the pxafb_info.fdadr[xx] for FBRx register values looks a bit odd.

Signed-off-by: Eric Miao <eric.miao@marvell.com>
Signed-off-by: Eric Miao <ycmiao@ycmiao-hp520.(none)>
arch/arm/mach-pxa/include/mach/regs-lcd.h
drivers/video/pxafb.c
drivers/video/pxafb.h

index f817878d256b523a20a6095e689a9f9e16bd3784..c15df557fa8ab63eaf81e4e16b10b28f56e7d084 100644 (file)
 #define LCCR3          (0x00C) /* LCD Controller Control Register 3 */
 #define LCCR4          (0x010) /* LCD Controller Control Register 4 */
 #define LCCR5          (0x014) /* LCD Controller Control Register 5 */
-#define DFBR0          (0x020) /* DMA Channel 0 Frame Branch Register */
-#define DFBR1          (0x024) /* DMA Channel 1 Frame Branch Register */
 #define LCSR           (0x038) /* LCD Controller Status Register */
 #define LIIDR          (0x03C) /* LCD Controller Interrupt ID Register */
 #define TMEDRGBR       (0x040) /* TMED RGB Seed Register */
 #define TMEDCR         (0x044) /* TMED Control Register */
 
+#define FBR0           (0x020) /* DMA Channel 0 Frame Branch Register */
+#define FBR1           (0x024) /* DMA Channel 1 Frame Branch Register */
+#define FBR2           (0x028) /* DMA Channel 2 Frame Branch Register */
+#define FBR3           (0x02C) /* DMA Channel 2 Frame Branch Register */
+#define FBR4           (0x030) /* DMA Channel 2 Frame Branch Register */
+#define FBR5           (0x110) /* DMA Channel 2 Frame Branch Register */
+#define FBR6           (0x114) /* DMA Channel 2 Frame Branch Register */
+
 #define CMDCR          (0x100) /* Command Control Register */
 #define PRSR           (0x104) /* Panel Read Status Register */
 
index ab816cadb470f9064a8ae50a674fbb4d7ecdcdde..b43907d36d66bee0e433bfff162fbdc4e781f91b 100644 (file)
@@ -71,6 +71,7 @@
 static int pxafb_activate_var(struct fb_var_screeninfo *var,
                                struct pxafb_info *);
 static void set_ctrlr_state(struct pxafb_info *fbi, u_int state);
+static void setup_base_frame(struct pxafb_info *fbi, int branch);
 
 static unsigned long video_mem_size = 0;
 
@@ -467,6 +468,24 @@ static int pxafb_set_par(struct fb_info *info)
        return 0;
 }
 
+static int pxafb_pan_display(struct fb_var_screeninfo *var,
+                            struct fb_info *info)
+{
+       struct pxafb_info *fbi = (struct pxafb_info *)info;
+       int dma = DMA_MAX + DMA_BASE;
+
+       if (fbi->state != C_ENABLE)
+               return 0;
+
+       setup_base_frame(fbi, 1);
+
+       if (fbi->lccr0 & LCCR0_SDS)
+               lcd_writel(fbi, FBR1, fbi->fdadr[dma + 1] | 0x1);
+
+       lcd_writel(fbi, FBR0, fbi->fdadr[dma] | 0x1);
+       return 0;
+}
+
 /*
  * pxafb_blank():
  *     Blank the display by setting all palette values to zero.  Note, the
@@ -506,6 +525,7 @@ static struct fb_ops pxafb_ops = {
        .owner          = THIS_MODULE,
        .fb_check_var   = pxafb_check_var,
        .fb_set_par     = pxafb_set_par,
+       .fb_pan_display = pxafb_pan_display,
        .fb_setcolreg   = pxafb_setcolreg,
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
@@ -597,7 +617,7 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,
        struct pxafb_dma_descriptor *dma_desc, *pal_desc;
        unsigned int dma_desc_off, pal_desc_off;
 
-       if (dma < 0 || dma >= DMA_MAX)
+       if (dma < 0 || dma >= DMA_MAX * 2)
                return -EINVAL;
 
        dma_desc = &fbi->dma_buff->dma_desc[dma];
@@ -607,7 +627,7 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,
        dma_desc->fidr  = 0;
        dma_desc->ldcmd = size;
 
-       if (pal < 0 || pal >= PAL_MAX) {
+       if (pal < 0 || pal >= PAL_MAX * 2) {
                dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;
                fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off;
        } else {
@@ -633,6 +653,27 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,
        return 0;
 }
 
+static void setup_base_frame(struct pxafb_info *fbi, int branch)
+{
+       struct fb_var_screeninfo *var = &fbi->fb.var;
+       struct fb_fix_screeninfo *fix = &fbi->fb.fix;
+       unsigned int nbytes, offset;
+       int dma, pal, bpp = var->bits_per_pixel;
+
+       dma = DMA_BASE + (branch ? DMA_MAX : 0);
+       pal = (bpp >= 16) ? PAL_NONE : PAL_BASE + (branch ? PAL_MAX : 0);
+
+       nbytes = fix->line_length * var->yres;
+       offset = fix->line_length * var->yoffset;
+
+       if (fbi->lccr0 & LCCR0_SDS) {
+               nbytes = nbytes / 2;
+               setup_frame_dma(fbi, dma + 1, PAL_NONE, offset + nbytes, nbytes);
+       }
+
+       setup_frame_dma(fbi, dma, pal, offset, nbytes);
+}
+
 #ifdef CONFIG_FB_PXA_SMARTPANEL
 static int setup_smart_dma(struct pxafb_info *fbi)
 {
@@ -880,7 +921,6 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
                              struct pxafb_info *fbi)
 {
        u_long flags;
-       size_t nbytes, offset;
 
 #if DEBUG_VAR
        if (!(fbi->lccr0 & LCCR0_LCDT)) {
@@ -935,25 +975,14 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
 #endif
                setup_parallel_timing(fbi, var);
 
+       setup_base_frame(fbi, 0);
+
        fbi->reg_lccr0 = fbi->lccr0 |
                (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM |
                 LCCR0_QDM | LCCR0_BM  | LCCR0_OUM);
 
        fbi->reg_lccr3 |= pxafb_bpp_to_lccr3(var);
 
-       nbytes = fbi->fb.fix.line_length * var->yres;
-       offset = fbi->fb.fix.line_length * var->yoffset;
-
-       if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual) {
-               nbytes = nbytes / 2;
-               setup_frame_dma(fbi, DMA_LOWER, PAL_NONE, offset + nbytes, nbytes);
-       }
-
-       if ((var->bits_per_pixel >= 16) || (fbi->lccr0 & LCCR0_LCDT))
-               setup_frame_dma(fbi, DMA_BASE, PAL_NONE, offset, nbytes);
-       else
-               setup_frame_dma(fbi, DMA_BASE, PAL_BASE, offset, nbytes);
-
        fbi->reg_lccr4 = lcd_readl(fbi, LCCR4) & ~LCCR4_PAL_FOR_MASK;
        fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK);
        local_irq_restore(flags);
index 0981938682ef0ea931f8b38b4ba1f9ccc949b291..e0f90f4c467d2c83af05d6a54642412f1461717d 100644 (file)
@@ -54,11 +54,14 @@ enum {
 #define PALETTE_SIZE   (256 * 4)
 #define CMD_BUFF_SIZE  (1024 * 50)
 
+/* NOTE: the palette and frame dma descriptors are doubled to allow
+ * the 2nd set for branch settings (FBRx)
+ */
 struct pxafb_dma_buff {
        unsigned char palette[PAL_MAX * PALETTE_SIZE];
        uint16_t cmd_buff[CMD_BUFF_SIZE];
-       struct pxafb_dma_descriptor pal_desc[PAL_MAX];
-       struct pxafb_dma_descriptor dma_desc[DMA_MAX];
+       struct pxafb_dma_descriptor pal_desc[PAL_MAX * 2];
+       struct pxafb_dma_descriptor dma_desc[DMA_MAX * 2];
 };
 
 struct pxafb_info {
@@ -71,7 +74,7 @@ struct pxafb_info {
        struct pxafb_dma_buff   *dma_buff;
        size_t                  dma_buff_size;
        dma_addr_t              dma_buff_phys;
-       dma_addr_t              fdadr[DMA_MAX];
+       dma_addr_t              fdadr[DMA_MAX * 2];
 
        void __iomem            *video_mem;     /* virtual address of frame buffer */
        unsigned long           video_mem_phys; /* physical address of frame buffer */