diff options
author | Eric Miao <eric.miao@marvell.com> | 2008-04-30 03:52:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:29:32 -0400 |
commit | 90eabbf0ec0c626cf5d186214cf8fc79150a7a29 (patch) | |
tree | a17d471960d783f046faf13f56db5794f419cfd3 /drivers | |
parent | 2ba162b9335c6e3ba90c77637372fc9f078aae67 (diff) |
pxafb: move parallel LCD timing setup into dedicate function
the new_regs stuff has been removed, and all the setup (modification to those
fbi->reg_*) is protected with IRQ disabled
* disable IRQ is too heavy here, provided that no IRQ context will
touch the fbi->reg_* and the only possible contending place is
in the CPUFREQ_POSTCHANGE (task context), a mutex will be better,
leave this for future improvement
Signed-off-by: eric miao <eric.miao@marvell.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/pxafb.c | 89 | ||||
-rw-r--r-- | drivers/video/pxafb.h | 8 |
2 files changed, 47 insertions, 50 deletions
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index a4ee7225fe2c..d11ea78a06d5 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -594,6 +594,43 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal, | |||
594 | return 0; | 594 | return 0; |
595 | } | 595 | } |
596 | 596 | ||
597 | static void setup_parallel_timing(struct pxafb_info *fbi, | ||
598 | struct fb_var_screeninfo *var) | ||
599 | { | ||
600 | unsigned int lines_per_panel, pcd = get_pcd(fbi, var->pixclock); | ||
601 | |||
602 | fbi->reg_lccr1 = | ||
603 | LCCR1_DisWdth(var->xres) + | ||
604 | LCCR1_HorSnchWdth(var->hsync_len) + | ||
605 | LCCR1_BegLnDel(var->left_margin) + | ||
606 | LCCR1_EndLnDel(var->right_margin); | ||
607 | |||
608 | /* | ||
609 | * If we have a dual scan LCD, we need to halve | ||
610 | * the YRES parameter. | ||
611 | */ | ||
612 | lines_per_panel = var->yres; | ||
613 | if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual) | ||
614 | lines_per_panel /= 2; | ||
615 | |||
616 | fbi->reg_lccr2 = | ||
617 | LCCR2_DisHght(lines_per_panel) + | ||
618 | LCCR2_VrtSnchWdth(var->vsync_len) + | ||
619 | LCCR2_BegFrmDel(var->upper_margin) + | ||
620 | LCCR2_EndFrmDel(var->lower_margin); | ||
621 | |||
622 | fbi->reg_lccr3 = fbi->lccr3 | | ||
623 | (var->sync & FB_SYNC_HOR_HIGH_ACT ? | ||
624 | LCCR3_HorSnchH : LCCR3_HorSnchL) | | ||
625 | (var->sync & FB_SYNC_VERT_HIGH_ACT ? | ||
626 | LCCR3_VrtSnchH : LCCR3_VrtSnchL); | ||
627 | |||
628 | if (pcd) { | ||
629 | fbi->reg_lccr3 |= LCCR3_PixClkDiv(pcd); | ||
630 | set_hsync_time(fbi, pcd); | ||
631 | } | ||
632 | } | ||
633 | |||
597 | /* | 634 | /* |
598 | * pxafb_activate_var(): | 635 | * pxafb_activate_var(): |
599 | * Configures LCD Controller based on entries in var parameter. | 636 | * Configures LCD Controller based on entries in var parameter. |
@@ -602,9 +639,7 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal, | |||
602 | static int pxafb_activate_var(struct fb_var_screeninfo *var, | 639 | static int pxafb_activate_var(struct fb_var_screeninfo *var, |
603 | struct pxafb_info *fbi) | 640 | struct pxafb_info *fbi) |
604 | { | 641 | { |
605 | struct pxafb_lcd_reg new_regs; | ||
606 | u_long flags; | 642 | u_long flags; |
607 | u_int lines_per_panel, pcd = get_pcd(fbi, var->pixclock); | ||
608 | size_t nbytes; | 643 | size_t nbytes; |
609 | 644 | ||
610 | #if DEBUG_VAR | 645 | #if DEBUG_VAR |
@@ -645,61 +680,31 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, | |||
645 | printk(KERN_ERR "%s: invalid lower_margin %d\n", | 680 | printk(KERN_ERR "%s: invalid lower_margin %d\n", |
646 | fbi->fb.fix.id, var->lower_margin); | 681 | fbi->fb.fix.id, var->lower_margin); |
647 | #endif | 682 | #endif |
683 | /* Update shadow copy atomically */ | ||
684 | local_irq_save(flags); | ||
685 | |||
686 | setup_parallel_timing(fbi, var); | ||
648 | 687 | ||
649 | new_regs.lccr0 = fbi->lccr0 | | 688 | fbi->reg_lccr0 = fbi->lccr0 | |
650 | (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | | 689 | (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | |
651 | LCCR0_QDM | LCCR0_BM | LCCR0_OUM); | 690 | LCCR0_QDM | LCCR0_BM | LCCR0_OUM); |
652 | 691 | ||
653 | new_regs.lccr1 = | 692 | fbi->reg_lccr3 |= pxafb_bpp_to_lccr3(var); |
654 | LCCR1_DisWdth(var->xres) + | ||
655 | LCCR1_HorSnchWdth(var->hsync_len) + | ||
656 | LCCR1_BegLnDel(var->left_margin) + | ||
657 | LCCR1_EndLnDel(var->right_margin); | ||
658 | |||
659 | /* | ||
660 | * If we have a dual scan LCD, we need to halve | ||
661 | * the YRES parameter. | ||
662 | */ | ||
663 | lines_per_panel = var->yres; | ||
664 | if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual) | ||
665 | lines_per_panel /= 2; | ||
666 | |||
667 | new_regs.lccr2 = | ||
668 | LCCR2_DisHght(lines_per_panel) + | ||
669 | LCCR2_VrtSnchWdth(var->vsync_len) + | ||
670 | LCCR2_BegFrmDel(var->upper_margin) + | ||
671 | LCCR2_EndFrmDel(var->lower_margin); | ||
672 | 693 | ||
673 | new_regs.lccr3 = fbi->lccr3 | | 694 | nbytes = var->yres * fbi->fb.fix.line_length; |
674 | pxafb_bpp_to_lccr3(var) | | ||
675 | (var->sync & FB_SYNC_HOR_HIGH_ACT ? | ||
676 | LCCR3_HorSnchH : LCCR3_HorSnchL) | | ||
677 | (var->sync & FB_SYNC_VERT_HIGH_ACT ? | ||
678 | LCCR3_VrtSnchH : LCCR3_VrtSnchL); | ||
679 | 695 | ||
680 | if (pcd) | 696 | if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual) { |
681 | new_regs.lccr3 |= LCCR3_PixClkDiv(pcd); | 697 | nbytes = nbytes / 2; |
682 | |||
683 | /* Update shadow copy atomically */ | ||
684 | local_irq_save(flags); | ||
685 | |||
686 | nbytes = lines_per_panel * fbi->fb.fix.line_length; | ||
687 | |||
688 | if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual) | ||
689 | setup_frame_dma(fbi, DMA_LOWER, PAL_NONE, nbytes, nbytes); | 698 | setup_frame_dma(fbi, DMA_LOWER, PAL_NONE, nbytes, nbytes); |
699 | } | ||
690 | 700 | ||
691 | if (var->bits_per_pixel >= 16) | 701 | if (var->bits_per_pixel >= 16) |
692 | setup_frame_dma(fbi, DMA_BASE, PAL_NONE, 0, nbytes); | 702 | setup_frame_dma(fbi, DMA_BASE, PAL_NONE, 0, nbytes); |
693 | else | 703 | else |
694 | setup_frame_dma(fbi, DMA_BASE, PAL_BASE, 0, nbytes); | 704 | setup_frame_dma(fbi, DMA_BASE, PAL_BASE, 0, nbytes); |
695 | 705 | ||
696 | fbi->reg_lccr0 = new_regs.lccr0; | ||
697 | fbi->reg_lccr1 = new_regs.lccr1; | ||
698 | fbi->reg_lccr2 = new_regs.lccr2; | ||
699 | fbi->reg_lccr3 = new_regs.lccr3; | ||
700 | fbi->reg_lccr4 = lcd_readl(fbi, LCCR4) & ~LCCR4_PAL_FOR_MASK; | 706 | fbi->reg_lccr4 = lcd_readl(fbi, LCCR4) & ~LCCR4_PAL_FOR_MASK; |
701 | fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK); | 707 | fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK); |
702 | set_hsync_time(fbi, pcd); | ||
703 | local_irq_restore(flags); | 708 | local_irq_restore(flags); |
704 | 709 | ||
705 | /* | 710 | /* |
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h index f47f139fc5ed..c627b83497da 100644 --- a/drivers/video/pxafb.h +++ b/drivers/video/pxafb.h | |||
@@ -21,14 +21,6 @@ | |||
21 | * for more details. | 21 | * for more details. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* Shadows for LCD controller registers */ | ||
25 | struct pxafb_lcd_reg { | ||
26 | unsigned int lccr0; | ||
27 | unsigned int lccr1; | ||
28 | unsigned int lccr2; | ||
29 | unsigned int lccr3; | ||
30 | }; | ||
31 | |||
32 | /* PXA LCD DMA descriptor */ | 24 | /* PXA LCD DMA descriptor */ |
33 | struct pxafb_dma_descriptor { | 25 | struct pxafb_dma_descriptor { |
34 | unsigned int fdadr; | 26 | unsigned int fdadr; |