aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2018-06-06 10:49:37 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2018-09-03 09:13:30 -0400
commit35d944cbee2199312c6832a4acd0201a921545f4 (patch)
tree7fc1fee6cb7d2186bb07f4b1b6bab053b0174367
parent28120302c2fdf29b515c8cbd4e3a3867cb0cde7d (diff)
drm/omap: Query timing information from analog TV encoder
Timings for the TV output are currently reported by the analog TV connector. This has the disadvantage of having to handle timing-related operations in a connector omap_dss_device that has, at the hardware level, no knowledge of any timing information. Implement the .get_timings() operation in the venc driver, and get timings from the first component in the pipeline that implements the operatation. This switches the duty of reporting analog TV timings from the connector to the encoder. 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>
-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)
568 mutex_unlock(&venc->venc_lock); 568 mutex_unlock(&venc->venc_lock);
569} 569}
570 570
571static void venc_get_timings(struct omap_dss_device *dssdev,
572 struct videomode *vm)
573{
574 struct venc_device *venc = dssdev_to_venc(dssdev);
575
576 mutex_lock(&venc->venc_lock);
577 *vm = venc->vm;
578 mutex_unlock(&venc->venc_lock);
579}
580
571static void venc_set_timings(struct omap_dss_device *dssdev, 581static void venc_set_timings(struct omap_dss_device *dssdev,
572 const struct videomode *vm) 582 const struct videomode *vm)
573{ 583{
@@ -720,6 +730,7 @@ static const struct omap_dss_device_ops venc_ops = {
720 .disable = venc_display_disable, 730 .disable = venc_display_disable,
721 731
722 .check_timings = venc_check_timings, 732 .check_timings = venc_check_timings,
733 .get_timings = venc_get_timings,
723 .set_timings = venc_set_timings, 734 .set_timings = venc_set_timings,
724}; 735};
725 736
@@ -877,6 +888,7 @@ static int venc_probe(struct platform_device *pdev)
877 mutex_init(&venc->venc_lock); 888 mutex_init(&venc->venc_lock);
878 889
879 venc->wss_data = 0; 890 venc->wss_data = 0;
891 venc->vm = omap_dss_pal_vm;
880 892
881 venc_mem = platform_get_resource(venc->pdev, IORESOURCE_MEM, 0); 893 venc_mem = platform_get_resource(venc->pdev, IORESOURCE_MEM, 0);
882 venc->base = devm_ioremap_resource(&pdev->dev, venc_mem); 894 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)
218 218
219 /* 219 /*
220 * If display exposes EDID, then we parse that in the normal way to 220 * If display exposes EDID, then we parse that in the normal way to
221 * build table of supported modes. Otherwise (ie. fixed resolution 221 * build table of supported modes.
222 * LCD panels) we just return a single mode corresponding to the
223 * currently configured timings.
224 */ 222 */
225 dssdev = omap_connector_find_device(connector, 223 dssdev = omap_connector_find_device(connector,
226 OMAP_DSS_DEVICE_OP_EDID); 224 OMAP_DSS_DEVICE_OP_EDID);
227 if (dssdev) 225 if (dssdev)
228 return omap_connector_get_modes_edid(connector, dssdev); 226 return omap_connector_get_modes_edid(connector, dssdev);
229 227
228 /*
229 * Otherwise we have either a fixed resolution panel or an output that
230 * doesn't support modes discovery (e.g. DVI or VGA with the DDC bus
231 * unconnected, or analog TV). Start by querying the size.
232 */
233 dssdev = omap_connector->display;
234 if (dssdev->driver && dssdev->driver->get_size)
235 dssdev->driver->get_size(dssdev,
236 &connector->display_info.width_mm,
237 &connector->display_info.height_mm);
238
239 /*
240 * Iterate over the pipeline to find the first device that can provide
241 * timing information. If we can't find any, we just let the KMS core
242 * add the default modes.
243 */
244 for (dssdev = omap_connector->display; dssdev; dssdev = dssdev->src) {
245 if (dssdev->ops->get_timings)
246 break;
247 }
248 if (!dssdev)
249 return 0;
250
251 /* Add a single mode corresponding to the fixed panel timings. */
230 mode = drm_mode_create(connector->dev); 252 mode = drm_mode_create(connector->dev);
231 if (!mode) 253 if (!mode)
232 return 0; 254 return 0;
233 255
234 dssdev = omap_connector->display;
235 dssdev->ops->get_timings(dssdev, &vm); 256 dssdev->ops->get_timings(dssdev, &vm);
236 257
237 drm_display_mode_from_videomode(&vm, mode); 258 drm_display_mode_from_videomode(&vm, mode);
@@ -240,11 +261,6 @@ static int omap_connector_get_modes(struct drm_connector *connector)
240 drm_mode_set_name(mode); 261 drm_mode_set_name(mode);
241 drm_mode_probed_add(connector, mode); 262 drm_mode_probed_add(connector, mode);
242 263
243 if (dssdev->driver && dssdev->driver->get_size)
244 dssdev->driver->get_size(dssdev,
245 &connector->display_info.width_mm,
246 &connector->display_info.height_mm);
247
248 return 1; 264 return 1;
249} 265}
250 266