diff options
author | eric miao <eric.miao@marvell.com> | 2008-04-30 03:52:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:29:31 -0400 |
commit | 2c42dd8ebdd92ad59d9a68f88f0e20ad9f45270a (patch) | |
tree | 1013b04a3543aa1f1e1c9a2472ba15eb2e8f0cd9 | |
parent | ce4fb7b892a6d6c6a0f87366b26fd834d2923dd7 (diff) |
pxafb: introduce "struct pxafb_dma_buff" for palette and dma descriptors
Use structure and array for palette buffer and dma descriptors to:
1. better organize code for future expansion like overlays
2. separate palette and dma descriptors from frame buffer
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>
-rw-r--r-- | drivers/video/pxafb.c | 132 | ||||
-rw-r--r-- | drivers/video/pxafb.h | 46 |
2 files changed, 95 insertions, 83 deletions
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index d97dc9383d4..4e8f68b7c5b 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -361,7 +361,6 @@ static int pxafb_set_par(struct fb_info *info) | |||
361 | { | 361 | { |
362 | struct pxafb_info *fbi = (struct pxafb_info *)info; | 362 | struct pxafb_info *fbi = (struct pxafb_info *)info; |
363 | struct fb_var_screeninfo *var = &info->var; | 363 | struct fb_var_screeninfo *var = &info->var; |
364 | unsigned long palette_mem_size; | ||
365 | 364 | ||
366 | if (var->bits_per_pixel == 16) | 365 | if (var->bits_per_pixel == 16) |
367 | fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR; | 366 | fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR; |
@@ -384,13 +383,7 @@ static int pxafb_set_par(struct fb_info *info) | |||
384 | fbi->palette_size = var->bits_per_pixel == 1 ? | 383 | fbi->palette_size = var->bits_per_pixel == 1 ? |
385 | 4 : 1 << var->bits_per_pixel; | 384 | 4 : 1 << var->bits_per_pixel; |
386 | 385 | ||
387 | if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0) | 386 | fbi->palette_cpu = (u16 *)&fbi->dma_buff->palette[0]; |
388 | palette_mem_size = fbi->palette_size * sizeof(u16); | ||
389 | else | ||
390 | palette_mem_size = fbi->palette_size * sizeof(u32); | ||
391 | |||
392 | fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size); | ||
393 | fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size; | ||
394 | 387 | ||
395 | /* | 388 | /* |
396 | * Set (any) board control register to handle new color depth | 389 | * Set (any) board control register to handle new color depth |
@@ -546,6 +539,48 @@ unsigned long pxafb_get_hsync_time(struct device *dev) | |||
546 | } | 539 | } |
547 | EXPORT_SYMBOL(pxafb_get_hsync_time); | 540 | EXPORT_SYMBOL(pxafb_get_hsync_time); |
548 | 541 | ||
542 | static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal, | ||
543 | unsigned int offset, size_t size) | ||
544 | { | ||
545 | struct pxafb_dma_descriptor *dma_desc, *pal_desc; | ||
546 | unsigned int dma_desc_off, pal_desc_off; | ||
547 | |||
548 | if (dma < 0 || dma >= DMA_MAX) | ||
549 | return -EINVAL; | ||
550 | |||
551 | dma_desc = &fbi->dma_buff->dma_desc[dma]; | ||
552 | dma_desc_off = offsetof(struct pxafb_dma_buff, dma_desc[dma]); | ||
553 | |||
554 | dma_desc->fsadr = fbi->screen_dma + offset; | ||
555 | dma_desc->fidr = 0; | ||
556 | dma_desc->ldcmd = size; | ||
557 | |||
558 | if (pal < 0 || pal >= PAL_MAX) { | ||
559 | dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; | ||
560 | fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off; | ||
561 | } else { | ||
562 | pal_desc = &fbi->dma_buff->pal_desc[dma]; | ||
563 | pal_desc_off = offsetof(struct pxafb_dma_buff, dma_desc[pal]); | ||
564 | |||
565 | pal_desc->fsadr = fbi->dma_buff_phys + pal * PALETTE_SIZE; | ||
566 | pal_desc->fidr = 0; | ||
567 | |||
568 | if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0) | ||
569 | pal_desc->ldcmd = fbi->palette_size * sizeof(u16); | ||
570 | else | ||
571 | pal_desc->ldcmd = fbi->palette_size * sizeof(u32); | ||
572 | |||
573 | pal_desc->ldcmd |= LDCMD_PAL; | ||
574 | |||
575 | /* flip back and forth between palette and frame buffer */ | ||
576 | pal_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; | ||
577 | dma_desc->fdadr = fbi->dma_buff_phys + pal_desc_off; | ||
578 | fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off; | ||
579 | } | ||
580 | |||
581 | return 0; | ||
582 | } | ||
583 | |||
549 | /* | 584 | /* |
550 | * pxafb_activate_var(): | 585 | * pxafb_activate_var(): |
551 | * Configures LCD Controller based on entries in var parameter. | 586 | * Configures LCD Controller based on entries in var parameter. |
@@ -557,6 +592,7 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, | |||
557 | struct pxafb_lcd_reg new_regs; | 592 | struct pxafb_lcd_reg new_regs; |
558 | u_long flags; | 593 | u_long flags; |
559 | u_int lines_per_panel, pcd = get_pcd(fbi, var->pixclock); | 594 | u_int lines_per_panel, pcd = get_pcd(fbi, var->pixclock); |
595 | size_t nbytes; | ||
560 | 596 | ||
561 | #if DEBUG_VAR | 597 | #if DEBUG_VAR |
562 | if (var->xres < 16 || var->xres > 1024) | 598 | if (var->xres < 16 || var->xres > 1024) |
@@ -634,54 +670,15 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, | |||
634 | /* Update shadow copy atomically */ | 670 | /* Update shadow copy atomically */ |
635 | local_irq_save(flags); | 671 | local_irq_save(flags); |
636 | 672 | ||
637 | /* setup dma descriptors */ | 673 | nbytes = lines_per_panel * fbi->fb.fix.line_length; |
638 | fbi->dmadesc_fblow_cpu = (struct pxafb_dma_descriptor *) | ||
639 | ((unsigned int)fbi->palette_cpu - 3*16); | ||
640 | fbi->dmadesc_fbhigh_cpu = (struct pxafb_dma_descriptor *) | ||
641 | ((unsigned int)fbi->palette_cpu - 2*16); | ||
642 | fbi->dmadesc_palette_cpu = (struct pxafb_dma_descriptor *) | ||
643 | ((unsigned int)fbi->palette_cpu - 1*16); | ||
644 | |||
645 | fbi->dmadesc_fblow_dma = fbi->palette_dma - 3*16; | ||
646 | fbi->dmadesc_fbhigh_dma = fbi->palette_dma - 2*16; | ||
647 | fbi->dmadesc_palette_dma = fbi->palette_dma - 1*16; | ||
648 | |||
649 | #define BYTES_PER_PANEL (lines_per_panel * fbi->fb.fix.line_length) | ||
650 | |||
651 | /* populate descriptors */ | ||
652 | fbi->dmadesc_fblow_cpu->fdadr = fbi->dmadesc_fblow_dma; | ||
653 | fbi->dmadesc_fblow_cpu->fsadr = fbi->screen_dma + BYTES_PER_PANEL; | ||
654 | fbi->dmadesc_fblow_cpu->fidr = 0; | ||
655 | fbi->dmadesc_fblow_cpu->ldcmd = BYTES_PER_PANEL; | ||
656 | |||
657 | fbi->fdadr1 = fbi->dmadesc_fblow_dma; /* only used in dual-panel mode */ | ||
658 | |||
659 | fbi->dmadesc_fbhigh_cpu->fsadr = fbi->screen_dma; | ||
660 | fbi->dmadesc_fbhigh_cpu->fidr = 0; | ||
661 | fbi->dmadesc_fbhigh_cpu->ldcmd = BYTES_PER_PANEL; | ||
662 | |||
663 | fbi->dmadesc_palette_cpu->fsadr = fbi->palette_dma; | ||
664 | fbi->dmadesc_palette_cpu->fidr = 0; | ||
665 | if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0) | ||
666 | fbi->dmadesc_palette_cpu->ldcmd = fbi->palette_size * | ||
667 | sizeof(u16); | ||
668 | else | ||
669 | fbi->dmadesc_palette_cpu->ldcmd = fbi->palette_size * | ||
670 | sizeof(u32); | ||
671 | fbi->dmadesc_palette_cpu->ldcmd |= LDCMD_PAL; | ||
672 | 674 | ||
673 | if (var->bits_per_pixel == 16) { | 675 | if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual) |
674 | /* palette shouldn't be loaded in true-color mode */ | 676 | setup_frame_dma(fbi, DMA_LOWER, PAL_NONE, nbytes, nbytes); |
675 | fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_fbhigh_dma; | 677 | |
676 | fbi->fdadr0 = fbi->dmadesc_fbhigh_dma; /* no pal just fbhigh */ | 678 | if (var->bits_per_pixel >= 16) |
677 | /* init it to something, even though we won't be using it */ | 679 | setup_frame_dma(fbi, DMA_BASE, PAL_NONE, 0, nbytes); |
678 | fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_palette_dma; | 680 | else |
679 | } else { | 681 | setup_frame_dma(fbi, DMA_BASE, PAL_BASE, 0, nbytes); |
680 | /* flips back and forth between pal and fbhigh */ | ||
681 | fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_fbhigh_dma; | ||
682 | fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_palette_dma; | ||
683 | fbi->fdadr0 = fbi->dmadesc_palette_dma; | ||
684 | } | ||
685 | 682 | ||
686 | fbi->reg_lccr0 = new_regs.lccr0; | 683 | fbi->reg_lccr0 = new_regs.lccr0; |
687 | fbi->reg_lccr1 = new_regs.lccr1; | 684 | fbi->reg_lccr1 = new_regs.lccr1; |
@@ -701,8 +698,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, | |||
701 | (__raw_readl(fbi->mmio_base + LCCR1) != fbi->reg_lccr1) || | 698 | (__raw_readl(fbi->mmio_base + LCCR1) != fbi->reg_lccr1) || |
702 | (__raw_readl(fbi->mmio_base + LCCR2) != fbi->reg_lccr2) || | 699 | (__raw_readl(fbi->mmio_base + LCCR2) != fbi->reg_lccr2) || |
703 | (__raw_readl(fbi->mmio_base + LCCR3) != fbi->reg_lccr3) || | 700 | (__raw_readl(fbi->mmio_base + LCCR3) != fbi->reg_lccr3) || |
704 | (__raw_readl(fbi->mmio_base + FDADR0) != fbi->fdadr0) || | 701 | (__raw_readl(fbi->mmio_base + FDADR0) != fbi->fdadr[0]) || |
705 | (__raw_readl(fbi->mmio_base + FDADR1) != fbi->fdadr1)) | 702 | (__raw_readl(fbi->mmio_base + FDADR1) != fbi->fdadr[1])) |
706 | pxafb_schedule_work(fbi, C_REENABLE); | 703 | pxafb_schedule_work(fbi, C_REENABLE); |
707 | 704 | ||
708 | return 0; | 705 | return 0; |
@@ -777,8 +774,8 @@ static void pxafb_setup_gpio(struct pxafb_info *fbi) | |||
777 | static void pxafb_enable_controller(struct pxafb_info *fbi) | 774 | static void pxafb_enable_controller(struct pxafb_info *fbi) |
778 | { | 775 | { |
779 | pr_debug("pxafb: Enabling LCD controller\n"); | 776 | pr_debug("pxafb: Enabling LCD controller\n"); |
780 | pr_debug("fdadr0 0x%08x\n", (unsigned int) fbi->fdadr0); | 777 | pr_debug("fdadr0 0x%08x\n", (unsigned int) fbi->fdadr[0]); |
781 | pr_debug("fdadr1 0x%08x\n", (unsigned int) fbi->fdadr1); | 778 | pr_debug("fdadr1 0x%08x\n", (unsigned int) fbi->fdadr[1]); |
782 | pr_debug("reg_lccr0 0x%08x\n", (unsigned int) fbi->reg_lccr0); | 779 | pr_debug("reg_lccr0 0x%08x\n", (unsigned int) fbi->reg_lccr0); |
783 | pr_debug("reg_lccr1 0x%08x\n", (unsigned int) fbi->reg_lccr1); | 780 | pr_debug("reg_lccr1 0x%08x\n", (unsigned int) fbi->reg_lccr1); |
784 | pr_debug("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2); | 781 | pr_debug("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2); |
@@ -793,8 +790,8 @@ static void pxafb_enable_controller(struct pxafb_info *fbi) | |||
793 | __raw_writel(fbi->reg_lccr1, fbi->mmio_base + LCCR1); | 790 | __raw_writel(fbi->reg_lccr1, fbi->mmio_base + LCCR1); |
794 | __raw_writel(fbi->reg_lccr0 & ~LCCR0_ENB, fbi->mmio_base + LCCR0); | 791 | __raw_writel(fbi->reg_lccr0 & ~LCCR0_ENB, fbi->mmio_base + LCCR0); |
795 | 792 | ||
796 | __raw_writel(fbi->fdadr0, fbi->mmio_base + FDADR0); | 793 | __raw_writel(fbi->fdadr[0], fbi->mmio_base + FDADR0); |
797 | __raw_writel(fbi->fdadr1, fbi->mmio_base + FDADR1); | 794 | __raw_writel(fbi->fdadr[1], fbi->mmio_base + FDADR1); |
798 | __raw_writel(fbi->reg_lccr0 | LCCR0_ENB, fbi->mmio_base + LCCR0); | 795 | __raw_writel(fbi->reg_lccr0 | LCCR0_ENB, fbi->mmio_base + LCCR0); |
799 | } | 796 | } |
800 | 797 | ||
@@ -1038,8 +1035,6 @@ static int pxafb_resume(struct platform_device *dev) | |||
1038 | */ | 1035 | */ |
1039 | static int __init pxafb_map_video_memory(struct pxafb_info *fbi) | 1036 | static int __init pxafb_map_video_memory(struct pxafb_info *fbi) |
1040 | { | 1037 | { |
1041 | u_long palette_mem_size; | ||
1042 | |||
1043 | /* | 1038 | /* |
1044 | * We reserve one page for the palette, plus the size | 1039 | * We reserve one page for the palette, plus the size |
1045 | * of the framebuffer. | 1040 | * of the framebuffer. |
@@ -1062,14 +1057,9 @@ static int __init pxafb_map_video_memory(struct pxafb_info *fbi) | |||
1062 | fbi->fb.fix.smem_start = fbi->screen_dma; | 1057 | fbi->fb.fix.smem_start = fbi->screen_dma; |
1063 | fbi->palette_size = fbi->fb.var.bits_per_pixel == 8 ? 256 : 16; | 1058 | fbi->palette_size = fbi->fb.var.bits_per_pixel == 8 ? 256 : 16; |
1064 | 1059 | ||
1065 | if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0) | 1060 | fbi->dma_buff = (void *)fbi->map_cpu; |
1066 | palette_mem_size = fbi->palette_size * sizeof(u16); | 1061 | fbi->dma_buff_phys = fbi->map_dma; |
1067 | else | 1062 | fbi->palette_cpu = (u16 *)&fbi->dma_buff->palette[0]; |
1068 | palette_mem_size = fbi->palette_size * sizeof(u32); | ||
1069 | |||
1070 | fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE | ||
1071 | - palette_mem_size); | ||
1072 | fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size; | ||
1073 | } | 1063 | } |
1074 | 1064 | ||
1075 | return fbi->map_cpu ? 0 : -ENOMEM; | 1065 | return fbi->map_cpu ? 0 : -ENOMEM; |
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h index c7c561df3b6..b777641c5e7 100644 --- a/drivers/video/pxafb.h +++ b/drivers/video/pxafb.h | |||
@@ -37,6 +37,36 @@ struct pxafb_dma_descriptor { | |||
37 | unsigned int ldcmd; | 37 | unsigned int ldcmd; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | enum { | ||
41 | PAL_NONE = -1, | ||
42 | PAL_BASE = 0, | ||
43 | PAL_OV1 = 1, | ||
44 | PAL_OV2 = 2, | ||
45 | PAL_MAX, | ||
46 | }; | ||
47 | |||
48 | enum { | ||
49 | DMA_BASE = 0, | ||
50 | DMA_UPPER = 0, | ||
51 | DMA_LOWER = 1, | ||
52 | DMA_OV1 = 1, | ||
53 | DMA_OV2_Y = 2, | ||
54 | DMA_OV2_Cb = 3, | ||
55 | DMA_OV2_Cr = 4, | ||
56 | DMA_CURSOR = 5, | ||
57 | DMA_CMD = 6, | ||
58 | DMA_MAX, | ||
59 | }; | ||
60 | |||
61 | /* maximum palette size - 256 entries, each 4 bytes long */ | ||
62 | #define PALETTE_SIZE (256 * 4) | ||
63 | |||
64 | struct pxafb_dma_buff { | ||
65 | unsigned char palette[PAL_MAX * PALETTE_SIZE]; | ||
66 | struct pxafb_dma_descriptor pal_desc[PAL_MAX]; | ||
67 | struct pxafb_dma_descriptor dma_desc[DMA_MAX]; | ||
68 | }; | ||
69 | |||
40 | struct pxafb_info { | 70 | struct pxafb_info { |
41 | struct fb_info fb; | 71 | struct fb_info fb; |
42 | struct device *dev; | 72 | struct device *dev; |
@@ -44,6 +74,10 @@ struct pxafb_info { | |||
44 | 74 | ||
45 | void __iomem *mmio_base; | 75 | void __iomem *mmio_base; |
46 | 76 | ||
77 | struct pxafb_dma_buff *dma_buff; | ||
78 | dma_addr_t dma_buff_phys; | ||
79 | dma_addr_t fdadr[DMA_MAX]; | ||
80 | |||
47 | /* | 81 | /* |
48 | * These are the addresses we mapped | 82 | * These are the addresses we mapped |
49 | * the framebuffer memory region to. | 83 | * the framebuffer memory region to. |
@@ -57,20 +91,8 @@ struct pxafb_info { | |||
57 | u_char * screen_cpu; /* virtual address of frame buffer */ | 91 | u_char * screen_cpu; /* virtual address of frame buffer */ |
58 | dma_addr_t screen_dma; /* physical address of frame buffer */ | 92 | dma_addr_t screen_dma; /* physical address of frame buffer */ |
59 | u16 * palette_cpu; /* virtual address of palette memory */ | 93 | u16 * palette_cpu; /* virtual address of palette memory */ |
60 | dma_addr_t palette_dma; /* physical address of palette memory */ | ||
61 | u_int palette_size; | 94 | u_int palette_size; |
62 | 95 | ||
63 | /* DMA descriptors */ | ||
64 | struct pxafb_dma_descriptor * dmadesc_fblow_cpu; | ||
65 | dma_addr_t dmadesc_fblow_dma; | ||
66 | struct pxafb_dma_descriptor * dmadesc_fbhigh_cpu; | ||
67 | dma_addr_t dmadesc_fbhigh_dma; | ||
68 | struct pxafb_dma_descriptor * dmadesc_palette_cpu; | ||
69 | dma_addr_t dmadesc_palette_dma; | ||
70 | |||
71 | dma_addr_t fdadr0; | ||
72 | dma_addr_t fdadr1; | ||
73 | |||
74 | u_int lccr0; | 96 | u_int lccr0; |
75 | u_int lccr3; | 97 | u_int lccr3; |
76 | u_int lccr4; | 98 | u_int lccr4; |