aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/omap_connector.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_connector.c')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_connector.c101
1 files changed, 58 insertions, 43 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index 344414ef3962..5091991363d6 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -170,65 +170,80 @@ static void omap_connector_destroy(struct drm_connector *connector)
170 170
171#define MAX_EDID 512 171#define MAX_EDID 512
172 172
173static int omap_connector_get_modes_edid(struct drm_connector *connector,
174 struct omap_dss_device *dssdev)
175{
176 struct omap_connector *omap_connector = to_omap_connector(connector);
177 enum drm_connector_status status;
178 void *edid;
179 int n;
180
181 status = omap_connector_detect(connector, false);
182 if (status != connector_status_connected)
183 goto no_edid;
184
185 edid = kzalloc(MAX_EDID, GFP_KERNEL);
186 if (!edid)
187 goto no_edid;
188
189 if (dssdev->ops->read_edid(dssdev, edid, MAX_EDID) <= 0 ||
190 !drm_edid_is_valid(edid)) {
191 kfree(edid);
192 goto no_edid;
193 }
194
195 drm_connector_update_edid_property(connector, edid);
196 n = drm_add_edid_modes(connector, edid);
197
198 omap_connector->hdmi_mode = drm_detect_hdmi_monitor(edid);
199
200 kfree(edid);
201 return n;
202
203no_edid:
204 drm_connector_update_edid_property(connector, NULL);
205 return 0;
206}
207
173static int omap_connector_get_modes(struct drm_connector *connector) 208static int omap_connector_get_modes(struct drm_connector *connector)
174{ 209{
175 struct omap_connector *omap_connector = to_omap_connector(connector); 210 struct omap_connector *omap_connector = to_omap_connector(connector);
176 struct omap_dss_device *dssdev = omap_connector->dssdev; 211 struct omap_dss_device *dssdev;
177 struct drm_device *dev = connector->dev; 212 struct drm_display_mode *mode;
178 int n = 0; 213 struct videomode vm = {0};
179 214
180 DBG("%s", omap_connector->dssdev->name); 215 DBG("%s", omap_connector->dssdev->name);
181 216
182 /* if display exposes EDID, then we parse that in the normal way to 217 /*
183 * build table of supported modes.. otherwise (ie. fixed resolution 218 * If display exposes EDID, then we parse that in the normal way to
219 * build table of supported modes. Otherwise (ie. fixed resolution
184 * LCD panels) we just return a single mode corresponding to the 220 * LCD panels) we just return a single mode corresponding to the
185 * currently configured timings: 221 * currently configured timings.
186 */ 222 */
187 if (dssdev->ops->read_edid) { 223 dssdev = omap_connector_find_device(connector,
188 void *edid = kzalloc(MAX_EDID, GFP_KERNEL); 224 OMAP_DSS_DEVICE_OP_EDID);
189 225 if (dssdev)
190 if (!edid) 226 return omap_connector_get_modes_edid(connector, dssdev);
191 return 0;
192
193 if ((dssdev->ops->read_edid(dssdev, edid, MAX_EDID) > 0) &&
194 drm_edid_is_valid(edid)) {
195 drm_connector_update_edid_property(
196 connector, edid);
197 n = drm_add_edid_modes(connector, edid);
198
199 omap_connector->hdmi_mode =
200 drm_detect_hdmi_monitor(edid);
201 } else {
202 drm_connector_update_edid_property(
203 connector, NULL);
204 }
205
206 kfree(edid);
207 } else {
208 struct drm_display_mode *mode = drm_mode_create(dev);
209 struct videomode vm = {0};
210 227
211 if (!mode) 228 mode = drm_mode_create(connector->dev);
212 return 0; 229 if (!mode)
230 return 0;
213 231
214 dssdev->ops->get_timings(dssdev, &vm); 232 dssdev = omap_connector->dssdev;
233 dssdev->ops->get_timings(dssdev, &vm);
215 234
216 drm_display_mode_from_videomode(&vm, mode); 235 drm_display_mode_from_videomode(&vm, mode);
217 236
218 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 237 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
219 drm_mode_set_name(mode); 238 drm_mode_set_name(mode);
220 drm_mode_probed_add(connector, mode); 239 drm_mode_probed_add(connector, mode);
221 240
222 if (dssdev->driver && dssdev->driver->get_size) { 241 if (dssdev->driver && dssdev->driver->get_size)
223 dssdev->driver->get_size(dssdev, 242 dssdev->driver->get_size(dssdev,
224 &connector->display_info.width_mm, 243 &connector->display_info.width_mm,
225 &connector->display_info.height_mm); 244 &connector->display_info.height_mm);
226 }
227 245
228 n = 1; 246 return 1;
229 }
230
231 return n;
232} 247}
233 248
234static int omap_connector_mode_valid(struct drm_connector *connector, 249static int omap_connector_mode_valid(struct drm_connector *connector,