diff options
-rw-r--r-- | arch/arm/mach-omap2/board-generic.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/common.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/display.c | 105 | ||||
-rw-r--r-- | arch/arm/mach-omap2/display.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-omap2/dss-common.c | 18 |
5 files changed, 130 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 8e3daa11602b..fcb7f5c271c9 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -36,6 +36,8 @@ static struct of_device_id omap_dt_match_table[] __initdata = { static void __init omap_generic_init(void) { pdata_quirks_init(omap_dt_match_table); + + omapdss_init_of(); } #ifdef CONFIG_SOC_OMAP2420 diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index a6aae300542c..1864282dbddf 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -315,5 +315,7 @@ extern int omap_dss_reset(struct omap_hwmod *); /* SoC specific clock initializer */ int omap_clk_init(void); +int __init omapdss_init_of(void); + #endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 4cf165502b35..a83ada38cae2 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -23,6 +23,8 @@ #include <linux/clk.h> #include <linux/err.h> #include <linux/delay.h> +#include <linux/of.h> +#include <linux/of_platform.h> #include <video/omapdss.h> #include "omap_hwmod.h" @@ -552,3 +554,106 @@ int omap_dss_reset(struct omap_hwmod *oh) return r; } + +struct device_node * __init omapdss_find_dss_of_node(void) +{ + struct device_node *node; + + node = of_find_compatible_node(NULL, NULL, "ti,omap2-dss"); + if (node) + return node; + + node = of_find_compatible_node(NULL, NULL, "ti,omap3-dss"); + if (node) + return node; + + node = of_find_compatible_node(NULL, NULL, "ti,omap4-dss"); + if (node) + return node; + + return NULL; +} + +int __init omapdss_init_of(void) +{ + int r; + enum omapdss_version ver; + struct device_node *node; + struct platform_device *pdev; + + static struct omap_dss_board_info board_data = { + .dsi_enable_pads = omap_dsi_enable_pads, + .dsi_disable_pads = omap_dsi_disable_pads, + .get_context_loss_count = omap_pm_get_dev_context_loss_count, + .set_min_bus_tput = omap_dss_set_min_bus_tput, + }; + + /* only create dss helper devices if dss is enabled in the .dts */ + + node = omapdss_find_dss_of_node(); + if (!node) + return 0; + + if (!of_device_is_available(node)) + return 0; + + ver = omap_display_get_version(); + + if (ver == OMAPDSS_VER_UNKNOWN) { + pr_err("DSS not supported on this SoC\n"); + return -ENODEV; + } + + pdev = of_find_device_by_node(node); + + if (!pdev) { + pr_err("Unable to find DSS platform device\n"); + return -ENODEV; + } + + r = of_platform_populate(node, NULL, NULL, &pdev->dev); + if (r) { + pr_err("Unable to populate DSS submodule devices\n"); + return r; + } + + board_data.version = ver; + + omap_display_device.dev.platform_data = &board_data; + + r = platform_device_register(&omap_display_device); + if (r < 0) { + pr_err("Unable to register omapdss device\n"); + return r; + } + + /* create DRM device */ + r = omap_init_drm(); + if (r < 0) { + pr_err("Unable to register omapdrm device\n"); + return r; + } + + /* create vrfb device */ + r = omap_init_vrfb(); + if (r < 0) { + pr_err("Unable to register omapvrfb device\n"); + return r; + } + + /* create FB device */ + r = omap_init_fb(); + if (r < 0) { + pr_err("Unable to register omapfb device\n"); + return r; + } + + /* create V4L2 display device */ + r = omap_init_vout(); + if (r < 0) { + pr_err("Unable to register omap_vout device\n"); + return r; + } + + return 0; +} diff --git a/arch/arm/mach-omap2/display.h b/arch/arm/mach-omap2/display.h index f3d2ce4bc262..7375854b16c7 100644 --- a/arch/arm/mach-omap2/display.h +++ b/arch/arm/mach-omap2/display.h @@ -30,4 +30,7 @@ int omap_init_drm(void); int omap_init_vrfb(void); int omap_init_fb(void); int omap_init_vout(void); + +struct device_node * __init omapdss_find_dss_of_node(void); + #endif diff --git a/arch/arm/mach-omap2/dss-common.c b/arch/arm/mach-omap2/dss-common.c index dadccc91488c..ab8cf26d5096 100644 --- a/arch/arm/mach-omap2/dss-common.c +++ b/arch/arm/mach-omap2/dss-common.c @@ -33,6 +33,7 @@ #include "soc.h" #include "dss-common.h" #include "mux.h" +#include "display.h" #define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */ #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ @@ -101,6 +102,12 @@ static struct omap_dss_board_info omap4_panda_dss_data = { void __init omap4_panda_display_init_of(void) { + struct device_node *node; + + node = omapdss_find_dss_of_node(); + if (node && of_device_is_available(node)) + return; + omap_display_init(&omap4_panda_dss_data); platform_device_register(&omap4_panda_tfp410_device); @@ -194,6 +201,11 @@ static struct omap_dss_board_info sdp4430_dss_data = { void __init omap_4430sdp_display_init_of(void) { int r; + struct device_node *node; + + node = omapdss_find_dss_of_node(); + if (node && of_device_is_available(node)) + return; r = gpio_request_one(DISPLAY_SEL_GPIO, GPIOF_OUT_INIT_HIGH, "display_sel"); @@ -252,6 +264,12 @@ static struct omap_dss_board_info igep2_dss_data = { void __init omap3_igep2_display_init_of(void) { + struct device_node *node; + + node = omapdss_find_dss_of_node(); + if (node && of_device_is_available(node)) + return; + omap_display_init(&igep2_dss_data); platform_device_register(&omap3_igep2_tfp410_device); |