{
        struct pxafb_info *fbi = (struct pxafb_info *)info;
        struct fb_var_screeninfo *var = &info->var;
-       unsigned long palette_mem_size;
 
        if (var->bits_per_pixel == 16)
                fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR;
                fbi->palette_size = var->bits_per_pixel == 1 ?
                                        4 : 1 << var->bits_per_pixel;
 
-       if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
-               palette_mem_size = fbi->palette_size * sizeof(u16);
-       else
-               palette_mem_size = fbi->palette_size * sizeof(u32);
-
-       fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
-       fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size;
+       fbi->palette_cpu = (u16 *)&fbi->dma_buff->palette[0];
 
        /*
         * Set (any) board control register to handle new color depth
 }
 EXPORT_SYMBOL(pxafb_get_hsync_time);
 
+static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,
+               unsigned int offset, size_t size)
+{
+       struct pxafb_dma_descriptor *dma_desc, *pal_desc;
+       unsigned int dma_desc_off, pal_desc_off;
+
+       if (dma < 0 || dma >= DMA_MAX)
+               return -EINVAL;
+
+       dma_desc = &fbi->dma_buff->dma_desc[dma];
+       dma_desc_off = offsetof(struct pxafb_dma_buff, dma_desc[dma]);
+
+       dma_desc->fsadr = fbi->screen_dma + offset;
+       dma_desc->fidr  = 0;
+       dma_desc->ldcmd = size;
+
+       if (pal < 0 || pal >= PAL_MAX) {
+               dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;
+               fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off;
+       } else {
+               pal_desc = &fbi->dma_buff->pal_desc[dma];
+               pal_desc_off = offsetof(struct pxafb_dma_buff, dma_desc[pal]);
+
+               pal_desc->fsadr = fbi->dma_buff_phys + pal * PALETTE_SIZE;
+               pal_desc->fidr  = 0;
+
+               if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
+                       pal_desc->ldcmd = fbi->palette_size * sizeof(u16);
+               else
+                       pal_desc->ldcmd = fbi->palette_size * sizeof(u32);
+
+               pal_desc->ldcmd |= LDCMD_PAL;
+
+               /* flip back and forth between palette and frame buffer */
+               pal_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;
+               dma_desc->fdadr = fbi->dma_buff_phys + pal_desc_off;
+               fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off;
+       }
+
+       return 0;
+}
+
 /*
  * pxafb_activate_var():
  *     Configures LCD Controller based on entries in var parameter.
        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
        if (var->xres < 16 || var->xres > 1024)
        /* Update shadow copy atomically */
        local_irq_save(flags);
 
-       /* setup dma descriptors */
-       fbi->dmadesc_fblow_cpu = (struct pxafb_dma_descriptor *)
-                               ((unsigned int)fbi->palette_cpu - 3*16);
-       fbi->dmadesc_fbhigh_cpu = (struct pxafb_dma_descriptor *)
-                               ((unsigned int)fbi->palette_cpu - 2*16);
-       fbi->dmadesc_palette_cpu = (struct pxafb_dma_descriptor *)
-                               ((unsigned int)fbi->palette_cpu - 1*16);
-
-       fbi->dmadesc_fblow_dma = fbi->palette_dma - 3*16;
-       fbi->dmadesc_fbhigh_dma = fbi->palette_dma - 2*16;
-       fbi->dmadesc_palette_dma = fbi->palette_dma - 1*16;
-
-#define BYTES_PER_PANEL (lines_per_panel * fbi->fb.fix.line_length)
-
-       /* populate descriptors */
-       fbi->dmadesc_fblow_cpu->fdadr = fbi->dmadesc_fblow_dma;
-       fbi->dmadesc_fblow_cpu->fsadr = fbi->screen_dma + BYTES_PER_PANEL;
-       fbi->dmadesc_fblow_cpu->fidr  = 0;
-       fbi->dmadesc_fblow_cpu->ldcmd = BYTES_PER_PANEL;
-
-       fbi->fdadr1 = fbi->dmadesc_fblow_dma; /* only used in dual-panel mode */
-
-       fbi->dmadesc_fbhigh_cpu->fsadr = fbi->screen_dma;
-       fbi->dmadesc_fbhigh_cpu->fidr = 0;
-       fbi->dmadesc_fbhigh_cpu->ldcmd = BYTES_PER_PANEL;
-
-       fbi->dmadesc_palette_cpu->fsadr = fbi->palette_dma;
-       fbi->dmadesc_palette_cpu->fidr  = 0;
-       if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
-               fbi->dmadesc_palette_cpu->ldcmd = fbi->palette_size *
-                                                       sizeof(u16);
-       else
-               fbi->dmadesc_palette_cpu->ldcmd = fbi->palette_size *
-                                                       sizeof(u32);
-       fbi->dmadesc_palette_cpu->ldcmd |= LDCMD_PAL;
+       nbytes = lines_per_panel * fbi->fb.fix.line_length;
 
