aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2013-03-26 09:45:20 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2013-04-11 06:25:52 -0400
commitbddabbe174cfb6f944baaf13ed5b93c6ee89ec3d (patch)
tree99ebe6a65bd2a22973bcbf34069c70f5f1bbb635
parent581382e31090aa2459e8046e0bafb0f1daa2ecd8 (diff)
drm/omap: Make fixed resolution panels work
The omapdrm driver requires omapdss panel drivers to expose ops like detect, set_timings and check_timings. These can be NULL for fixed panel DPI, DBI, DSI and SDI drivers. At some places, there are no checks to see if the panel driver has these ops or not, and that leads to a crash. The following things are done to make fixed panels work: - The omap_connector's detect function is modified such that it considers panel types which are generally fixed panels as always connected(provided the panel driver doesn't have a detect op). Hence, the connector corresponding to these panels is always in a 'connected' state. - If a panel driver doesn't have a check_timings op, assume that it supports the mode passed to omap_connector_mode_valid(the 'mode_valid' drm helper function) - The function omap_encoder_update shouldn't really do anything for fixed resolution panels, make sure that it calls set_timings only if the panel driver has one. Signed-off-by: Archit Taneja <archit@ti.com> Reviewed-by: Rob Clark <robdclark@gmail.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r--drivers/gpu/drm/omapdrm/omap_connector.c27
-rw-r--r--drivers/gpu/drm/omapdrm/omap_encoder.c17
2 files changed, 40 insertions, 4 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index c451c41a7a7d..912759daf562 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -110,6 +110,11 @@ static enum drm_connector_status omap_connector_detect(
110 ret = connector_status_connected; 110 ret = connector_status_connected;
111 else 111 else
112 ret = connector_status_disconnected; 112 ret = connector_status_disconnected;
113 } else if (dssdev->type == OMAP_DISPLAY_TYPE_DPI ||
114 dssdev->type == OMAP_DISPLAY_TYPE_DBI ||
115 dssdev->type == OMAP_DISPLAY_TYPE_SDI ||
116 dssdev->type == OMAP_DISPLAY_TYPE_DSI) {
117 ret = connector_status_connected;
113 } else { 118 } else {
114 ret = connector_status_unknown; 119 ret = connector_status_unknown;
115 } 120 }
@@ -189,12 +194,30 @@ static int omap_connector_mode_valid(struct drm_connector *connector,
189 struct omap_video_timings timings = {0}; 194 struct omap_video_timings timings = {0};
190 struct drm_device *dev = connector->dev; 195 struct drm_device *dev = connector->dev;
191 struct drm_display_mode *new_mode; 196 struct drm_display_mode *new_mode;
192 int ret = MODE_BAD; 197 int r, ret = MODE_BAD;
193 198
194 copy_timings_drm_to_omap(&timings, mode); 199 copy_timings_drm_to_omap(&timings, mode);
195 mode->vrefresh = drm_mode_vrefresh(mode); 200 mode->vrefresh = drm_mode_vrefresh(mode);
196 201
197 if (!dssdrv->check_timings(dssdev, &timings)) { 202 /*
203 * if the panel driver doesn't have a check_timings, it's most likely
204 * a fixed resolution panel, check if the timings match with the
205 * panel's timings
206 */
207 if (dssdrv->check_timings) {
208 r = dssdrv->check_timings(dssdev, &timings);
209 } else {
210 struct omap_video_timings t = {0};
211
212 dssdrv->get_timings(dssdev, &t);
213
214 if (memcmp(&timings, &t, sizeof(struct omap_video_timings)))
215 r = -EINVAL;
216 else
217 r = 0;
218 }
219
220 if (!r) {
198 /* check if vrefresh is still valid */ 221 /* check if vrefresh is still valid */
199 new_mode = drm_mode_duplicate(dev, mode); 222 new_mode = drm_mode_duplicate(dev, mode);
200 new_mode->clock = timings.pixel_clock; 223 new_mode->clock = timings.pixel_clock;
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 21d126d0317e..18be00dd7b5e 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -128,13 +128,26 @@ int omap_encoder_update(struct drm_encoder *encoder,
128 128
129 dssdev->output->manager = mgr; 129 dssdev->output->manager = mgr;
130 130
131 ret = dssdrv->check_timings(dssdev, timings); 131 if (dssdrv->check_timings) {
132 ret = dssdrv->check_timings(dssdev, timings);
133 } else {
134 struct omap_video_timings t = {0};
135
136 dssdrv->get_timings(dssdev, &t);
137
138 if (memcmp(timings, &t, sizeof(struct omap_video_timings)))
139 ret = -EINVAL;
140 else
141 ret = 0;
142 }
143
132 if (ret) { 144 if (ret) {
133 dev_err(dev->dev, "could not set timings: %d\n", ret); 145 dev_err(dev->dev, "could not set timings: %d\n", ret);
134 return ret; 146 return ret;
135 } 147 }
136 148
137 dssdrv->set_timings(dssdev, timings); 149 if (dssdrv->set_timings)
150 dssdrv->set_timings(dssdev, timings);
138 151
139 return 0; 152 return 0;
140} 153}