aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/pxafb.c89
-rw-r--r--drivers/video/pxafb.h8
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
597static 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,
602static int pxafb_activate_var(struct fb_var_screeninfo *var, 639static 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 */
25struct 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 */
33struct pxafb_dma_descriptor { 25struct pxafb_dma_descriptor {
34 unsigned int fdadr; 26 unsigned int fdadr;