aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-26 09:46:29 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-26 09:46:29 -0400
commit866f0956cba7d28432f20f8a696e5c1a2b40b915 (patch)
tree87b1d203cef69785448a7b07611314c2a203ae23
parente84dc1cc1503150e3bc37268a0b0f0bc0097622c (diff)
parent3c2995ac34eb559106504be962b162aef215895b (diff)
Merge branch 'archit/outputs-for-3.7'
Merge omapdss output work, that creates a new entity "output" to represent the outputs (DPI, DSI, HDMI, ...) from DSS. An output sits in between an overlay manager and a panel, and helps us to remove references to panel devices from the omapdss core. * archit/outputs-for-3.7: (23 commits) OMAPDSS: Remove old way of setting manager and device links OMAPDSS: APPLY: Remove omap_dss_device references from dss_ovl_enable/disable OMAPDSS: OVERLAY/MANAGER: Get device via output OMAPDSS: MANAGER: Update display sysfs store OMAPFB: Change dssdev->manager references OMAPDSS: HDMI: Replace dssdev->manager with dssdev->output->manager references OMAPDSS: VENC: Replace dssdev->manager with dssdev->output->manager references OMAPDSS: RFBI: Replace dssdev->manager with dssdev->output->manager references OMAPDSS: SDI: Replace dssdev->manager with dssdev->output->manager references OMAPDSS: DSI: Replace dssdev->manager with dssdev->output->manager references OMAPDSS: DSI: Remove dsi_pdev_map global struct OMAPDSS: DPI: Replace dssdev->manager with dssdev->output->manager references OMAPDSS: Create links between managers, outputs and devices OMAPDRM: Remove manager->device references OMAPFB: remove manager->device references OMAP_VOUT: Remove manager->device references OMAPDSS: Remove manager->device references OMAPDSS: APPLY: Add manager set/unset output ops for omap_overlay_manager OMAPDSS: output: Add set/unset device ops for omap_dss_output OMAPDSS: outputs: Create and register output instances ...
-rw-r--r--drivers/media/video/omap/omap_vout.c75
-rw-r--r--drivers/staging/omapdrm/omap_drv.c5
-rw-r--r--drivers/video/omap2/dss/Makefile2
-rw-r--r--drivers/video/omap2/dss/apply.c88
-rw-r--r--drivers/video/omap2/dss/dispc.c10
-rw-r--r--drivers/video/omap2/dss/display.c35
-rw-r--r--drivers/video/omap2/dss/dpi.c49
-rw-r--r--drivers/video/omap2/dss/dsi.c168
-rw-r--r--drivers/video/omap2/dss/dss.h8
-rw-r--r--drivers/video/omap2/dss/dss_features.c71
-rw-r--r--drivers/video/omap2/dss/dss_features.h1
-rw-r--r--drivers/video/omap2/dss/hdmi.c40
-rw-r--r--drivers/video/omap2/dss/manager-sysfs.c27
-rw-r--r--drivers/video/omap2/dss/manager.c17
-rw-r--r--drivers/video/omap2/dss/output.c148
-rw-r--r--drivers/video/omap2/dss/overlay.c8
-rw-r--r--drivers/video/omap2/dss/rfbi.c41
-rw-r--r--drivers/video/omap2/dss/sdi.c44
-rw-r--r--drivers/video/omap2/dss/venc.c38
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c7
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c6
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h5
-rw-r--r--include/video/omapdss.h48
23 files changed, 743 insertions, 198 deletions
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 88cf9d952631..f721fd2155f7 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -454,11 +454,15 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)
454 454
455 win = &vout->win; 455 win = &vout->win;
456 for (i = 0; i < ovid->num_overlays; i++) { 456 for (i = 0; i < ovid->num_overlays; i++) {
457 struct omap_dss_device *dssdev;
458
457 ovl = ovid->overlays[i]; 459 ovl = ovid->overlays[i];
458 if (!ovl->manager || !ovl->manager->device) 460 dssdev = ovl->get_device(ovl);
461
462 if (!dssdev)
459 return -EINVAL; 463 return -EINVAL;
460 464
461 timing = &ovl->manager->device->panel.timings; 465 timing = &dssdev->panel.timings;
462 466
463 outw = win->w.width; 467 outw = win->w.width;
464 outh = win->w.height; 468 outh = win->w.height;
@@ -515,8 +519,11 @@ static int omapvid_apply_changes(struct omap_vout_device *vout)
515 struct omapvideo_info *ovid = &vout->vid_info; 519 struct omapvideo_info *ovid = &vout->vid_info;
516 520
517 for (i = 0; i < ovid->num_overlays; i++) { 521 for (i = 0; i < ovid->num_overlays; i++) {
522 struct omap_dss_device *dssdev;
523
518 ovl = ovid->overlays[i]; 524 ovl = ovid->overlays[i];
519 if (!ovl->manager || !ovl->manager->device) 525 dssdev = ovl->get_device(ovl);
526 if (!dssdev)
520 return -EINVAL; 527 return -EINVAL;
521 ovl->manager->apply(ovl->manager); 528 ovl->manager->apply(ovl->manager);
522 } 529 }
@@ -579,12 +586,14 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)
579 586
580 ovid = &vout->vid_info; 587 ovid = &vout->vid_info;
581 ovl = ovid->overlays[0]; 588 ovl = ovid->overlays[0];
582 /* get the display device attached to the overlay */
583 if (!ovl->manager || !ovl->manager->device)
584 return;
585 589
586 mgr_id = ovl->manager->id; 590 mgr_id = ovl->manager->id;
587 cur_display = ovl->manager->device; 591
592 /* get the display device attached to the overlay */
593 cur_display = ovl->get_device(ovl);
594
595 if (!cur_display)
596 return;
588 597
589 spin_lock(&vout->vbq_lock); 598 spin_lock(&vout->vbq_lock);
590 do_gettimeofday(&timevalue); 599 do_gettimeofday(&timevalue);
@@ -948,7 +957,9 @@ static int omap_vout_release(struct file *file)
948 /* Disable all the overlay managers connected with this interface */ 957 /* Disable all the overlay managers connected with this interface */
949 for (i = 0; i < ovid->num_overlays; i++) { 958 for (i = 0; i < ovid->num_overlays; i++) {
950 struct omap_overlay *ovl = ovid->overlays[i]; 959 struct omap_overlay *ovl = ovid->overlays[i];
951 if (ovl->manager && ovl->manager->device) 960 struct omap_dss_device *dssdev = ovl->get_device(ovl);
961
962 if (dssdev)
952 ovl->disable(ovl); 963 ovl->disable(ovl);
953 } 964 }
954 /* Turn off the pipeline */ 965 /* Turn off the pipeline */
@@ -1081,14 +1092,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
1081 struct omapvideo_info *ovid; 1092 struct omapvideo_info *ovid;
1082 struct omap_video_timings *timing; 1093 struct omap_video_timings *timing;
1083 struct omap_vout_device *vout = fh; 1094 struct omap_vout_device *vout = fh;
1095 struct omap_dss_device *dssdev;
1084 1096
1085 ovid = &vout->vid_info; 1097 ovid = &vout->vid_info;
1086 ovl = ovid->overlays[0]; 1098 ovl = ovid->overlays[0];
1099 /* get the display device attached to the overlay */
1100 dssdev = ovl->get_device(ovl);
1087 1101
1088 if (!ovl->manager || !ovl->manager->device) 1102 if (!dssdev)
1089 return -EINVAL; 1103 return -EINVAL;
1090 /* get the display device attached to the overlay */ 1104
1091 timing = &ovl->manager->device->panel.timings; 1105 timing = &dssdev->panel.timings;
1092 1106
1093 vout->fbuf.fmt.height = timing->y_res; 1107 vout->fbuf.fmt.height = timing->y_res;
1094 vout->fbuf.fmt.width = timing->x_res; 1108 vout->fbuf.fmt.width = timing->x_res;
@@ -1105,6 +1119,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
1105 struct omapvideo_info *ovid; 1119 struct omapvideo_info *ovid;
1106 struct omap_video_timings *timing; 1120 struct omap_video_timings *timing;
1107 struct omap_vout_device *vout = fh; 1121 struct omap_vout_device *vout = fh;
1122 struct omap_dss_device *dssdev;
1108 1123
1109 if (vout->streaming) 1124 if (vout->streaming)
1110 return -EBUSY; 1125 return -EBUSY;
@@ -1113,13 +1128,14 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
1113 1128
1114 ovid = &vout->vid_info; 1129 ovid = &vout->vid_info;
1115 ovl = ovid->overlays[0]; 1130 ovl = ovid->overlays[0];
1131 dssdev = ovl->get_device(ovl);
1116 1132
1117 /* get the display device attached to the overlay */ 1133 /* get the display device attached to the overlay */
1118 if (!ovl->manager || !ovl->manager->device) { 1134 if (!dssdev) {
1119 ret = -EINVAL; 1135 ret = -EINVAL;
1120 goto s_fmt_vid_out_exit; 1136 goto s_fmt_vid_out_exit;
1121 } 1137 }
1122 timing = &ovl->manager->device->panel.timings; 1138 timing = &dssdev->panel.timings;
1123 1139
1124 /* We dont support RGB24-packed mode if vrfb rotation 1140 /* We dont support RGB24-packed mode if vrfb rotation
1125 * is enabled*/ 1141 * is enabled*/
@@ -1298,6 +1314,7 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
1298 struct omapvideo_info *ovid; 1314 struct omapvideo_info *ovid;
1299 struct omap_overlay *ovl; 1315 struct omap_overlay *ovl;
1300 struct omap_video_timings *timing; 1316 struct omap_video_timings *timing;
1317 struct omap_dss_device *dssdev;
1301 1318
1302 if (vout->streaming) 1319 if (vout->streaming)
1303 return -EBUSY; 1320 return -EBUSY;
@@ -1305,13 +1322,15 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
1305 mutex_lock(&vout->lock); 1322 mutex_lock(&vout->lock);
1306 ovid = &vout->vid_info; 1323 ovid = &vout->vid_info;
1307 ovl = ovid->overlays[0]; 1324 ovl = ovid->overlays[0];
1325 /* get the display device attached to the overlay */
1326 dssdev = ovl->get_device(ovl);
1308 1327
1309 if (!ovl->manager || !ovl->manager->device) { 1328 if (!dssdev) {
1310 ret = -EINVAL; 1329 ret = -EINVAL;
1311 goto s_crop_err; 1330 goto s_crop_err;
1312 } 1331 }
1313 /* get the display device attached to the overlay */ 1332
1314 timing = &ovl->manager->device->panel.timings; 1333 timing = &dssdev->panel.timings;
1315 1334
1316 if (is_rotation_90_or_270(vout)) { 1335 if (is_rotation_90_or_270(vout)) {
1317 vout->fbuf.fmt.height = timing->x_res; 1336 vout->fbuf.fmt.height = timing->x_res;
@@ -1667,7 +1686,7 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1667 for (j = 0; j < ovid->num_overlays; j++) { 1686 for (j = 0; j < ovid->num_overlays; j++) {
1668 struct omap_overlay *ovl = ovid->overlays[j]; 1687 struct omap_overlay *ovl = ovid->overlays[j];
1669 1688
1670 if (ovl->manager && ovl->manager->device) { 1689 if (ovl->get_device(ovl)) {
1671 struct omap_overlay_info info; 1690 struct omap_overlay_info info;
1672 ovl->get_overlay_info(ovl, &info); 1691 ovl->get_overlay_info(ovl, &info);
1673 info.paddr = addr; 1692 info.paddr = addr;
@@ -1690,8 +1709,9 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1690 1709
1691 for (j = 0; j < ovid->num_overlays; j++) { 1710 for (j = 0; j < ovid->num_overlays; j++) {
1692 struct omap_overlay *ovl = ovid->overlays[j]; 1711 struct omap_overlay *ovl = ovid->overlays[j];
1712 struct omap_dss_device *dssdev = ovl->get_device(ovl);
1693 1713
1694 if (ovl->manager && ovl->manager->device) { 1714 if (dssdev) {
1695 ret = ovl->enable(ovl); 1715 ret = ovl->enable(ovl);
1696 if (ret) 1716 if (ret)
1697 goto streamon_err1; 1717 goto streamon_err1;
@@ -1726,8 +1746,9 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1726 1746
1727 for (j = 0; j < ovid->num_overlays; j++) { 1747 for (j = 0; j < ovid->num_overlays; j++) {
1728 struct omap_overlay *ovl = ovid->overlays[j]; 1748 struct omap_overlay *ovl = ovid->overlays[j];
1749 struct omap_dss_device *dssdev = ovl->get_device(ovl);
1729 1750
1730 if (ovl->manager && ovl->manager->device) 1751 if (dssdev)
1731 ovl->disable(ovl); 1752 ovl->disable(ovl);
1732 } 1753 }
1733 1754
@@ -1890,8 +1911,8 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
1890 struct video_device *vfd; 1911 struct video_device *vfd;
1891 struct v4l2_pix_format *pix; 1912 struct v4l2_pix_format *pix;
1892 struct v4l2_control *control; 1913 struct v4l2_control *control;
1893 struct omap_dss_device *display = 1914 struct omap_overlay *ovl = vout->vid_info.overlays[0];
1894 vout->vid_info.overlays[0]->manager->device; 1915 struct omap_dss_device *display = ovl->get_device(ovl);
1895 1916
1896 /* set the default pix */ 1917 /* set the default pix */
1897 pix = &vout->pix; 1918 pix = &vout->pix;
@@ -2205,8 +2226,10 @@ static int __init omap_vout_probe(struct platform_device *pdev)
2205 */ 2226 */
2206 for (i = 1; i < vid_dev->num_overlays; i++) { 2227 for (i = 1; i < vid_dev->num_overlays; i++) {
2207 ovl = omap_dss_get_overlay(i); 2228 ovl = omap_dss_get_overlay(i);
2208 if (ovl->manager && ovl->manager->device) { 2229 dssdev = ovl->get_device(ovl);
2209 def_display = ovl->manager->device; 2230
2231 if (dssdev) {
2232 def_display = dssdev;
2210 } else { 2233 } else {
2211 dev_warn(&pdev->dev, "cannot find display\n"); 2234 dev_warn(&pdev->dev, "cannot find display\n");
2212 def_display = NULL; 2235 def_display = NULL;
@@ -2253,8 +2276,10 @@ probe_err1:
2253 for (i = 1; i < vid_dev->num_overlays; i++) { 2276 for (i = 1; i < vid_dev->num_overlays; i++) {
2254 def_display = NULL; 2277 def_display = NULL;
2255 ovl = omap_dss_get_overlay(i); 2278 ovl = omap_dss_get_overlay(i);
2256 if (ovl->manager && ovl->manager->device) 2279 dssdev = ovl->get_device(ovl);
2257 def_display = ovl->manager->device; 2280
2281 if (dssdev)
2282 def_display = dssdev;
2258 2283
2259 if (def_display && def_display->driver) 2284 if (def_display && def_display->driver)
2260 def_display->driver->disable(def_display); 2285 def_display->driver->disable(def_display);
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index 4beab9447ceb..64a354a54737 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -106,7 +106,8 @@ static void dump_video_chains(void)
106 for (i = 0; i < omap_dss_get_num_overlays(); i++) { 106 for (i = 0; i < omap_dss_get_num_overlays(); i++) {
107 struct omap_overlay *ovl = omap_dss_get_overlay(i); 107 struct omap_overlay *ovl = omap_dss_get_overlay(i);
108 struct omap_overlay_manager *mgr = ovl->manager; 108 struct omap_overlay_manager *mgr = ovl->manager;
109 struct omap_dss_device *dssdev = mgr ? mgr->device : NULL; 109 struct omap_dss_device *dssdev = mgr ?
110 mgr->get_device(mgr) : NULL;
110 if (dssdev) { 111 if (dssdev) {
111 DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name, 112 DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name,
112 dssdev->name); 113 dssdev->name);
@@ -185,7 +186,7 @@ static int create_connector(struct drm_device *dev,
185 for (j = 0; j < priv->num_encoders; j++) { 186 for (j = 0; j < priv->num_encoders; j++) {
186 struct omap_overlay_manager *mgr = 187 struct omap_overlay_manager *mgr =
187 omap_encoder_get_manager(priv->encoders[j]); 188 omap_encoder_get_manager(priv->encoders[j]);
188 if (mgr->device == dssdev) { 189 if (mgr->get_device(mgr) == dssdev) {
189 drm_mode_connector_attach_encoder(connector, 190 drm_mode_connector_attach_encoder(connector,
190 priv->encoders[j]); 191 priv->encoders[j]);
191 } 192 }
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 00a6eb566bb6..4549869bfe1a 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,6 +1,6 @@
1obj-$(CONFIG_OMAP2_DSS) += omapdss.o 1obj-$(CONFIG_OMAP2_DSS) += omapdss.o
2omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ 2omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
3 manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o 3 manager.o manager-sysfs.o overlay.o overlay-sysfs.o output.o apply.o
4omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o 4omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
5omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o 5omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
6omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o 6omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 6354bb842856..2b1fa851a8b9 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -421,17 +421,25 @@ static void wait_pending_extra_info_updates(void)
421int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) 421int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
422{ 422{
423 unsigned long timeout = msecs_to_jiffies(500); 423 unsigned long timeout = msecs_to_jiffies(500);
424 struct mgr_priv_data *mp; 424 struct mgr_priv_data *mp = get_mgr_priv(mgr);
425 u32 irq; 425 u32 irq;
426 unsigned long flags;
426 int r; 427 int r;
427 int i; 428 int i;
428 struct omap_dss_device *dssdev = mgr->device;
429 429
430 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 430 spin_lock_irqsave(&data_lock, flags);
431
432 if (mgr_manual_update(mgr)) {
433 spin_unlock_irqrestore(&data_lock, flags);
431 return 0; 434 return 0;
435 }
432 436
433 if (mgr_manual_update(mgr)) 437 if (!mp->enabled) {
438 spin_unlock_irqrestore(&data_lock, flags);
434 return 0; 439 return 0;
440 }
441
442 spin_unlock_irqrestore(&data_lock, flags);
435 443
436 r = dispc_runtime_get(); 444 r = dispc_runtime_get();
437 if (r) 445 if (r)
@@ -439,10 +447,8 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
439 447
440 irq = dispc_mgr_get_vsync_irq(mgr->id); 448 irq = dispc_mgr_get_vsync_irq(mgr->id);
441 449
442 mp = get_mgr_priv(mgr);
443 i = 0; 450 i = 0;
444 while (1) { 451 while (1) {
445 unsigned long flags;
446 bool shadow_dirty, dirty; 452 bool shadow_dirty, dirty;
447 453
448 spin_lock_irqsave(&data_lock, flags); 454 spin_lock_irqsave(&data_lock, flags);
@@ -486,21 +492,30 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
486{ 492{
487 unsigned long timeout = msecs_to_jiffies(500); 493 unsigned long timeout = msecs_to_jiffies(500);
488 struct ovl_priv_data *op; 494 struct ovl_priv_data *op;
489 struct omap_dss_device *dssdev; 495 struct mgr_priv_data *mp;
490 u32 irq; 496 u32 irq;
497 unsigned long flags;
491 int r; 498 int r;
492 int i; 499 int i;
493 500
494 if (!ovl->manager) 501 if (!ovl->manager)
495 return 0; 502 return 0;
496 503
497 dssdev = ovl->manager->device; 504 mp = get_mgr_priv(ovl->manager);
505
506 spin_lock_irqsave(&data_lock, flags);
498 507
499 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 508 if (ovl_manual_update(ovl)) {
509 spin_unlock_irqrestore(&data_lock, flags);
500 return 0; 510 return 0;
511 }
501 512
502 if (ovl_manual_update(ovl)) 513 if (!mp->enabled) {
514 spin_unlock_irqrestore(&data_lock, flags);
503 return 0; 515 return 0;
516 }
517
518 spin_unlock_irqrestore(&data_lock, flags);
504 519
505 r = dispc_runtime_get(); 520 r = dispc_runtime_get();
506 if (r) 521 if (r)
@@ -511,7 +526,6 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
511 op = get_ovl_priv(ovl); 526 op = get_ovl_priv(ovl);
512 i = 0; 527 i = 0;
513 while (1) { 528 while (1) {
514 unsigned long flags;
515 bool shadow_dirty, dirty; 529 bool shadow_dirty, dirty;
516 530
517 spin_lock_irqsave(&data_lock, flags); 531 spin_lock_irqsave(&data_lock, flags);
@@ -1096,29 +1110,29 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
1096 spin_unlock_irqrestore(&data_lock, flags); 1110 spin_unlock_irqrestore(&data_lock, flags);
1097} 1111}
1098 1112
1099int dss_mgr_set_device(struct omap_overlay_manager *mgr, 1113int dss_mgr_set_output(struct omap_overlay_manager *mgr,
1100 struct omap_dss_device *dssdev) 1114 struct omap_dss_output *output)
1101{ 1115{
1102 int r; 1116 int r;
1103 1117
1104 mutex_lock(&apply_lock); 1118 mutex_lock(&apply_lock);
1105 1119
1106 if (dssdev->manager) { 1120 if (mgr->output) {
1107 DSSERR("display '%s' already has a manager '%s'\n", 1121 DSSERR("manager %s is already connected to an output\n",
1108 dssdev->name, dssdev->manager->name); 1122 mgr->name);
1109 r = -EINVAL; 1123 r = -EINVAL;
1110 goto err; 1124 goto err;
1111 } 1125 }
1112 1126
1113 if ((mgr->supported_displays & dssdev->type) == 0) { 1127 if ((mgr->supported_outputs & output->id) == 0) {
1114 DSSERR("display '%s' does not support manager '%s'\n", 1128 DSSERR("output does not support manager %s\n",
1115 dssdev->name, mgr->name); 1129 mgr->name);
1116 r = -EINVAL; 1130 r = -EINVAL;
1117 goto err; 1131 goto err;
1118 } 1132 }
1119 1133
1120 dssdev->manager = mgr; 1134 output->manager = mgr;
1121 mgr->device = dssdev; 1135 mgr->output = output;
1122 1136
1123 mutex_unlock(&apply_lock); 1137 mutex_unlock(&apply_lock);
1124 1138
@@ -1128,35 +1142,41 @@ err:
1128 return r; 1142 return r;
1129} 1143}
1130 1144
1131int dss_mgr_unset_device(struct omap_overlay_manager *mgr) 1145int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
1132{ 1146{
1133 int r; 1147 int r;
1148 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1149 unsigned long flags;
1134 1150
1135 mutex_lock(&apply_lock); 1151 mutex_lock(&apply_lock);
1136 1152
1137 if (!mgr->device) { 1153 if (!mgr->output) {
1138 DSSERR("failed to unset display, display not set.\n"); 1154 DSSERR("failed to unset output, output not set\n");
1139 r = -EINVAL; 1155 r = -EINVAL;
1140 goto err; 1156 goto err;
1141 } 1157 }
1142 1158
1143 /* 1159 spin_lock_irqsave(&data_lock, flags);
1144 * Don't allow currently enabled displays to have the overlay manager 1160
1145 * pulled out from underneath them 1161 if (mp->enabled) {
1146 */ 1162 DSSERR("output can't be unset when manager is enabled\n");
1147 if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
1148 r = -EINVAL; 1163 r = -EINVAL;
1149 goto err; 1164 goto err1;
1150 } 1165 }
1151 1166
1152 mgr->device->manager = NULL; 1167 spin_unlock_irqrestore(&data_lock, flags);
1153 mgr->device = NULL; 1168
1169 mgr->output->manager = NULL;
1170 mgr->output = NULL;
1154 1171
1155 mutex_unlock(&apply_lock); 1172 mutex_unlock(&apply_lock);
1156 1173
1157 return 0; 1174 return 0;
1175err1:
1176 spin_unlock_irqrestore(&data_lock, flags);
1158err: 1177err:
1159 mutex_unlock(&apply_lock); 1178 mutex_unlock(&apply_lock);
1179
1160 return r; 1180 return r;
1161} 1181}
1162 1182
@@ -1380,7 +1400,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1380 goto err1; 1400 goto err1;
1381 } 1401 }
1382 1402
1383 if (ovl->manager == NULL || ovl->manager->device == NULL) { 1403 if (ovl->manager == NULL || ovl->manager->output == NULL) {
1384 r = -EINVAL; 1404 r = -EINVAL;
1385 goto err1; 1405 goto err1;
1386 } 1406 }
@@ -1430,7 +1450,7 @@ int dss_ovl_disable(struct omap_overlay *ovl)
1430 goto err; 1450 goto err;
1431 } 1451 }
1432 1452
1433 if (ovl->manager == NULL || ovl->manager->device == NULL) { 1453 if (ovl->manager == NULL || ovl->manager->output == NULL) {
1434 r = -EINVAL; 1454 r = -EINVAL;
1435 goto err; 1455 goto err;
1436 } 1456 }
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 2137d2a2cc5d..811fe381aaea 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3595,7 +3595,7 @@ static void dispc_error_worker(struct work_struct *work)
3595 bit = mgr_desc[i].sync_lost_irq; 3595 bit = mgr_desc[i].sync_lost_irq;
3596 3596
3597 if (bit & errors) { 3597 if (bit & errors) {
3598 struct omap_dss_device *dssdev = mgr->device; 3598 struct omap_dss_device *dssdev = mgr->get_device(mgr);
3599 bool enable; 3599 bool enable;
3600 3600
3601 DSSERR("SYNC_LOST on channel %s, restarting the output " 3601 DSSERR("SYNC_LOST on channel %s, restarting the output "
@@ -3626,9 +3626,13 @@ static void dispc_error_worker(struct work_struct *work)
3626 DSSERR("OCP_ERR\n"); 3626 DSSERR("OCP_ERR\n");
3627 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { 3627 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
3628 struct omap_overlay_manager *mgr; 3628 struct omap_overlay_manager *mgr;
3629 struct omap_dss_device *dssdev;
3630
3629 mgr = omap_dss_get_overlay_manager(i); 3631 mgr = omap_dss_get_overlay_manager(i);
3630 if (mgr->device && mgr->device->driver) 3632 dssdev = mgr->get_device(mgr);
3631 mgr->device->driver->disable(mgr->device); 3633
3634 if (dssdev && dssdev->driver)
3635 dssdev->driver->disable(dssdev);
3632 } 3636 }
3633 } 3637 }
3634 3638
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index db83ae81a713..ccf8550fafde 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -327,22 +327,35 @@ EXPORT_SYMBOL(omapdss_default_get_timings);
327 */ 327 */
328static int dss_init_connections(struct omap_dss_device *dssdev, bool force) 328static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
329{ 329{
330 struct omap_dss_output *out;
330 struct omap_overlay_manager *mgr; 331 struct omap_overlay_manager *mgr;
331 int i, r; 332 int i, r;
332 333
333 WARN_ON(dssdev->manager); 334 out = omapdss_get_output_from_dssdev(dssdev);
335
336 WARN_ON(dssdev->output);
337 WARN_ON(out->device);
338
339 r = omapdss_output_set_device(out, dssdev);
340 if (r) {
341 DSSERR("failed to connect output to new device\n");
342 return r;
343 }
334 344
335 mgr = omap_dss_get_overlay_manager(dssdev->channel); 345 mgr = omap_dss_get_overlay_manager(dssdev->channel);
336 346
337 if (mgr->device && !force) 347 if (mgr->output && !force)
338 return 0; 348 return 0;
339 349
340 if (mgr->device) 350 if (mgr->output)
341 mgr->unset_device(mgr); 351 mgr->unset_output(mgr);
342 352
343 r = mgr->set_device(mgr, dssdev); 353 r = mgr->set_output(mgr, out);
344 if (r) { 354 if (r) {
345 DSSERR("failed to set initial manager\n"); 355 DSSERR("failed to connect manager to output of new device\n");
356
357 /* remove the output-device connection we just made */
358 omapdss_output_unset_device(out);
346 return r; 359 return r;
347 } 360 }
348 361
@@ -366,8 +379,14 @@ static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
366 379
367static void dss_uninit_connections(struct omap_dss_device *dssdev) 380static void dss_uninit_connections(struct omap_dss_device *dssdev)
368{ 381{
369 if (dssdev->manager) 382 if (dssdev->output) {
370 dssdev->manager->unset_device(dssdev->manager); 383 struct omap_overlay_manager *mgr = dssdev->output->manager;
384
385 if (mgr)
386 mgr->unset_output(mgr);
387
388 omapdss_output_unset_device(dssdev->output);
389 }
371} 390}
372 391
373int dss_init_device(struct platform_device *pdev, 392int dss_init_device(struct platform_device *pdev,
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index f6800e19bbcb..d73a549050e4 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -44,6 +44,8 @@ static struct {
44 struct omap_video_timings timings; 44 struct omap_video_timings timings;
45 struct dss_lcd_mgr_config mgr_config; 45 struct dss_lcd_mgr_config mgr_config;
46 int data_lines; 46 int data_lines;
47
48 struct omap_dss_output output;
47} dpi; 49} dpi;
48 50
49static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk) 51static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
@@ -126,6 +128,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
126static int dpi_set_mode(struct omap_dss_device *dssdev) 128static int dpi_set_mode(struct omap_dss_device *dssdev)
127{ 129{
128 struct omap_video_timings *t = &dpi.timings; 130 struct omap_video_timings *t = &dpi.timings;
131 struct omap_overlay_manager *mgr = dssdev->output->manager;
129 int lck_div = 0, pck_div = 0; 132 int lck_div = 0, pck_div = 0;
130 unsigned long fck = 0; 133 unsigned long fck = 0;
131 unsigned long pck; 134 unsigned long pck;
@@ -150,13 +153,15 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
150 t->pixel_clock = pck; 153 t->pixel_clock = pck;
151 } 154 }
152 155
153 dss_mgr_set_timings(dssdev->manager, t); 156 dss_mgr_set_timings(mgr, t);
154 157
155 return 0; 158 return 0;
156} 159}
157 160
158static void dpi_config_lcd_manager(struct omap_dss_device *dssdev) 161static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
159{ 162{
163 struct omap_overlay_manager *mgr = dssdev->output->manager;
164
160 dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; 165 dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
161 166
162 dpi.mgr_config.stallmode = false; 167 dpi.mgr_config.stallmode = false;
@@ -166,11 +171,12 @@ static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
166 171
167 dpi.mgr_config.lcden_sig_polarity = 0; 172 dpi.mgr_config.lcden_sig_polarity = 0;
168 173
169 dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config); 174 dss_mgr_set_lcd_config(mgr, &dpi.mgr_config);
170} 175}
171 176
172int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) 177int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
173{ 178{
179 struct omap_dss_output *out = dssdev->output;
174 int r; 180 int r;
175 181
176 mutex_lock(&dpi.lock); 182 mutex_lock(&dpi.lock);
@@ -181,10 +187,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
181 goto err_no_reg; 187 goto err_no_reg;
182 } 188 }
183 189
184 if (dssdev->manager == NULL) { 190 if (out == NULL || out->manager == NULL) {
185 DSSERR("failed to enable display: no manager\n"); 191 DSSERR("failed to enable display: no output/manager\n");
186 r = -ENODEV; 192 r = -ENODEV;
187 goto err_no_mgr; 193 goto err_no_out_mgr;
188 } 194 }
189 195
190 r = omap_dss_start_device(dssdev); 196 r = omap_dss_start_device(dssdev);
@@ -225,7 +231,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
225 231
226 mdelay(2); 232 mdelay(2);
227 233
228 r = dss_mgr_enable(dssdev->manager); 234 r = dss_mgr_enable(out->manager);
229 if (r) 235 if (r)
230 goto err_mgr_enable; 236 goto err_mgr_enable;
231 237
@@ -249,7 +255,7 @@ err_get_dispc:
249err_reg_enable: 255err_reg_enable:
250 omap_dss_stop_device(dssdev); 256 omap_dss_stop_device(dssdev);
251err_start_dev: 257err_start_dev:
252err_no_mgr: 258err_no_out_mgr:
253err_no_reg: 259err_no_reg:
254 mutex_unlock(&dpi.lock); 260 mutex_unlock(&dpi.lock);
255 return r; 261 return r;
@@ -258,9 +264,11 @@ EXPORT_SYMBOL(omapdss_dpi_display_enable);
258 264
259void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) 265void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
260{ 266{
267 struct omap_overlay_manager *mgr = dssdev->output->manager;
268
261 mutex_lock(&dpi.lock); 269 mutex_lock(&dpi.lock);
262 270
263 dss_mgr_disable(dssdev->manager); 271 dss_mgr_disable(mgr);
264 272
265 if (dpi_use_dsi_pll(dssdev)) { 273 if (dpi_use_dsi_pll(dssdev)) {
266 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); 274 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
@@ -296,12 +304,13 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
296 struct omap_video_timings *timings) 304 struct omap_video_timings *timings)
297{ 305{
298 int r; 306 int r;
307 struct omap_overlay_manager *mgr = dssdev->output->manager;
299 int lck_div, pck_div; 308 int lck_div, pck_div;
300 unsigned long fck; 309 unsigned long fck;
301 unsigned long pck; 310 unsigned long pck;
302 struct dispc_clock_info dispc_cinfo; 311 struct dispc_clock_info dispc_cinfo;
303 312
304 if (dss_mgr_check_timings(dssdev->manager, timings)) 313 if (dss_mgr_check_timings(mgr, timings))
305 return -EINVAL; 314 return -EINVAL;
306 315
307 if (timings->pixel_clock == 0) 316 if (timings->pixel_clock == 0)
@@ -436,10 +445,30 @@ static void __init dpi_probe_pdata(struct platform_device *dpidev)
436 } 445 }
437} 446}
438 447
448static void __init dpi_init_output(struct platform_device *pdev)
449{
450 struct omap_dss_output *out = &dpi.output;
451
452 out->pdev = pdev;
453 out->id = OMAP_DSS_OUTPUT_DPI;
454 out->type = OMAP_DISPLAY_TYPE_DPI;
455
456 dss_register_output(out);
457}
458
459static void __exit dpi_uninit_output(struct platform_device *pdev)
460{
461 struct omap_dss_output *out = &dpi.output;
462
463 dss_unregister_output(out);
464}
465
439static int __init omap_dpi_probe(struct platform_device *pdev) 466static int __init omap_dpi_probe(struct platform_device *pdev)
440{ 467{
441 mutex_init(&dpi.lock); 468 mutex_init(&dpi.lock);
442 469
470 dpi_init_output(pdev);
471
443 dpi_probe_pdata(pdev); 472 dpi_probe_pdata(pdev);
444 473
445 return 0; 474 return 0;
@@ -449,6 +478,8 @@ static int __exit omap_dpi_remove(struct platform_device *pdev)
449{ 478{
450 dss_unregister_child_devices(&pdev->dev); 479 dss_unregister_child_devices(&pdev->dev);
451 480
481 dpi_uninit_output(pdev);
482
452 return 0; 483 return 0;
453} 484}
454 485
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index abe335abca53..e37e6d868acd 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -336,6 +336,8 @@ struct dsi_data {
336 enum omap_dss_dsi_pixel_format pix_fmt; 336 enum omap_dss_dsi_pixel_format pix_fmt;
337 enum omap_dss_dsi_mode mode; 337 enum omap_dss_dsi_mode mode;
338 struct omap_dss_dsi_videomode_timings vm_timings; 338 struct omap_dss_dsi_videomode_timings vm_timings;
339
340 struct omap_dss_output output;
339}; 341};
340 342
341struct dsi_packet_sent_handler_data { 343struct dsi_packet_sent_handler_data {
@@ -343,8 +345,6 @@ struct dsi_packet_sent_handler_data {
343 struct completion *completion; 345 struct completion *completion;
344}; 346};
345 347
346static struct platform_device *dsi_pdev_map[MAX_NUM_DSI];
347
348#ifdef DEBUG 348#ifdef DEBUG
349static bool dsi_perf; 349static bool dsi_perf;
350module_param(dsi_perf, bool, 0644); 350module_param(dsi_perf, bool, 0644);
@@ -357,12 +357,19 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside
357 357
358static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev) 358static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev)
359{ 359{
360 return dsi_pdev_map[dssdev->phy.dsi.module]; 360 return dssdev->output->pdev;
361} 361}
362 362
363struct platform_device *dsi_get_dsidev_from_id(int module) 363struct platform_device *dsi_get_dsidev_from_id(int module)
364{ 364{
365 return dsi_pdev_map[module]; 365 struct omap_dss_output *out;
366 enum omap_dss_output_id id;
367
368 id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
369
370 out = omap_dss_get_output(id);
371
372 return out->pdev;
366} 373}
367 374
368static inline void dsi_write_reg(struct platform_device *dsidev, 375static inline void dsi_write_reg(struct platform_device *dsidev,
@@ -2163,9 +2170,8 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
2163 } 2170 }
2164} 2171}
2165 2172
2166static int dsi_set_lane_config(struct omap_dss_device *dssdev) 2173static int dsi_set_lane_config(struct platform_device *dsidev)
2167{ 2174{
2168 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2169 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 2175 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2170 static const u8 offsets[] = { 0, 4, 8, 12, 16 }; 2176 static const u8 offsets[] = { 0, 4, 8, 12, 16 };
2171 static const enum dsi_lane_function functions[] = { 2177 static const enum dsi_lane_function functions[] = {
@@ -2307,10 +2313,9 @@ static void dsi_cio_timings(struct platform_device *dsidev)
2307} 2313}
2308 2314
2309/* lane masks have lane 0 at lsb. mask_p for positive lines, n for negative */ 2315/* lane masks have lane 0 at lsb. mask_p for positive lines, n for negative */
2310static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev, 2316static void dsi_cio_enable_lane_override(struct platform_device *dsidev,
2311 unsigned mask_p, unsigned mask_n) 2317 unsigned mask_p, unsigned mask_n)
2312{ 2318{
2313 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2314 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 2319 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2315 int i; 2320 int i;
2316 u32 l; 2321 u32 l;
@@ -2357,9 +2362,8 @@ static void dsi_cio_disable_lane_override(struct platform_device *dsidev)
2357 REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 22, 17); 2362 REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 22, 17);
2358} 2363}
2359 2364
2360static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev) 2365static int dsi_cio_wait_tx_clk_esc_reset(struct platform_device *dsidev)
2361{ 2366{
2362 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2363 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 2367 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2364 int t, i; 2368 int t, i;
2365 bool in_use[DSI_MAX_NR_LANES]; 2369 bool in_use[DSI_MAX_NR_LANES];
@@ -2407,9 +2411,8 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
2407} 2411}
2408 2412
2409/* return bitmask of enabled lanes, lane0 being the lsb */ 2413/* return bitmask of enabled lanes, lane0 being the lsb */
2410static unsigned dsi_get_lane_mask(struct omap_dss_device *dssdev) 2414static unsigned dsi_get_lane_mask(struct platform_device *dsidev)
2411{ 2415{
2412 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2413 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 2416 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2414 unsigned mask = 0; 2417 unsigned mask = 0;
2415 int i; 2418 int i;
@@ -2422,16 +2425,15 @@ static unsigned dsi_get_lane_mask(struct omap_dss_device *dssdev)
2422 return mask; 2425 return mask;
2423} 2426}
2424 2427
2425static int dsi_cio_init(struct omap_dss_device *dssdev) 2428static int dsi_cio_init(struct platform_device *dsidev)
2426{ 2429{
2427 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2428 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 2430 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2429 int r; 2431 int r;
2430 u32 l; 2432 u32 l;
2431 2433
2432 DSSDBGF(); 2434 DSSDBGF();
2433 2435
2434 r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); 2436 r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
2435 if (r) 2437 if (r)
2436 return r; 2438 return r;
2437 2439
@@ -2448,7 +2450,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
2448 goto err_scp_clk_dom; 2450 goto err_scp_clk_dom;
2449 } 2451 }
2450 2452
2451 r = dsi_set_lane_config(dssdev); 2453 r = dsi_set_lane_config(dsidev);
2452 if (r) 2454 if (r)
2453 goto err_scp_clk_dom; 2455 goto err_scp_clk_dom;
2454 2456
@@ -2483,7 +2485,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
2483 mask_p |= 1 << i; 2485 mask_p |= 1 << i;
2484 } 2486 }
2485 2487
2486 dsi_cio_enable_lane_override(dssdev, mask_p, 0); 2488 dsi_cio_enable_lane_override(dsidev, mask_p, 0);
2487 } 2489 }
2488 2490
2489 r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON); 2491 r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON);
@@ -2500,7 +2502,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
2500 dsi_if_enable(dsidev, false); 2502 dsi_if_enable(dsidev, false);
2501 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */ 2503 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */
2502 2504
2503 r = dsi_cio_wait_tx_clk_esc_reset(dssdev); 2505 r = dsi_cio_wait_tx_clk_esc_reset(dsidev);
2504 if (r) 2506 if (r)
2505 goto err_tx_clk_esc_rst; 2507 goto err_tx_clk_esc_rst;
2506 2508
@@ -2541,13 +2543,12 @@ err_cio_pwr:
2541 dsi_cio_disable_lane_override(dsidev); 2543 dsi_cio_disable_lane_override(dsidev);
2542err_scp_clk_dom: 2544err_scp_clk_dom:
2543 dsi_disable_scp_clk(dsidev); 2545 dsi_disable_scp_clk(dsidev);
2544 dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); 2546 dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
2545 return r; 2547 return r;
2546} 2548}
2547 2549
2548static void dsi_cio_uninit(struct omap_dss_device *dssdev) 2550static void dsi_cio_uninit(struct platform_device *dsidev)
2549{ 2551{
2550 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2551 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 2552 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2552 2553
2553 /* DDR_CLK_ALWAYS_ON */ 2554 /* DDR_CLK_ALWAYS_ON */
@@ -2555,7 +2556,7 @@ static void dsi_cio_uninit(struct omap_dss_device *dssdev)
2555 2556
2556 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); 2557 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
2557 dsi_disable_scp_clk(dsidev); 2558 dsi_disable_scp_clk(dsidev);
2558 dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); 2559 dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
2559} 2560}
2560 2561
2561static void dsi_config_tx_fifo(struct platform_device *dsidev, 2562static void dsi_config_tx_fifo(struct platform_device *dsidev,
@@ -3148,10 +3149,9 @@ int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel)
3148} 3149}
3149EXPORT_SYMBOL(dsi_vc_send_null); 3150EXPORT_SYMBOL(dsi_vc_send_null);
3150 3151
3151static int dsi_vc_write_nosync_common(struct omap_dss_device *dssdev, 3152static int dsi_vc_write_nosync_common(struct platform_device *dsidev,
3152 int channel, u8 *data, int len, enum dss_dsi_content_type type) 3153 int channel, u8 *data, int len, enum dss_dsi_content_type type)
3153{ 3154{
3154 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3155 int r; 3155 int r;
3156 3156
3157 if (len == 0) { 3157 if (len == 0) {
@@ -3182,7 +3182,9 @@ static int dsi_vc_write_nosync_common(struct omap_dss_device *dssdev,
3182int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, 3182int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
3183 u8 *data, int len) 3183 u8 *data, int len)
3184{ 3184{
3185 return dsi_vc_write_nosync_common(dssdev, channel, data, len, 3185 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3186
3187 return dsi_vc_write_nosync_common(dsidev, channel, data, len,
3186 DSS_DSI_CONTENT_DCS); 3188 DSS_DSI_CONTENT_DCS);
3187} 3189}
3188EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); 3190EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
@@ -3190,7 +3192,9 @@ EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
3190int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel, 3192int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
3191 u8 *data, int len) 3193 u8 *data, int len)
3192{ 3194{
3193 return dsi_vc_write_nosync_common(dssdev, channel, data, len, 3195 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3196
3197 return dsi_vc_write_nosync_common(dsidev, channel, data, len,
3194 DSS_DSI_CONTENT_GENERIC); 3198 DSS_DSI_CONTENT_GENERIC);
3195} 3199}
3196EXPORT_SYMBOL(dsi_vc_generic_write_nosync); 3200EXPORT_SYMBOL(dsi_vc_generic_write_nosync);
@@ -3201,7 +3205,7 @@ static int dsi_vc_write_common(struct omap_dss_device *dssdev, int channel,
3201 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3205 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3202 int r; 3206 int r;
3203 3207
3204 r = dsi_vc_write_nosync_common(dssdev, channel, data, len, type); 3208 r = dsi_vc_write_nosync_common(dsidev, channel, data, len, type);
3205 if (r) 3209 if (r)
3206 goto err; 3210 goto err;
3207 3211
@@ -3279,10 +3283,9 @@ int dsi_vc_generic_write_2(struct omap_dss_device *dssdev, int channel,
3279} 3283}
3280EXPORT_SYMBOL(dsi_vc_generic_write_2); 3284EXPORT_SYMBOL(dsi_vc_generic_write_2);
3281 3285
3282static int dsi_vc_dcs_send_read_request(struct omap_dss_device *dssdev, 3286static int dsi_vc_dcs_send_read_request(struct platform_device *dsidev,
3283 int channel, u8 dcs_cmd) 3287 int channel, u8 dcs_cmd)
3284{ 3288{
3285 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3286 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 3289 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3287 int r; 3290 int r;
3288 3291
@@ -3300,10 +3303,9 @@ static int dsi_vc_dcs_send_read_request(struct omap_dss_device *dssdev,
3300 return 0; 3303 return 0;
3301} 3304}
3302 3305
3303static int dsi_vc_generic_send_read_request(struct omap_dss_device *dssdev, 3306static int dsi_vc_generic_send_read_request(struct platform_device *dsidev,
3304 int channel, u8 *reqdata, int reqlen) 3307 int channel, u8 *reqdata, int reqlen)
3305{ 3308{
3306 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3307 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 3309 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3308 u16 data; 3310 u16 data;
3309 u8 data_type; 3311 u8 data_type;
@@ -3452,7 +3454,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3452 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3454 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3453 int r; 3455 int r;
3454 3456
3455 r = dsi_vc_dcs_send_read_request(dssdev, channel, dcs_cmd); 3457 r = dsi_vc_dcs_send_read_request(dsidev, channel, dcs_cmd);
3456 if (r) 3458 if (r)
3457 goto err; 3459 goto err;
3458 3460
@@ -3483,7 +3485,7 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel,
3483 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3485 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3484 int r; 3486 int r;
3485 3487
3486 r = dsi_vc_generic_send_read_request(dssdev, channel, reqdata, reqlen); 3488 r = dsi_vc_generic_send_read_request(dsidev, channel, reqdata, reqlen);
3487 if (r) 3489 if (r)
3488 return r; 3490 return r;
3489 3491
@@ -3765,14 +3767,12 @@ static void dsi_set_hs_tx_timeout(struct platform_device *dsidev,
3765 (total_ticks * 1000) / (fck / 1000 / 1000)); 3767 (total_ticks * 1000) / (fck / 1000 / 1000));
3766} 3768}
3767 3769
3768static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev) 3770static void dsi_config_vp_num_line_buffers(struct platform_device *dsidev)
3769{ 3771{
3770 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3771 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 3772 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3772 int num_line_buffers; 3773 int num_line_buffers;
3773 3774
3774 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 3775 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
3775 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3776 int bpp = dsi_get_pixel_size(dsi->pix_fmt); 3776 int bpp = dsi_get_pixel_size(dsi->pix_fmt);
3777 unsigned line_buf_size = dsi_get_line_buf_size(dsidev); 3777 unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
3778 struct omap_video_timings *timings = &dsi->timings; 3778 struct omap_video_timings *timings = &dsi->timings;
@@ -3793,9 +3793,8 @@ static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev)
3793 REG_FLD_MOD(dsidev, DSI_CTRL, num_line_buffers, 13, 12); 3793 REG_FLD_MOD(dsidev, DSI_CTRL, num_line_buffers, 13, 12);
3794} 3794}
3795 3795
3796static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev) 3796static void dsi_config_vp_sync_events(struct platform_device *dsidev)
3797{ 3797{
3798 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3799 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 3798 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3800 bool vsync_end = dsi->vm_timings.vp_vsync_end; 3799 bool vsync_end = dsi->vm_timings.vp_vsync_end;
3801 bool hsync_end = dsi->vm_timings.vp_hsync_end; 3800 bool hsync_end = dsi->vm_timings.vp_hsync_end;
@@ -3812,9 +3811,8 @@ static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev)
3812 dsi_write_reg(dsidev, DSI_CTRL, r); 3811 dsi_write_reg(dsidev, DSI_CTRL, r);
3813} 3812}
3814 3813
3815static void dsi_config_blanking_modes(struct omap_dss_device *dssdev) 3814static void dsi_config_blanking_modes(struct platform_device *dsidev)
3816{ 3815{
3817 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3818 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 3816 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3819 int blanking_mode = dsi->vm_timings.blanking_mode; 3817 int blanking_mode = dsi->vm_timings.blanking_mode;
3820 int hfp_blanking_mode = dsi->vm_timings.hfp_blanking_mode; 3818 int hfp_blanking_mode = dsi->vm_timings.hfp_blanking_mode;
@@ -4069,11 +4067,11 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
4069 4067
4070 dsi_write_reg(dsidev, DSI_CTRL, r); 4068 dsi_write_reg(dsidev, DSI_CTRL, r);
4071 4069
4072 dsi_config_vp_num_line_buffers(dssdev); 4070 dsi_config_vp_num_line_buffers(dsidev);
4073 4071
4074 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 4072 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
4075 dsi_config_vp_sync_events(dssdev); 4073 dsi_config_vp_sync_events(dsidev);
4076 dsi_config_blanking_modes(dssdev); 4074 dsi_config_blanking_modes(dsidev);
4077 dsi_config_cmd_mode_interleaving(dssdev); 4075 dsi_config_cmd_mode_interleaving(dssdev);
4078 } 4076 }
4079 4077
@@ -4085,9 +4083,8 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
4085 return 0; 4083 return 0;
4086} 4084}
4087 4085
4088static void dsi_proto_timings(struct omap_dss_device *dssdev) 4086static void dsi_proto_timings(struct platform_device *dsidev)
4089{ 4087{
4090 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4091 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4088 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4092 unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail; 4089 unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail;
4093 unsigned tclk_pre, tclk_post; 4090 unsigned tclk_pre, tclk_post;
@@ -4336,6 +4333,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
4336{ 4333{
4337 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4334 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4338 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4335 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4336 struct omap_overlay_manager *mgr = dssdev->output->manager;
4339 int bpp = dsi_get_pixel_size(dsi->pix_fmt); 4337 int bpp = dsi_get_pixel_size(dsi->pix_fmt);
4340 u8 data_type; 4338 u8 data_type;
4341 u16 word_count; 4339 u16 word_count;
@@ -4375,7 +4373,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
4375 dsi_if_enable(dsidev, true); 4373 dsi_if_enable(dsidev, true);
4376 } 4374 }
4377 4375
4378 r = dss_mgr_enable(dssdev->manager); 4376 r = dss_mgr_enable(mgr);
4379 if (r) { 4377 if (r) {
4380 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 4378 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
4381 dsi_if_enable(dsidev, false); 4379 dsi_if_enable(dsidev, false);
@@ -4393,6 +4391,7 @@ void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
4393{ 4391{
4394 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4392 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4395 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4393 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4394 struct omap_overlay_manager *mgr = dssdev->output->manager;
4396 4395
4397 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 4396 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
4398 dsi_if_enable(dsidev, false); 4397 dsi_if_enable(dsidev, false);
@@ -4405,7 +4404,7 @@ void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
4405 dsi_if_enable(dsidev, true); 4404 dsi_if_enable(dsidev, true);
4406 } 4405 }
4407 4406
4408 dss_mgr_disable(dssdev->manager); 4407 dss_mgr_disable(mgr);
4409} 4408}
4410EXPORT_SYMBOL(dsi_disable_video_output); 4409EXPORT_SYMBOL(dsi_disable_video_output);
4411 4410
@@ -4413,6 +4412,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev)
4413{ 4412{
4414 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4413 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4415 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4414 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4415 struct omap_overlay_manager *mgr = dssdev->output->manager;
4416 unsigned bytespp; 4416 unsigned bytespp;
4417 unsigned bytespl; 4417 unsigned bytespl;
4418 unsigned bytespf; 4418 unsigned bytespf;
@@ -4474,9 +4474,9 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev)
4474 msecs_to_jiffies(250)); 4474 msecs_to_jiffies(250));
4475 BUG_ON(r == 0); 4475 BUG_ON(r == 0);
4476 4476
4477 dss_mgr_set_timings(dssdev->manager, &dsi->timings); 4477 dss_mgr_set_timings(mgr, &dsi->timings);
4478 4478
4479 dss_mgr_start_update(dssdev->manager); 4479 dss_mgr_start_update(mgr);
4480 4480
4481 if (dsi->te_enabled) { 4481 if (dsi->te_enabled) {
4482 /* disable LP_RX_TO, so that we can receive TE. Time to wait 4482 /* disable LP_RX_TO, so that we can receive TE. Time to wait
@@ -4534,8 +4534,7 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)
4534 4534
4535static void dsi_framedone_irq_callback(void *data, u32 mask) 4535static void dsi_framedone_irq_callback(void *data, u32 mask)
4536{ 4536{
4537 struct omap_dss_device *dssdev = (struct omap_dss_device *) data; 4537 struct platform_device *dsidev = (struct platform_device *) data;
4538 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4539 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4538 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4540 4539
4541 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and 4540 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and
@@ -4605,6 +4604,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4605{ 4604{
4606 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4605 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4607 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4606 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4607 struct omap_overlay_manager *mgr = dssdev->output->manager;
4608 int r; 4608 int r;
4609 u32 irq = 0; 4609 u32 irq = 0;
4610 4610
@@ -4616,10 +4616,10 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4616 dsi->timings.vfp = 0; 4616 dsi->timings.vfp = 0;
4617 dsi->timings.vbp = 0; 4617 dsi->timings.vbp = 0;
4618 4618
4619 irq = dispc_mgr_get_framedone_irq(dssdev->manager->id); 4619 irq = dispc_mgr_get_framedone_irq(mgr->id);
4620 4620
4621 r = omap_dispc_register_isr(dsi_framedone_irq_callback, 4621 r = omap_dispc_register_isr(dsi_framedone_irq_callback,
4622 (void *) dssdev, irq); 4622 (void *) dsidev, irq);
4623 if (r) { 4623 if (r) {
4624 DSSERR("can't get FRAMEDONE irq\n"); 4624 DSSERR("can't get FRAMEDONE irq\n");
4625 goto err; 4625 goto err;
@@ -4643,7 +4643,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4643 dsi->timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH; 4643 dsi->timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
4644 dsi->timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; 4644 dsi->timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
4645 4645
4646 dss_mgr_set_timings(dssdev->manager, &dsi->timings); 4646 dss_mgr_set_timings(mgr, &dsi->timings);
4647 4647
4648 r = dsi_configure_dispc_clocks(dssdev); 4648 r = dsi_configure_dispc_clocks(dssdev);
4649 if (r) 4649 if (r)
@@ -4654,13 +4654,13 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4654 dsi_get_pixel_size(dsi->pix_fmt); 4654 dsi_get_pixel_size(dsi->pix_fmt);
4655 dsi->mgr_config.lcden_sig_polarity = 0; 4655 dsi->mgr_config.lcden_sig_polarity = 0;
4656 4656
4657 dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config); 4657 dss_mgr_set_lcd_config(mgr, &dsi->mgr_config);
4658 4658
4659 return 0; 4659 return 0;
4660err1: 4660err1:
4661 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) 4661 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
4662 omap_dispc_unregister_isr(dsi_framedone_irq_callback, 4662 omap_dispc_unregister_isr(dsi_framedone_irq_callback,
4663 (void *) dssdev, irq); 4663 (void *) dsidev, irq);
4664err: 4664err:
4665 return r; 4665 return r;
4666} 4666}
@@ -4669,14 +4669,15 @@ static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
4669{ 4669{
4670 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4670 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4671 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4671 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4672 struct omap_overlay_manager *mgr = dssdev->output->manager;
4672 4673
4673 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { 4674 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
4674 u32 irq; 4675 u32 irq;
4675 4676
4676 irq = dispc_mgr_get_framedone_irq(dssdev->manager->id); 4677 irq = dispc_mgr_get_framedone_irq(mgr->id);
4677 4678
4678 omap_dispc_unregister_isr(dsi_framedone_irq_callback, 4679 omap_dispc_unregister_isr(dsi_framedone_irq_callback,
4679 (void *) dssdev, irq); 4680 (void *) dsidev, irq);
4680 } 4681 }
4681} 4682}
4682 4683
@@ -4709,6 +4710,7 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
4709{ 4710{
4710 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4711 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4711 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4712 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4713 struct omap_overlay_manager *mgr = dssdev->output->manager;
4712 int r; 4714 int r;
4713 4715
4714 r = dsi_pll_init(dsidev, true, true); 4716 r = dsi_pll_init(dsidev, true, true);
@@ -4721,18 +4723,18 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
4721 4723
4722 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); 4724 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
4723 dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src); 4725 dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src);
4724 dss_select_lcd_clk_source(dssdev->manager->id, 4726 dss_select_lcd_clk_source(mgr->id,
4725 dssdev->clocks.dispc.channel.lcd_clk_src); 4727 dssdev->clocks.dispc.channel.lcd_clk_src);
4726 4728
4727 DSSDBG("PLL OK\n"); 4729 DSSDBG("PLL OK\n");
4728 4730
4729 r = dsi_cio_init(dssdev); 4731 r = dsi_cio_init(dsidev);
4730 if (r) 4732 if (r)
4731 goto err2; 4733 goto err2;
4732 4734
4733 _dsi_print_reset_status(dsidev); 4735 _dsi_print_reset_status(dsidev);
4734 4736
4735 dsi_proto_timings(dssdev); 4737 dsi_proto_timings(dsidev);
4736 dsi_set_lp_clk_divisor(dssdev); 4738 dsi_set_lp_clk_divisor(dssdev);
4737 4739
4738 if (1) 4740 if (1)
@@ -4752,11 +4754,11 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
4752 4754
4753 return 0; 4755 return 0;
4754err3: 4756err3:
4755 dsi_cio_uninit(dssdev); 4757 dsi_cio_uninit(dsidev);
4756err2: 4758err2:
4757 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); 4759 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
4758 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); 4760 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
4759 dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK); 4761 dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
4760 4762
4761err1: 4763err1:
4762 dsi_pll_uninit(dsidev, true); 4764 dsi_pll_uninit(dsidev, true);
@@ -4769,6 +4771,7 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
4769{ 4771{
4770 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4772 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4771 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4773 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4774 struct omap_overlay_manager *mgr = dssdev->output->manager;
4772 4775
4773 if (enter_ulps && !dsi->ulps_enabled) 4776 if (enter_ulps && !dsi->ulps_enabled)
4774 dsi_enter_ulps(dsidev); 4777 dsi_enter_ulps(dsidev);
@@ -4782,8 +4785,8 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
4782 4785
4783 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); 4786 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
4784 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); 4787 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
4785 dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK); 4788 dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
4786 dsi_cio_uninit(dssdev); 4789 dsi_cio_uninit(dsidev);
4787 dsi_pll_uninit(dsidev, disconnect_lanes); 4790 dsi_pll_uninit(dsidev, disconnect_lanes);
4788} 4791}
4789 4792
@@ -4791,6 +4794,7 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
4791{ 4794{
4792 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4795 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4793 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4796 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4797 struct omap_dss_output *out = dssdev->output;
4794 int r = 0; 4798 int r = 0;
4795 4799
4796 DSSDBG("dsi_display_enable\n"); 4800 DSSDBG("dsi_display_enable\n");
@@ -4799,8 +4803,8 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
4799 4803
4800 mutex_lock(&dsi->lock); 4804 mutex_lock(&dsi->lock);
4801 4805
4802 if (dssdev->manager == NULL) { 4806 if (out == NULL || out->manager == NULL) {
4803 DSSERR("failed to enable display: no manager\n"); 4807 DSSERR("failed to enable display: no output/manager\n");
4804 r = -ENODEV; 4808 r = -ENODEV;
4805 goto err_start_dev; 4809 goto err_start_dev;
4806 } 4810 }
@@ -4957,7 +4961,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_videomode_timings);
4957 4961
4958static int __init dsi_init_display(struct omap_dss_device *dssdev) 4962static int __init dsi_init_display(struct omap_dss_device *dssdev)
4959{ 4963{
4960 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4964 struct platform_device *dsidev =
4965 dsi_get_dsidev_from_id(dssdev->phy.dsi.module);
4961 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4966 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4962 4967
4963 DSSDBG("DSI init\n"); 4968 DSSDBG("DSI init\n");
@@ -5167,6 +5172,28 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
5167 } 5172 }
5168} 5173}
5169 5174
5175static void __init dsi_init_output(struct platform_device *dsidev)
5176{
5177 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
5178 struct omap_dss_output *out = &dsi->output;
5179
5180 out->pdev = dsidev;
5181 out->id = dsi->module_id == 0 ?
5182 OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
5183
5184 out->type = OMAP_DISPLAY_TYPE_DSI;
5185
5186 dss_register_output(out);
5187}
5188
5189static void __exit dsi_uninit_output(struct platform_device *dsidev)
5190{
5191 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
5192 struct omap_dss_output *out = &dsi->output;
5193
5194 dss_unregister_output(out);
5195}
5196
5170/* DSI1 HW IP initialisation */ 5197/* DSI1 HW IP initialisation */
5171static int __init omap_dsihw_probe(struct platform_device *dsidev) 5198static int __init omap_dsihw_probe(struct platform_device *dsidev)
5172{ 5199{
@@ -5181,7 +5208,6 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
5181 5208
5182 dsi->module_id = dsidev->id; 5209 dsi->module_id = dsidev->id;
5183 dsi->pdev = dsidev; 5210 dsi->pdev = dsidev;
5184 dsi_pdev_map[dsi->module_id] = dsidev;
5185 dev_set_drvdata(&dsidev->dev, dsi); 5211 dev_set_drvdata(&dsidev->dev, dsi);
5186 5212
5187 spin_lock_init(&dsi->irq_lock); 5213 spin_lock_init(&dsi->irq_lock);
@@ -5261,6 +5287,8 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
5261 else 5287 else
5262 dsi->num_lanes_supported = 3; 5288 dsi->num_lanes_supported = 3;
5263 5289
5290 dsi_init_output(dsidev);
5291
5264 dsi_probe_pdata(dsidev); 5292 dsi_probe_pdata(dsidev);
5265 5293
5266 dsi_runtime_put(dsidev); 5294 dsi_runtime_put(dsidev);
@@ -5292,6 +5320,8 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
5292 5320
5293 dss_unregister_child_devices(&dsidev->dev); 5321 dss_unregister_child_devices(&dsidev->dev);
5294 5322
5323 dsi_uninit_output(dsidev);
5324
5295 pm_runtime_disable(&dsidev->dev); 5325 pm_runtime_disable(&dsidev->dev);
5296 5326
5297 dsi_put_clocks(dsidev); 5327 dsi_put_clocks(dsidev);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 40c36cafec6e..a14528bcfeab 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -209,6 +209,9 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
209int dss_mgr_set_device(struct omap_overlay_manager *mgr, 209int dss_mgr_set_device(struct omap_overlay_manager *mgr,
210 struct omap_dss_device *dssdev); 210 struct omap_dss_device *dssdev);
211int dss_mgr_unset_device(struct omap_overlay_manager *mgr); 211int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
212int dss_mgr_set_output(struct omap_overlay_manager *mgr,
213 struct omap_dss_output *output);
214int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
212void dss_mgr_set_timings(struct omap_overlay_manager *mgr, 215void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
213 const struct omap_video_timings *timings); 216 const struct omap_video_timings *timings);
214void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, 217void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
@@ -226,6 +229,11 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
226 struct omap_overlay_manager *mgr); 229 struct omap_overlay_manager *mgr);
227int dss_ovl_unset_manager(struct omap_overlay *ovl); 230int dss_ovl_unset_manager(struct omap_overlay *ovl);
228 231
232/* output */
233void dss_register_output(struct omap_dss_output *out);
234void dss_unregister_output(struct omap_dss_output *out);
235struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev);
236
229/* display */ 237/* display */
230int dss_suspend_all_devices(void); 238int dss_suspend_all_devices(void);
231int dss_resume_all_devices(void); 239int dss_resume_all_devices(void);
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 406913949e2c..bfe7fc7b8593 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -47,6 +47,7 @@ struct omap_dss_features {
47 const int num_mgrs; 47 const int num_mgrs;
48 const int num_ovls; 48 const int num_ovls;
49 const enum omap_display_type *supported_displays; 49 const enum omap_display_type *supported_displays;
50 const enum omap_dss_output_id *supported_outputs;
50 const enum omap_color_mode *supported_color_modes; 51 const enum omap_color_mode *supported_color_modes;
51 const enum omap_overlay_caps *overlay_caps; 52 const enum omap_overlay_caps *overlay_caps;
52 const char * const *clksrc_names; 53 const char * const *clksrc_names;
@@ -172,6 +173,63 @@ static const enum omap_display_type omap5_dss_supported_displays[] = {
172 OMAP_DISPLAY_TYPE_DSI, 173 OMAP_DISPLAY_TYPE_DSI,
173}; 174};
174 175
176static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
177 /* OMAP_DSS_CHANNEL_LCD */
178 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
179
180 /* OMAP_DSS_CHANNEL_DIGIT */
181 OMAP_DSS_OUTPUT_VENC,
182};
183
184static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
185 /* OMAP_DSS_CHANNEL_LCD */
186 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
187 OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
188
189 /* OMAP_DSS_CHANNEL_DIGIT */
190 OMAP_DSS_OUTPUT_VENC,
191};
192
193static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
194 /* OMAP_DSS_CHANNEL_LCD */
195 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
196 OMAP_DSS_OUTPUT_DSI1,
197
198 /* OMAP_DSS_CHANNEL_DIGIT */
199 OMAP_DSS_OUTPUT_VENC,
200};
201
202static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
203 /* OMAP_DSS_CHANNEL_LCD */
204 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
205 OMAP_DSS_OUTPUT_DSI1,
206
207 /* OMAP_DSS_CHANNEL_DIGIT */
208 OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI |
209 OMAP_DSS_OUTPUT_DPI,
210
211 /* OMAP_DSS_CHANNEL_LCD2 */
212 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
213 OMAP_DSS_OUTPUT_DSI2,
214};
215
216static const enum omap_dss_output_id omap5_dss_supported_outputs[] = {
217 /* OMAP_DSS_CHANNEL_LCD */
218 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
219 OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2,
220
221 /* OMAP_DSS_CHANNEL_DIGIT */
222 OMAP_DSS_OUTPUT_HDMI | OMAP_DSS_OUTPUT_DPI,
223
224 /* OMAP_DSS_CHANNEL_LCD2 */
225 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
226 OMAP_DSS_OUTPUT_DSI1,
227
228 /* OMAP_DSS_CHANNEL_LCD3 */
229 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
230 OMAP_DSS_OUTPUT_DSI2,
231};
232
175static const enum omap_color_mode omap2_dss_supported_color_modes[] = { 233static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
176 /* OMAP_DSS_GFX */ 234 /* OMAP_DSS_GFX */
177 OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 | 235 OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
@@ -554,6 +612,7 @@ static const struct omap_dss_features omap2_dss_features = {
554 .num_mgrs = 2, 612 .num_mgrs = 2,
555 .num_ovls = 3, 613 .num_ovls = 3,
556 .supported_displays = omap2_dss_supported_displays, 614 .supported_displays = omap2_dss_supported_displays,
615 .supported_outputs = omap2_dss_supported_outputs,
557 .supported_color_modes = omap2_dss_supported_color_modes, 616 .supported_color_modes = omap2_dss_supported_color_modes,
558 .overlay_caps = omap2_dss_overlay_caps, 617 .overlay_caps = omap2_dss_overlay_caps,
559 .clksrc_names = omap2_dss_clk_source_names, 618 .clksrc_names = omap2_dss_clk_source_names,
@@ -574,6 +633,7 @@ static const struct omap_dss_features omap3430_dss_features = {
574 .num_mgrs = 2, 633 .num_mgrs = 2,
575 .num_ovls = 3, 634 .num_ovls = 3,
576 .supported_displays = omap3430_dss_supported_displays, 635 .supported_displays = omap3430_dss_supported_displays,
636 .supported_outputs = omap3430_dss_supported_outputs,
577 .supported_color_modes = omap3_dss_supported_color_modes, 637 .supported_color_modes = omap3_dss_supported_color_modes,
578 .overlay_caps = omap3430_dss_overlay_caps, 638 .overlay_caps = omap3430_dss_overlay_caps,
579 .clksrc_names = omap3_dss_clk_source_names, 639 .clksrc_names = omap3_dss_clk_source_names,
@@ -597,6 +657,7 @@ static const struct omap_dss_features am35xx_dss_features = {
597 .num_mgrs = 2, 657 .num_mgrs = 2,
598 .num_ovls = 3, 658 .num_ovls = 3,
599 .supported_displays = omap3430_dss_supported_displays, 659 .supported_displays = omap3430_dss_supported_displays,
660 .supported_outputs = omap3430_dss_supported_outputs,
600 .supported_color_modes = omap3_dss_supported_color_modes, 661 .supported_color_modes = omap3_dss_supported_color_modes,
601 .overlay_caps = omap3430_dss_overlay_caps, 662 .overlay_caps = omap3430_dss_overlay_caps,
602 .clksrc_names = omap3_dss_clk_source_names, 663 .clksrc_names = omap3_dss_clk_source_names,
@@ -616,6 +677,7 @@ static const struct omap_dss_features omap3630_dss_features = {
616 .num_mgrs = 2, 677 .num_mgrs = 2,
617 .num_ovls = 3, 678 .num_ovls = 3,
618 .supported_displays = omap3630_dss_supported_displays, 679 .supported_displays = omap3630_dss_supported_displays,
680 .supported_outputs = omap3630_dss_supported_outputs,
619 .supported_color_modes = omap3_dss_supported_color_modes, 681 .supported_color_modes = omap3_dss_supported_color_modes,
620 .overlay_caps = omap3630_dss_overlay_caps, 682 .overlay_caps = omap3630_dss_overlay_caps,
621 .clksrc_names = omap3_dss_clk_source_names, 683 .clksrc_names = omap3_dss_clk_source_names,
@@ -637,6 +699,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
637 .num_mgrs = 3, 699 .num_mgrs = 3,
638 .num_ovls = 4, 700 .num_ovls = 4,
639 .supported_displays = omap4_dss_supported_displays, 701 .supported_displays = omap4_dss_supported_displays,
702 .supported_outputs = omap4_dss_supported_outputs,
640 .supported_color_modes = omap4_dss_supported_color_modes, 703 .supported_color_modes = omap4_dss_supported_color_modes,
641 .overlay_caps = omap4_dss_overlay_caps, 704 .overlay_caps = omap4_dss_overlay_caps,
642 .clksrc_names = omap4_dss_clk_source_names, 705 .clksrc_names = omap4_dss_clk_source_names,
@@ -657,6 +720,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
657 .num_mgrs = 3, 720 .num_mgrs = 3,
658 .num_ovls = 4, 721 .num_ovls = 4,
659 .supported_displays = omap4_dss_supported_displays, 722 .supported_displays = omap4_dss_supported_displays,
723 .supported_outputs = omap4_dss_supported_outputs,
660 .supported_color_modes = omap4_dss_supported_color_modes, 724 .supported_color_modes = omap4_dss_supported_color_modes,
661 .overlay_caps = omap4_dss_overlay_caps, 725 .overlay_caps = omap4_dss_overlay_caps,
662 .clksrc_names = omap4_dss_clk_source_names, 726 .clksrc_names = omap4_dss_clk_source_names,
@@ -677,6 +741,7 @@ static const struct omap_dss_features omap4_dss_features = {
677 .num_mgrs = 3, 741 .num_mgrs = 3,
678 .num_ovls = 4, 742 .num_ovls = 4,
679 .supported_displays = omap4_dss_supported_displays, 743 .supported_displays = omap4_dss_supported_displays,
744 .supported_outputs = omap4_dss_supported_outputs,
680 .supported_color_modes = omap4_dss_supported_color_modes, 745 .supported_color_modes = omap4_dss_supported_color_modes,
681 .overlay_caps = omap4_dss_overlay_caps, 746 .overlay_caps = omap4_dss_overlay_caps,
682 .clksrc_names = omap4_dss_clk_source_names, 747 .clksrc_names = omap4_dss_clk_source_names,
@@ -697,6 +762,7 @@ static const struct omap_dss_features omap5_dss_features = {
697 .num_mgrs = 3, 762 .num_mgrs = 3,
698 .num_ovls = 4, 763 .num_ovls = 4,
699 .supported_displays = omap5_dss_supported_displays, 764 .supported_displays = omap5_dss_supported_displays,
765 .supported_outputs = omap5_dss_supported_outputs,
700 .supported_color_modes = omap4_dss_supported_color_modes, 766 .supported_color_modes = omap4_dss_supported_color_modes,
701 .overlay_caps = omap4_dss_overlay_caps, 767 .overlay_caps = omap4_dss_overlay_caps,
702 .clksrc_names = omap5_dss_clk_source_names, 768 .clksrc_names = omap5_dss_clk_source_names,
@@ -766,6 +832,11 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
766 return omap_current_dss_features->supported_displays[channel]; 832 return omap_current_dss_features->supported_displays[channel];
767} 833}
768 834
835enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
836{
837 return omap_current_dss_features->supported_outputs[channel];
838}
839
769enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane) 840enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
770{ 841{
771 return omap_current_dss_features->supported_color_modes[plane]; 842 return omap_current_dss_features->supported_color_modes[plane];
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index aacad863fa22..89df2aa860d4 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -108,6 +108,7 @@ int dss_feat_get_num_ovls(void);
108unsigned long dss_feat_get_param_min(enum dss_range_param param); 108unsigned long dss_feat_get_param_min(enum dss_range_param param);
109unsigned long dss_feat_get_param_max(enum dss_range_param param); 109unsigned long dss_feat_get_param_max(enum dss_range_param param);
110enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); 110enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
111enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
111enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); 112enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
112enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane); 113enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
113bool dss_feat_color_mode_supported(enum omap_plane plane, 114bool dss_feat_color_mode_supported(enum omap_plane plane,
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 23daf7dcf54a..a48a7dd75b33 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -68,6 +68,8 @@ static struct {
68 int ct_cp_hpd_gpio; 68 int ct_cp_hpd_gpio;
69 int ls_oe_gpio; 69 int ls_oe_gpio;
70 int hpd_gpio; 70 int hpd_gpio;
71
72 struct omap_dss_output output;
71} hdmi; 73} hdmi;
72 74
73/* 75/*
@@ -502,6 +504,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
502{ 504{
503 int r; 505 int r;
504 struct omap_video_timings *p; 506 struct omap_video_timings *p;
507 struct omap_overlay_manager *mgr = dssdev->output->manager;
505 unsigned long phy; 508 unsigned long phy;
506 509
507 gpio_set_value(hdmi.ct_cp_hpd_gpio, 1); 510 gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
@@ -518,7 +521,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
518 if (r) 521 if (r)
519 goto err_runtime_get; 522 goto err_runtime_get;
520 523
521 dss_mgr_disable(dssdev->manager); 524 dss_mgr_disable(mgr);
522 525
523 p = &hdmi.ip_data.cfg.timings; 526 p = &hdmi.ip_data.cfg.timings;
524 527
@@ -560,13 +563,13 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
560 dispc_enable_gamma_table(0); 563 dispc_enable_gamma_table(0);
561 564
562 /* tv size */ 565 /* tv size */
563 dss_mgr_set_timings(dssdev->manager, p); 566 dss_mgr_set_timings(mgr, p);
564 567
565 r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data); 568 r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
566 if (r) 569 if (r)
567 goto err_vid_enable; 570 goto err_vid_enable;
568 571
569 r = dss_mgr_enable(dssdev->manager); 572 r = dss_mgr_enable(mgr);
570 if (r) 573 if (r)
571 goto err_mgr_enable; 574 goto err_mgr_enable;
572 575
@@ -590,7 +593,9 @@ err_vdac_enable:
590 593
591static void hdmi_power_off(struct omap_dss_device *dssdev) 594static void hdmi_power_off(struct omap_dss_device *dssdev)
592{ 595{
593 dss_mgr_disable(dssdev->manager); 596 struct omap_overlay_manager *mgr = dssdev->output->manager;
597
598 dss_mgr_disable(mgr);
594 599
595 hdmi.ip_data.ops->video_disable(&hdmi.ip_data); 600 hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
596 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); 601 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
@@ -687,14 +692,15 @@ bool omapdss_hdmi_detect(void)
687 692
688int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) 693int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
689{ 694{
695 struct omap_dss_output *out = dssdev->output;
690 int r = 0; 696 int r = 0;
691 697
692 DSSDBG("ENTER hdmi_display_enable\n"); 698 DSSDBG("ENTER hdmi_display_enable\n");
693 699
694 mutex_lock(&hdmi.lock); 700 mutex_lock(&hdmi.lock);
695 701
696 if (dssdev->manager == NULL) { 702 if (out == NULL || out->manager == NULL) {
697 DSSERR("failed to enable display: no manager\n"); 703 DSSERR("failed to enable display: no output/manager\n");
698 r = -ENODEV; 704 r = -ENODEV;
699 goto err0; 705 goto err0;
700 } 706 }
@@ -970,6 +976,24 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
970 } 976 }
971} 977}
972 978
979static void __init hdmi_init_output(struct platform_device *pdev)
980{
981 struct omap_dss_output *out = &hdmi.output;
982
983 out->pdev = pdev;
984 out->id = OMAP_DSS_OUTPUT_HDMI;
985 out->type = OMAP_DISPLAY_TYPE_HDMI;
986
987 dss_register_output(out);
988}
989
990static void __exit hdmi_uninit_output(struct platform_device *pdev)
991{
992 struct omap_dss_output *out = &hdmi.output;
993
994 dss_unregister_output(out);
995}
996
973/* HDMI HW IP initialisation */ 997/* HDMI HW IP initialisation */
974static int __init omapdss_hdmihw_probe(struct platform_device *pdev) 998static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
975{ 999{
@@ -1013,6 +1037,8 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
1013 1037
1014 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 1038 dss_debugfs_create_file("hdmi", hdmi_dump_regs);
1015 1039
1040 hdmi_init_output(pdev);
1041
1016 hdmi_probe_pdata(pdev); 1042 hdmi_probe_pdata(pdev);
1017 1043
1018 return 0; 1044 return 0;
@@ -1033,6 +1059,8 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
1033 1059
1034 hdmi_panel_exit(); 1060 hdmi_panel_exit();
1035 1061
1062 hdmi_uninit_output(pdev);
1063
1036 pm_runtime_disable(&pdev->dev); 1064 pm_runtime_disable(&pdev->dev);
1037 1065
1038 hdmi_put_clocks(); 1066 hdmi_put_clocks();
diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/omap2/dss/manager-sysfs.c
index 9b875fbe757e..9a2fb59b6f89 100644
--- a/drivers/video/omap2/dss/manager-sysfs.c
+++ b/drivers/video/omap2/dss/manager-sysfs.c
@@ -38,8 +38,10 @@ static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
38 38
39static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf) 39static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
40{ 40{
41 return snprintf(buf, PAGE_SIZE, "%s\n", 41 struct omap_dss_device *dssdev = mgr->get_device(mgr);
42 mgr->device ? mgr->device->name : "<none>"); 42
43 return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ?
44 dssdev->name : "<none>");
43} 45}
44 46
45static ssize_t manager_display_store(struct omap_overlay_manager *mgr, 47static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
@@ -67,18 +69,29 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
67 if (dssdev) 69 if (dssdev)
68 DSSDBG("display %s found\n", dssdev->name); 70 DSSDBG("display %s found\n", dssdev->name);
69 71
70 if (mgr->device) { 72 if (mgr->output) {
71 r = mgr->unset_device(mgr); 73 r = mgr->unset_output(mgr);
72 if (r) { 74 if (r) {
73 DSSERR("failed to unset display\n"); 75 DSSERR("failed to unset current output\n");
74 goto put_device; 76 goto put_device;
75 } 77 }
76 } 78 }
77 79
78 if (dssdev) { 80 if (dssdev) {
79 r = mgr->set_device(mgr, dssdev); 81 struct omap_dss_output *out = dssdev->output;
82
83 /*
84 * a registered device should have an output connected to it
85 * already
86 */
87 if (!out) {
88 DSSERR("device has no output connected to it\n");
89 goto put_device;
90 }
91
92 r = mgr->set_output(mgr, out);
80 if (r) { 93 if (r) {
81 DSSERR("failed to set manager\n"); 94 DSSERR("failed to set manager output\n");
82 goto put_device; 95 goto put_device;
83 } 96 }
84 97
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 383314f222b0..c54d2f620ce3 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -36,9 +36,15 @@
36static int num_managers; 36static int num_managers;
37static struct omap_overlay_manager *managers; 37static struct omap_overlay_manager *managers;
38 38
39static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
40{
41 return mgr->output ? mgr->output->device : NULL;
42}
43
39static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) 44static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
40{ 45{
41 unsigned long timeout = msecs_to_jiffies(500); 46 unsigned long timeout = msecs_to_jiffies(500);
47 struct omap_dss_device *dssdev = mgr->get_device(mgr);
42 u32 irq; 48 u32 irq;
43 int r; 49 int r;
44 50
@@ -46,9 +52,9 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
46 if (r) 52 if (r)
47 return r; 53 return r;
48 54
49 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) 55 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
50 irq = DISPC_IRQ_EVSYNC_ODD; 56 irq = DISPC_IRQ_EVSYNC_ODD;
51 else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) 57 else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
52 irq = DISPC_IRQ_EVSYNC_EVEN; 58 irq = DISPC_IRQ_EVSYNC_EVEN;
53 else 59 else
54 irq = dispc_mgr_get_vsync_irq(mgr->id); 60 irq = dispc_mgr_get_vsync_irq(mgr->id);
@@ -93,17 +99,20 @@ int dss_init_overlay_managers(struct platform_device *pdev)
93 break; 99 break;
94 } 100 }
95 101
96 mgr->set_device = &dss_mgr_set_device; 102 mgr->set_output = &dss_mgr_set_output;
97 mgr->unset_device = &dss_mgr_unset_device; 103 mgr->unset_output = &dss_mgr_unset_output;
98 mgr->apply = &omap_dss_mgr_apply; 104 mgr->apply = &omap_dss_mgr_apply;
99 mgr->set_manager_info = &dss_mgr_set_info; 105 mgr->set_manager_info = &dss_mgr_set_info;
100 mgr->get_manager_info = &dss_mgr_get_info; 106 mgr->get_manager_info = &dss_mgr_get_info;
101 mgr->wait_for_go = &dss_mgr_wait_for_go; 107 mgr->wait_for_go = &dss_mgr_wait_for_go;
102 mgr->wait_for_vsync = &dss_mgr_wait_for_vsync; 108 mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
109 mgr->get_device = &dss_mgr_get_device;
103 110
104 mgr->caps = 0; 111 mgr->caps = 0;
105 mgr->supported_displays = 112 mgr->supported_displays =
106 dss_feat_get_supported_displays(mgr->id); 113 dss_feat_get_supported_displays(mgr->id);
114 mgr->supported_outputs =
115 dss_feat_get_supported_outputs(mgr->id);
107 116
108 INIT_LIST_HEAD(&mgr->overlays); 117 INIT_LIST_HEAD(&mgr->overlays);
109 118
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
new file mode 100644
index 000000000000..813f26682b7a
--- /dev/null
+++ b/drivers/video/omap2/dss/output.c
@@ -0,0 +1,148 @@
1/*
2 * Copyright (C) 2012 Texas Instruments Ltd
3 * Author: Archit Taneja <archit@ti.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h>
22
23#include <video/omapdss.h>
24
25#include "dss.h"
26
27static LIST_HEAD(output_list);
28static DEFINE_MUTEX(output_lock);
29
30int omapdss_output_set_device(struct omap_dss_output *out,
31 struct omap_dss_device *dssdev)
32{
33 int r;
34
35 mutex_lock(&output_lock);
36
37 if (out->device) {
38 DSSERR("output already has device %s connected to it\n",
39 out->device->name);
40 r = -EINVAL;
41 goto err;
42 }
43
44 if (out->type != dssdev->type) {
45 DSSERR("output type and display type don't match\n");
46 r = -EINVAL;
47 goto err;
48 }
49
50 out->device = dssdev;
51 dssdev->output = out;
52
53 mutex_unlock(&output_lock);
54
55 return 0;
56err:
57 mutex_unlock(&output_lock);
58
59 return r;
60}
61EXPORT_SYMBOL(omapdss_output_set_device);
62
63int omapdss_output_unset_device(struct omap_dss_output *out)
64{
65 int r;
66
67 mutex_lock(&output_lock);
68
69 if (!out->device) {
70 DSSERR("output doesn't have a device connected to it\n");
71 r = -EINVAL;
72 goto err;
73 }
74
75 if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
76 DSSERR("device %s is not disabled, cannot unset device\n",
77 out->device->name);
78 r = -EINVAL;
79 goto err;
80 }
81
82 out->device->output = NULL;
83 out->device = NULL;
84
85 mutex_unlock(&output_lock);
86
87 return 0;
88err:
89 mutex_unlock(&output_lock);
90
91 return r;
92}
93EXPORT_SYMBOL(omapdss_output_unset_device);
94
95void dss_register_output(struct omap_dss_output *out)
96{
97 list_add_tail(&out->list, &output_list);
98}
99
100void dss_unregister_output(struct omap_dss_output *out)
101{
102 list_del(&out->list);
103}
104
105struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
106{
107 struct omap_dss_output *out;
108
109 list_for_each_entry(out, &output_list, list) {
110 if (out->id == id)
111 return out;
112 }
113
114 return NULL;
115}
116
117struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev)
118{
119 struct omap_dss_output *out = NULL;
120 enum omap_dss_output_id id;
121
122 switch (dssdev->type) {
123 case OMAP_DISPLAY_TYPE_DPI:
124 out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI);
125 break;
126 case OMAP_DISPLAY_TYPE_DBI:
127 out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI);
128 break;
129 case OMAP_DISPLAY_TYPE_SDI:
130 out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI);
131 break;
132 case OMAP_DISPLAY_TYPE_VENC:
133 out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC);
134 break;
135 case OMAP_DISPLAY_TYPE_HDMI:
136 out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI);
137 break;
138 case OMAP_DISPLAY_TYPE_DSI:
139 id = dssdev->phy.dsi.module == 0 ? OMAP_DSS_OUTPUT_DSI1 :
140 OMAP_DSS_OUTPUT_DSI2;
141 out = omap_dss_get_output(id);
142 break;
143 default:
144 break;
145 }
146
147 return out;
148}
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 52455a0609cb..45f4994bc6b0 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -38,6 +38,13 @@
38static int num_overlays; 38static int num_overlays;
39static struct omap_overlay *overlays; 39static struct omap_overlay *overlays;
40 40
41static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)
42{
43 return ovl->manager ?
44 (ovl->manager->output ? ovl->manager->output->device : NULL) :
45 NULL;
46}
47
41int omap_dss_get_num_overlays(void) 48int omap_dss_get_num_overlays(void)
42{ 49{
43 return num_overlays; 50 return num_overlays;
@@ -94,6 +101,7 @@ void dss_init_overlays(struct platform_device *pdev)
94 ovl->set_overlay_info = &dss_ovl_set_info; 101 ovl->set_overlay_info = &dss_ovl_set_info;
95 ovl->get_overlay_info = &dss_ovl_get_info; 102 ovl->get_overlay_info = &dss_ovl_get_info;
96 ovl->wait_for_go = &dss_mgr_wait_for_go_ovl; 103 ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
104 ovl->get_device = &dss_ovl_get_device;
97 105
98 ovl->caps = dss_feat_get_overlay_caps(ovl->id); 106 ovl->caps = dss_feat_get_overlay_caps(ovl->id);
99 ovl->supported_modes = 107 ovl->supported_modes =
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 38d9b8ecbe3c..7282e5af3e1a 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -116,6 +116,8 @@ static struct {
116 int pixel_size; 116 int pixel_size;
117 int data_lines; 117 int data_lines;
118 struct rfbi_timings intf_timings; 118 struct rfbi_timings intf_timings;
119
120 struct omap_dss_output output;
119} rfbi; 121} rfbi;
120 122
121static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) 123static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
@@ -310,6 +312,7 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev,
310{ 312{
311 u32 l; 313 u32 l;
312 int r; 314 int r;
315 struct omap_overlay_manager *mgr = dssdev->output->manager;
313 u16 width = rfbi.timings.x_res; 316 u16 width = rfbi.timings.x_res;
314 u16 height = rfbi.timings.y_res; 317 u16 height = rfbi.timings.y_res;
315 318
@@ -318,9 +321,9 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev,
318 321
319 DSSDBG("rfbi_transfer_area %dx%d\n", width, height); 322 DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
320 323
321 dss_mgr_set_timings(dssdev->manager, &rfbi.timings); 324 dss_mgr_set_timings(mgr, &rfbi.timings);
322 325
323 r = dss_mgr_enable(dssdev->manager); 326 r = dss_mgr_enable(mgr);
324 if (r) 327 if (r)
325 return r; 328 return r;
326 329
@@ -849,6 +852,7 @@ static void rfbi_dump_regs(struct seq_file *s)
849 852
850static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev) 853static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
851{ 854{
855 struct omap_overlay_manager *mgr = dssdev->output->manager;
852 struct dss_lcd_mgr_config mgr_config; 856 struct dss_lcd_mgr_config mgr_config;
853 857
854 mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI; 858 mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
@@ -860,7 +864,7 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
860 mgr_config.video_port_width = rfbi.pixel_size; 864 mgr_config.video_port_width = rfbi.pixel_size;
861 mgr_config.lcden_sig_polarity = 0; 865 mgr_config.lcden_sig_polarity = 0;
862 866
863 dss_mgr_set_lcd_config(dssdev->manager, &mgr_config); 867 dss_mgr_set_lcd_config(mgr, &mgr_config);
864 868
865 /* 869 /*
866 * Set rfbi.timings with default values, the x_res and y_res fields 870 * Set rfbi.timings with default values, the x_res and y_res fields
@@ -881,15 +885,16 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
881 rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH; 885 rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
882 rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; 886 rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
883 887
884 dss_mgr_set_timings(dssdev->manager, &rfbi.timings); 888 dss_mgr_set_timings(mgr, &rfbi.timings);
885} 889}
886 890
887int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) 891int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
888{ 892{
893 struct omap_dss_output *out = dssdev->output;
889 int r; 894 int r;
890 895
891 if (dssdev->manager == NULL) { 896 if (out == NULL || out->manager == NULL) {
892 DSSERR("failed to enable display: no manager\n"); 897 DSSERR("failed to enable display: no output/manager\n");
893 return -ENODEV; 898 return -ENODEV;
894 } 899 }
895 900
@@ -1002,6 +1007,24 @@ static void __init rfbi_probe_pdata(struct platform_device *rfbidev)
1002 } 1007 }
1003} 1008}
1004 1009
1010static void __init rfbi_init_output(struct platform_device *pdev)
1011{
1012 struct omap_dss_output *out = &rfbi.output;
1013
1014 out->pdev = pdev;
1015 out->id = OMAP_DSS_OUTPUT_DBI;
1016 out->type = OMAP_DISPLAY_TYPE_DBI;
1017
1018 dss_register_output(out);
1019}
1020
1021static void __exit rfbi_uninit_output(struct platform_device *pdev)
1022{
1023 struct omap_dss_output *out = &rfbi.output;
1024
1025 dss_unregister_output(out);
1026}
1027
1005/* RFBI HW IP initialisation */ 1028/* RFBI HW IP initialisation */
1006static int __init omap_rfbihw_probe(struct platform_device *pdev) 1029static int __init omap_rfbihw_probe(struct platform_device *pdev)
1007{ 1030{
@@ -1053,6 +1076,8 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev)
1053 1076
1054 dss_debugfs_create_file("rfbi", rfbi_dump_regs); 1077 dss_debugfs_create_file("rfbi", rfbi_dump_regs);
1055 1078
1079 rfbi_init_output(pdev);
1080
1056 rfbi_probe_pdata(pdev); 1081 rfbi_probe_pdata(pdev);
1057 1082
1058 return 0; 1083 return 0;
@@ -1065,7 +1090,11 @@ err_runtime_get:
1065static int __exit omap_rfbihw_remove(struct platform_device *pdev) 1090static int __exit omap_rfbihw_remove(struct platform_device *pdev)
1066{ 1091{
1067 dss_unregister_child_devices(&pdev->dev); 1092 dss_unregister_child_devices(&pdev->dev);
1093
1094 rfbi_uninit_output(pdev);
1095
1068 pm_runtime_disable(&pdev->dev); 1096 pm_runtime_disable(&pdev->dev);
1097
1069 return 0; 1098 return 0;
1070} 1099}
1071 1100
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 919ff728c502..86f096aaf4fe 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -36,10 +36,14 @@ static struct {
36 struct dss_lcd_mgr_config mgr_config; 36 struct dss_lcd_mgr_config mgr_config;
37 struct omap_video_timings timings; 37 struct omap_video_timings timings;
38 int datapairs; 38 int datapairs;
39
40 struct omap_dss_output output;
39} sdi; 41} sdi;
40 42
41static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) 43static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
42{ 44{
45 struct omap_overlay_manager *mgr = dssdev->output->manager;
46
43 sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; 47 sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
44 48
45 sdi.mgr_config.stallmode = false; 49 sdi.mgr_config.stallmode = false;
@@ -48,19 +52,20 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
48 sdi.mgr_config.video_port_width = 24; 52 sdi.mgr_config.video_port_width = 24;
49 sdi.mgr_config.lcden_sig_polarity = 1; 53 sdi.mgr_config.lcden_sig_polarity = 1;
50 54
51 dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config); 55 dss_mgr_set_lcd_config(mgr, &sdi.mgr_config);
52} 56}
53 57
54int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) 58int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
55{ 59{
60 struct omap_dss_output *out = dssdev->output;
56 struct omap_video_timings *t = &sdi.timings; 61 struct omap_video_timings *t = &sdi.timings;
57 struct dss_clock_info dss_cinfo; 62 struct dss_clock_info dss_cinfo;
58 struct dispc_clock_info dispc_cinfo; 63 struct dispc_clock_info dispc_cinfo;
59 unsigned long pck; 64 unsigned long pck;
60 int r; 65 int r;
61 66
62 if (dssdev->manager == NULL) { 67 if (out == NULL || out->manager == NULL) {
63 DSSERR("failed to enable display: no manager\n"); 68 DSSERR("failed to enable display: no output/manager\n");
64 return -ENODEV; 69 return -ENODEV;
65 } 70 }
66 71
@@ -99,7 +104,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
99 } 104 }
100 105
101 106
102 dss_mgr_set_timings(dssdev->manager, t); 107 dss_mgr_set_timings(out->manager, t);
103 108
104 r = dss_set_clock_div(&dss_cinfo); 109 r = dss_set_clock_div(&dss_cinfo);
105 if (r) 110 if (r)
@@ -118,8 +123,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
118 * need to care about the shadow register mechanism for pck-free. The 123 * need to care about the shadow register mechanism for pck-free. The
119 * exact reason for this is unknown. 124 * exact reason for this is unknown.
120 */ 125 */
121 dispc_mgr_set_clock_div(dssdev->manager->id, 126 dispc_mgr_set_clock_div(out->manager->id, &sdi.mgr_config.clock_info);
122 &sdi.mgr_config.clock_info);
123 127
124 dss_sdi_init(sdi.datapairs); 128 dss_sdi_init(sdi.datapairs);
125 r = dss_sdi_enable(); 129 r = dss_sdi_enable();
@@ -127,7 +131,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
127 goto err_sdi_enable; 131 goto err_sdi_enable;
128 mdelay(2); 132 mdelay(2);
129 133
130 r = dss_mgr_enable(dssdev->manager); 134 r = dss_mgr_enable(out->manager);
131 if (r) 135 if (r)
132 goto err_mgr_enable; 136 goto err_mgr_enable;
133 137
@@ -150,7 +154,9 @@ EXPORT_SYMBOL(omapdss_sdi_display_enable);
150 154
151void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) 155void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
152{ 156{
153 dss_mgr_disable(dssdev->manager); 157 struct omap_overlay_manager *mgr = dssdev->output->manager;
158
159 dss_mgr_disable(mgr);
154 160
155 dss_sdi_disable(); 161 dss_sdi_disable();
156 162
@@ -255,8 +261,28 @@ static void __init sdi_probe_pdata(struct platform_device *sdidev)
255 } 261 }
256} 262}
257 263
264static void __init sdi_init_output(struct platform_device *pdev)
265{
266 struct omap_dss_output *out = &sdi.output;
267
268 out->pdev = pdev;
269 out->id = OMAP_DSS_OUTPUT_SDI;
270 out->type = OMAP_DISPLAY_TYPE_SDI;
271
272 dss_register_output(out);
273}
274
275static void __exit sdi_uninit_output(struct platform_device *pdev)
276{
277 struct omap_dss_output *out = &sdi.output;
278
279 dss_unregister_output(out);
280}
281
258static int __init omap_sdi_probe(struct platform_device *pdev) 282static int __init omap_sdi_probe(struct platform_device *pdev)
259{ 283{
284 sdi_init_output(pdev);
285
260 sdi_probe_pdata(pdev); 286 sdi_probe_pdata(pdev);
261 287
262 return 0; 288 return 0;
@@ -266,6 +292,8 @@ static int __exit omap_sdi_remove(struct platform_device *pdev)
266{ 292{
267 dss_unregister_child_devices(&pdev->dev); 293 dss_unregister_child_devices(&pdev->dev);
268 294
295 sdi_uninit_output(pdev);
296
269 return 0; 297 return 0;
270} 298}
271 299
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 996779c0204c..56efa3bb465d 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -303,6 +303,8 @@ static struct {
303 struct omap_video_timings timings; 303 struct omap_video_timings timings;
304 enum omap_dss_venc_type type; 304 enum omap_dss_venc_type type;
305 bool invert_polarity; 305 bool invert_polarity;
306
307 struct omap_dss_output output;
306} venc; 308} venc;
307 309
308static inline void venc_write_reg(int idx, u32 val) 310static inline void venc_write_reg(int idx, u32 val)
@@ -427,6 +429,7 @@ static const struct venc_config *venc_timings_to_config(
427 429
428static int venc_power_on(struct omap_dss_device *dssdev) 430static int venc_power_on(struct omap_dss_device *dssdev)
429{ 431{
432 struct omap_overlay_manager *mgr = dssdev->output->manager;
430 u32 l; 433 u32 l;
431 int r; 434 int r;
432 435
@@ -452,13 +455,13 @@ static int venc_power_on(struct omap_dss_device *dssdev)
452 455
453 venc_write_reg(VENC_OUTPUT_CONTROL, l); 456 venc_write_reg(VENC_OUTPUT_CONTROL, l);
454 457
455 dss_mgr_set_timings(dssdev->manager, &venc.timings); 458 dss_mgr_set_timings(mgr, &venc.timings);
456 459
457 r = regulator_enable(venc.vdda_dac_reg); 460 r = regulator_enable(venc.vdda_dac_reg);
458 if (r) 461 if (r)
459 goto err1; 462 goto err1;
460 463
461 r = dss_mgr_enable(dssdev->manager); 464 r = dss_mgr_enable(mgr);
462 if (r) 465 if (r)
463 goto err2; 466 goto err2;
464 467
@@ -477,10 +480,12 @@ err0:
477 480
478static void venc_power_off(struct omap_dss_device *dssdev) 481static void venc_power_off(struct omap_dss_device *dssdev)
479{ 482{
483 struct omap_overlay_manager *mgr = dssdev->output->manager;
484
480 venc_write_reg(VENC_OUTPUT_CONTROL, 0); 485 venc_write_reg(VENC_OUTPUT_CONTROL, 0);
481 dss_set_dac_pwrdn_bgz(0); 486 dss_set_dac_pwrdn_bgz(0);
482 487
483 dss_mgr_disable(dssdev->manager); 488 dss_mgr_disable(mgr);
484 489
485 regulator_disable(venc.vdda_dac_reg); 490 regulator_disable(venc.vdda_dac_reg);
486 491
@@ -495,14 +500,15 @@ unsigned long venc_get_pixel_clock(void)
495 500
496int omapdss_venc_display_enable(struct omap_dss_device *dssdev) 501int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
497{ 502{
503 struct omap_dss_output *out = dssdev->output;
498 int r; 504 int r;
499 505
500 DSSDBG("venc_display_enable\n"); 506 DSSDBG("venc_display_enable\n");
501 507
502 mutex_lock(&venc.venc_lock); 508 mutex_lock(&venc.venc_lock);
503 509
504 if (dssdev->manager == NULL) { 510 if (out == NULL || out->manager == NULL) {
505 DSSERR("Failed to enable display: no manager\n"); 511 DSSERR("Failed to enable display: no output/manager\n");
506 r = -ENODEV; 512 r = -ENODEV;
507 goto err0; 513 goto err0;
508 } 514 }
@@ -797,6 +803,24 @@ static void __init venc_probe_pdata(struct platform_device *vencdev)
797 } 803 }
798} 804}
799 805
806static void __init venc_init_output(struct platform_device *pdev)
807{
808 struct omap_dss_output *out = &venc.output;
809
810 out->pdev = pdev;
811 out->id = OMAP_DSS_OUTPUT_VENC;
812 out->type = OMAP_DISPLAY_TYPE_VENC;
813
814 dss_register_output(out);
815}
816
817static void __exit venc_uninit_output(struct platform_device *pdev)
818{
819 struct omap_dss_output *out = &venc.output;
820
821 dss_unregister_output(out);
822}
823
800/* VENC HW IP initialisation */ 824/* VENC HW IP initialisation */
801static int __init omap_venchw_probe(struct platform_device *pdev) 825static int __init omap_venchw_probe(struct platform_device *pdev)
802{ 826{
@@ -844,6 +868,8 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
844 868
845 dss_debugfs_create_file("venc", venc_dump_regs); 869 dss_debugfs_create_file("venc", venc_dump_regs);
846 870
871 venc_init_output(pdev);
872
847 venc_probe_pdata(pdev); 873 venc_probe_pdata(pdev);
848 874
849 return 0; 875 return 0;
@@ -866,6 +892,8 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
866 892
867 venc_panel_exit(); 893 venc_panel_exit();
868 894
895 venc_uninit_output(pdev);
896
869 pm_runtime_disable(&pdev->dev); 897 pm_runtime_disable(&pdev->dev);
870 venc_put_clocks(); 898 venc_put_clocks();
871 899
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index c6cf372d22c5..606b89f12351 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -599,6 +599,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
599 struct omapfb_info *ofbi = FB2OFB(fbi); 599 struct omapfb_info *ofbi = FB2OFB(fbi);
600 struct omapfb2_device *fbdev = ofbi->fbdev; 600 struct omapfb2_device *fbdev = ofbi->fbdev;
601 struct omap_dss_device *display = fb2display(fbi); 601 struct omap_dss_device *display = fb2display(fbi);
602 struct omap_overlay_manager *mgr;
602 603
603 union { 604 union {
604 struct omapfb_update_window_old uwnd_o; 605 struct omapfb_update_window_old uwnd_o;
@@ -786,12 +787,14 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
786 787
787 case OMAPFB_WAITFORVSYNC: 788 case OMAPFB_WAITFORVSYNC:
788 DBG("ioctl WAITFORVSYNC\n"); 789 DBG("ioctl WAITFORVSYNC\n");
789 if (!display) { 790 if (!display && !display->output && !display->output->manager) {
790 r = -EINVAL; 791 r = -EINVAL;
791 break; 792 break;
792 } 793 }
793 794
794 r = display->manager->wait_for_vsync(display->manager); 795 mgr = display->output->manager;
796
797 r = mgr->wait_for_vsync(mgr);
795 break; 798 break;
796 799
797 case OMAPFB_WAITFORGO: 800 case OMAPFB_WAITFORGO:
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 77ae9edbf2cd..b103793516db 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2379,6 +2379,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
2379 struct omap_overlay *ovl; 2379 struct omap_overlay *ovl;
2380 struct omap_dss_device *def_display; 2380 struct omap_dss_device *def_display;
2381 struct omap_dss_device *dssdev; 2381 struct omap_dss_device *dssdev;
2382 struct omap_dss_device *ovl_device;
2382 2383
2383 DBG("omapfb_probe\n"); 2384 DBG("omapfb_probe\n");
2384 2385
@@ -2452,8 +2453,9 @@ static int __init omapfb_probe(struct platform_device *pdev)
2452 /* gfx overlay should be the default one. find a display 2453 /* gfx overlay should be the default one. find a display
2453 * connected to that, and use it as default display */ 2454 * connected to that, and use it as default display */
2454 ovl = omap_dss_get_overlay(0); 2455 ovl = omap_dss_get_overlay(0);
2455 if (ovl->manager && ovl->manager->device) { 2456 ovl_device = ovl->get_device(ovl);
2456 def_display = ovl->manager->device; 2457 if (ovl_device) {
2458 def_display = ovl_device;
2457 } else { 2459 } else {
2458 dev_warn(&pdev->dev, "cannot find default display\n"); 2460 dev_warn(&pdev->dev, "cannot find default display\n");
2459 def_display = NULL; 2461 def_display = NULL;
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 30361a09aecd..5ced9b334d35 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -148,8 +148,9 @@ static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
148 148
149 /* XXX: returns the display connected to first attached overlay */ 149 /* XXX: returns the display connected to first attached overlay */
150 for (i = 0; i < ofbi->num_overlays; i++) { 150 for (i = 0; i < ofbi->num_overlays; i++) {
151 if (ofbi->overlays[i]->manager) 151 struct omap_overlay *ovl = ofbi->overlays[i];
152 return ofbi->overlays[i]->manager->device; 152
153 return ovl->get_device(ovl);
153 } 154 }
154 155
155 return NULL; 156 return NULL;
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index ac2e4cca5a23..e65e2e9e16eb 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -208,6 +208,16 @@ enum omap_hdmi_flags {
208 OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0, 208 OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
209}; 209};
210 210
211enum omap_dss_output_id {
212 OMAP_DSS_OUTPUT_DPI = 1 << 0,
213 OMAP_DSS_OUTPUT_DBI = 1 << 1,
214 OMAP_DSS_OUTPUT_SDI = 1 << 2,
215 OMAP_DSS_OUTPUT_DSI1 = 1 << 3,
216 OMAP_DSS_OUTPUT_DSI2 = 1 << 4,
217 OMAP_DSS_OUTPUT_VENC = 1 << 5,
218 OMAP_DSS_OUTPUT_HDMI = 1 << 6,
219};
220
211/* RFBI */ 221/* RFBI */
212 222
213struct rfbi_timings { 223struct rfbi_timings {
@@ -425,6 +435,8 @@ struct omap_overlay {
425 struct omap_overlay_info *info); 435 struct omap_overlay_info *info);
426 436
427 int (*wait_for_go)(struct omap_overlay *ovl); 437 int (*wait_for_go)(struct omap_overlay *ovl);
438
439 struct omap_dss_device *(*get_device)(struct omap_overlay *ovl);
428}; 440};
429 441
430struct omap_overlay_manager_info { 442struct omap_overlay_manager_info {
@@ -449,9 +461,10 @@ struct omap_overlay_manager {
449 enum omap_overlay_manager_caps caps; 461 enum omap_overlay_manager_caps caps;
450 struct list_head overlays; 462 struct list_head overlays;
451 enum omap_display_type supported_displays; 463 enum omap_display_type supported_displays;
464 enum omap_dss_output_id supported_outputs;
452 465
453 /* dynamic fields */ 466 /* dynamic fields */
454 struct omap_dss_device *device; 467 struct omap_dss_output *output;
455 468
456 /* 469 /*
457 * The following functions do not block: 470 * The following functions do not block:
@@ -464,9 +477,9 @@ struct omap_overlay_manager {
464 * interrupt context 477 * interrupt context
465 */ 478 */
466 479
467 int (*set_device)(struct omap_overlay_manager *mgr, 480 int (*set_output)(struct omap_overlay_manager *mgr,
468 struct omap_dss_device *dssdev); 481 struct omap_dss_output *output);
469 int (*unset_device)(struct omap_overlay_manager *mgr); 482 int (*unset_output)(struct omap_overlay_manager *mgr);
470 483
471 int (*set_manager_info)(struct omap_overlay_manager *mgr, 484 int (*set_manager_info)(struct omap_overlay_manager *mgr,
472 struct omap_overlay_manager_info *info); 485 struct omap_overlay_manager_info *info);
@@ -476,6 +489,8 @@ struct omap_overlay_manager {
476 int (*apply)(struct omap_overlay_manager *mgr); 489 int (*apply)(struct omap_overlay_manager *mgr);
477 int (*wait_for_go)(struct omap_overlay_manager *mgr); 490 int (*wait_for_go)(struct omap_overlay_manager *mgr);
478 int (*wait_for_vsync)(struct omap_overlay_manager *mgr); 491 int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
492
493 struct omap_dss_device *(*get_device)(struct omap_overlay_manager *mgr);
479}; 494};
480 495
481/* 22 pins means 1 clk lane and 10 data lanes */ 496/* 22 pins means 1 clk lane and 10 data lanes */
@@ -493,6 +508,24 @@ struct omap_dsi_pin_config {
493 int pins[OMAP_DSS_MAX_DSI_PINS]; 508 int pins[OMAP_DSS_MAX_DSI_PINS];
494}; 509};
495 510
511struct omap_dss_output {
512 struct list_head list;
513
514 /* display type supported by the output */
515 enum omap_display_type type;
516
517 /* output instance */
518 enum omap_dss_output_id id;
519
520 /* output's platform device pointer */
521 struct platform_device *pdev;
522
523 /* dynamic fields */
524 struct omap_overlay_manager *manager;
525
526 struct omap_dss_device *device;
527};
528
496struct omap_dss_device { 529struct omap_dss_device {
497 struct device dev; 530 struct device dev;
498 531
@@ -591,7 +624,7 @@ struct omap_dss_device {
591 624
592 enum omap_display_caps caps; 625 enum omap_display_caps caps;
593 626
594 struct omap_overlay_manager *manager; 627 struct omap_dss_output *output;
595 628
596 enum omap_dss_display_state state; 629 enum omap_dss_display_state state;
597 630
@@ -702,6 +735,11 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
702int omap_dss_get_num_overlays(void); 735int omap_dss_get_num_overlays(void);
703struct omap_overlay *omap_dss_get_overlay(int num); 736struct omap_overlay *omap_dss_get_overlay(int num);
704 737
738struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id);
739int omapdss_output_set_device(struct omap_dss_output *out,
740 struct omap_dss_device *dssdev);
741int omapdss_output_unset_device(struct omap_dss_output *out);
742
705void omapdss_default_get_resolution(struct omap_dss_device *dssdev, 743void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
706 u16 *xres, u16 *yres); 744 u16 *xres, u16 *yres);
707int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev); 745int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);