1
2
3
4
5
6
7
8
9
10
11
12#define DSS_SUBSYS_NAME "CORE"
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/clk.h>
17#include <linux/err.h>
18#include <linux/platform_device.h>
19#include <linux/seq_file.h>
20#include <linux/debugfs.h>
21#include <linux/io.h>
22#include <linux/device.h>
23#include <linux/regulator/consumer.h>
24#include <linux/suspend.h>
25#include <linux/slab.h>
26
27#include <video/omapfb_dss.h>
28
29#include "dss.h"
30#include "dss_features.h"
31
32static struct {
33 struct platform_device *pdev;
34
35 const char *default_display_name;
36} core;
37
38static char *def_disp_name;
39module_param_named(def_disp, def_disp_name, charp, 0);
40MODULE_PARM_DESC(def_disp, "default display name");
41
42const char *omapdss_get_default_display_name(void)
43{
44 return core.default_display_name;
45}
46EXPORT_SYMBOL(omapdss_get_default_display_name);
47
48enum omapdss_version omapdss_get_version(void)
49{
50 struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
51 return pdata->version;
52}
53EXPORT_SYMBOL(omapdss_get_version);
54
55struct platform_device *dss_get_core_pdev(void)
56{
57 return core.pdev;
58}
59
60int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask)
61{
62 struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
63
64 if (!board_data->dsi_enable_pads)
65 return -ENOENT;
66
67 return board_data->dsi_enable_pads(dsi_id, lane_mask);
68}
69
70void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask)
71{
72 struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
73
74 if (!board_data->dsi_disable_pads)
75 return;
76
77 return board_data->dsi_disable_pads(dsi_id, lane_mask);
78}
79
80int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
81{
82 struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
83
84 if (pdata->set_min_bus_tput)
85 return pdata->set_min_bus_tput(dev, tput);
86 else
87 return 0;
88}
89
90#if defined(CONFIG_FB_OMAP2_DSS_DEBUGFS)
91static int dss_show(struct seq_file *s, void *unused)
92{
93 void (*func)(struct seq_file *) = s->private;
94 func(s);
95 return 0;
96}
97
98DEFINE_SHOW_ATTRIBUTE(dss);
99
100static struct dentry *dss_debugfs_dir;
101
102static void dss_initialize_debugfs(void)
103{
104 dss_debugfs_dir = debugfs_create_dir("omapdss", NULL);
105
106 debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
107 &dss_debug_dump_clocks, &dss_fops);
108}
109
110static void dss_uninitialize_debugfs(void)
111{
112 debugfs_remove_recursive(dss_debugfs_dir);
113}
114
115void dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
116{
117 debugfs_create_file(name, S_IRUGO, dss_debugfs_dir, write, &dss_fops);
118}
119#else
120static inline void dss_initialize_debugfs(void)
121{
122}
123static inline void dss_uninitialize_debugfs(void)
124{
125}
126void dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
127{
128}
129#endif
130
131
132static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d)
133{
134 DSSDBG("pm notif %lu\n", v);
135
136 switch (v) {
137 case PM_SUSPEND_PREPARE:
138 case PM_HIBERNATION_PREPARE:
139 case PM_RESTORE_PREPARE:
140 DSSDBG("suspending displays\n");
141 return dss_suspend_all_devices();
142
143 case PM_POST_SUSPEND:
144 case PM_POST_HIBERNATION:
145 case PM_POST_RESTORE:
146 DSSDBG("resuming displays\n");
147 return dss_resume_all_devices();
148
149 default:
150 return 0;
151 }
152}
153
154static struct notifier_block omap_dss_pm_notif_block = {
155 .notifier_call = omap_dss_pm_notif,
156};
157
158static int __init omap_dss_probe(struct platform_device *pdev)
159{
160 core.pdev = pdev;
161
162 dss_features_init(omapdss_get_version());
163
164 dss_initialize_debugfs();
165
166 if (def_disp_name)
167 core.default_display_name = def_disp_name;
168
169 register_pm_notifier(&omap_dss_pm_notif_block);
170
171 return 0;
172}
173
174static int omap_dss_remove(struct platform_device *pdev)
175{
176 unregister_pm_notifier(&omap_dss_pm_notif_block);
177
178 dss_uninitialize_debugfs();
179
180 return 0;
181}
182
183static void omap_dss_shutdown(struct platform_device *pdev)
184{
185 DSSDBG("shutdown\n");
186 dss_disable_all_devices();
187}
188
189static struct platform_driver omap_dss_driver = {
190 .remove = omap_dss_remove,
191 .shutdown = omap_dss_shutdown,
192 .driver = {
193 .name = "omapdss",
194 },
195};
196
197
198static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
199 dss_init_platform_driver,
200 dispc_init_platform_driver,
201#ifdef CONFIG_FB_OMAP2_DSS_DSI
202 dsi_init_platform_driver,
203#endif
204#ifdef CONFIG_FB_OMAP2_DSS_DPI
205 dpi_init_platform_driver,
206#endif
207#ifdef CONFIG_FB_OMAP2_DSS_SDI
208 sdi_init_platform_driver,
209#endif
210#ifdef CONFIG_FB_OMAP2_DSS_VENC
211 venc_init_platform_driver,
212#endif
213#ifdef CONFIG_FB_OMAP4_DSS_HDMI
214 hdmi4_init_platform_driver,
215#endif
216#ifdef CONFIG_FB_OMAP5_DSS_HDMI
217 hdmi5_init_platform_driver,
218#endif
219};
220
221static void (*dss_output_drv_unreg_funcs[])(void) = {
222#ifdef CONFIG_FB_OMAP5_DSS_HDMI
223 hdmi5_uninit_platform_driver,
224#endif
225#ifdef CONFIG_FB_OMAP4_DSS_HDMI
226 hdmi4_uninit_platform_driver,
227#endif
228#ifdef CONFIG_FB_OMAP2_DSS_VENC
229 venc_uninit_platform_driver,
230#endif
231#ifdef CONFIG_FB_OMAP2_DSS_SDI
232 sdi_uninit_platform_driver,
233#endif
234#ifdef CONFIG_FB_OMAP2_DSS_DPI
235 dpi_uninit_platform_driver,
236#endif
237#ifdef CONFIG_FB_OMAP2_DSS_DSI
238 dsi_uninit_platform_driver,
239#endif
240 dispc_uninit_platform_driver,
241 dss_uninit_platform_driver,
242};
243
244static int __init omap_dss_init(void)
245{
246 int r;
247 int i;
248
249 r = platform_driver_probe(&omap_dss_driver, omap_dss_probe);
250 if (r)
251 return r;
252
253 for (i = 0; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) {
254 r = dss_output_drv_reg_funcs[i]();
255 if (r)
256 goto err_reg;
257 }
258
259 return 0;
260
261err_reg:
262 for (i = ARRAY_SIZE(dss_output_drv_reg_funcs) - i;
263 i < ARRAY_SIZE(dss_output_drv_reg_funcs);
264 ++i)
265 dss_output_drv_unreg_funcs[i]();
266
267 platform_driver_unregister(&omap_dss_driver);
268
269 return r;
270}
271
272static void __exit omap_dss_exit(void)
273{
274 int i;
275
276 for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i)
277 dss_output_drv_unreg_funcs[i]();
278
279 platform_driver_unregister(&omap_dss_driver);
280}
281
282module_init(omap_dss_init);
283module_exit(omap_dss_exit);
284
285MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
286MODULE_DESCRIPTION("OMAP2/3 Display Subsystem");
287MODULE_LICENSE("GPL v2");
288
289