aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 = {