diff options
-rw-r--r-- | arch/arm/mach-pxa/include/mach/regs-lcd.h | 10 | ||||
-rw-r--r-- | drivers/video/pxafb.c | 61 | ||||
-rw-r--r-- | drivers/video/pxafb.h | 9 |
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 @@ | |||
71 | static int pxafb_activate_var(struct fb_var_screeninfo *var, | 71 | static int pxafb_activate_var(struct fb_var_screeninfo *var, |
72 | struct pxafb_info *); | 72 | struct pxafb_info *); |
73 | static void set_ctrlr_state(struct pxafb_info *fbi, u_int state); | 73 | static void set_ctrlr_state(struct pxafb_info *fbi, u_int state); |
74 | static void setup_base_frame(struct pxafb_info *fbi, int branch); | ||
74 | 75 | ||
75 | static unsigned long video_mem_size = 0; | 76 | static 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 | ||
471 | static 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 | ||
656 | static 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 |
637 | static int setup_smart_dma(struct pxafb_info *fbi) | 678 | static 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 | */ | ||
57 | struct pxafb_dma_buff { | 60 | struct 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 | ||
64 | struct pxafb_info { | 67 | struct 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 */ |