diff options
author | Eric Miao <ycmiao@ycmiao-hp520.(none)> | 2008-12-17 03:50:43 -0500 |
---|---|---|
committer | Eric Miao <eric.miao@marvell.com> | 2008-12-29 04:59:17 -0500 |
commit | 6e354846e807e037751fdc8faaee8ad492177113 (patch) | |
tree | eb31ad176a03091ff02560d2623ed9952fa19dc6 /drivers/video/pxafb.c | |
parent | 7e4b19c95c8632b543bd510ec6c710bebb53b840 (diff) |
[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: Eric Miao <eric.miao@marvell.com>
Signed-off-by: Eric Miao <ycmiao@ycmiao-hp520.(none)>
Diffstat (limited to 'drivers/video/pxafb.c')
-rw-r--r-- | drivers/video/pxafb.c | 61 |
1 files changed, 45 insertions, 16 deletions
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); |