summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/omapdrm/dss/venc.c12
-rw-r--r--drivers/gpu/drm/omapdrm/omap_connector.c34
2 files changed, 37 insertions, 9 deletions
diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c
index 255bf2cd8afc..09ec8b0eafee 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -568,6 +568,16 @@ static void venc_display_disable(struct omap_dss_device *dssdev)
mutex_unlock(&venc->venc_lock);
}
+static void venc_get_timings(struct omap_dss_device *dssdev,
+ struct videomode *vm)
+{
+ struct venc_device *venc = dssdev_to_venc(dssdev);
+
+ mutex_lock(&venc->venc_lock);
+ *vm = venc->vm;
+ mutex_unlock(&venc->venc_lock);
+}
+
static void venc_set_timings(struct omap_dss_device *dssdev,
const struct videomode *vm)
{
@@ -720,6 +730,7 @@ static const struct omap_dss_device_ops venc_ops = {
.disable = venc_display_disable,
.check_timings = venc_check_timings,
+ .get_timings = venc_get_timings,
.set_timings = venc_set_timings,
};
@@ -877,6 +888,7 @@ static int venc_probe(struct platform_device *pdev)
mutex_init(&venc->venc_lock);
venc->wss_data = 0;
+ venc->vm = omap_dss_pal_vm;
venc_mem = platform_get_resource(venc->pdev, IORESOURCE_MEM, 0);
venc->base = devm_ioremap_resource(&pdev->dev, venc_mem);
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index 302f2ed245d0..b8317b697083 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -218,20 +218,41 @@ static int omap_connector_get_modes(struct drm_connector *connector)
/*
* If display exposes EDID, then we parse that in the normal way to
- * build table of supported modes. Otherwise (ie. fixed resolution
- * LCD panels) we just return a single mode corresponding to the
- * currently configured timings.
+ * build table of supported modes.
*/
dssdev = omap_connector_find_device(connector,
OMAP_DSS_DEVICE_OP_EDID);
if (dssdev)
return omap_connector_get_modes_edid(connector, dssdev);
+ /*
+ * Otherwise we have either a fixed resolution panel or an output that
+ * doesn't support modes discovery (e.g. DVI or VGA with the DDC bus
+ * unconnected, or analog TV). Start by querying the size.
+ */
+ dssdev = omap_connector->display;
+ if (dssdev->driver && dssdev->driver->get_size)
+ dssdev->driver->get_size(dssdev,
+ &connector->display_info.width_mm,
+ &connector->display_info.height_mm);
+
+ /*
+ * Iterate over the pipeline to find the first device that can provide
+ * timing information. If we can't find any, we just let the KMS core
+ * add the default modes.
+ */
+ for (dssdev = omap_connector->display; dssdev; dssdev = dssdev->src) {
+ if (dssdev->ops->get_timings)
+ break;
+ }
+ if (!dssdev)
+ return 0;
+
+ /* Add a single mode corresponding to the fixed panel timings. */
mode = drm_mode_create(connector->dev);
if (!mode)
return 0;
- dssdev = omap_connector->display;
dssdev->ops->get_timings(dssdev, &vm);
drm_display_mode_from_videomode(&vm, mode);
@@ -240,11 +261,6 @@ static int omap_connector_get_modes(struct drm_connector *connector)
drm_mode_set_name(mode);
drm_mode_probed_add(connector, mode);
- if (dssdev->driver && dssdev->driver->get_size)
- dssdev->driver->get_size(dssdev,
- &connector->display_info.width_mm,
- &connector->display_info.height_mm);
-
return 1;
}