diff options
| -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; |
