Commit 6e354846 authored by Eric Miao's avatar Eric Miao Committed by Eric Miao

[ARM] pxafb: add support for FBIOPAN_DISPLAY by dma braching

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: default avatarEric Miao <eric.miao@marvell.com>
Signed-off-by: default avatarEric Miao <ycmiao@ycmiao-hp520.(none)>
parent 7e4b19c9
...@@ -12,13 +12,19 @@ ...@@ -12,13 +12,19 @@
#define LCCR3 (0x00C) /* LCD Controller Control Register 3 */ #define LCCR3 (0x00C) /* LCD Controller Control Register 3 */
#define LCCR4 (0x010) /* LCD Controller Control Register 4 */ #define LCCR4 (0x010) /* LCD Controller Control Register 4 */
#define LCCR5 (0x014) /* LCD Controller Control Register 5 */ #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 LCSR (0x038) /* LCD Controller Status Register */
#define LIIDR (0x03C) /* LCD Controller Interrupt ID Register */ #define LIIDR (0x03C) /* LCD Controller Interrupt ID Register */
#define TMEDRGBR (0x040) /* TMED RGB Seed Register */ #define TMEDRGBR (0x040) /* TMED RGB Seed Register */
#define TMEDCR (0x044) /* TMED Control 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 CMDCR (0x100) /* Command Control Register */
#define PRSR (0x104) /* Panel Read Status Register */ #define PRSR (0x104) /* Panel Read Status Register */
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
static int pxafb_activate_var(struct fb_var_screeninfo *var, static int pxafb_activate_var(struct fb_var_screeninfo *var,
struct pxafb_info *); struct pxafb_info *);
static void set_ctrlr_state(struct pxafb_info *fbi, u_int state); 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; static unsigned long video_mem_size = 0;
...@@ -467,6 +468,24 @@ static int pxafb_set_par(struct fb_info *info) ...@@ -467,6 +468,24 @@ static int pxafb_set_par(struct fb_info *info)
return 0; 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(): * pxafb_blank():
* Blank the display by setting all palette values to zero. Note, the * Blank the display by setting all palette values to zero. Note, the
...@@ -506,6 +525,7 @@ static struct fb_ops pxafb_ops = { ...@@ -506,6 +525,7 @@ static struct fb_ops pxafb_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.fb_check_var = pxafb_check_var, .fb_check_var = pxafb_check_var,
.fb_set_par = pxafb_set_par, .fb_set_par = pxafb_set_par,
.fb_pan_display = pxafb_pan_display,
.fb_setcolreg = pxafb_setcolreg, .fb_setcolreg = pxafb_setcolreg,
.fb_fillrect = cfb_fillrect, .fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea, .fb_copyarea = cfb_copyarea,
...@@ -597,7 +617,7 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal, ...@@ -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; struct pxafb_dma_descriptor *dma_desc, *pal_desc;
unsigned int dma_desc_off, pal_desc_off; unsigned int dma_desc_off, pal_desc_off;
if (dma < 0 || dma >= DMA_MAX) if (dma < 0 || dma >= DMA_MAX * 2)
return -EINVAL; return -EINVAL;
dma_desc = &fbi->dma_buff->dma_desc[dma]; 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, ...@@ -607,7 +627,7 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,
dma_desc->fidr = 0; dma_desc->fidr = 0;
dma_desc->ldcmd = size; 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; dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;
fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off; fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off;
} else { } else {
...@@ -633,6 +653,27 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal, ...@@ -633,6 +653,27 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,
return 0; 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 #ifdef CONFIG_FB_PXA_SMARTPANEL
static int setup_smart_dma(struct pxafb_info *fbi) static int setup_smart_dma(struct pxafb_info *fbi)
{ {
...@@ -880,7 +921,6 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, ...@@ -880,7 +921,6 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
struct pxafb_info *fbi) struct pxafb_info *fbi)
{ {
u_long flags; u_long flags;
size_t nbytes, offset;
#if DEBUG_VAR #if DEBUG_VAR
if (!(fbi->lccr0 & LCCR0_LCDT)) { if (!(fbi->lccr0 & LCCR0_LCDT)) {
...@@ -935,25 +975,14 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, ...@@ -935,25 +975,14 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
#endif #endif
setup_parallel_timing(fbi, var); setup_parallel_timing(fbi, var);
setup_base_frame(fbi, 0);
fbi->reg_lccr0 = fbi->lccr0 | fbi->reg_lccr0 = fbi->lccr0 |
(LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM |
LCCR0_QDM | LCCR0_BM | LCCR0_OUM); LCCR0_QDM | LCCR0_BM | LCCR0_OUM);
fbi->reg_lccr3 |= pxafb_bpp_to_lccr3(var); 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 = lcd_readl(fbi, LCCR4) & ~LCCR4_PAL_FOR_MASK;
fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK); fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK);
local_irq_restore(flags); local_irq_restore(flags);
......
...@@ -54,11 +54,14 @@ enum { ...@@ -54,11 +54,14 @@ enum {
#define PALETTE_SIZE (256 * 4) #define PALETTE_SIZE (256 * 4)
#define CMD_BUFF_SIZE (1024 * 50) #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 { struct pxafb_dma_buff {
unsigned char palette[PAL_MAX * PALETTE_SIZE]; unsigned char palette[PAL_MAX * PALETTE_SIZE];
uint16_t cmd_buff[CMD_BUFF_SIZE]; uint16_t cmd_buff[CMD_BUFF_SIZE];
struct pxafb_dma_descriptor pal_desc[PAL_MAX]; struct pxafb_dma_descriptor pal_desc[PAL_MAX * 2];
struct pxafb_dma_descriptor dma_desc[DMA_MAX]; struct pxafb_dma_descriptor dma_desc[DMA_MAX * 2];
}; };
struct pxafb_info { struct pxafb_info {
...@@ -71,7 +74,7 @@ struct pxafb_info { ...@@ -71,7 +74,7 @@ struct pxafb_info {
struct pxafb_dma_buff *dma_buff; struct pxafb_dma_buff *dma_buff;
size_t dma_buff_size; size_t dma_buff_size;
dma_addr_t dma_buff_phys; 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 */ void __iomem *video_mem; /* virtual address of frame buffer */
unsigned long video_mem_phys; /* physical address of frame buffer */ unsigned long video_mem_phys; /* physical address of frame buffer */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment