aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2018-06-06 08:20:01 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2018-09-03 09:13:30 -0400
commitb4935e3a3cfa456b356e9714e75513be672c227e (patch)
tree46c33be0cd3cb1f039885b9feb39192dae33271e /drivers
parent26c91a3898f1fd52af4e90d03ad740586112a6f7 (diff)
drm/omap: Store bus flags in the omap_dss_device structure
Source components in the display pipeline need to configure their output signals polarities and clock driving edge based on the requirements of the sink component. Those requirements are currently shared across the whole pipeline in the flags of a videomode structure, instead of being local to each bus. This both prevents multiple buses from having different configurations (when the hardware supports it), and makes it difficult to move from videomode to drm_display_mode as the latter doesn't contain bus polarities and clock edge flags. Add a bus_flags field to the omap_dss_device structure and move the DISPLAY_FLAGS_DE_(LOW|HIGH), DISPLAY_FLAGS_PIXDATA_(POS|NEG)EDGE and DISPLAY_FLAGS_SYNC_(POS|NEG)EDGE videomode flags to bus_flags in all external encoders, connectors and panels. The videomode flags are still used internally for internal encoders, this will be addressed in a second step. The related videomode flags in the default mode of the DVI connector can simply be dropped, as they are always overridden by the TFP410 driver. Note that this results in both the DISPLAY_FLAGS_SYNC_POSEDGE and DISPLAY_FLAGS_SYNC_NEGEDGE flags being set, which is invalid, but only the former is tested for when programming the DISPC, so the DVI connector flags are effectively overridden by the TFP410 flags. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/omapdrm/displays/connector-dvi.c4
-rw-r--r--drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c10
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c17
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c6
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c15
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c6
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c15
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c15
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dsi.c9
-rw-r--r--drivers/gpu/drm/omapdrm/dss/omapdss.h1
-rw-r--r--drivers/gpu/drm/omapdrm/dss/sdi.c5
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c42
12 files changed, 79 insertions, 66 deletions
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index b89555ed53a0..5871872ae19b 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -33,9 +33,7 @@ static const struct videomode dvic_default_vm = {
33 .vsync_len = 4, 33 .vsync_len = 4,
34 .vback_porch = 7, 34 .vback_porch = 7,
35 35
36 .flags = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH | 36 .flags = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH,
37 DISPLAY_FLAGS_SYNC_NEGEDGE | DISPLAY_FLAGS_DE_HIGH |
38 DISPLAY_FLAGS_PIXDATA_POSEDGE,
39}; 37};
40 38
41struct panel_drv_data { 39struct panel_drv_data {
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
index 86c90c15681e..56b78cd38701 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
@@ -76,12 +76,6 @@ static void tfp410_disable(struct omap_dss_device *dssdev)
76 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 76 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
77} 77}
78 78
79static void tfp410_fix_timings(struct videomode *vm)
80{
81 vm->flags |= DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
82 DISPLAY_FLAGS_SYNC_POSEDGE;
83}
84
85static void tfp410_set_timings(struct omap_dss_device *dssdev, 79static void tfp410_set_timings(struct omap_dss_device *dssdev,
86 const struct videomode *vm) 80 const struct videomode *vm)
87{ 81{
@@ -95,8 +89,6 @@ static int tfp410_check_timings(struct omap_dss_device *dssdev,
95{ 89{
96 struct omap_dss_device *src = dssdev->src; 90 struct omap_dss_device *src = dssdev->src;
97 91
98 tfp410_fix_timings(vm);
99
100 return src->ops->check_timings(src, vm); 92 return src->ops->check_timings(src, vm);
101} 93}
102 94
@@ -137,6 +129,8 @@ static int tfp410_probe(struct platform_device *pdev)
137 dssdev->output_type = OMAP_DISPLAY_TYPE_DVI; 129 dssdev->output_type = OMAP_DISPLAY_TYPE_DVI;
138 dssdev->owner = THIS_MODULE; 130 dssdev->owner = THIS_MODULE;
139 dssdev->of_ports = BIT(1) | BIT(0); 131 dssdev->of_ports = BIT(1) | BIT(0);
132 dssdev->bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_SYNC_POSEDGE
133 | DRM_BUS_FLAG_PIXDATA_POSEDGE;
140 134
141 dssdev->next = omapdss_of_find_connected_device(pdev->dev.of_node, 1); 135 dssdev->next = omapdss_of_find_connected_device(pdev->dev.of_node, 1);
142 if (IS_ERR(dssdev->next)) { 136 if (IS_ERR(dssdev->next)) {
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
index ffa69fd44d87..a211506506c0 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
@@ -33,14 +33,7 @@ static const struct videomode lb035q02_vm = {
33 .vfront_porch = 4, 33 .vfront_porch = 4,
34 .vback_porch = 18, 34 .vback_porch = 18,
35 35
36 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | 36 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
37 DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_SYNC_NEGEDGE |
38 DISPLAY_FLAGS_PIXDATA_POSEDGE,
39 /*
40 * Note: According to the panel documentation:
41 * DE is active LOW
42 * DATA needs to be driven on the FALLING edge
43 */
44}; 37};
45 38
46struct panel_drv_data { 39struct panel_drv_data {
@@ -252,6 +245,14 @@ static int lb035q02_panel_spi_probe(struct spi_device *spi)
252 dssdev->owner = THIS_MODULE; 245 dssdev->owner = THIS_MODULE;
253 dssdev->of_ports = BIT(0); 246 dssdev->of_ports = BIT(0);
254 247
248 /*
249 * Note: According to the panel documentation:
250 * DE is active LOW
251 * DATA needs to be driven on the FALLING edge
252 */
253 dssdev->bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_SYNC_NEGEDGE
254 | DRM_BUS_FLAG_PIXDATA_POSEDGE;
255
255 omapdss_display_init(dssdev); 256 omapdss_display_init(dssdev);
256 omapdss_device_register(dssdev); 257 omapdss_device_register(dssdev);
257 258
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
index 26af95a71eab..1b2f33d43bd9 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
@@ -71,9 +71,7 @@ static const struct videomode nec_8048_panel_vm = {
71 .vsync_len = 1, 71 .vsync_len = 1,
72 .vback_porch = 4, 72 .vback_porch = 4,
73 73
74 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | 74 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
75 DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_SYNC_POSEDGE |
76 DISPLAY_FLAGS_PIXDATA_POSEDGE,
77}; 75};
78 76
79#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) 77#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
@@ -241,6 +239,8 @@ static int nec_8048_probe(struct spi_device *spi)
241 dssdev->type = OMAP_DISPLAY_TYPE_DPI; 239 dssdev->type = OMAP_DISPLAY_TYPE_DPI;
242 dssdev->owner = THIS_MODULE; 240 dssdev->owner = THIS_MODULE;
243 dssdev->of_ports = BIT(0); 241 dssdev->of_ports = BIT(0);
242 dssdev->bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_SYNC_POSEDGE
243 | DRM_BUS_FLAG_PIXDATA_POSEDGE;
244 244
245 omapdss_display_init(dssdev); 245 omapdss_display_init(dssdev);
246 omapdss_device_register(dssdev); 246 omapdss_device_register(dssdev);
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
index a83cd9f4bdb0..fbf88aaaaf56 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
@@ -46,13 +46,7 @@ static const struct videomode sharp_ls_vm = {
46 .vfront_porch = 1, 46 .vfront_porch = 1,
47 .vback_porch = 1, 47 .vback_porch = 1,
48 48
49 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | 49 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
50 DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_SYNC_NEGEDGE |
51 DISPLAY_FLAGS_PIXDATA_POSEDGE,
52 /*
53 * Note: According to the panel documentation:
54 * DATA needs to be driven on the FALLING edge
55 */
56}; 50};
57 51
58#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) 52#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
@@ -250,6 +244,13 @@ static int sharp_ls_probe(struct platform_device *pdev)
250 dssdev->owner = THIS_MODULE; 244 dssdev->owner = THIS_MODULE;
251 dssdev->of_ports = BIT(0); 245 dssdev->of_ports = BIT(0);
252 246
247 /*
248 * Note: According to the panel documentation:
249 * DATA needs to be driven on the FALLING edge
250 */
251 dssdev->bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_SYNC_NEGEDGE
252 | DRM_BUS_FLAG_PIXDATA_POSEDGE;
253
253 omapdss_display_init(dssdev); 254 omapdss_display_init(dssdev);
254 omapdss_device_register(dssdev); 255 omapdss_device_register(dssdev);
255 256
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
index 8e45c5e64efa..7e99d546132f 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
@@ -97,9 +97,7 @@ static const struct videomode acx565akm_panel_vm = {
97 .vsync_len = 3, 97 .vsync_len = 3,
98 .vback_porch = 4, 98 .vback_porch = 4,
99 99
100 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | 100 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
101 DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_SYNC_NEGEDGE |
102 DISPLAY_FLAGS_PIXDATA_POSEDGE,
103}; 101};
104 102
105#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) 103#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
@@ -764,6 +762,8 @@ static int acx565akm_probe(struct spi_device *spi)
764 dssdev->type = OMAP_DISPLAY_TYPE_SDI; 762 dssdev->type = OMAP_DISPLAY_TYPE_SDI;
765 dssdev->owner = THIS_MODULE; 763 dssdev->owner = THIS_MODULE;
766 dssdev->of_ports = BIT(0); 764 dssdev->of_ports = BIT(0);
765 dssdev->bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_SYNC_NEGEDGE
766 | DRM_BUS_FLAG_PIXDATA_POSEDGE;
767 767
768 omapdss_display_init(dssdev); 768 omapdss_display_init(dssdev);
769 omapdss_device_register(dssdev); 769 omapdss_device_register(dssdev);
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
index b2a16c470f73..e8c73ad48e0c 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
@@ -49,13 +49,7 @@ static const struct videomode td028ttec1_panel_vm = {
49 .vsync_len = 2, 49 .vsync_len = 2,
50 .vback_porch = 2, 50 .vback_porch = 2,
51 51
52 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | 52 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
53 DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_SYNC_POSEDGE |
54 DISPLAY_FLAGS_PIXDATA_NEGEDGE,
55 /*
56 * Note: According to the panel documentation:
57 * SYNC needs to be driven on the FALLING edge
58 */
59}; 53};
60 54
61#define JBT_COMMAND 0x000 55#define JBT_COMMAND 0x000
@@ -374,6 +368,13 @@ static int td028ttec1_panel_probe(struct spi_device *spi)
374 dssdev->owner = THIS_MODULE; 368 dssdev->owner = THIS_MODULE;
375 dssdev->of_ports = BIT(0); 369 dssdev->of_ports = BIT(0);
376 370
371 /*
372 * Note: According to the panel documentation:
373 * SYNC needs to be driven on the FALLING edge
374 */
375 dssdev->bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_SYNC_POSEDGE
376 | DRM_BUS_FLAG_PIXDATA_NEGEDGE;
377
377 omapdss_display_init(dssdev); 378 omapdss_display_init(dssdev);
378 omapdss_device_register(dssdev); 379 omapdss_device_register(dssdev);
379 380
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
index 42f80b3ec350..ae7a40a1759a 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
@@ -81,13 +81,7 @@ static const struct videomode tpo_td043_vm = {
81 .vfront_porch = 39, 81 .vfront_porch = 39,
82 .vback_porch = 34, 82 .vback_porch = 34,
83 83
84 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | 84 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
85 DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_SYNC_POSEDGE |
86 DISPLAY_FLAGS_PIXDATA_NEGEDGE,
87 /*
88 * Note: According to the panel documentation:
89 * SYNC needs to be driven on the FALLING edge
90 */
91}; 85};
92 86
93#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) 87#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
@@ -472,6 +466,13 @@ static int tpo_td043_probe(struct spi_device *spi)
472 dssdev->owner = THIS_MODULE; 466 dssdev->owner = THIS_MODULE;
473 dssdev->of_ports = BIT(0); 467 dssdev->of_ports = BIT(0);
474 468
469 /*
470 * Note: According to the panel documentation:
471 * SYNC needs to be driven on the FALLING edge
472 */
473 dssdev->bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_SYNC_POSEDGE
474 | DRM_BUS_FLAG_PIXDATA_NEGEDGE;
475
475 omapdss_display_init(dssdev); 476 omapdss_display_init(dssdev);
476 omapdss_device_register(dssdev); 477 omapdss_device_register(dssdev);
477 478
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 0afefac4bf65..280f63081224 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -4053,12 +4053,6 @@ static int dsi_display_init_dispc(struct dsi_data *dsi)
4053 dsi->vm.flags |= DISPLAY_FLAGS_HSYNC_HIGH; 4053 dsi->vm.flags |= DISPLAY_FLAGS_HSYNC_HIGH;
4054 dsi->vm.flags &= ~DISPLAY_FLAGS_VSYNC_LOW; 4054 dsi->vm.flags &= ~DISPLAY_FLAGS_VSYNC_LOW;
4055 dsi->vm.flags |= DISPLAY_FLAGS_VSYNC_HIGH; 4055 dsi->vm.flags |= DISPLAY_FLAGS_VSYNC_HIGH;
4056 dsi->vm.flags &= ~DISPLAY_FLAGS_PIXDATA_NEGEDGE;
4057 dsi->vm.flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
4058 dsi->vm.flags &= ~DISPLAY_FLAGS_DE_LOW;
4059 dsi->vm.flags |= DISPLAY_FLAGS_DE_HIGH;
4060 dsi->vm.flags &= ~DISPLAY_FLAGS_SYNC_POSEDGE;
4061 dsi->vm.flags |= DISPLAY_FLAGS_SYNC_NEGEDGE;
4062 4056
4063 dss_mgr_set_timings(&dsi->output, &dsi->vm); 4057 dss_mgr_set_timings(&dsi->output, &dsi->vm);
4064 4058
@@ -5142,6 +5136,9 @@ static int dsi_init_output(struct dsi_data *dsi)
5142 out->ops = &dsi_ops; 5136 out->ops = &dsi_ops;
5143 out->owner = THIS_MODULE; 5137 out->owner = THIS_MODULE;
5144 out->of_ports = BIT(0); 5138 out->of_ports = BIT(0);
5139 out->bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE
5140 | DRM_BUS_FLAG_DE_HIGH
5141 | DRM_BUS_FLAG_SYNC_NEGEDGE;
5145 5142
5146 out->next = omapdss_of_find_connected_device(out->dev->of_node, 0); 5143 out->next = omapdss_of_find_connected_device(out->dev->of_node, 0);
5147 if (IS_ERR(out->next)) { 5144 if (IS_ERR(out->next)) {
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 87306014a53a..251e092dfb05 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -432,6 +432,7 @@ struct omap_dss_device {
432 const struct omap_dss_driver *driver; 432 const struct omap_dss_driver *driver;
433 const struct omap_dss_device_ops *ops; 433 const struct omap_dss_device_ops *ops;
434 unsigned long ops_flags; 434 unsigned long ops_flags;
435 unsigned long bus_flags;
435 436
436 /* helper variable for driver suspend/resume */ 437 /* helper variable for driver suspend/resume */
437 bool activate_after_resume; 438 bool activate_after_resume;
diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c
index 3b5f97932475..8e111afe5958 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -151,9 +151,6 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
151 if (r) 151 if (r)
152 goto err_get_dispc; 152 goto err_get_dispc;
153 153
154 /* 15.5.9.1.2 */
155 vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE | DISPLAY_FLAGS_SYNC_POSEDGE;
156
157 r = sdi_calc_clock_div(sdi, vm->pixelclock, &fck, &dispc_cinfo); 154 r = sdi_calc_clock_div(sdi, vm->pixelclock, &fck, &dispc_cinfo);
158 if (r) 155 if (r)
159 goto err_calc_clock_div; 156 goto err_calc_clock_div;
@@ -298,6 +295,8 @@ static int sdi_init_output(struct sdi_device *sdi)
298 out->of_ports = BIT(1); 295 out->of_ports = BIT(1);
299 out->ops = &sdi_ops; 296 out->ops = &sdi_ops;
300 out->owner = THIS_MODULE; 297 out->owner = THIS_MODULE;
298 out->bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE /* 15.5.9.1.2 */
299 | DRM_BUS_FLAG_SYNC_POSEDGE;
301 300
302 out->next = omapdss_of_find_connected_device(out->dev->of_node, 1); 301 out->next = omapdss_of_find_connected_device(out->dev->of_node, 1);
303 if (IS_ERR(out->next)) { 302 if (IS_ERR(out->next)) {
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 6e7a777907f5..39693dfe54af 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -419,12 +419,9 @@ static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc,
419static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc) 419static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
420{ 420{
421 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 421 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
422 struct omap_dss_device *display = omap_crtc->pipe->display;
423 struct drm_display_mode *mode = &crtc->state->adjusted_mode; 422 struct drm_display_mode *mode = &crtc->state->adjusted_mode;
424 const u32 flags_mask = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_DE_LOW | 423 struct videomode *vm = &omap_crtc->vm;
425 DISPLAY_FLAGS_PIXDATA_POSEDGE | DISPLAY_FLAGS_PIXDATA_NEGEDGE | 424 struct omap_dss_device *dssdev;
426 DISPLAY_FLAGS_SYNC_POSEDGE | DISPLAY_FLAGS_SYNC_NEGEDGE;
427 struct videomode vm = {0};
428 425
429 DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 426 DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
430 omap_crtc->name, mode->base.id, mode->name, 427 omap_crtc->name, mode->base.id, mode->name,
@@ -433,7 +430,7 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
433 mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal, 430 mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal,
434 mode->type, mode->flags); 431 mode->type, mode->flags);
435 432
436 drm_display_mode_to_videomode(mode, &omap_crtc->vm); 433 drm_display_mode_to_videomode(mode, vm);
437 434
438 /* 435 /*
439 * HACK: This fixes the vm flags. 436 * HACK: This fixes the vm flags.
@@ -442,13 +439,36 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
442 * struct drm_display_mode and struct videomode. The hack below 439 * struct drm_display_mode and struct videomode. The hack below
443 * goes and fetches the missing flags from the panel drivers. 440 * goes and fetches the missing flags from the panel drivers.
444 * 441 *
445 * Correct solution would be to use DRM's bus-flags, but that's not 442 * A better solution is to use DRM's bus-flags through the whole driver.
446 * easily possible before the omapdrm's panel/encoder driver model
447 * has been changed to the DRM model.
448 */ 443 */
449 444
450 display->ops->get_timings(display, &vm); 445 for (dssdev = omap_crtc->pipe->output; dssdev; dssdev = dssdev->next) {
451 omap_crtc->vm.flags |= vm.flags & flags_mask; 446 unsigned long bus_flags = dssdev->bus_flags;
447
448 if (!(vm->flags & (DISPLAY_FLAGS_DE_LOW |
449 DISPLAY_FLAGS_DE_HIGH))) {
450 if (bus_flags & DRM_BUS_FLAG_DE_LOW)
451 vm->flags |= DISPLAY_FLAGS_DE_LOW;
452 else if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
453 vm->flags |= DISPLAY_FLAGS_DE_HIGH;
454 }
455
456 if (!(vm->flags & (DISPLAY_FLAGS_PIXDATA_POSEDGE |
457 DISPLAY_FLAGS_PIXDATA_NEGEDGE))) {
458 if (bus_flags & DRM_BUS_FLAG_PIXDATA_POSEDGE)
459 vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
460 else if (bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE)
461 vm->flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE;
462 }
463
464 if (!(vm->flags & (DISPLAY_FLAGS_SYNC_POSEDGE |
465 DISPLAY_FLAGS_SYNC_NEGEDGE))) {
466 if (bus_flags & DRM_BUS_FLAG_SYNC_POSEDGE)
467 vm->flags |= DISPLAY_FLAGS_SYNC_POSEDGE;
468 else if (bus_flags & DRM_BUS_FLAG_SYNC_NEGEDGE)
469 vm->flags |= DISPLAY_FLAGS_SYNC_NEGEDGE;
470 }
471 }
452} 472}
453 473
454static int omap_crtc_atomic_check(struct drm_crtc *crtc, 474static int omap_crtc_atomic_check(struct drm_crtc *crtc,