aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c24
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c12
-rw-r--r--drivers/video/omap2/dss/apply.c14
-rw-r--r--drivers/video/omap2/dss/core.c44
-rw-r--r--drivers/video/omap2/dss/display-sysfs.c28
-rw-r--r--drivers/video/omap2/dss/manager-sysfs.c45
-rw-r--r--drivers/video/omap2/dss/output.c14
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c25
-rw-r--r--include/video/omapdss.h23
9 files changed, 188 insertions, 41 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 02075bfcd8fd..b2ab2f5d3cb9 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -94,6 +94,28 @@ uint32_t pipe2vbl(struct drm_crtc *crtc)
94static struct omap_crtc *omap_crtcs[8]; 94static struct omap_crtc *omap_crtcs[8];
95 95
96/* we can probably ignore these until we support command-mode panels: */ 96/* we can probably ignore these until we support command-mode panels: */
97static int omap_crtc_connect(struct omap_overlay_manager *mgr,
98 struct omap_dss_output *dst)
99{
100 if (mgr->output)
101 return -EINVAL;
102
103 if ((mgr->supported_outputs & dst->id) == 0)
104 return -EINVAL;
105
106 dst->manager = mgr;
107 mgr->output = dst;
108
109 return 0;
110}
111
112static void omap_crtc_disconnect(struct omap_overlay_manager *mgr,
113 struct omap_dss_output *dst)
114{
115 mgr->output->manager = NULL;
116 mgr->output = NULL;
117}
118
97static void omap_crtc_start_update(struct omap_overlay_manager *mgr) 119static void omap_crtc_start_update(struct omap_overlay_manager *mgr)
98{ 120{
99} 121}
@@ -138,6 +160,8 @@ static void omap_crtc_unregister_framedone_handler(
138} 160}
139 161
140static const struct dss_mgr_ops mgr_ops = { 162static const struct dss_mgr_ops mgr_ops = {
163 .connect = omap_crtc_connect,
164 .disconnect = omap_crtc_disconnect,
141 .start_update = omap_crtc_start_update, 165 .start_update = omap_crtc_start_update,
142 .enable = omap_crtc_enable, 166 .enable = omap_crtc_enable,
143 .disable = omap_crtc_disable, 167 .disable = omap_crtc_disable,
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index ff9b49276b81..c65dd0d6b01d 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -97,6 +97,7 @@ static int omap_modeset_init(struct drm_device *dev)
97 int num_mgrs = dss_feat_get_num_mgrs(); 97 int num_mgrs = dss_feat_get_num_mgrs();
98 int num_crtcs; 98 int num_crtcs;
99 int i, id = 0; 99 int i, id = 0;
100 int r;
100 101
101 omap_crtc_pre_init(); 102 omap_crtc_pre_init();
102 103
@@ -118,6 +119,7 @@ static int omap_modeset_init(struct drm_device *dev)
118 struct drm_connector *connector; 119 struct drm_connector *connector;
119 struct drm_encoder *encoder; 120 struct drm_encoder *encoder;
120 enum omap_channel channel; 121 enum omap_channel channel;
122 struct omap_overlay_manager *mgr;
121 123
122 if (!dssdev->driver) { 124 if (!dssdev->driver) {
123 dev_warn(dev->dev, "%s has no driver.. skipping it\n", 125 dev_warn(dev->dev, "%s has no driver.. skipping it\n",
@@ -133,6 +135,13 @@ static int omap_modeset_init(struct drm_device *dev)
133 continue; 135 continue;
134 } 136 }
135 137
138 r = dssdev->driver->connect(dssdev);
139 if (r) {
140 dev_err(dev->dev, "could not connect display: %s\n",
141 dssdev->name);
142 continue;
143 }
144
136 encoder = omap_encoder_init(dev, dssdev); 145 encoder = omap_encoder_init(dev, dssdev);
137 146
138 if (!encoder) { 147 if (!encoder) {
@@ -174,8 +183,9 @@ static int omap_modeset_init(struct drm_device *dev)
174 * other possible channels to which the encoder can connect are 183 * other possible channels to which the encoder can connect are
175 * not considered. 184 * not considered.
176 */ 185 */
177 channel = dssdev->output->dispc_channel;
178 186
187 mgr = omapdss_find_mgr_from_display(dssdev);
188 channel = mgr->id;
179 /* 189 /*
180 * if this channel hasn't already been taken by a previously 190 * if this channel hasn't already been taken by a previously
181 * allocated crtc, we create a new crtc for it 191 * allocated crtc, we create a new crtc for it
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index c844071e8e28..dbd3c2f28a83 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -790,6 +790,18 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
790 } 790 }
791} 791}
792 792
793static int dss_mgr_connect_compat(struct omap_overlay_manager *mgr,
794 struct omap_dss_output *dst)
795{
796 return mgr->set_output(mgr, dst);
797}
798
799static void dss_mgr_disconnect_compat(struct omap_overlay_manager *mgr,
800 struct omap_dss_output *dst)
801{
802 mgr->unset_output(mgr);
803}
804
793static void dss_mgr_start_update_compat(struct omap_overlay_manager *mgr) 805static void dss_mgr_start_update_compat(struct omap_overlay_manager *mgr)
794{ 806{
795 struct mgr_priv_data *mp = get_mgr_priv(mgr); 807 struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -1552,6 +1564,8 @@ static void dss_mgr_unregister_framedone_handler_compat(struct omap_overlay_mana
1552} 1564}
1553 1565
1554static const struct dss_mgr_ops apply_mgr_ops = { 1566static const struct dss_mgr_ops apply_mgr_ops = {
1567 .connect = dss_mgr_connect_compat,
1568 .disconnect = dss_mgr_disconnect_compat,
1555 .start_update = dss_mgr_start_update_compat, 1569 .start_update = dss_mgr_start_update_compat,
1556 .enable = dss_mgr_enable_compat, 1570 .enable = dss_mgr_enable_compat,
1557 .disable = dss_mgr_disable_compat, 1571 .disable = dss_mgr_disable_compat,
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 710e9f9a4436..831abec565f2 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -379,6 +379,46 @@ static int dss_driver_remove(struct device *dev)
379 return 0; 379 return 0;
380} 380}
381 381
382static int omapdss_default_connect(struct omap_dss_device *dssdev)
383{
384 struct omap_dss_output *out;
385 struct omap_overlay_manager *mgr;
386 int r;
387
388 out = dssdev->output;
389
390 if (out == NULL)
391 return -ENODEV;
392
393 mgr = omap_dss_get_overlay_manager(out->dispc_channel);
394 if (!mgr)
395 return -ENODEV;
396
397 r = dss_mgr_connect(mgr, out);
398 if (r)
399 return r;
400
401 return 0;
402}
403
404static void omapdss_default_disconnect(struct omap_dss_device *dssdev)
405{
406 struct omap_dss_output *out;
407 struct omap_overlay_manager *mgr;
408
409 out = dssdev->output;
410
411 if (out == NULL)
412 return;
413
414 mgr = out->manager;
415
416 if (mgr == NULL)
417 return;
418
419 dss_mgr_disconnect(mgr, out);
420}
421
382int omap_dss_register_driver(struct omap_dss_driver *dssdriver) 422int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
383{ 423{
384 dssdriver->driver.bus = &dss_bus_type; 424 dssdriver->driver.bus = &dss_bus_type;
@@ -392,6 +432,10 @@ int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
392 omapdss_default_get_recommended_bpp; 432 omapdss_default_get_recommended_bpp;
393 if (dssdriver->get_timings == NULL) 433 if (dssdriver->get_timings == NULL)
394 dssdriver->get_timings = omapdss_default_get_timings; 434 dssdriver->get_timings = omapdss_default_get_timings;
435 if (dssdriver->connect == NULL)
436 dssdriver->connect = omapdss_default_connect;
437 if (dssdriver->disconnect == NULL)
438 dssdriver->disconnect = omapdss_default_disconnect;
395 439
396 return driver_register(&dssdriver->driver); 440 return driver_register(&dssdriver->driver);
397} 441}
diff --git a/drivers/video/omap2/dss/display-sysfs.c b/drivers/video/omap2/dss/display-sysfs.c
index 18211a9ab354..81d5dc6e509f 100644
--- a/drivers/video/omap2/dss/display-sysfs.c
+++ b/drivers/video/omap2/dss/display-sysfs.c
@@ -33,9 +33,9 @@ static ssize_t display_enabled_show(struct device *dev,
33 struct device_attribute *attr, char *buf) 33 struct device_attribute *attr, char *buf)
34{ 34{
35 struct omap_dss_device *dssdev = to_dss_device(dev); 35 struct omap_dss_device *dssdev = to_dss_device(dev);
36 bool enabled = dssdev->state != OMAP_DSS_DISPLAY_DISABLED;
37 36
38 return snprintf(buf, PAGE_SIZE, "%d\n", enabled); 37 return snprintf(buf, PAGE_SIZE, "%d\n",
38 omapdss_device_is_enabled(dssdev));
39} 39}
40 40
41static ssize_t display_enabled_store(struct device *dev, 41static ssize_t display_enabled_store(struct device *dev,
@@ -44,20 +44,24 @@ static ssize_t display_enabled_store(struct device *dev,
44{ 44{
45 struct omap_dss_device *dssdev = to_dss_device(dev); 45 struct omap_dss_device *dssdev = to_dss_device(dev);
46 int r; 46 int r;
47 bool enabled; 47 bool enable;
48 48
49 r = strtobool(buf, &enabled); 49 r = strtobool(buf, &enable);
50 if (r) 50 if (r)
51 return r; 51 return r;
52 52
53 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) { 53 if (enable == omapdss_device_is_enabled(dssdev))
54 if (enabled) { 54 return size;
55 r = dssdev->driver->enable(dssdev); 55
56 if (r) 56 if (omapdss_device_is_connected(dssdev) == false)
57 return r; 57 return -ENODEV;
58 } else { 58
59 dssdev->driver->disable(dssdev); 59 if (enable) {
60 } 60 r = dssdev->driver->enable(dssdev);
61 if (r)
62 return r;
63 } else {
64 dssdev->driver->disable(dssdev);
61 } 65 }
62 66
63 return size; 67 return size;
diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/omap2/dss/manager-sysfs.c
index 72784b3aad27..de7e7b5b1b7c 100644
--- a/drivers/video/omap2/dss/manager-sysfs.c
+++ b/drivers/video/omap2/dss/manager-sysfs.c
@@ -50,6 +50,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
50 int r = 0; 50 int r = 0;
51 size_t len = size; 51 size_t len = size;
52 struct omap_dss_device *dssdev = NULL; 52 struct omap_dss_device *dssdev = NULL;
53 struct omap_dss_device *old_dssdev;
53 54
54 int match(struct omap_dss_device *dssdev, void *data) 55 int match(struct omap_dss_device *dssdev, void *data)
55 { 56 {
@@ -66,34 +67,44 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
66 if (len > 0 && dssdev == NULL) 67 if (len > 0 && dssdev == NULL)
67 return -EINVAL; 68 return -EINVAL;
68 69
69 if (dssdev) 70 if (dssdev) {
70 DSSDBG("display %s found\n", dssdev->name); 71 DSSDBG("display %s found\n", dssdev->name);
71 72
72 if (mgr->output) { 73 if (omapdss_device_is_connected(dssdev)) {
73 r = mgr->unset_output(mgr); 74 DSSERR("new display is already connected\n");
74 if (r) { 75 r = -EINVAL;
75 DSSERR("failed to unset current output\n"); 76 goto put_device;
77 }
78
79 if (omapdss_device_is_enabled(dssdev)) {
80 DSSERR("new display is not disabled\n");
81 r = -EINVAL;
76 goto put_device; 82 goto put_device;
77 } 83 }
78 } 84 }
79 85
80 if (dssdev) { 86 old_dssdev = mgr->get_device(mgr);
81 struct omap_dss_output *out; 87 if (old_dssdev) {
88 if (omapdss_device_is_enabled(old_dssdev)) {
89 DSSERR("old display is not disabled\n");
90 r = -EINVAL;
91 goto put_device;
92 }
82 93
83 out = omapdss_find_output_from_display(dssdev); 94 old_dssdev->driver->disconnect(old_dssdev);
95 }
84 96
85 /* 97 if (dssdev) {
86 * a registered device should have an output connected to it 98 r = dssdev->driver->connect(dssdev);
87 * already 99 if (r) {
88 */ 100 DSSERR("failed to connect new device\n");
89 if (!out) {
90 DSSERR("device has no output connected to it\n");
91 goto put_device; 101 goto put_device;
92 } 102 }
93 103
94 r = mgr->set_output(mgr, out); 104 old_dssdev = mgr->get_device(mgr);
95 if (r) { 105 if (old_dssdev != dssdev) {
96 DSSERR("failed to set manager output\n"); 106 DSSERR("failed to connect device to this manager\n");
107 dssdev->driver->disconnect(dssdev);
97 goto put_device; 108 goto put_device;
98 } 109 }
99 110
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index ab2c0f0ab244..a53b08b2249b 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -179,6 +179,20 @@ void dss_uninstall_mgr_ops(void)
179} 179}
180EXPORT_SYMBOL(dss_uninstall_mgr_ops); 180EXPORT_SYMBOL(dss_uninstall_mgr_ops);
181 181
182int dss_mgr_connect(struct omap_overlay_manager *mgr,
183 struct omap_dss_output *dst)
184{
185 return dss_mgr_ops->connect(mgr, dst);
186}
187EXPORT_SYMBOL(dss_mgr_connect);
188
189void dss_mgr_disconnect(struct omap_overlay_manager *mgr,
190 struct omap_dss_output *dst)
191{
192 dss_mgr_ops->disconnect(mgr, dst);
193}
194EXPORT_SYMBOL(dss_mgr_disconnect);
195
182void dss_mgr_set_timings(struct omap_overlay_manager *mgr, 196void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
183 const struct omap_video_timings *timings) 197 const struct omap_video_timings *timings)
184{ 198{
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index cc8953c4faa1..528e453e8e11 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1853,6 +1853,8 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
1853 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) 1853 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)
1854 dssdev->driver->disable(dssdev); 1854 dssdev->driver->disable(dssdev);
1855 1855
1856 dssdev->driver->disconnect(dssdev);
1857
1856 omap_dss_put_device(dssdev); 1858 omap_dss_put_device(dssdev);
1857 } 1859 }
1858 1860
@@ -2363,22 +2365,23 @@ static int omapfb_init_connections(struct omapfb2_device *fbdev,
2363 int i, r; 2365 int i, r;
2364 struct omap_overlay_manager *mgr; 2366 struct omap_overlay_manager *mgr;
2365 2367
2368 r = def_dssdev->driver->connect(def_dssdev);
2369 if (r) {
2370 dev_err(fbdev->dev, "failed to connect default display\n");
2371 return r;
2372 }
2373
2366 for (i = 0; i < fbdev->num_displays; ++i) { 2374 for (i = 0; i < fbdev->num_displays; ++i) {
2367 struct omap_dss_device *dssdev = fbdev->displays[i].dssdev; 2375 struct omap_dss_device *dssdev = fbdev->displays[i].dssdev;
2368 struct omap_dss_output *out;
2369 2376
2370 out = omapdss_find_output_from_display(dssdev); 2377 if (dssdev == def_dssdev)
2371 if (!out)
2372 continue; 2378 continue;
2373 2379
2374 mgr = omap_dss_get_overlay_manager(out->dispc_channel); 2380 /*
2375 if (!mgr) 2381 * We don't care if the connect succeeds or not. We just want to
2376 continue; 2382 * connect as many displays as possible.
2377 2383 */
2378 if (mgr->output) 2384 dssdev->driver->connect(dssdev);
2379 mgr->unset_output(mgr);
2380
2381 mgr->set_output(mgr, out);
2382 } 2385 }
2383 2386
2384 mgr = omapdss_find_mgr_from_display(def_dssdev); 2387 mgr = omapdss_find_mgr_from_display(def_dssdev);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 898f81247859..4f52f523fba4 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -689,6 +689,9 @@ struct omap_dss_driver {
689 int (*probe)(struct omap_dss_device *); 689 int (*probe)(struct omap_dss_device *);
690 void (*remove)(struct omap_dss_device *); 690 void (*remove)(struct omap_dss_device *);
691 691
692 int (*connect)(struct omap_dss_device *dssdev);
693 void (*disconnect)(struct omap_dss_device *dssdev);
694
692 int (*enable)(struct omap_dss_device *display); 695 int (*enable)(struct omap_dss_device *display);
693 void (*disable)(struct omap_dss_device *display); 696 void (*disable)(struct omap_dss_device *display);
694 int (*run_test)(struct omap_dss_device *display, int test); 697 int (*run_test)(struct omap_dss_device *display, int test);
@@ -889,6 +892,11 @@ int omapdss_compat_init(void);
889void omapdss_compat_uninit(void); 892void omapdss_compat_uninit(void);
890 893
891struct dss_mgr_ops { 894struct dss_mgr_ops {
895 int (*connect)(struct omap_overlay_manager *mgr,
896 struct omap_dss_output *dst);
897 void (*disconnect)(struct omap_overlay_manager *mgr,
898 struct omap_dss_output *dst);
899
892 void (*start_update)(struct omap_overlay_manager *mgr); 900 void (*start_update)(struct omap_overlay_manager *mgr);
893 int (*enable)(struct omap_overlay_manager *mgr); 901 int (*enable)(struct omap_overlay_manager *mgr);
894 void (*disable)(struct omap_overlay_manager *mgr); 902 void (*disable)(struct omap_overlay_manager *mgr);
@@ -905,6 +913,10 @@ struct dss_mgr_ops {
905int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops); 913int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops);
906void dss_uninstall_mgr_ops(void); 914void dss_uninstall_mgr_ops(void);
907 915
916int dss_mgr_connect(struct omap_overlay_manager *mgr,
917 struct omap_dss_output *dst);
918void dss_mgr_disconnect(struct omap_overlay_manager *mgr,
919 struct omap_dss_output *dst);
908void dss_mgr_set_timings(struct omap_overlay_manager *mgr, 920void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
909 const struct omap_video_timings *timings); 921 const struct omap_video_timings *timings);
910void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, 922void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
@@ -916,4 +928,15 @@ int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr,
916 void (*handler)(void *), void *data); 928 void (*handler)(void *), void *data);
917void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr, 929void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr,
918 void (*handler)(void *), void *data); 930 void (*handler)(void *), void *data);
931
932static inline bool omapdss_device_is_connected(struct omap_dss_device *dssdev)
933{
934 return dssdev->output;
935}
936
937static inline bool omapdss_device_is_enabled(struct omap_dss_device *dssdev)
938{
939 return dssdev->state == OMAP_DSS_DISPLAY_ACTIVE;
940}
941
919#endif 942#endif