aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-01-18 15:12:10 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-02-19 06:09:22 -0500
commit3414ba8c899023b604e6066d25bc9d516e059401 (patch)
tree6ea493bd520bec03c68f604f519ebfe35a811693 /arch
parent9dfec4fe6d2eb5580e5adcee8827dee3a16be49d (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/Kconfig1
-rw-r--r--arch/arm/mach-versatile/core.c186
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
479static struct clcd_panel vga = { 480static 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
502static 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
525static 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
548static 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 */
577static 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
681static 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 */
683static int versatile_clcd_setup(struct clcd_fb *fb) 568static 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
702static 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
710static 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
716static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs) 599static 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
725static struct clcd_board clcd_plat_data = { 608static 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
736static struct pl061_platform_data gpio0_plat_data = { 620static struct pl061_platform_data gpio0_plat_data = {