From patchwork Thu Aug 24 13:33:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrzej Hajda X-Patchwork-Id: 9920049 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 430F760349 for ; Thu, 24 Aug 2017 13:34:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3AF102847D for ; Thu, 24 Aug 2017 13:34:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2F31328639; Thu, 24 Aug 2017 13:34:34 +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=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9ED5128500 for ; Thu, 24 Aug 2017 13:34:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752993AbdHXNe2 (ORCPT ); Thu, 24 Aug 2017 09:34:28 -0400 Received: from mailout1.w1.samsung.com ([210.118.77.11]:43182 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752844AbdHXNeN (ORCPT ); Thu, 24 Aug 2017 09:34:13 -0400 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20170824133411euoutp01ebb103aac9e01a525ef2e237527cb53a~dy4utoZug1779717797euoutp01f; Thu, 24 Aug 2017 13:34:11 +0000 (GMT) Received: from eusmges4.samsung.com (unknown [203.254.199.244]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170824133410eucas1p2c602c78e54aaaaac14b4e331aa2efe7b~dy4tsFp8q3195231952eucas1p2a; Thu, 24 Aug 2017 13:34:10 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges4.samsung.com (EUCPMTA) with SMTP id 74.C8.12944.1D5DE995; Thu, 24 Aug 2017 14:34:10 +0100 (BST) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170824133409eucas1p170d11c2037d1f20629751f04c6f77c49~dy4tAwFsu2915629156eucas1p1M; Thu, 24 Aug 2017 13:34:09 +0000 (GMT) X-AuditID: cbfec7f4-f79ab6d000003290-ed-599ed5d12d66 Received: from eusync4.samsung.com ( [203.254.199.214]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 10.0D.18832.1D5DE995; Thu, 24 Aug 2017 14:34:09 +0100 (BST) Received: from AMDC2768.DIGITAL.local ([106.120.43.17]) by eusync4.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OV60031EZ0V8CD0@eusync4.samsung.com>; Thu, 24 Aug 2017 14:34:09 +0100 (BST) From: Andrzej Hajda To: Inki Dae Cc: Andrzej Hajda , Bartlomiej Zolnierkiewicz , Marek Szyprowski , dri-devel@lists.freedesktop.org, linux-samsung-soc@vger.kernel.org, devicetree@vger.kernel.org, Krzysztof Kozlowski Subject: [PATCH v2 03/10] drm/exynos/dsi: refactor panel detection logic Date: Thu, 24 Aug 2017 15:33:52 +0200 Message-id: <1503581639-580-4-git-send-email-a.hajda@samsung.com> X-Mailer: git-send-email 2.7.4 In-reply-to: <1503581639-580-1-git-send-email-a.hajda@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrFIsWRmVeSWpSXmKPExsWy7djPc7qXrs6LNFi5g9Hi1rpzrBYbZ6xn tZh/BMi68vU9m8Wk+xNYLM6f38BuMeP8PiaLtUfusjtweGxa1cnmcb/7OJNH35ZVjB6fN8kF sERx2aSk5mSWpRbp2yVwZayY9ZGx4KttxceGRrYGxpnGXYycHBICJhLz3jYxQthiEhfurWfr YuTiEBJYyigxpX0vO4TzmVFi846JLDAd25onM0IkljFKtCx8AtXyn1Hid+N+sFlsApoSfzff ZAOxRQSUJVbta2cHsZkFpjNJHGrRALGFBTwkbv5fDTaVRUBV4vOru2A1vAKOEgtXX2CC2CYn cfNcJzOIzSngJHFwzwqwZRIC79kkJj75yNrFyAHkyEpsOsAMUe8i8ePDRahLhSVeHd/CDmHL SHR2HGSC6O1mlPjUf4IdwpnCKPHvwwyobmuJw8cvskJcyicxadt0ZogFvBIdbUIQpofEpg1i ENWOEu+fvYV6fiqjxPZfWxgnMMosYGRYxSiSWlqcm55abKJXnJhbXJqXrpecn7uJERjDp/8d /7KDcfExq0OMAhyMSjy8N67MixRiTSwrrsw9xCjBwawkwrtrI1CINyWxsiq1KD++qDQntfgQ ozQHi5I4r21UW6SQQHpiSWp2ampBahFMlomDU6qBUbvHlC0mlJf5w49gnybzZ/1tc0I0wh7e NvobMt105o1DZs9l739+w5M0IcdgbZj7qs7fhzVrXhwJU2uMfam1ctGiRa9iwt9sfj9n4uGS M5eWKy4QeCCWs8E25j1vDVuF451AtlBbxbotqX+sLRw77ul56W3dE2EXv336V6cb7urc/FeY Vdw5lFiKMxINtZiLihMBLwxnGt0CAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrJLMWRmVeSWpSXmKPExsVy+t/xa7oXr86LNDhyTcHi1rpzrBYbZ6xn tZh/BMi68vU9m8Wk+xNYLM6f38BuMeP8PiaLtUfusjtweGxa1cnmcb/7OJNH35ZVjB6fN8kF sES52WSkJqakFimk5iXnp2TmpdsqhYa46VooKeQl5qbaKkXo+oYEKSmUJeaUAnlGBmjAwTnA PVhJ3y7BLWPFrI+MBV9tKz42NLI1MM407mLk5JAQMJHY1jyZEcIWk7hwbz1bFyMXh5DAEkaJ 3X+nMEM4jUwSdw7MZwapYhPQlPi7+SYbiC0ioCyxal87O4jNLDCTSaJ5DweILSzgIXHz/2oW EJtFQFXi86u7YDW8Ao4SC1dfYILYJidx81wn2ExOASeJg3tWgM0UAqq5+nofywRG3gWMDKsY RVJLi3PTc4sN9YoTc4tL89L1kvNzNzECg3nbsZ+bdzBe2hh8iFGAg1GJh7fh0rxIIdbEsuLK 3EOMEhzMSiK8uzYChXhTEiurUovy44tKc1KLDzGaAh01kVlKNDkfGGl5JfGGJobmloZGxhYW 5kZGSuK86pebIoUE0hNLUrNTUwtSi2D6mDg4pRoYZ8T8rE8v3C2+0XrP8sDamD2xey7VttkW e7f02ihHzOv6H5THdGWGU/GyMtnoxTw/X3/iy8l/teOT2h3niWuEq3lke0UCvdx2dssUz1x0 OOH/O70nm/JTivkbDx6oSG9aofdATuDX7NdvnP3Kzsjw5snPY1NRe5pj9k81i+tp66uybrnP n/yUWIozEg21mIuKEwHizy11fAIAAA== X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170824133409eucas1p170d11c2037d1f20629751f04c6f77c49 X-Msg-Generator: CA X-Sender-IP: 182.198.249.179 X-Local-Sender: =?UTF-8?B?QW5kcnplaiBIYWpkYRtTUlBPTC1LZXJuZWwgKFRQKRvsgrw=?= =?UTF-8?B?7ISx7KCE7J6QG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Global-Sender: =?UTF-8?B?QW5kcnplaiBIYWpkYRtTUlBPTC1LZXJuZWwgKFRQKRtTYW1z?= =?UTF-8?B?dW5nIEVsZWN0cm9uaWNzG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Sender-Code: =?UTF-8?B?QzEwG0VIURtDMTBDRDAyQ0QwMjczOTI=?= CMS-TYPE: 201P X-CMS-RootMailID: 20170824133409eucas1p170d11c2037d1f20629751f04c6f77c49 X-RootMTR: 20170824133409eucas1p170d11c2037d1f20629751f04c6f77c49 References: <1503581639-580-1-git-send-email-a.hajda@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Description of drm_helper_hpd_irq_event clearly states that drivers supporting hotplug events per connector should use different helper - drm_kms_helper_hotplug_event. To achieve it following changes have been performed: - moved down all DSI ops - they require exynos_dsi_disable function to be defined earlier, - simplified exynos_dsi_detect - there is no real detection, it just returns if panel is attached, - DSI attach/detach callbacks attaches/detaches DRM panel and sets connector status and other context fields accordingly, all this is performed under mutex, as these callbacks are asynchronous. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 203 ++++++++++++++++---------------- 1 file changed, 102 insertions(+), 101 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 6b46df6..063bac3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -254,7 +254,6 @@ struct exynos_dsi { struct drm_encoder encoder; struct mipi_dsi_host dsi_host; struct drm_connector connector; - struct device_node *panel_node; struct drm_panel *panel; struct device *dev; @@ -1329,12 +1328,13 @@ static int exynos_dsi_init(struct exynos_dsi *dsi) return 0; } -static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi) +static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi, + struct device *panel) { int ret; int te_gpio_irq; - dsi->te_gpio = of_get_named_gpio(dsi->panel_node, "te-gpios", 0); + dsi->te_gpio = of_get_named_gpio(panel->of_node, "te-gpios", 0); if (dsi->te_gpio == -ENOENT) return 0; @@ -1374,85 +1374,6 @@ static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsi) } } -static int exynos_dsi_host_attach(struct mipi_dsi_host *host, - struct mipi_dsi_device *device) -{ - struct exynos_dsi *dsi = host_to_dsi(host); - - dsi->lanes = device->lanes; - dsi->format = device->format; - dsi->mode_flags = device->mode_flags; - dsi->panel_node = device->dev.of_node; - - /* - * This is a temporary solution and should be made by more generic way. - * - * If attached panel device is for command mode one, dsi should register - * TE interrupt handler. - */ - if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO)) { - int ret = exynos_dsi_register_te_irq(dsi); - - if (ret) - return ret; - } - - if (dsi->connector.dev) - drm_helper_hpd_irq_event(dsi->connector.dev); - - return 0; -} - -static int exynos_dsi_host_detach(struct mipi_dsi_host *host, - struct mipi_dsi_device *device) -{ - struct exynos_dsi *dsi = host_to_dsi(host); - - exynos_dsi_unregister_te_irq(dsi); - - dsi->panel_node = NULL; - - if (dsi->connector.dev) - drm_helper_hpd_irq_event(dsi->connector.dev); - - return 0; -} - -static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host, - const struct mipi_dsi_msg *msg) -{ - struct exynos_dsi *dsi = host_to_dsi(host); - struct exynos_dsi_transfer xfer; - int ret; - - if (!(dsi->state & DSIM_STATE_ENABLED)) - return -EINVAL; - - if (!(dsi->state & DSIM_STATE_INITIALIZED)) { - ret = exynos_dsi_init(dsi); - if (ret) - return ret; - dsi->state |= DSIM_STATE_INITIALIZED; - } - - ret = mipi_dsi_create_packet(&xfer.packet, msg); - if (ret < 0) - return ret; - - xfer.rx_len = msg->rx_len; - xfer.rx_payload = msg->rx_buf; - xfer.flags = msg->flags; - - ret = exynos_dsi_transfer(dsi, &xfer); - return (ret < 0) ? ret : xfer.rx_done; -} - -static const struct mipi_dsi_host_ops exynos_dsi_ops = { - .attach = exynos_dsi_host_attach, - .detach = exynos_dsi_host_detach, - .transfer = exynos_dsi_host_transfer, -}; - static void exynos_dsi_enable(struct drm_encoder *encoder) { struct exynos_dsi *dsi = encoder_to_dsi(encoder); @@ -1508,25 +1429,7 @@ static void exynos_dsi_disable(struct drm_encoder *encoder) static enum drm_connector_status exynos_dsi_detect(struct drm_connector *connector, bool force) { - struct exynos_dsi *dsi = connector_to_dsi(connector); - - if (!dsi->panel) { - dsi->panel = of_drm_find_panel(dsi->panel_node); - if (dsi->panel) - drm_panel_attach(dsi->panel, &dsi->connector); - } else if (!dsi->panel_node) { - struct drm_encoder *encoder; - - encoder = platform_get_drvdata(to_platform_device(dsi->dev)); - exynos_dsi_disable(encoder); - drm_panel_detach(dsi->panel); - dsi->panel = NULL; - } - - if (dsi->panel) - return connector_status_connected; - - return connector_status_disconnected; + return connector->status; } static void exynos_dsi_connector_destroy(struct drm_connector *connector) @@ -1575,6 +1478,7 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder) return ret; } + connector->status = connector_status_disconnected; drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs); drm_mode_connector_attach_encoder(connector, encoder); @@ -1611,6 +1515,103 @@ static const struct drm_encoder_funcs exynos_dsi_encoder_funcs = { MODULE_DEVICE_TABLE(of, exynos_dsi_of_match); +static int exynos_dsi_host_attach(struct mipi_dsi_host *host, + struct mipi_dsi_device *device) +{ + struct exynos_dsi *dsi = host_to_dsi(host); + struct drm_device *drm = dsi->connector.dev; + + /* + * This is a temporary solution and should be made by more generic way. + * + * If attached panel device is for command mode one, dsi should register + * TE interrupt handler. + */ + if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) { + int ret = exynos_dsi_register_te_irq(dsi, &device->dev); + if (ret) + return ret; + } + + mutex_lock(&drm->mode_config.mutex); + + dsi->lanes = device->lanes; + dsi->format = device->format; + dsi->mode_flags = device->mode_flags; + dsi->panel = of_drm_find_panel(device->dev.of_node); + if (dsi->panel) { + drm_panel_attach(dsi->panel, &dsi->connector); + dsi->connector.status = connector_status_connected; + } + + mutex_unlock(&drm->mode_config.mutex); + + if (drm->mode_config.poll_enabled) + drm_kms_helper_hotplug_event(drm); + + return 0; +} + +static int exynos_dsi_host_detach(struct mipi_dsi_host *host, + struct mipi_dsi_device *device) +{ + struct exynos_dsi *dsi = host_to_dsi(host); + struct drm_device *drm = dsi->connector.dev; + + mutex_lock(&drm->mode_config.mutex); + + if (dsi->panel) { + exynos_dsi_disable(&dsi->encoder); + drm_panel_detach(dsi->panel); + dsi->panel = NULL; + dsi->connector.status = connector_status_disconnected; + } + + mutex_unlock(&drm->mode_config.mutex); + + if (drm->mode_config.poll_enabled) + drm_kms_helper_hotplug_event(drm); + + exynos_dsi_unregister_te_irq(dsi); + + return 0; +} + +static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host, + const struct mipi_dsi_msg *msg) +{ + struct exynos_dsi *dsi = host_to_dsi(host); + struct exynos_dsi_transfer xfer; + int ret; + + if (!(dsi->state & DSIM_STATE_ENABLED)) + return -EINVAL; + + if (!(dsi->state & DSIM_STATE_INITIALIZED)) { + ret = exynos_dsi_init(dsi); + if (ret) + return ret; + dsi->state |= DSIM_STATE_INITIALIZED; + } + + ret = mipi_dsi_create_packet(&xfer.packet, msg); + if (ret < 0) + return ret; + + xfer.rx_len = msg->rx_len; + xfer.rx_payload = msg->rx_buf; + xfer.flags = msg->flags; + + ret = exynos_dsi_transfer(dsi, &xfer); + return (ret < 0) ? ret : xfer.rx_done; +} + +static const struct mipi_dsi_host_ops exynos_dsi_ops = { + .attach = exynos_dsi_host_attach, + .detach = exynos_dsi_host_detach, + .transfer = exynos_dsi_host_transfer, +}; + static int exynos_dsi_of_read_u32(const struct device_node *np, const char *propname, u32 *out_value) {