diff options
Diffstat (limited to 'arch/arm/mach-versatile')
-rw-r--r-- | arch/arm/mach-versatile/core.c | 186 |
1 files changed, 35 insertions, 151 deletions
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 = { |