diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-18 15:12:10 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-02-19 06:09:22 -0500 |
commit | 3414ba8c899023b604e6066d25bc9d516e059401 (patch) | |
tree | 6ea493bd520bec03c68f604f519ebfe35a811693 /arch | |
parent | 9dfec4fe6d2eb5580e5adcee8827dee3a16be49d (diff) |
ARM: versatile: switch Versatile to use consolidated CLCD
This switches Versatile platforms to use the consolidated CLCD panel
support, including the display capabilities. Versatile can support
RGB5551, BGR5551, RGB565 and BGR565 modes.
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-versatile/core.c | 186 |
2 files changed, 36 insertions, 151 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3087985010b9..b0d55b9f184e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -256,6 +256,7 @@ config ARCH_VERSATILE | |||
256 | select GENERIC_CLOCKEVENTS | 256 | select GENERIC_CLOCKEVENTS |
257 | select ARCH_WANT_OPTIONAL_GPIOLIB | 257 | select ARCH_WANT_OPTIONAL_GPIOLIB |
258 | select PLAT_VERSATILE | 258 | select PLAT_VERSATILE |
259 | select PLAT_VERSATILE_CLCD | ||
259 | select ARM_TIMER_SP804 | 260 | select ARM_TIMER_SP804 |
260 | help | 261 | help |
261 | This enables support for ARM Ltd Versatile board. | 262 | This enables support for ARM Ltd Versatile board. |
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 2866c114e682..b4f1f17eeb8d 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <mach/platform.h> | 50 | #include <mach/platform.h> |
51 | #include <asm/hardware/timer-sp.h> | 51 | #include <asm/hardware/timer-sp.h> |
52 | 52 | ||
53 | #include <plat/clcd.h> | ||
53 | #include <plat/sched_clock.h> | 54 | #include <plat/sched_clock.h> |
54 | 55 | ||
55 | #include "core.h" | 56 | #include "core.h" |
@@ -476,127 +477,7 @@ static struct clk_lookup lookups[] = { | |||
476 | #define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8) | 477 | #define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8) |
477 | #define SYS_CLCD_ID_VGA (0x1f << 8) | 478 | #define SYS_CLCD_ID_VGA (0x1f << 8) |
478 | 479 | ||
479 | static struct clcd_panel vga = { | 480 | static bool is_sanyo_2_5_lcd; |
480 | .mode = { | ||
481 | .name = "VGA", | ||
482 | .refresh = 60, | ||
483 | .xres = 640, | ||
484 | .yres = 480, | ||
485 | .pixclock = 39721, | ||
486 | .left_margin = 40, | ||
487 | .right_margin = 24, | ||
488 | .upper_margin = 32, | ||
489 | .lower_margin = 11, | ||
490 | .hsync_len = 96, | ||
491 | .vsync_len = 2, | ||
492 | .sync = 0, | ||
493 | .vmode = FB_VMODE_NONINTERLACED, | ||
494 | }, | ||
495 | .width = -1, | ||
496 | .height = -1, | ||
497 | .tim2 = TIM2_BCD | TIM2_IPC, | ||
498 | .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), | ||
499 | .bpp = 16, | ||
500 | }; | ||
501 | |||
502 | static struct clcd_panel sanyo_3_8_in = { | ||
503 | .mode = { | ||
504 | .name = "Sanyo QVGA", | ||
505 | .refresh = 116, | ||
506 | .xres = 320, | ||
507 | .yres = 240, | ||
508 | .pixclock = 100000, | ||
509 | .left_margin = 6, | ||
510 | .right_margin = 6, | ||
511 | .upper_margin = 5, | ||
512 | .lower_margin = 5, | ||
513 | .hsync_len = 6, | ||
514 | .vsync_len = 6, | ||
515 | .sync = 0, | ||
516 | .vmode = FB_VMODE_NONINTERLACED, | ||
517 | }, | ||
518 | .width = -1, | ||
519 | .height = -1, | ||
520 | .tim2 = TIM2_BCD, | ||
521 | .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), | ||
522 | .bpp = 16, | ||
523 | }; | ||
524 | |||
525 | static struct clcd_panel sanyo_2_5_in = { | ||
526 | .mode = { | ||
527 | .name = "Sanyo QVGA Portrait", | ||
528 | .refresh = 116, | ||
529 | .xres = 240, | ||
530 | .yres = 320, | ||
531 | .pixclock = 100000, | ||
532 | .left_margin = 20, | ||
533 | .right_margin = 10, | ||
534 | .upper_margin = 2, | ||
535 | .lower_margin = 2, | ||
536 | .hsync_len = 10, | ||
537 | .vsync_len = 2, | ||
538 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
539 | .vmode = FB_VMODE_NONINTERLACED, | ||
540 | }, | ||
541 | .width = -1, | ||
542 | .height = -1, | ||
543 | .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC, | ||
544 | .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), | ||
545 | .bpp = 16, | ||
546 | }; | ||
547 | |||
548 | static struct clcd_panel epson_2_2_in = { | ||
549 | .mode = { | ||
550 | .name = "Epson QCIF", | ||
551 | .refresh = 390, | ||
552 | .xres = 176, | ||
553 | .yres = 220, | ||
554 | .pixclock = 62500, | ||
555 | .left_margin = 3, | ||
556 | .right_margin = 2, | ||
557 | .upper_margin = 1, | ||
558 | .lower_margin = 0, | ||
559 | .hsync_len = 3, | ||
560 | .vsync_len = 2, | ||
561 | .sync = 0, | ||
562 | .vmode = FB_VMODE_NONINTERLACED, | ||
563 | }, | ||
564 | .width = -1, | ||
565 | .height = -1, | ||
566 | .tim2 = TIM2_BCD | TIM2_IPC, | ||
567 | .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), | ||
568 | .bpp = 16, | ||
569 | }; | ||
570 | |||
571 | /* | ||
572 | * Detect which LCD panel is connected, and return the appropriate | ||
573 | * clcd_panel structure. Note: we do not have any information on | ||
574 | * the required timings for the 8.4in panel, so we presently assume | ||
575 | * VGA timings. | ||
576 | */ | ||
577 | static struct clcd_panel *versatile_clcd_panel(void) | ||
578 | { | ||
579 | void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET; | ||
580 | struct clcd_panel *panel = &vga; | ||
581 | u32 val; | ||
582 | |||
583 | val = readl(sys_clcd) & SYS_CLCD_ID_MASK; | ||
584 | if (val == SYS_CLCD_ID_SANYO_3_8) | ||
585 | panel = &sanyo_3_8_in; | ||
586 | else if (val == SYS_CLCD_ID_SANYO_2_5) | ||
587 | panel = &sanyo_2_5_in; | ||
588 | else if (val == SYS_CLCD_ID_EPSON_2_2) | ||
589 | panel = &epson_2_2_in; | ||
590 | else if (val == SYS_CLCD_ID_VGA) | ||
591 | panel = &vga; | ||
592 | else { | ||
593 | printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n", | ||
594 | val); | ||
595 | panel = &vga; | ||
596 | } | ||
597 | |||
598 | return panel; | ||
599 | } | ||
600 | 481 | ||
601 | /* | 482 | /* |
602 | * Disable all display connectors on the interface module. | 483 | * Disable all display connectors on the interface module. |
@@ -614,7 +495,7 @@ static void versatile_clcd_disable(struct clcd_fb *fb) | |||
614 | /* | 495 | /* |
615 | * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off | 496 | * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off |
616 | */ | 497 | */ |
617 | if (machine_is_versatile_ab() && fb->panel == &sanyo_2_5_in) { | 498 | if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) { |
618 | void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL); | 499 | void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL); |
619 | unsigned long ctrl; | 500 | unsigned long ctrl; |
620 | 501 | ||
@@ -667,7 +548,7 @@ static void versatile_clcd_enable(struct clcd_fb *fb) | |||
667 | /* | 548 | /* |
668 | * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on | 549 | * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on |
669 | */ | 550 | */ |
670 | if (machine_is_versatile_ab() && fb->panel == &sanyo_2_5_in) { | 551 | if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) { |
671 | void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL); | 552 | void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL); |
672 | unsigned long ctrl; | 553 | unsigned long ctrl; |
673 | 554 | ||
@@ -678,39 +559,41 @@ static void versatile_clcd_enable(struct clcd_fb *fb) | |||
678 | #endif | 559 | #endif |
679 | } | 560 | } |
680 | 561 | ||
681 | static unsigned long framesize = SZ_1M; | 562 | /* |
682 | 563 | * Detect which LCD panel is connected, and return the appropriate | |
564 | * clcd_panel structure. Note: we do not have any information on | ||
565 | * the required timings for the 8.4in panel, so we presently assume | ||
566 | * VGA timings. | ||
567 | */ | ||
683 | static int versatile_clcd_setup(struct clcd_fb *fb) | 568 | static int versatile_clcd_setup(struct clcd_fb *fb) |
684 | { | 569 | { |
685 | dma_addr_t dma; | 570 | void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET; |
571 | const char *panel_name; | ||
572 | u32 val; | ||
686 | 573 | ||
687 | fb->panel = versatile_clcd_panel(); | 574 | is_sanyo_2_5_lcd = false; |
688 | 575 | ||
689 | fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, | 576 | val = readl(sys_clcd) & SYS_CLCD_ID_MASK; |
690 | &dma, GFP_KERNEL); | 577 | if (val == SYS_CLCD_ID_SANYO_3_8) |
691 | if (!fb->fb.screen_base) { | 578 | panel_name = "Sanyo TM38QV67A02A"; |
692 | printk(KERN_ERR "CLCD: unable to map framebuffer\n"); | 579 | else if (val == SYS_CLCD_ID_SANYO_2_5) { |
693 | return -ENOMEM; | 580 | panel_name = "Sanyo QVGA Portrait"; |
581 | is_sanyo_2_5_lcd = true; | ||
582 | } else if (val == SYS_CLCD_ID_EPSON_2_2) | ||
583 | panel_name = "Epson L2F50113T00"; | ||
584 | else if (val == SYS_CLCD_ID_VGA) | ||
585 | panel_name = "VGA"; | ||
586 | else { | ||
587 | printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n", | ||
588 | val); | ||
589 | panel_name = "VGA"; | ||
694 | } | 590 | } |
695 | 591 | ||
696 | fb->fb.fix.smem_start = dma; | 592 | fb->panel = versatile_clcd_get_panel(panel_name); |
697 | fb->fb.fix.smem_len = framesize; | 593 | if (!fb->panel) |
594 | return -EINVAL; | ||
698 | 595 | ||
699 | return 0; | 596 | return versatile_clcd_setup_dma(fb, SZ_1M); |
700 | } | ||
701 | |||
702 | static int versatile_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) | ||
703 | { | ||
704 | return dma_mmap_writecombine(&fb->dev->dev, vma, | ||
705 | fb->fb.screen_base, | ||
706 | fb->fb.fix.smem_start, | ||
707 | fb->fb.fix.smem_len); | ||
708 | } | ||
709 | |||
710 | static void versatile_clcd_remove(struct clcd_fb *fb) | ||
711 | { | ||
712 | dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, | ||
713 | fb->fb.screen_base, fb->fb.fix.smem_start); | ||
714 | } | 597 | } |
715 | 598 | ||
716 | static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs) | 599 | static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs) |
@@ -724,13 +607,14 @@ static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs) | |||
724 | 607 | ||
725 | static struct clcd_board clcd_plat_data = { | 608 | static struct clcd_board clcd_plat_data = { |
726 | .name = "Versatile", | 609 | .name = "Versatile", |
610 | .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888, | ||
727 | .check = clcdfb_check, | 611 | .check = clcdfb_check, |
728 | .decode = versatile_clcd_decode, | 612 | .decode = versatile_clcd_decode, |
729 | .disable = versatile_clcd_disable, | 613 | .disable = versatile_clcd_disable, |
730 | .enable = versatile_clcd_enable, | 614 | .enable = versatile_clcd_enable, |
731 | .setup = versatile_clcd_setup, | 615 | .setup = versatile_clcd_setup, |
732 | .mmap = versatile_clcd_mmap, | 616 | .mmap = versatile_clcd_mmap_dma, |
733 | .remove = versatile_clcd_remove, | 617 | .remove = versatile_clcd_remove_dma, |
734 | }; | 618 | }; |
735 | 619 | ||
736 | static struct pl061_platform_data gpio0_plat_data = { | 620 | static struct pl061_platform_data gpio0_plat_data = { |