From patchwork Wed Jun 6 09:36:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 10449945 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id AFD1760375 for ; Wed, 6 Jun 2018 09:38:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A100F29736 for ; Wed, 6 Jun 2018 09:38:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 95EA6299AA; Wed, 6 Jun 2018 09:38:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0534B29736 for ; Wed, 6 Jun 2018 09:38:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2BFB56E98C; Wed, 6 Jun 2018 09:36:58 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8F91A6E701 for ; Wed, 6 Jun 2018 09:36:55 +0000 (UTC) Received: from avalon.bb.dnainternet.fi (dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 909B134B6; Wed, 6 Jun 2018 11:36:46 +0200 (CEST) From: Laurent Pinchart To: dri-devel@lists.freedesktop.org Subject: [PATCH 18/21] drm/omap: Don't call EDID read operation recursively Date: Wed, 6 Jun 2018 12:36:47 +0300 Message-Id: <20180606093650.26034-19-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180606093650.26034-1-laurent.pinchart@ideasonboard.com> References: <20180606093650.26034-1-laurent.pinchart@ideasonboard.com> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Tomi Valkeinen MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Instead of calling the EDID read operation (.read_edid()) recursively from the display device back to the first device that provides EDID read support, iterate over the devices manually in the DRM connector code. This moves the complexity to a single central location and simplifies the logic in omap_dss_device drivers. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/displays/connector-dvi.c | 15 +-- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 11 --- .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 13 --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 1 + drivers/gpu/drm/omapdrm/dss/hdmi5.c | 1 + drivers/gpu/drm/omapdrm/omap_connector.c | 101 ++++++++++++--------- 6 files changed, 65 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c index 6be260ff6458..eae4108330f1 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c @@ -166,12 +166,6 @@ static int dvic_read_edid(struct omap_dss_device *dssdev, struct panel_drv_data *ddata = to_panel_data(dssdev); int r, l, bytes_read; - if (ddata->hpd_gpio && !gpiod_get_value_cansleep(ddata->hpd_gpio)) - return -ENODEV; - - if (!ddata->i2c_adapter) - return -ENODEV; - l = min(EDID_LENGTH, len); r = dvic_ddc_read(ddata->i2c_adapter, edid, l, 0); if (r) @@ -341,10 +335,11 @@ static int dvic_probe(struct platform_device *pdev) dssdev->of_ports = BIT(0); if (ddata->hpd_gpio) - dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT - | OMAP_DSS_DEVICE_OP_HPD; - else if (ddata->i2c_adapter) - dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT; + dssdev->ops_flags |= OMAP_DSS_DEVICE_OP_DETECT + | OMAP_DSS_DEVICE_OP_HPD; + if (ddata->i2c_adapter) + dssdev->ops_flags |= OMAP_DSS_DEVICE_OP_DETECT + | OMAP_DSS_DEVICE_OP_EDID; omapdss_display_init(dssdev); omapdss_device_register(dssdev); diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 6f2364afb14a..16dc22edcb8e 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -15,8 +15,6 @@ #include #include -#include - #include "../dss/omapdss.h" static const struct videomode hdmic_default_vm = { @@ -126,14 +124,6 @@ static int hdmic_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); } -static int hdmic_read_edid(struct omap_dss_device *dssdev, - u8 *edid, int len) -{ - struct omap_dss_device *src = dssdev->src; - - return src->ops->read_edid(src, edid, len); -} - static bool hdmic_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); @@ -190,7 +180,6 @@ static const struct omap_dss_device_ops hdmic_ops = { .get_timings = hdmic_get_timings, .check_timings = hdmic_check_timings, - .read_edid = hdmic_read_edid, .detect = hdmic_detect, .register_hpd_cb = hdmic_register_hpd_cb, .unregister_hpd_cb = hdmic_unregister_hpd_cb, diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index 2772af84531a..dbbf9683bd51 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -115,18 +115,6 @@ static int tpd_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); } -static int tpd_read_edid(struct omap_dss_device *dssdev, - u8 *edid, int len) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *src = dssdev->src; - - if (!gpiod_get_value_cansleep(ddata->hpd_gpio)) - return -ENODEV; - - return src->ops->read_edid(src, edid, len); -} - static bool tpd_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); @@ -180,7 +168,6 @@ static const struct omap_dss_device_ops tpd_ops = { .disable = tpd_disable, .check_timings = tpd_check_timings, .set_timings = tpd_set_timings, - .read_edid = tpd_read_edid, .detect = tpd_detect, .register_hpd_cb = tpd_register_hpd_cb, .unregister_hpd_cb = tpd_unregister_hpd_cb, diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index bebce93fed3e..c92564300446 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -711,6 +711,7 @@ static int hdmi4_init_output(struct omap_hdmi *hdmi) out->ops = &hdmi_ops; out->owner = THIS_MODULE; out->of_ports = BIT(0); + out->ops_flags = OMAP_DSS_DEVICE_OP_EDID; out->next = omapdss_of_find_connected_device(out->dev->of_node, 0); if (IS_ERR(out->next)) { diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index 7c07e0208107..2aaa8ee61662 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -703,6 +703,7 @@ static int hdmi5_init_output(struct omap_hdmi *hdmi) out->ops = &hdmi_ops; out->owner = THIS_MODULE; out->of_ports = BIT(0); + out->ops_flags = OMAP_DSS_DEVICE_OP_EDID; out->next = omapdss_of_find_connected_device(out->dev->of_node, 0); if (IS_ERR(out->next)) { diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index 1b3f85a02c85..a1d379816732 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) #define MAX_EDID 512 +static int omap_connector_get_modes_edid(struct drm_connector *connector, + struct omap_dss_device *dssdev) +{ + struct omap_connector *omap_connector = to_omap_connector(connector); + enum drm_connector_status status; + void *edid; + int n; + + status = omap_connector_detect(connector, false); + if (status != connector_status_connected) + goto no_edid; + + edid = kzalloc(MAX_EDID, GFP_KERNEL); + if (!edid) + goto no_edid; + + if (dssdev->ops->read_edid(dssdev, edid, MAX_EDID) <= 0 || + !drm_edid_is_valid(edid)) { + kfree(edid); + goto no_edid; + } + + drm_mode_connector_update_edid_property(connector, edid); + n = drm_add_edid_modes(connector, edid); + + omap_connector->hdmi_mode = drm_detect_hdmi_monitor(edid); + + kfree(edid); + return n; + +no_edid: + drm_mode_connector_update_edid_property(connector, NULL); + return 0; +} + static int omap_connector_get_modes(struct drm_connector *connector) { struct omap_connector *omap_connector = to_omap_connector(connector); - struct omap_dss_device *dssdev = omap_connector->dssdev; - struct drm_device *dev = connector->dev; - int n = 0; + struct omap_dss_device *dssdev; + struct drm_display_mode *mode; + struct videomode vm = {0}; DBG("%s", omap_connector->dssdev->name); - /* if display exposes EDID, then we parse that in the normal way to - * build table of supported modes.. otherwise (ie. fixed resolution + /* + * 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: + * currently configured timings. */ - if (dssdev->ops->read_edid) { - void *edid = kzalloc(MAX_EDID, GFP_KERNEL); - - if (!edid) - return 0; - - if ((dssdev->ops->read_edid(dssdev, edid, MAX_EDID) > 0) && - drm_edid_is_valid(edid)) { - drm_mode_connector_update_edid_property( - connector, edid); - n = drm_add_edid_modes(connector, edid); - - omap_connector->hdmi_mode = - drm_detect_hdmi_monitor(edid); - } else { - drm_mode_connector_update_edid_property( - connector, NULL); - } - - kfree(edid); - } else { - struct drm_display_mode *mode = drm_mode_create(dev); - struct videomode vm = {0}; + dssdev = omap_connector_find_device(connector, + OMAP_DSS_DEVICE_OP_EDID); + if (dssdev) + return omap_connector_get_modes_edid(connector, dssdev); - if (!mode) - return 0; + mode = drm_mode_create(connector->dev); + if (!mode) + return 0; - dssdev->ops->get_timings(dssdev, &vm); + dssdev = omap_connector->dssdev; + dssdev->ops->get_timings(dssdev, &vm); - drm_display_mode_from_videomode(&vm, mode); + drm_display_mode_from_videomode(&vm, mode); - mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; - drm_mode_set_name(mode); - drm_mode_probed_add(connector, mode); + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + drm_mode_set_name(mode); + drm_mode_probed_add(connector, mode); - if (dssdev->driver && dssdev->driver->get_size) { - dssdev->driver->get_size(dssdev, + if (dssdev->driver && dssdev->driver->get_size) + dssdev->driver->get_size(dssdev, &connector->display_info.width_mm, &connector->display_info.height_mm); - } - n = 1; - } - - return n; + return 1; } static int omap_connector_mode_valid(struct drm_connector *connector,