aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/display.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/display.c')
-rw-r--r--arch/arm/mach-omap2/display.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index b18db84b0349..256d23fb79ab 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -23,6 +23,8 @@
23#include <linux/err.h> 23#include <linux/err.h>
24 24
25#include <plat/display.h> 25#include <plat/display.h>
26#include <plat/omap_hwmod.h>
27#include <plat/omap_device.h>
26 28
27static struct platform_device omap_display_device = { 29static struct platform_device omap_display_device = {
28 .name = "omapdss", 30 .name = "omapdss",
@@ -32,9 +34,87 @@ static struct platform_device omap_display_device = {
32 }, 34 },
33}; 35};
34 36
37static struct omap_device_pm_latency omap_dss_latency[] = {
38 [0] = {
39 .deactivate_func = omap_device_idle_hwmods,
40 .activate_func = omap_device_enable_hwmods,
41 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
42 },
43};
44
45/* oh_core is used for getting opt-clocks */
46static struct omap_hwmod *oh_core;
47
48static bool opt_clock_available(const char *clk_role)
49{
50 int i;
51
52 for (i = 0; i < oh_core->opt_clks_cnt; i++) {
53 if (!strcmp(oh_core->opt_clks[i].role, clk_role))
54 return true;
55 }
56 return false;
57}
58
35int __init omap_display_init(struct omap_dss_board_info *board_data) 59int __init omap_display_init(struct omap_dss_board_info *board_data)
36{ 60{
37 int r = 0; 61 int r = 0;
62 struct omap_hwmod *oh;
63 struct omap_device *od;
64 int i;
65 struct omap_display_platform_data pdata;
66
67 /*
68 * omap: valid DSS hwmod names
69 * omap2,3,4: dss_core, dss_dispc, dss_rfbi, dss_venc
70 * omap3,4: dss_dsi1
71 * omap4: dss_dsi2, dss_hdmi
72 */
73 char *oh_name[] = { "dss_core", "dss_dispc", "dss_rfbi", "dss_venc",
74 "dss_dsi1", "dss_dsi2", "dss_hdmi" };
75 char *dev_name[] = { "omapdss_dss", "omapdss_dispc", "omapdss_rfbi",
76 "omapdss_venc", "omapdss_dsi1", "omapdss_dsi2",
77 "omapdss_hdmi" };
78 int oh_count;
79
80 memset(&pdata, 0, sizeof(pdata));
81
82 if (cpu_is_omap24xx())
83 oh_count = ARRAY_SIZE(oh_name) - 3;
84 /* last 3 hwmod dev in oh_name are not available for omap2 */
85 else if (cpu_is_omap44xx())
86 oh_count = ARRAY_SIZE(oh_name);
87 else
88 oh_count = ARRAY_SIZE(oh_name) - 2;
89 /* last 2 hwmod dev in oh_name are not available for omap3 */
90
91 /* opt_clks are always associated with dss hwmod */
92 oh_core = omap_hwmod_lookup("dss_core");
93 if (!oh_core) {
94 pr_err("Could not look up dss_core.\n");
95 return -ENODEV;
96 }
97
98 pdata.board_data = board_data;
99 pdata.board_data->get_last_off_on_transaction_id = NULL;
100 pdata.opt_clock_available = opt_clock_available;
101
102 for (i = 0; i < oh_count; i++) {
103 oh = omap_hwmod_lookup(oh_name[i]);
104 if (!oh) {
105 pr_err("Could not look up %s\n", oh_name[i]);
106 return -ENODEV;
107 }
108
109 od = omap_device_build(dev_name[i], -1, oh, &pdata,
110 sizeof(struct omap_display_platform_data),
111 omap_dss_latency,
112 ARRAY_SIZE(omap_dss_latency), 0);
113
114 if (WARN((IS_ERR(od)), "Could not build omap_device for %s\n",
115 oh_name[i]))
116 return -ENODEV;
117 }
38 omap_display_device.dev.platform_data = board_data; 118 omap_display_device.dev.platform_data = board_data;
39 119
40 r = platform_device_register(&omap_display_device); 120 r = platform_device_register(&omap_display_device);