From patchwork Tue Apr 18 12:39:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrzej Hajda X-Patchwork-Id: 9685475 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 BACA2602C9 for ; Tue, 18 Apr 2017 12:40:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AC4EC2522B for ; Tue, 18 Apr 2017 12:40:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A10422841C; Tue, 18 Apr 2017 12:40:22 +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 D6AFB2522B for ; Tue, 18 Apr 2017 12:40:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753376AbdDRMkU (ORCPT ); Tue, 18 Apr 2017 08:40:20 -0400 Received: from mailout3.w1.samsung.com ([210.118.77.13]:46152 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753212AbdDRMkR (ORCPT ); Tue, 18 Apr 2017 08:40:17 -0400 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OOL00EL0V72VI90@mailout3.w1.samsung.com> for linux-samsung-soc@vger.kernel.org; Tue, 18 Apr 2017 13:40:14 +0100 (BST) Received: from eusmges4.samsung.com (unknown [203.254.199.244]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170418124013eucas1p1e8247a771531bb23b94852871094a55a~2flE0wBpf3088130881eucas1p1g; Tue, 18 Apr 2017 12:40:13 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges4.samsung.com (EUCPMTA) with SMTP id 57.CB.04729.D2906F85; Tue, 18 Apr 2017 13:40:13 +0100 (BST) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170418124013eucas1p13103c8630a1acd86d607d02d95916786~2flENFi0m1108411084eucas1p1m; Tue, 18 Apr 2017 12:40:13 +0000 (GMT) X-AuditID: cbfec7f4-f79806d000001279-cf-58f6092d2284 Received: from eusync1.samsung.com ( [203.254.199.211]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 72.E6.17452.DA906F85; Tue, 18 Apr 2017 13:42:21 +0100 (BST) Received: from AMDC2768.DIGITAL.local ([106.120.43.17]) by eusync1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OOL006UZV6ZTM40@eusync1.samsung.com>; Tue, 18 Apr 2017 13:40:13 +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 Subject: [PATCH 3/7] drm/exynos/dsi: refactor panel detection logic Date: Tue, 18 Apr 2017 14:39:59 +0200 Message-id: <1492519203-23537-4-git-send-email-a.hajda@samsung.com> X-Mailer: git-send-email 2.7.4 In-reply-to: <1492519203-23537-1-git-send-email-a.hajda@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrLIsWRmVeSWpSXmKPExsWy7djP87q6nN8iDE7tkLO4te4cq8XGGetZ La58fc9mMen+BBaLGef3MVmsPXKX3YHN4373cSaPvi2rGD0+b5ILYI7isklJzcksSy3St0vg ymh+MIe54KNtxb++70wNjLOMuxg5OSQETCQeXV/FAmGLSVy4t56ti5GLQ0hgKaPEhgfXmSGc z4wSu6b+YoTpONJ5AqpqGaPEhLmrmCCc/4wSp7r6mUCq2AQ0Jf5uvskGYosIKEus2tfODlLE LHCJUeL1yW6wUcICzhJzNq9lBbFZBFQlXn56DWbzAsVn7vgHtU5O4ua5TmYQm1PARaL33GlW kEESAtfZJH7N/ABUxAHkyEpsOsAMUe8i8fr0JzYIW1ji1fEt7BC2jERnx0EmiN5uRolP/SfY IZwpjBL/PsyA6raWOHz8ItgVzAJ8EpO2TWeGWMAr0dEmBFHiIfGq6y3UUEeJh4+3QcNiOqNE 9/LzjBMYZRYwMqxiFEktLc5NTy020StOzC0uzUvXS87P3cQIjNTT/45/2cG4+JjVIUYBDkYl Ht4V+75ECLEmlhVX5h5ilOBgVhLhXffha4QQb0piZVVqUX58UWlOavEhRmkOFiVxXq5T1yKE BNITS1KzU1MLUotgskwcnFINjEWr/xzXlfd52nPA/ZoaQ39arnHM4eYt087+Ld/+2kvc4Q9v 1GSZZSJ/lGYKiR71eSSUvdRX4q9H6cIAxasPzzTaiy8zVqlyWzJdNPxTeiHfMaOe/9Wlvaa1 8jx1s5PuCxqHpbY5xBrEK9w3MhGU9+R/4rXlkeCVizvP6c1ac+Lel+7wG0ublFiKMxINtZiL ihMBQcZDxNACAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrNLMWRmVeSWpSXmKPExsVy+t/xy7prOb9FGGzr17G4te4cq8XGGetZ La58fc9mMen+BBaLGef3MVmsPXKX3YHN4373cSaPvi2rGD0+b5ILYI5ys8lITUxJLVJIzUvO T8nMS7dVCg1x07VQUshLzE21VYrQ9Q0JUlIoS8wpBfKMDNCAg3OAe7CSvl2CW0bzgznMBR9t K/71fWdqYJxl3MXIySEhYCJxpPMEG4QtJnHh3nogm4tDSGAJo8S900+gnEYmiUkPlzODVLEJ aEr83XwTrENEQFli1b52dpAiZoErjBLt37rYQRLCAs4SczavZQWxWQRUJV5+eg1m8wLFZ+74 xwixTk7i5rlOsKGcAi4SvedOg9UIAdWsn3OScQIj7wJGhlWMIqmlxbnpucWGesWJucWleel6 yfm5mxiBAbvt2M/NOxgvbQw+xCjAwajEw7ti35cIIdbEsuLK3EOMEhzMSiK86z58jRDiTUms rEotyo8vKs1JLT7EaAp01ERmKdHkfGA05ZXEG5oYmlsaGhlbWJgbGSmJ85Z8uBIuJJCeWJKa nZpakFoE08fEwSnVwMjcqm8duFZrh4z5yhfhmso9yimma1iKOL6fsvrrZvTYv8+/n8XVg3nt lmq/uXOX2t6anpOe2jdZc7Vso8VE39XZyx4cYtfQNWjJ9PlV9nNtnxIr28RV+zdt/89sHRA1 1Sn04bz4kKrj6hG/fGbqRafWvd691fF7ibMOX2BtrceMHTM+uN0VUGIpzkg01GIuKk4EAKn7 FF1uAgAA X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170418124013eucas1p13103c8630a1acd86d607d02d95916786 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-HopCount: 7 X-CMS-RootMailID: 20170418124013eucas1p13103c8630a1acd86d607d02d95916786 X-RootMTR: 20170418124013eucas1p13103c8630a1acd86d607d02d95916786 References: <1492519203-23537-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 | 204 ++++++++++++++++---------------- 1 file changed, 103 insertions(+), 101 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 3ae459f..515090f 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) @@ -1576,6 +1479,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); @@ -1612,6 +1516,104 @@ 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) {