aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss/core.c')
-rw-r--r--drivers/video/omap2/dss/core.c255
1 files changed, 152 insertions, 103 deletions
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index e8a120771ac6..72ded9cd2cb0 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -43,6 +43,8 @@ static struct {
43 43
44 struct regulator *vdds_dsi_reg; 44 struct regulator *vdds_dsi_reg;
45 struct regulator *vdds_sdi_reg; 45 struct regulator *vdds_sdi_reg;
46
47 const char *default_display_name;
46} core; 48} core;
47 49
48static char *def_disp_name; 50static char *def_disp_name;
@@ -54,9 +56,6 @@ bool dss_debug;
54module_param_named(debug, dss_debug, bool, 0644); 56module_param_named(debug, dss_debug, bool, 0644);
55#endif 57#endif
56 58
57static int omap_dss_register_device(struct omap_dss_device *);
58static void omap_dss_unregister_device(struct omap_dss_device *);
59
60/* REGULATORS */ 59/* REGULATORS */
61 60
62struct regulator *dss_get_vdds_dsi(void) 61struct regulator *dss_get_vdds_dsi(void)
@@ -87,6 +86,51 @@ struct regulator *dss_get_vdds_sdi(void)
87 return reg; 86 return reg;
88} 87}
89 88
89int dss_get_ctx_loss_count(struct device *dev)
90{
91 struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
92 int cnt;
93
94 if (!board_data->get_context_loss_count)
95 return -ENOENT;
96
97 cnt = board_data->get_context_loss_count(dev);
98
99 WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt);
100
101 return cnt;
102}
103
104int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask)
105{
106 struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
107
108 if (!board_data->dsi_enable_pads)
109 return -ENOENT;
110
111 return board_data->dsi_enable_pads(dsi_id, lane_mask);
112}
113
114void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask)
115{
116 struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
117
118 if (!board_data->dsi_enable_pads)
119 return;
120
121 return board_data->dsi_disable_pads(dsi_id, lane_mask);
122}
123
124int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
125{
126 struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
127
128 if (pdata->set_min_bus_tput)
129 return pdata->set_min_bus_tput(dev, tput);
130 else
131 return 0;
132}
133
90#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 134#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
91static int dss_debug_show(struct seq_file *s, void *unused) 135static int dss_debug_show(struct seq_file *s, void *unused)
92{ 136{
@@ -121,34 +165,6 @@ static int dss_initialize_debugfs(void)
121 debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, 165 debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
122 &dss_debug_dump_clocks, &dss_debug_fops); 166 &dss_debug_dump_clocks, &dss_debug_fops);
123 167
124#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
125 debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir,
126 &dispc_dump_irqs, &dss_debug_fops);
127#endif
128
129#if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS)
130 dsi_create_debugfs_files_irq(dss_debugfs_dir, &dss_debug_fops);
131#endif
132
133 debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir,
134 &dss_dump_regs, &dss_debug_fops);
135 debugfs_create_file("dispc", S_IRUGO, dss_debugfs_dir,
136 &dispc_dump_regs, &dss_debug_fops);
137#ifdef CONFIG_OMAP2_DSS_RFBI
138 debugfs_create_file("rfbi", S_IRUGO, dss_debugfs_dir,
139 &rfbi_dump_regs, &dss_debug_fops);
140#endif
141#ifdef CONFIG_OMAP2_DSS_DSI
142 dsi_create_debugfs_files_reg(dss_debugfs_dir, &dss_debug_fops);
143#endif
144#ifdef CONFIG_OMAP2_DSS_VENC
145 debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir,
146 &venc_dump_regs, &dss_debug_fops);
147#endif
148#ifdef CONFIG_OMAP4_DSS_HDMI
149 debugfs_create_file("hdmi", S_IRUGO, dss_debugfs_dir,
150 &hdmi_dump_regs, &dss_debug_fops);
151#endif
152 return 0; 168 return 0;
153} 169}
154 170
@@ -157,6 +173,19 @@ static void dss_uninitialize_debugfs(void)
157 if (dss_debugfs_dir) 173 if (dss_debugfs_dir)
158 debugfs_remove_recursive(dss_debugfs_dir); 174 debugfs_remove_recursive(dss_debugfs_dir);
159} 175}
176
177int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
178{
179 struct dentry *d;
180
181 d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir,
182 write, &dss_debug_fops);
183
184 if (IS_ERR(d))
185 return PTR_ERR(d);
186
187 return 0;
188}
160#else /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */ 189#else /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */
161static inline int dss_initialize_debugfs(void) 190static inline int dss_initialize_debugfs(void)
162{ 191{
@@ -165,14 +194,18 @@ static inline int dss_initialize_debugfs(void)
165static inline void dss_uninitialize_debugfs(void) 194static inline void dss_uninitialize_debugfs(void)
166{ 195{
167} 196}
197static inline int dss_debugfs_create_file(const char *name,
198 void (*write)(struct seq_file *))
199{
200 return 0;
201}
168#endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */ 202#endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */
169 203
170/* PLATFORM DEVICE */ 204/* PLATFORM DEVICE */
171static int omap_dss_probe(struct platform_device *pdev) 205static int __init omap_dss_probe(struct platform_device *pdev)
172{ 206{
173 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 207 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
174 int r; 208 int r;
175 int i;
176 209
177 core.pdev = pdev; 210 core.pdev = pdev;
178 211
@@ -187,28 +220,13 @@ static int omap_dss_probe(struct platform_device *pdev)
187 if (r) 220 if (r)
188 goto err_debugfs; 221 goto err_debugfs;
189 222
190 for (i = 0; i < pdata->num_devices; ++i) { 223 if (def_disp_name)
191 struct omap_dss_device *dssdev = pdata->devices[i]; 224 core.default_display_name = def_disp_name;
192 225 else if (pdata->default_device)
193 r = omap_dss_register_device(dssdev); 226 core.default_display_name = pdata->default_device->name;
194 if (r) {
195 DSSERR("device %d %s register failed %d\n", i,
196 dssdev->name ?: "unnamed", r);
197
198 while (--i >= 0)
199 omap_dss_unregister_device(pdata->devices[i]);
200
201 goto err_register;
202 }
203
204 if (def_disp_name && strcmp(def_disp_name, dssdev->name) == 0)
205 pdata->default_device = dssdev;
206 }
207 227
208 return 0; 228 return 0;
209 229
210err_register:
211 dss_uninitialize_debugfs();
212err_debugfs: 230err_debugfs:
213 231
214 return r; 232 return r;
@@ -216,17 +234,11 @@ err_debugfs:
216 234
217static int omap_dss_remove(struct platform_device *pdev) 235static int omap_dss_remove(struct platform_device *pdev)
218{ 236{
219 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
220 int i;
221
222 dss_uninitialize_debugfs(); 237 dss_uninitialize_debugfs();
223 238
224 dss_uninit_overlays(pdev); 239 dss_uninit_overlays(pdev);
225 dss_uninit_overlay_managers(pdev); 240 dss_uninit_overlay_managers(pdev);
226 241
227 for (i = 0; i < pdata->num_devices; ++i)
228 omap_dss_unregister_device(pdata->devices[i]);
229
230 return 0; 242 return 0;
231} 243}
232 244
@@ -251,7 +263,6 @@ static int omap_dss_resume(struct platform_device *pdev)
251} 263}
252 264
253static struct platform_driver omap_dss_driver = { 265static struct platform_driver omap_dss_driver = {
254 .probe = omap_dss_probe,
255 .remove = omap_dss_remove, 266 .remove = omap_dss_remove,
256 .shutdown = omap_dss_shutdown, 267 .shutdown = omap_dss_shutdown,
257 .suspend = omap_dss_suspend, 268 .suspend = omap_dss_suspend,
@@ -326,7 +337,6 @@ static int dss_driver_probe(struct device *dev)
326 int r; 337 int r;
327 struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver); 338 struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver);
328 struct omap_dss_device *dssdev = to_dss_device(dev); 339 struct omap_dss_device *dssdev = to_dss_device(dev);
329 struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
330 bool force; 340 bool force;
331 341
332 DSSDBG("driver_probe: dev %s/%s, drv %s\n", 342 DSSDBG("driver_probe: dev %s/%s, drv %s\n",
@@ -335,7 +345,8 @@ static int dss_driver_probe(struct device *dev)
335 345
336 dss_init_device(core.pdev, dssdev); 346 dss_init_device(core.pdev, dssdev);
337 347
338 force = pdata->default_device == dssdev; 348 force = core.default_display_name &&
349 strcmp(core.default_display_name, dssdev->name) == 0;
339 dss_recheck_connections(dssdev, force); 350 dss_recheck_connections(dssdev, force);
340 351
341 r = dssdrv->probe(dssdev); 352 r = dssdrv->probe(dssdev);
@@ -381,6 +392,8 @@ int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
381 if (dssdriver->get_recommended_bpp == NULL) 392 if (dssdriver->get_recommended_bpp == NULL)
382 dssdriver->get_recommended_bpp = 393 dssdriver->get_recommended_bpp =
383 omapdss_default_get_recommended_bpp; 394 omapdss_default_get_recommended_bpp;
395 if (dssdriver->get_timings == NULL)
396 dssdriver->get_timings = omapdss_default_get_timings;
384 397
385 return driver_register(&dssdriver->driver); 398 return driver_register(&dssdriver->driver);
386} 399}
@@ -427,27 +440,38 @@ static void omap_dss_dev_release(struct device *dev)
427 reset_device(dev, 0); 440 reset_device(dev, 0);
428} 441}
429 442
430static int omap_dss_register_device(struct omap_dss_device *dssdev) 443int omap_dss_register_device(struct omap_dss_device *dssdev,
444 struct device *parent, int disp_num)
431{ 445{
432 static int dev_num;
433
434 WARN_ON(!dssdev->driver_name); 446 WARN_ON(!dssdev->driver_name);
435 447
436 reset_device(&dssdev->dev, 1); 448 reset_device(&dssdev->dev, 1);
437 dssdev->dev.bus = &dss_bus_type; 449 dssdev->dev.bus = &dss_bus_type;
438 dssdev->dev.parent = &dss_bus; 450 dssdev->dev.parent = parent;
439 dssdev->dev.release = omap_dss_dev_release; 451 dssdev->dev.release = omap_dss_dev_release;
440 dev_set_name(&dssdev->dev, "display%d", dev_num++); 452 dev_set_name(&dssdev->dev, "display%d", disp_num);
441 return device_register(&dssdev->dev); 453 return device_register(&dssdev->dev);
442} 454}
443 455
444static void omap_dss_unregister_device(struct omap_dss_device *dssdev) 456void omap_dss_unregister_device(struct omap_dss_device *dssdev)
445{ 457{
446 device_unregister(&dssdev->dev); 458 device_unregister(&dssdev->dev);
447} 459}
448 460
461static int dss_unregister_dss_dev(struct device *dev, void *data)
462{
463 struct omap_dss_device *dssdev = to_dss_device(dev);
464 omap_dss_unregister_device(dssdev);
465 return 0;
466}
467
468void omap_dss_unregister_child_devices(struct device *parent)
469{
470 device_for_each_child(parent, NULL, dss_unregister_dss_dev);
471}
472
449/* BUS */ 473/* BUS */
450static int omap_dss_bus_register(void) 474static int __init omap_dss_bus_register(void)
451{ 475{
452 int r; 476 int r;
453 477
@@ -469,12 +493,56 @@ static int omap_dss_bus_register(void)
469} 493}
470 494
471/* INIT */ 495/* INIT */
496static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
497#ifdef CONFIG_OMAP2_DSS_DPI
498 dpi_init_platform_driver,
499#endif
500#ifdef CONFIG_OMAP2_DSS_SDI
501 sdi_init_platform_driver,
502#endif
503#ifdef CONFIG_OMAP2_DSS_RFBI
504 rfbi_init_platform_driver,
505#endif
506#ifdef CONFIG_OMAP2_DSS_VENC
507 venc_init_platform_driver,
508#endif
509#ifdef CONFIG_OMAP2_DSS_DSI
510 dsi_init_platform_driver,
511#endif
512#ifdef CONFIG_OMAP4_DSS_HDMI
513 hdmi_init_platform_driver,
514#endif
515};
516
517static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = {
518#ifdef CONFIG_OMAP2_DSS_DPI
519 dpi_uninit_platform_driver,
520#endif
521#ifdef CONFIG_OMAP2_DSS_SDI
522 sdi_uninit_platform_driver,
523#endif
524#ifdef CONFIG_OMAP2_DSS_RFBI
525 rfbi_uninit_platform_driver,
526#endif
527#ifdef CONFIG_OMAP2_DSS_VENC
528 venc_uninit_platform_driver,
529#endif
530#ifdef CONFIG_OMAP2_DSS_DSI
531 dsi_uninit_platform_driver,
532#endif
533#ifdef CONFIG_OMAP4_DSS_HDMI
534 hdmi_uninit_platform_driver,
535#endif
536};
537
538static bool dss_output_drv_loaded[ARRAY_SIZE(dss_output_drv_reg_funcs)];
472 539
473static int __init omap_dss_register_drivers(void) 540static int __init omap_dss_register_drivers(void)
474{ 541{
475 int r; 542 int r;
543 int i;
476 544
477 r = platform_driver_register(&omap_dss_driver); 545 r = platform_driver_probe(&omap_dss_driver, omap_dss_probe);
478 if (r) 546 if (r)
479 return r; 547 return r;
480 548
@@ -490,40 +558,18 @@ static int __init omap_dss_register_drivers(void)
490 goto err_dispc; 558 goto err_dispc;
491 } 559 }
492 560
493 r = rfbi_init_platform_driver(); 561 /*
494 if (r) { 562 * It's ok if the output-driver register fails. It happens, for example,
495 DSSERR("Failed to initialize rfbi platform driver\n"); 563 * when there is no output-device (e.g. SDI for OMAP4).
496 goto err_rfbi; 564 */
497 } 565 for (i = 0; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) {
498 566 r = dss_output_drv_reg_funcs[i]();
499 r = venc_init_platform_driver(); 567 if (r == 0)
500 if (r) { 568 dss_output_drv_loaded[i] = true;
501 DSSERR("Failed to initialize venc platform driver\n");
502 goto err_venc;
503 }
504
505 r = dsi_init_platform_driver();
506 if (r) {
507 DSSERR("Failed to initialize DSI platform driver\n");
508 goto err_dsi;
509 }
510
511 r = hdmi_init_platform_driver();
512 if (r) {
513 DSSERR("Failed to initialize hdmi\n");
514 goto err_hdmi;
515 } 569 }
516 570
517 return 0; 571 return 0;
518 572
519err_hdmi:
520 dsi_uninit_platform_driver();
521err_dsi:
522 venc_uninit_platform_driver();
523err_venc:
524 rfbi_uninit_platform_driver();
525err_rfbi:
526 dispc_uninit_platform_driver();
527err_dispc: 573err_dispc:
528 dss_uninit_platform_driver(); 574 dss_uninit_platform_driver();
529err_dss: 575err_dss:
@@ -534,10 +580,13 @@ err_dss:
534 580
535static void __exit omap_dss_unregister_drivers(void) 581static void __exit omap_dss_unregister_drivers(void)
536{ 582{
537 hdmi_uninit_platform_driver(); 583 int i;
538 dsi_uninit_platform_driver(); 584
539 venc_uninit_platform_driver(); 585 for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i) {
540 rfbi_uninit_platform_driver(); 586 if (dss_output_drv_loaded[i])
587 dss_output_drv_unreg_funcs[i]();
588 }
589
541 dispc_uninit_platform_driver(); 590 dispc_uninit_platform_driver();
542 dss_uninit_platform_driver(); 591 dss_uninit_platform_driver();
543 592