-       if (var->bits_per_pixel == 16) {
-               /* palette shouldn't be loaded in true-color mode */
-               fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
-               fbi->fdadr0 = fbi->dmadesc_fbhigh_dma; /* no pal just fbhigh */
-               /* init it to something, even though we won't be using it */
-               fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_palette_dma;
-       } else {
-               /* flips back and forth between pal and fbhigh */
-               fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
-               fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_palette_dma;
-               fbi->fdadr0 = fbi->dmadesc_palette_dma;
-       }
+       if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual)
+               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;
            (__raw_readl(fbi->mmio_base + LCCR1) != fbi->reg_lccr1) ||
            (__raw_readl(fbi->mmio_base + LCCR2) != fbi->reg_lccr2) ||
            (__raw_readl(fbi->mmio_base + LCCR3) != fbi->reg_lccr3) ||
-           (__raw_readl(fbi->mmio_base + FDADR0) != fbi->fdadr0) ||
-           (__raw_readl(fbi->mmio_base + FDADR1) != fbi->fdadr1))
+           (__raw_readl(fbi->mmio_base + FDADR0) != fbi->fdadr[0]) ||
+           (__raw_readl(fbi->mmio_base + FDADR1) != fbi->fdadr[1]))
                pxafb_schedule_work(fbi, C_REENABLE);
 
        return 0;
 static void pxafb_enable_controller(struct pxafb_info *fbi)
 {
        pr_debug("pxafb: Enabling LCD controller\n");
-       pr_debug("fdadr0 0x%08x\n", (unsigned int) fbi->fdadr0);
-       pr_debug("fdadr1 0x%08x\n", (unsigned int) fbi->fdadr1);
+       pr_debug("fdadr0 0x%08x\n", (unsigned int) fbi->fdadr[0]);
+       pr_debug("fdadr1 0x%08x\n", (unsigned int) fbi->fdadr[1]);
        pr_debug("reg_lccr0 0x%08x\n", (unsigned int) fbi->reg_lccr0);
        pr_debug("reg_lccr1 0x%08x\n", (unsigned int) fbi->reg_lccr1);
        pr_debug("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2);
        __raw_writel(fbi->reg_lccr1, fbi->mmio_base + LCCR1);
        __raw_writel(fbi->reg_lccr0 & ~LCCR0_ENB, fbi->mmio_base + LCCR0);
 
-       __raw_writel(fbi->fdadr0, fbi->mmio_base + FDADR0);
-       __raw_writel(fbi->fdadr1, fbi->mmio_base + FDADR1);
+       __raw_writel(fbi->fdadr[0], fbi->mmio_base + FDADR0);
+       __raw_writel(fbi->fdadr[1], fbi->mmio_base + FDADR1);
        __raw_writel(fbi->reg_lccr0 | LCCR0_ENB, fbi->mmio_base + LCCR0);
 }
 
  */
 static int __init pxafb_map_video_memory(struct pxafb_info *fbi)
 {
-       u_long palette_mem_size;
-
        /*
         * We reserve one page for the palette, plus the size
         * of the framebuffer.
                fbi->fb.fix.smem_start = fbi->screen_dma;
                fbi->palette_size = fbi->fb.var.bits_per_pixel == 8 ? 256 : 16;
 
-               if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
-                       palette_mem_size = fbi->palette_size * sizeof(u16);
-               else
-                       palette_mem_size = fbi->palette_size * sizeof(u32);
-
-               fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE
-                                               - palette_mem_size);
-               fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size;
+               fbi->dma_buff = (void *)fbi->map_cpu;
+               fbi->dma_buff_phys = fbi->map_dma;
+               fbi->palette_cpu = (u16 *)&fbi->dma_buff->palette[0];
        }
 
        return fbi->map_cpu ? 0 : -ENOMEM;