From patchwork Mon Feb 11 09:46:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 10805451 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DD3C11515 for ; Mon, 11 Feb 2019 09:49:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C884029938 for ; Mon, 11 Feb 2019 09:49:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B9D9829936; Mon, 11 Feb 2019 09:49:01 +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 3886A29936 for ; Mon, 11 Feb 2019 09:49:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 89F7D6E4D2; Mon, 11 Feb 2019 09:48:06 +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 237716E43E for ; Mon, 11 Feb 2019 09:47:40 +0000 (UTC) Received: from pendragon.brusselsairlines.com (233.56-78-194.adsl-static.isp.belgacom.be [194.78.56.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DE8DB2201; Mon, 11 Feb 2019 10:47:18 +0100 (CET) From: Laurent Pinchart To: dri-devel@lists.freedesktop.org Subject: [PATCH v3 33/50] drm/omap: Refactor initialization sequence Date: Mon, 11 Feb 2019 11:46:48 +0200 Message-Id: <20190211094705.2845-34-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190211094705.2845-1-laurent.pinchart@ideasonboard.com> References: <20190211094705.2845-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP The omapdrm driver initialization procedure starts by connecting all available pipelines, gathering related information (such as output and display DSS devices, and DT aliases), sorting them by alias, and finally creates all the DRM/KMS objects. When using DRM bridges instead of DSS devices, we will need to attach to the bridges before getting the aliases. As attaching to bridges requires an encoder object, we have to reorganize the initialization sequence to create encoders before getting aliases and sorting the pipelines. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel Tested-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/omap_drv.c | 123 +++++++++++++---------------- 1 file changed, 56 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 008eec6356fd..33f79c490011 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -150,48 +150,27 @@ static void omap_disconnect_pipelines(struct drm_device *ddev) priv->num_pipes = 0; } -static int omap_compare_pipes(const void *a, const void *b) -{ - const struct omap_drm_pipeline *pipe1 = a; - const struct omap_drm_pipeline *pipe2 = b; - - if (pipe1->alias_id > pipe2->alias_id) - return 1; - else if (pipe1->alias_id < pipe2->alias_id) - return -1; - return 0; -} - static int omap_connect_pipelines(struct drm_device *ddev) { struct omap_drm_private *priv = ddev->dev_private; struct omap_dss_device *output = NULL; - unsigned int i; int r; - if (!omapdss_stack_is_ready()) - return -EPROBE_DEFER; - for_each_dss_output(output) { r = omapdss_device_connect(priv->dss, NULL, output); if (r == -EPROBE_DEFER) { omapdss_device_put(output); - goto cleanup; + return r; } else if (r) { dev_warn(output->dev, "could not connect output %s\n", output->name); } else { struct omap_drm_pipeline *pipe; - int id; pipe = &priv->pipes[priv->num_pipes++]; pipe->output = omapdss_device_get(output); pipe->display = omapdss_display_get(output); - id = of_alias_get_id(pipe->display->dev->of_node, - "display"); - pipe->alias_id = id >= 0 ? id : priv->num_pipes - 1; - if (priv->num_pipes == ARRAY_SIZE(priv->pipes)) { /* To balance the 'for_each_dss_output' loop */ omapdss_device_put(output); @@ -200,36 +179,19 @@ static int omap_connect_pipelines(struct drm_device *ddev) } } - /* Sort the list by DT aliases */ - sort(priv->pipes, priv->num_pipes, sizeof(priv->pipes[0]), - omap_compare_pipes, NULL); - - /* - * Populate the pipeline lookup table by DISPC channel. Only one display - * is allowed per channel. - */ - for (i = 0; i < priv->num_pipes; ++i) { - struct omap_drm_pipeline *pipe = &priv->pipes[i]; - enum omap_channel channel = pipe->output->dispc_channel; - - if (WARN_ON(priv->channels[channel] != NULL)) { - r = -EINVAL; - goto cleanup; - } - - priv->channels[channel] = pipe; - } - return 0; +} -cleanup: - /* - * if we are deferring probe, we disconnect the devices we previously - * connected - */ - omap_disconnect_pipelines(ddev); +static int omap_compare_pipelines(const void *a, const void *b) +{ + const struct omap_drm_pipeline *pipe1 = a; + const struct omap_drm_pipeline *pipe2 = b; - return r; + if (pipe1->alias_id > pipe2->alias_id) + return 1; + else if (pipe1->alias_id < pipe2->alias_id) + return -1; + return 0; } static int omap_modeset_init_properties(struct drm_device *dev) @@ -254,6 +216,9 @@ static int omap_modeset_init(struct drm_device *dev) int ret; u32 plane_crtc_mask; + if (!omapdss_stack_is_ready()) + return -EPROBE_DEFER; + drm_mode_config_init(dev); ret = omap_modeset_init_properties(dev); @@ -268,6 +233,10 @@ static int omap_modeset_init(struct drm_device *dev) * configuration does not match the expectations or exceeds * the available resources, the configuration is rejected. */ + ret = omap_connect_pipelines(dev); + if (ret < 0) + return ret; + if (priv->num_pipes > num_mgrs || priv->num_pipes > num_ovls) { dev_err(dev->dev, "%s(): Too many connected displays\n", __func__); @@ -293,33 +262,58 @@ static int omap_modeset_init(struct drm_device *dev) priv->planes[priv->num_planes++] = plane; } - /* Create the CRTCs, encoders and connectors. */ + /* Create the encoders and get the pipelines aliases. */ for (i = 0; i < priv->num_pipes; i++) { struct omap_drm_pipeline *pipe = &priv->pipes[i]; - struct omap_dss_device *display = pipe->display; + int id; + + pipe->encoder = omap_encoder_init(dev, pipe->output); + if (!pipe->encoder) + return -ENOMEM; + + id = of_alias_get_id(pipe->display->dev->of_node, "display"); + pipe->alias_id = id >= 0 ? id : i; + } + + /* Sort the pipelines by DT aliases. */ + sort(priv->pipes, priv->num_pipes, sizeof(priv->pipes[0]), + omap_compare_pipelines, NULL); + + /* + * Populate the pipeline lookup table by DISPC channel. Only one display + * is allowed per channel. + */ + for (i = 0; i < priv->num_pipes; ++i) { + struct omap_drm_pipeline *pipe = &priv->pipes[i]; + enum omap_channel channel = pipe->output->dispc_channel; + + if (WARN_ON(priv->channels[channel] != NULL)) + return -EINVAL; + + priv->channels[channel] = pipe; + } + + /* Create the connectors and CRTCs. */ + for (i = 0; i < priv->num_pipes; i++) { + struct omap_drm_pipeline *pipe = &priv->pipes[i]; + struct drm_encoder *encoder = pipe->encoder; struct drm_connector *connector; - struct drm_encoder *encoder; struct drm_crtc *crtc; - encoder = omap_encoder_init(dev, pipe->output); - if (!encoder) - return -ENOMEM; - - connector = omap_connector_init(dev, pipe->output, display, - encoder); + connector = omap_connector_init(dev, pipe->output, + pipe->display, encoder); if (!connector) return -ENOMEM; + drm_connector_attach_encoder(connector, encoder); + pipe->connector = connector; + crtc = omap_crtc_init(dev, pipe, priv->planes[i]); if (IS_ERR(crtc)) return PTR_ERR(crtc); - drm_connector_attach_encoder(connector, encoder); encoder->possible_crtcs = 1 << i; - pipe->crtc = crtc; - pipe->encoder = encoder; - pipe->connector = connector; } DBG("registered %u planes, %u crtcs/encoders/connectors\n", @@ -556,10 +550,6 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) omap_crtc_pre_init(priv); - ret = omap_connect_pipelines(ddev); - if (ret) - goto err_crtc_uninit; - soc = soc_device_match(omapdrm_soc_devices); priv->omaprev = soc ? (unsigned int)soc->data : 0; priv->wq = alloc_ordered_workqueue("omapdrm", 0); @@ -617,7 +607,6 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) omap_gem_deinit(ddev); destroy_workqueue(priv->wq); omap_disconnect_pipelines(ddev); -err_crtc_uninit: omap_crtc_pre_uninit(priv); drm_dev_put(ddev); return ret;