summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/board-generic.c2
-rw-r--r--arch/arm/mach-omap2/common.h2
-rw-r--r--arch/arm/mach-omap2/display.c105
-rw-r--r--arch/arm/mach-omap2/display.h3
-rw-r--r--arch/arm/mach-omap2/dss-common.c18
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);