diff options
Diffstat (limited to 'drivers/gpu/drm/omapdrm')
-rw-r--r-- | drivers/gpu/drm/omapdrm/dss/venc.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_connector.c | 34 |
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; } |