aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-lcd.h10
-rw-r--r--drivers/video/pxafb.c61
-rw-r--r--drivers/video/pxafb.h9
3 files changed, 59 insertions, 21 deletions
diff --git a/arch/arm/mach-pxa/include/mach/regs-lcd.h b/arch/arm/mach-pxa/include/mach/regs-lcd.h
index f817878d256b..c15df557fa8a 100644
--- a/arch/arm/mach-pxa/include/mach/regs-lcd.h
+++ b/arch/arm/mach-pxa/include/mach/regs-lcd.h
@@ -12,13 +12,19 @@
12#define LCCR3 (0x00C) /* LCD Controller Control Register 3 */ 12#define LCCR3 (0x00C) /* LCD Controller Control Register 3 */
13#define LCCR4 (0x010) /* LCD Controller Control Register 4 */ 13#define LCCR4 (0x010) /* LCD Controller Control Register 4 */
14#define LCCR5 (0x014) /* LCD Controller Control Register 5 */ 14#define LCCR5 (0x014) /* LCD Controller Control Register 5 */
15#define DFBR0 (0x020) /* DMA Channel 0 Frame Branch Register */
16#define DFBR1 (0x024) /* DMA Channel 1 Frame Branch Register */
17#define LCSR (0x038) /* LCD Controller Status Register */ 15#define LCSR (0x038) /* LCD Controller Status Register */
18#define LIIDR (0x03C) /* LCD Controller Interrupt ID Register */ 16#define LIIDR (0x03C) /* LCD Controller Interrupt ID Register */
19#define TMEDRGBR (0x040) /* TMED RGB Seed Register */ 17#define TMEDRGBR (0x040) /* TMED RGB Seed Register */
20#define TMEDCR (0x044) /* TMED Control Register */ 18#define TMEDCR (0x044) /* TMED Control Register */
21 19
20#define FBR0 (0x020) /* DMA Channel 0 Frame Branch Register */
21#define FBR1 (0x024) /* DMA Channel 1 Frame Branch Register */
22#define FBR2 (0x028) /* DMA Channel 2 Frame Branch Register */
23#define FBR3 (0x02C) /* DMA Channel 2 Frame Branch Register */
24#define FBR4 (0x030) /* DMA Channel 2 Frame Branch Register */
25#define FBR5 (0x110) /* DMA Channel 2 Frame Branch Register */
26#define FBR6 (0x114) /* DMA Channel 2 Frame Branch Register */
27
22#define CMDCR (0x100) /* Command Control Register */ 28#define CMDCR (0x100) /* Command Control Register */
23#define PRSR (0x104) /* Panel Read Status Register */ 29#define PRSR (0x104) /* Panel Read Status Register */
24 30
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index ab816cadb470..b43907d36d66 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -71,6 +71,7 @@
71static int pxafb_activate_var(struct fb_var_screeninfo *var, 71static int pxafb_activate_var(struct fb_var_screeninfo *var,
72 struct pxafb_info *); 72 struct pxafb_info *);
73static void set_ctrlr_state(struct pxafb_info *fbi, u_int state); 73static void set_ctrlr_state(struct pxafb_info *fbi, u_int state);
74static void setup_base_frame(struct pxafb_info *fbi, int branch);
74 75
75static unsigned long video_mem_size = 0; 76static unsigned long video_mem_size = 0;
76 77
@@ -467,6 +468,24 @@ static int pxafb_set_par(struct fb_info *info)
467 return 0; 468 return 0;
468} 469}
469 470
471static int pxafb_pan_display(struct fb_var_screeninfo *var,
472 struct fb_info *info)
473{
474 struct pxafb_info *fbi = (struct pxafb_info *)info;
475 int dma = DMA_MAX + DMA_BASE;
476
477 if (fbi->state != C_ENABLE)
478 return 0;
479
480 setup_base_frame(fbi, 1);
481
482 if (fbi->lccr0 & LCCR0_SDS)
483 lcd_writel(fbi, FBR1, fbi->fdadr[dma + 1] | 0x1);
484
485 lcd_writel(fbi, FBR0, fbi->fdadr[dma] | 0x1);
486 return 0;
487}
488
470/* 489/*
471 * pxafb_blank(): 490 * pxafb_blank():
472 * Blank the display by setting all palette values to zero. Note, the 491 * Blank the display by setting all palette values to zero. Note, the
@@ -506,6 +525,7 @@ static struct fb_ops pxafb_ops = {
506 .owner = THIS_MODULE, 525 .owner = THIS_MODULE,
507 .fb_check_var = pxafb_check_var, 526 .fb_check_var = pxafb_check_var,
508 .fb_set_par = pxafb_set_par, 527 .fb_set_par = pxafb_set_par,
528 .fb_pan_display = pxafb_pan_display,
509 .fb_setcolreg = pxafb_setcolreg, 529 .fb_setcolreg = pxafb_setcolreg,
510 .fb_fillrect = cfb_fillrect, 530 .fb_fillrect = cfb_fillrect,
511 .fb_copyarea = cfb_copyarea, 531 .fb_copyarea = cfb_copyarea,
@@ -597,7 +617,7 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,
597 struct pxafb_dma_descriptor *dma_desc, *pal_desc; 617 struct pxafb_dma_descriptor *dma_desc, *pal_desc;
598 unsigned int dma_desc_off, pal_desc_off; 618 unsigned int dma_desc_off, pal_desc_off;
599 619
600 if (dma < 0 || dma >= DMA_MAX) 620 if (dma < 0 || dma >= DMA_MAX * 2)
601 return -EINVAL; 621 return -EINVAL;
602 622
603 dma_desc = &fbi->dma_buff->dma_desc[dma]; 623 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 dma_desc->fidr = 0; 627 dma_desc->fidr = 0;
608 dma_desc->ldcmd = size; 628 dma_desc->ldcmd = size;
609 629
610 if (pal < 0 || pal >= PAL_MAX) { 630 if (pal < 0 || pal >= PAL_MAX * 2) {
611 dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; 631 dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;
612 fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off; 632 fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off;
613 } else { 633 } else {
@@ -633,6 +653,27 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,
633 return 0; 653 return 0;
634} 654}
635 655
656static void setup_base_frame(struct pxafb_info *fbi, int branch)
657{
658 struct fb_var_screeninfo *var = &fbi->fb.var;
659 struct fb_fix_screeninfo *fix = &fbi->fb.fix;
660 unsigned int nbytes, offset;
661 int dma, pal, bpp = var->bits_per_pixel;
662
663 dma = DMA_BASE + (branch ? DMA_MAX : 0);
664 pal = (bpp >= 16) ? PAL_NONE : PAL_BASE + (branch ? PAL_MAX : 0);
665
666 nbytes = fix->line_length * var->yres;
667 offset = fix->line_length * var->yoffset;
668
669 if (fbi->lccr0 & LCCR0_SDS) {
670 nbytes = nbytes / 2;
671 setup_frame_dma(fbi, dma + 1, PAL_NONE, offset + nbytes, nbytes);
672 }
673
674 setup_frame_dma(fbi, dma, pal, offset, nbytes);
675}
676
636#ifdef CONFIG_FB_PXA_SMARTPANEL 677#ifdef CONFIG_FB_PXA_SMARTPANEL
637static int setup_smart_dma(struct pxafb_info *fbi) 678static int setup_smart_dma(struct pxafb_info *fbi)
638{ 679{
@@ -880,7 +921,6 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
880 struct pxafb_info *fbi) 921 struct pxafb_info *fbi)
881{ 922{
882 u_long flags; 923 u_long flags;
883 size_t nbytes, offset;
884 924
885#if DEBUG_VAR 925#if DEBUG_VAR
886 if (!(fbi->lccr0 & LCCR0_LCDT)) { 926 if (!(fbi->lccr0 & LCCR0_LCDT)) {
@@ -935,25 +975,14 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
935#endif 975#endif
936 setup_parallel_timing(fbi, var); 976 setup_parallel_timing(fbi, var);
937 977
978 setup_base_frame(fbi, 0);
979
938 fbi->reg_lccr0 = fbi->lccr0 | 980 fbi->reg_lccr0 = fbi->lccr0 |
939 (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | 981 (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM |
940 LCCR0_QDM | LCCR0_BM | LCCR0_OUM); 982 LCCR0_QDM | LCCR0_BM | LCCR0_OUM);
941 983
942 fbi->reg_lccr3 |= pxafb_bpp_to_lccr3(var); 984 fbi->reg_lccr3 |= pxafb_bpp_to_lccr3(var);
943 985
944 nbytes = fbi->fb.fix.line_length * var->yres;
945 offset = fbi->fb.fix.line_length * var->yoffset;
946
947 if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual) {
948 nbytes = nbytes / 2;
949 setup_frame_dma(fbi, DMA_LOWER, PAL_NONE, offset + nbytes, nbytes);
950 }
951
952 if ((var->bits_per_pixel >= 16) || (fbi->lccr0 & LCCR0_LCDT))
953 setup_frame_dma(fbi, DMA_BASE, PAL_NONE, offset, nbytes);
954 else
955 setup_frame_dma(fbi, DMA_BASE, PAL_BASE, offset, nbytes);
956
957 fbi->reg_lccr4 = lcd_readl(fbi, LCCR4) & ~LCCR4_PAL_FOR_MASK; 986 fbi->reg_lccr4 = lcd_readl(fbi, LCCR4) & ~LCCR4_PAL_FOR_MASK;
958 fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK); 987 fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK);
959 local_irq_restore(flags); 988 local_irq_restore(flags);
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
index 0981938682ef..e0f90f4c467d 100644
--- a/drivers/video/pxafb.h
+++ b/drivers/video/pxafb.h
@@ -54,11 +54,14 @@ enum {
54#define PALETTE_SIZE (256 * 4) 54#define PALETTE_SIZE (256 * 4)
55#define CMD_BUFF_SIZE (1024 * 50) 55#define CMD_BUFF_SIZE (1024 * 50)
56 56
57/* NOTE: the palette and frame dma descriptors are doubled to allow
58 * the 2nd set for branch settings (FBRx)
59 */
57struct pxafb_dma_buff { 60struct pxafb_dma_buff {
58 unsigned char palette[PAL_MAX * PALETTE_SIZE]; 61 unsigned char palette[PAL_MAX * PALETTE_SIZE];
59 uint16_t cmd_buff[CMD_BUFF_SIZE]; 62 uint16_t cmd_buff[CMD_BUFF_SIZE];
60 struct pxafb_dma_descriptor pal_desc[PAL_MAX]; 63 struct pxafb_dma_descriptor pal_desc[PAL_MAX * 2];
61 struct pxafb_dma_descriptor dma_desc[DMA_MAX]; 64 struct pxafb_dma_descriptor dma_desc[DMA_MAX * 2];
62}; 65};
63 66
64struct pxafb_info { 67struct pxafb_info {
@@ -71,7 +74,7 @@ struct pxafb_info {
71 struct pxafb_dma_buff *dma_buff; 74 struct pxafb_dma_buff *dma_buff;
72 size_t dma_buff_size; 75 size_t dma_buff_size;
73 dma_addr_t dma_buff_phys; 76 dma_addr_t dma_buff_phys;
74 dma_addr_t fdadr[DMA_MAX]; 77 dma_addr_t fdadr[DMA_MAX * 2];
75 78
76 void __iomem *video_mem; /* virtual address of frame buffer */ 79 void __iomem *video_mem; /* virtual address of frame buffer */
77 unsigned long video_mem_phys; /* physical address of frame buffer */ 80 unsigned long video_mem_phys; /* physical address of frame buffer */