ARM: OMAP2+: add omapdss_init_of()
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Mon, 18 Mar 2013 13:50:25 +0000 (15:50 +0200)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Wed, 19 Mar 2014 08:52:23 +0000 (10:52 +0200)
The OMAP display architecture requires a bunch of platform devices which
are not created via .dts (for now). We also need to pass a few function
pointers and the DSS hardware version from the arch code to omapdss
driver.

This patch adds omapdss_init_of() function, called from board-generic at
init time, which handles those tasks.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Archit Taneja <archit@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/display.c
arch/arm/mach-omap2/display.h
arch/arm/mach-omap2/dss-common.c

index 8e3daa11602b305473b63ded02749cf152c6f415..fcb7f5c271c95d43870cc70573646595fb3579f3 100644 (file)
@@ -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
index a6aae300542cd822a873501e7670ea2dc273dd14..1864282dbddf93eb8330acfcc309bde97f2d52e5 100644 (file)
@@ -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 */
index 4cf165502b35cfdd06c09696a20b09758d974169..a83ada38cae2150baaaedbfa21e11551209ffbc9 100644 (file)
@@ -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;
+}
index f3d2ce4bc262350420d8ff57eb4805d2894ff87a..7375854b16c7a9dd39d7ab5793adc4f1b6669ecf 100644 (file)
@@ -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
index dadccc91488c64e94c06e9bf93b54bc5c294e26e..ab8cf26d50963f0a69155f09ebe3cc5be1c17cce 100644 (file)
@@ -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);