2 * linux/drivers/video/omap2/dss/core.c
4 * Copyright (C) 2009 Nokia Corporation
5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
7 * Some code and ideas taken from drivers/video/omap/ driver
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * You should have received a copy of the GNU General Public License along with
20 * this program. If not, see <http://www.gnu.org/licenses/>.
23 #define DSS_SUBSYS_NAME "CORE"
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/clk.h>
28 #include <linux/err.h>
29 #include <linux/platform_device.h>
30 #include <linux/seq_file.h>
31 #include <linux/debugfs.h>
33 #include <linux/device.h>
34 #include <linux/regulator/consumer.h>
35 #include <linux/suspend.h>
36 #include <linux/slab.h>
38 #include <video/omapdss.h>
41 #include "dss_features.h"
44 struct platform_device
*pdev
;
46 struct regulator
*vdds_dsi_reg
;
47 struct regulator
*vdds_sdi_reg
;
49 const char *default_display_name
;
52 static char *def_disp_name
;
53 module_param_named(def_disp
, def_disp_name
, charp
, 0);
54 MODULE_PARM_DESC(def_disp
, "default display name");
56 static bool dss_initialized
;
58 const char *omapdss_get_default_display_name(void)
60 return core
.default_display_name
;
62 EXPORT_SYMBOL(omapdss_get_default_display_name
);
64 enum omapdss_version
omapdss_get_version(void)
66 struct omap_dss_board_info
*pdata
= core
.pdev
->dev
.platform_data
;
67 return pdata
->version
;
69 EXPORT_SYMBOL(omapdss_get_version
);
71 bool omapdss_is_initialized(void)
73 return dss_initialized
;
75 EXPORT_SYMBOL(omapdss_is_initialized
);
77 struct platform_device
*dss_get_core_pdev(void)
84 struct regulator
*dss_get_vdds_dsi(void)
86 struct regulator
*reg
;
88 if (core
.vdds_dsi_reg
!= NULL
)
89 return core
.vdds_dsi_reg
;
91 reg
= regulator_get(&core
.pdev
->dev
, "vdds_dsi");
93 core
.vdds_dsi_reg
= reg
;
98 struct regulator
*dss_get_vdds_sdi(void)
100 struct regulator
*reg
;
102 if (core
.vdds_sdi_reg
!= NULL
)
103 return core
.vdds_sdi_reg
;
105 reg
= regulator_get(&core
.pdev
->dev
, "vdds_sdi");
107 core
.vdds_sdi_reg
= reg
;
112 int dss_dsi_enable_pads(int dsi_id
, unsigned lane_mask
)
114 struct omap_dss_board_info
*board_data
= core
.pdev
->dev
.platform_data
;
116 if (!board_data
->dsi_enable_pads
)
119 return board_data
->dsi_enable_pads(dsi_id
, lane_mask
);
122 void dss_dsi_disable_pads(int dsi_id
, unsigned lane_mask
)
124 struct omap_dss_board_info
*board_data
= core
.pdev
->dev
.platform_data
;
126 if (!board_data
->dsi_disable_pads
)
129 return board_data
->dsi_disable_pads(dsi_id
, lane_mask
);
132 int dss_set_min_bus_tput(struct device
*dev
, unsigned long tput
)
134 struct omap_dss_board_info
*pdata
= core
.pdev
->dev
.platform_data
;
136 if (pdata
->set_min_bus_tput
)
137 return pdata
->set_min_bus_tput(dev
, tput
);
142 #if defined(CONFIG_OMAP2_DSS_DEBUGFS)
143 static int dss_debug_show(struct seq_file
*s
, void *unused
)
145 void (*func
)(struct seq_file
*) = s
->private;
150 static int dss_debug_open(struct inode
*inode
, struct file
*file
)
152 return single_open(file
, dss_debug_show
, inode
->i_private
);
155 static const struct file_operations dss_debug_fops
= {
156 .open
= dss_debug_open
,
159 .release
= single_release
,
162 static struct dentry
*dss_debugfs_dir
;
164 static int dss_initialize_debugfs(void)
166 dss_debugfs_dir
= debugfs_create_dir("omapdss", NULL
);
167 if (IS_ERR(dss_debugfs_dir
)) {
168 int err
= PTR_ERR(dss_debugfs_dir
);
169 dss_debugfs_dir
= NULL
;
173 debugfs_create_file("clk", S_IRUGO
, dss_debugfs_dir
,
174 &dss_debug_dump_clocks
, &dss_debug_fops
);
179 static void dss_uninitialize_debugfs(void)
182 debugfs_remove_recursive(dss_debugfs_dir
);
185 int dss_debugfs_create_file(const char *name
, void (*write
)(struct seq_file
*))
189 d
= debugfs_create_file(name
, S_IRUGO
, dss_debugfs_dir
,
190 write
, &dss_debug_fops
);
194 #else /* CONFIG_OMAP2_DSS_DEBUGFS */
195 static inline int dss_initialize_debugfs(void)
199 static inline void dss_uninitialize_debugfs(void)
202 int dss_debugfs_create_file(const char *name
, void (*write
)(struct seq_file
*))
206 #endif /* CONFIG_OMAP2_DSS_DEBUGFS */
208 /* PLATFORM DEVICE */
209 static int omap_dss_pm_notif(struct notifier_block
*b
, unsigned long v
, void *d
)
211 DSSDBG("pm notif %lu\n", v
);
214 case PM_SUSPEND_PREPARE
:
215 DSSDBG("suspending displays\n");
216 return dss_suspend_all_devices();
218 case PM_POST_SUSPEND
:
219 DSSDBG("resuming displays\n");
220 return dss_resume_all_devices();
227 static struct notifier_block omap_dss_pm_notif_block
= {
228 .notifier_call
= omap_dss_pm_notif
,
231 static int __init
omap_dss_probe(struct platform_device
*pdev
)
233 struct omap_dss_board_info
*pdata
= pdev
->dev
.platform_data
;
238 dss_features_init(omapdss_get_version());
240 r
= dss_initialize_debugfs();
245 core
.default_display_name
= def_disp_name
;
246 else if (pdata
->default_device
)
247 core
.default_display_name
= pdata
->default_device
->name
;
249 register_pm_notifier(&omap_dss_pm_notif_block
);
258 static int omap_dss_remove(struct platform_device
*pdev
)
260 unregister_pm_notifier(&omap_dss_pm_notif_block
);
262 dss_uninitialize_debugfs();
267 static void omap_dss_shutdown(struct platform_device
*pdev
)
269 DSSDBG("shutdown\n");
270 dss_disable_all_devices();
273 static struct platform_driver omap_dss_driver
= {
274 .remove
= omap_dss_remove
,
275 .shutdown
= omap_dss_shutdown
,
278 .owner
= THIS_MODULE
,
283 static int dss_bus_match(struct device
*dev
, struct device_driver
*driver
)
285 struct omap_dss_device
*dssdev
= to_dss_device(dev
);
287 DSSDBG("bus_match. dev %s/%s, drv %s\n",
288 dev_name(dev
), dssdev
->driver_name
, driver
->name
);
290 return strcmp(dssdev
->driver_name
, driver
->name
) == 0;
293 static ssize_t
device_name_show(struct device
*dev
,
294 struct device_attribute
*attr
, char *buf
)
296 struct omap_dss_device
*dssdev
= to_dss_device(dev
);
297 return snprintf(buf
, PAGE_SIZE
, "%s\n",
302 static struct device_attribute default_dev_attrs
[] = {
303 __ATTR(name
, S_IRUGO
, device_name_show
, NULL
),
307 static ssize_t
driver_name_show(struct device_driver
*drv
, char *buf
)
309 struct omap_dss_driver
*dssdrv
= to_dss_driver(drv
);
310 return snprintf(buf
, PAGE_SIZE
, "%s\n",
311 dssdrv
->driver
.name
?
312 dssdrv
->driver
.name
: "");
314 static struct driver_attribute default_drv_attrs
[] = {
315 __ATTR(name
, S_IRUGO
, driver_name_show
, NULL
),
319 static struct bus_type dss_bus_type
= {
321 .match
= dss_bus_match
,
322 .dev_attrs
= default_dev_attrs
,
323 .drv_attrs
= default_drv_attrs
,
326 static void dss_bus_release(struct device
*dev
)
328 DSSDBG("bus_release\n");
331 static struct device dss_bus
= {
332 .release
= dss_bus_release
,
335 struct bus_type
*dss_get_bus(void)
337 return &dss_bus_type
;
341 static int dss_driver_probe(struct device
*dev
)
344 struct omap_dss_driver
*dssdrv
= to_dss_driver(dev
->driver
);
345 struct omap_dss_device
*dssdev
= to_dss_device(dev
);
347 DSSDBG("driver_probe: dev %s/%s, drv %s\n",
348 dev_name(dev
), dssdev
->driver_name
,
349 dssdrv
->driver
.name
);
351 r
= dssdrv
->probe(dssdev
);
354 DSSERR("driver probe failed: %d\n", r
);
358 DSSDBG("probe done for device %s\n", dev_name(dev
));
360 dssdev
->driver
= dssdrv
;
365 static int dss_driver_remove(struct device
*dev
)
367 struct omap_dss_driver
*dssdrv
= to_dss_driver(dev
->driver
);
368 struct omap_dss_device
*dssdev
= to_dss_device(dev
);
370 DSSDBG("driver_remove: dev %s/%s\n", dev_name(dev
),
371 dssdev
->driver_name
);
373 dssdrv
->remove(dssdev
);
375 dssdev
->driver
= NULL
;
380 int omap_dss_register_driver(struct omap_dss_driver
*dssdriver
)
382 dssdriver
->driver
.bus
= &dss_bus_type
;
383 dssdriver
->driver
.probe
= dss_driver_probe
;
384 dssdriver
->driver
.remove
= dss_driver_remove
;
386 if (dssdriver
->get_resolution
== NULL
)
387 dssdriver
->get_resolution
= omapdss_default_get_resolution
;
388 if (dssdriver
->get_recommended_bpp
== NULL
)
389 dssdriver
->get_recommended_bpp
=
390 omapdss_default_get_recommended_bpp
;
391 if (dssdriver
->get_timings
== NULL
)
392 dssdriver
->get_timings
= omapdss_default_get_timings
;
394 return driver_register(&dssdriver
->driver
);
396 EXPORT_SYMBOL(omap_dss_register_driver
);
398 void omap_dss_unregister_driver(struct omap_dss_driver
*dssdriver
)
400 driver_unregister(&dssdriver
->driver
);
402 EXPORT_SYMBOL(omap_dss_unregister_driver
);
406 static void omap_dss_dev_release(struct device
*dev
)
408 struct omap_dss_device
*dssdev
= to_dss_device(dev
);
412 static int disp_num_counter
;
414 struct omap_dss_device
*dss_alloc_and_init_device(struct device
*parent
)
416 struct omap_dss_device
*dssdev
;
418 dssdev
= kzalloc(sizeof(*dssdev
), GFP_KERNEL
);
422 dssdev
->dev
.bus
= &dss_bus_type
;
423 dssdev
->dev
.parent
= parent
;
424 dssdev
->dev
.release
= omap_dss_dev_release
;
425 dev_set_name(&dssdev
->dev
, "display%d", disp_num_counter
++);
427 device_initialize(&dssdev
->dev
);
432 int dss_add_device(struct omap_dss_device
*dssdev
)
434 return device_add(&dssdev
->dev
);
437 void dss_put_device(struct omap_dss_device
*dssdev
)
439 put_device(&dssdev
->dev
);
442 void dss_unregister_device(struct omap_dss_device
*dssdev
)
444 device_unregister(&dssdev
->dev
);
447 static int dss_unregister_dss_dev(struct device
*dev
, void *data
)
449 struct omap_dss_device
*dssdev
= to_dss_device(dev
);
450 dss_unregister_device(dssdev
);
454 void dss_unregister_child_devices(struct device
*parent
)
456 device_for_each_child(parent
, NULL
, dss_unregister_dss_dev
);
459 void dss_copy_device_pdata(struct omap_dss_device
*dst
,
460 const struct omap_dss_device
*src
)
464 size_t dsize
= sizeof(struct device
);
466 memcpy(d
+ dsize
, s
+ dsize
, sizeof(struct omap_dss_device
) - dsize
);
470 static int __init
omap_dss_bus_register(void)
474 r
= bus_register(&dss_bus_type
);
476 DSSERR("bus register failed\n");
480 dev_set_name(&dss_bus
, "omapdss");
481 r
= device_register(&dss_bus
);
483 DSSERR("bus driver register failed\n");
484 bus_unregister(&dss_bus_type
);
492 static int (*dss_output_drv_reg_funcs
[])(void) __initdata
= {
493 #ifdef CONFIG_OMAP2_DSS_DSI
494 dsi_init_platform_driver
,
496 #ifdef CONFIG_OMAP2_DSS_DPI
497 dpi_init_platform_driver
,
499 #ifdef CONFIG_OMAP2_DSS_SDI
500 sdi_init_platform_driver
,
502 #ifdef CONFIG_OMAP2_DSS_RFBI
503 rfbi_init_platform_driver
,
505 #ifdef CONFIG_OMAP2_DSS_VENC
506 venc_init_platform_driver
,
508 #ifdef CONFIG_OMAP4_DSS_HDMI
509 hdmi_init_platform_driver
,
513 static void (*dss_output_drv_unreg_funcs
[])(void) __exitdata
= {
514 #ifdef CONFIG_OMAP2_DSS_DSI
515 dsi_uninit_platform_driver
,
517 #ifdef CONFIG_OMAP2_DSS_DPI
518 dpi_uninit_platform_driver
,
520 #ifdef CONFIG_OMAP2_DSS_SDI
521 sdi_uninit_platform_driver
,
523 #ifdef CONFIG_OMAP2_DSS_RFBI
524 rfbi_uninit_platform_driver
,
526 #ifdef CONFIG_OMAP2_DSS_VENC
527 venc_uninit_platform_driver
,
529 #ifdef CONFIG_OMAP4_DSS_HDMI
530 hdmi_uninit_platform_driver
,
534 static bool dss_output_drv_loaded
[ARRAY_SIZE(dss_output_drv_reg_funcs
)];
536 static int __init
omap_dss_register_drivers(void)
541 r
= platform_driver_probe(&omap_dss_driver
, omap_dss_probe
);
545 r
= dss_init_platform_driver();
547 DSSERR("Failed to initialize DSS platform driver\n");
551 r
= dispc_init_platform_driver();
553 DSSERR("Failed to initialize dispc platform driver\n");
558 * It's ok if the output-driver register fails. It happens, for example,
559 * when there is no output-device (e.g. SDI for OMAP4).
561 for (i
= 0; i
< ARRAY_SIZE(dss_output_drv_reg_funcs
); ++i
) {
562 r
= dss_output_drv_reg_funcs
[i
]();
564 dss_output_drv_loaded
[i
] = true;
570 dss_uninit_platform_driver();
572 platform_driver_unregister(&omap_dss_driver
);
577 static void __exit
omap_dss_unregister_drivers(void)
581 for (i
= 0; i
< ARRAY_SIZE(dss_output_drv_unreg_funcs
); ++i
) {
582 if (dss_output_drv_loaded
[i
])
583 dss_output_drv_unreg_funcs
[i
]();
586 dispc_uninit_platform_driver();
587 dss_uninit_platform_driver();
589 platform_driver_unregister(&omap_dss_driver
);
592 #ifdef CONFIG_OMAP2_DSS_MODULE
593 static void omap_dss_bus_unregister(void)
595 device_unregister(&dss_bus
);
597 bus_unregister(&dss_bus_type
);
600 static int __init
omap_dss_init(void)
604 r
= omap_dss_bus_register();
608 r
= omap_dss_register_drivers();
610 omap_dss_bus_unregister();
614 dss_initialized
= true;
619 static void __exit
omap_dss_exit(void)
621 if (core
.vdds_dsi_reg
!= NULL
) {
622 regulator_put(core
.vdds_dsi_reg
);
623 core
.vdds_dsi_reg
= NULL
;
626 if (core
.vdds_sdi_reg
!= NULL
) {
627 regulator_put(core
.vdds_sdi_reg
);
628 core
.vdds_sdi_reg
= NULL
;
631 omap_dss_unregister_drivers();
633 omap_dss_bus_unregister();
636 module_init(omap_dss_init
);
637 module_exit(omap_dss_exit
);
639 static int __init
omap_dss_init(void)
641 return omap_dss_bus_register();
644 static int __init
omap_dss_init2(void)
648 r
= omap_dss_register_drivers();
652 dss_initialized
= true;
657 core_initcall(omap_dss_init
);
658 device_initcall(omap_dss_init2
);
661 MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
662 MODULE_DESCRIPTION("OMAP2/3 Display Subsystem");
663 MODULE_LICENSE("GPL v2");