diff options
Diffstat (limited to 'arch/arm/mach-omap2/display.c')
| -rw-r--r-- | arch/arm/mach-omap2/display.c | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 93ebb4007ea9..16d33d831287 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c | |||
| @@ -23,6 +23,9 @@ | |||
| 23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
| 24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
| 25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
| 26 | #include <linux/of.h> | ||
| 27 | #include <linux/of_platform.h> | ||
| 28 | #include <linux/slab.h> | ||
| 26 | 29 | ||
| 27 | #include <video/omapdss.h> | 30 | #include <video/omapdss.h> |
| 28 | #include "omap_hwmod.h" | 31 | #include "omap_hwmod.h" |
| @@ -551,3 +554,166 @@ int omap_dss_reset(struct omap_hwmod *oh) | |||
| 551 | 554 | ||
| 552 | return r; | 555 | return r; |
| 553 | } | 556 | } |
| 557 | |||
| 558 | /* list of 'compatible' nodes to convert to omapdss specific */ | ||
| 559 | static const char * const dss_compat_conv_list[] __initconst = { | ||
| 560 | "composite-connector", | ||
| 561 | "dvi-connector", | ||
| 562 | "hdmi-connector", | ||
| 563 | "panel-dpi", | ||
| 564 | "panel-dsi-cm", | ||
| 565 | "sony,acx565akm", | ||
| 566 | "svideo-connector", | ||
| 567 | "ti,tfp410", | ||
| 568 | "ti,tpd12s015", | ||
| 569 | }; | ||
| 570 | |||
| 571 | /* prepend compatible string with "omapdss," */ | ||
| 572 | static __init void omapdss_omapify_node(struct device_node *node, | ||
| 573 | const char *compat) | ||
| 574 | { | ||
| 575 | char *new_compat; | ||
| 576 | struct property *prop; | ||
| 577 | |||
| 578 | new_compat = kasprintf(GFP_KERNEL, "omapdss,%s", compat); | ||
| 579 | |||
| 580 | prop = kzalloc(sizeof(*prop), GFP_KERNEL); | ||
| 581 | |||
| 582 | if (!prop) { | ||
| 583 | pr_err("omapdss_omapify_node: kzalloc failed\n"); | ||
| 584 | return; | ||
| 585 | } | ||
| 586 | |||
| 587 | prop->name = "compatible"; | ||
| 588 | prop->value = new_compat; | ||
| 589 | prop->length = strlen(new_compat) + 1; | ||
| 590 | |||
| 591 | of_update_property(node, prop); | ||
| 592 | } | ||
| 593 | |||
| 594 | /* | ||
| 595 | * As omapdss panel drivers are omapdss specific, but we want to define the | ||
| 596 | * DT-data in generic manner, we convert the compatible strings of the panel | ||
| 597 | * nodes from "panel-foo" to "omapdss,panel-foo". This way we can have both | ||
| 598 | * correct DT data and omapdss specific drivers. | ||
| 599 | * | ||
| 600 | * When we get generic panel drivers to the kernel, this will be removed. | ||
| 601 | */ | ||
| 602 | void __init omapdss_early_init_of(void) | ||
| 603 | { | ||
| 604 | int i; | ||
| 605 | |||
| 606 | for (i = 0; i < ARRAY_SIZE(dss_compat_conv_list); ++i) { | ||
| 607 | const char *compat = dss_compat_conv_list[i]; | ||
| 608 | struct device_node *node = NULL; | ||
| 609 | |||
| 610 | while ((node = of_find_compatible_node(node, NULL, compat))) { | ||
| 611 | if (!of_device_is_available(node)) | ||
| 612 | continue; | ||
| 613 | |||
| 614 | omapdss_omapify_node(node, compat); | ||
| 615 | } | ||
| 616 | } | ||
| 617 | } | ||
| 618 | |||
| 619 | struct device_node * __init omapdss_find_dss_of_node(void) | ||
| 620 | { | ||
| 621 | struct device_node *node; | ||
| 622 | |||
| 623 | node = of_find_compatible_node(NULL, NULL, "ti,omap2-dss"); | ||
| 624 | if (node) | ||
| 625 | return node; | ||
| 626 | |||
| 627 | node = of_find_compatible_node(NULL, NULL, "ti,omap3-dss"); | ||
| 628 | if (node) | ||
| 629 | return node; | ||
| 630 | |||
| 631 | node = of_find_compatible_node(NULL, NULL, "ti,omap4-dss"); | ||
| 632 | if (node) | ||
| 633 | return node; | ||
| 634 | |||
| 635 | return NULL; | ||
| 636 | } | ||
| 637 | |||
| 638 | int __init omapdss_init_of(void) | ||
| 639 | { | ||
| 640 | int r; | ||
| 641 | enum omapdss_version ver; | ||
| 642 | struct device_node *node; | ||
| 643 | struct platform_device *pdev; | ||
| 644 | |||
| 645 | static struct omap_dss_board_info board_data = { | ||
| 646 | .dsi_enable_pads = omap_dsi_enable_pads, | ||
| 647 | .dsi_disable_pads = omap_dsi_disable_pads, | ||
| 648 | .set_min_bus_tput = omap_dss_set_min_bus_tput, | ||
| 649 | }; | ||
| 650 | |||
| 651 | /* only create dss helper devices if dss is enabled in the .dts */ | ||
| 652 | |||
| 653 | node = omapdss_find_dss_of_node(); | ||
| 654 | if (!node) | ||
| 655 | return 0; | ||
| 656 | |||
| 657 | if (!of_device_is_available(node)) | ||
| 658 | return 0; | ||
| 659 | |||
| 660 | ver = omap_display_get_version(); | ||
| 661 | |||
| 662 | if (ver == OMAPDSS_VER_UNKNOWN) { | ||
| 663 | pr_err("DSS not supported on this SoC\n"); | ||
| 664 | return -ENODEV; | ||
| 665 | } | ||
| 666 | |||
| 667 | pdev = of_find_device_by_node(node); | ||
| 668 | |||
| 669 | if (!pdev) { | ||
| 670 | pr_err("Unable to find DSS platform device\n"); | ||
| 671 | return -ENODEV; | ||
| 672 | } | ||
| 673 | |||
| 674 | r = of_platform_populate(node, NULL, NULL, &pdev->dev); | ||
| 675 | if (r) { | ||
| 676 | pr_err("Unable to populate DSS submodule devices\n"); | ||
| 677 | return r; | ||
| 678 | } | ||
| 679 | |||
| 680 | board_data.version = ver; | ||
| 681 | |||
| 682 | omap_display_device.dev.platform_data = &board_data; | ||
| 683 | |||
| 684 | r = platform_device_register(&omap_display_device); | ||
| 685 | if (r < 0) { | ||
| 686 | pr_err("Unable to register omapdss device\n"); | ||
| 687 | return r; | ||
| 688 | } | ||
| 689 | |||
| 690 | /* create DRM device */ | ||
| 691 | r = omap_init_drm(); | ||
| 692 | if (r < 0) { | ||
| 693 | pr_err("Unable to register omapdrm device\n"); | ||
| 694 | return r; | ||
| 695 | } | ||
| 696 | |||
| 697 | /* create vrfb device */ | ||
| 698 | r = omap_init_vrfb(); | ||
| 699 | if (r < 0) { | ||
| 700 | pr_err("Unable to register omapvrfb device\n"); | ||
| 701 | return r; | ||
| 702 | } | ||
| 703 | |||
| 704 | /* create FB device */ | ||
| 705 | r = omap_init_fb(); | ||
| 706 | if (r < 0) { | ||
| 707 | pr_err("Unable to register omapfb device\n"); | ||
| 708 | return r; | ||
| 709 | } | ||
| 710 | |||
| 711 | /* create V4L2 display device */ | ||
| 712 | r = omap_init_vout(); | ||
| 713 | if (r < 0) { | ||
| 714 | pr_err("Unable to register omap_vout device\n"); | ||
| 715 | return r; | ||
| 716 | } | ||
| 717 | |||
| 718 | return 0; | ||
| 719 | } | ||
