From patchwork Thu Aug 31 21:35:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 9932969 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 230A460362 for ; Thu, 31 Aug 2017 21:36:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1494C25EA6 for ; Thu, 31 Aug 2017 21:36:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 076722621D; Thu, 31 Aug 2017 21:36:00 +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=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 457F025EA6 for ; Thu, 31 Aug 2017 21:35:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=Xv9uSAKc493ZXppO6EYC8t5bbpN2t96J3yoKrIt1CJs=; b=WHK bjj0+ZtMpPlg+BBco/IjWyqbj1fwiUeBLh+eIar46fgOK6lt6iJc5QyVy6zvox1WpQdARJbz1VGv5 +Vw2MDKjOS+TDJRarZEadpQq+iJFMJmVvCAEI0KUVHesu9yciDPI0AOc3V8rwzF6YnR+juAM5f9/X qq0VQS2I8fHWw0FFTa2zUVsRKkvCPOxVWDuNi05k5widhWyMXRoZveEILtTB5m0zvMleCFrfqNQ1Q NwPxKTWfGyzReA2b9IErmRQrQw+AthMaDZE6SJWB6iwwPG/7bcb6TU7dRfQqfI8tWy0TYR18IWSr1 qdd1FL9/QjJdRo8WJWfGZUXREQV9tzA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dnX7w-0007Ww-A0; Thu, 31 Aug 2017 21:35:52 +0000 Received: from mail-lf0-x230.google.com ([2a00:1450:4010:c07::230]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dnX7r-0007MR-9R for linux-arm-kernel@lists.infradead.org; Thu, 31 Aug 2017 21:35:50 +0000 Received: by mail-lf0-x230.google.com with SMTP id z12so3247514lfd.3 for ; Thu, 31 Aug 2017 14:35:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=OjGLr3zBJb0EByTcWKldYdr9yJ7NmOI90KbOBRuAEDI=; b=IlrpblUBVUDCecPpjHiz9LhnSu4iPZJY6vm2RoB647nFdEFp+lV/nZgtYBpGUgRevg SWpUS9bjIOmResZRYx3mgK6jY/L0eU3c71lEKGDr9vQakWy7THNzafKVpgsDs2//r1Ux NjxrbHSRy7f+T+PXsUV0q93baTWvenE6dOkDw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=OjGLr3zBJb0EByTcWKldYdr9yJ7NmOI90KbOBRuAEDI=; b=EDcK/LjLuwRh3/aNXDZXa39BEn3gLm8UId+0yecVzCOLDJMrxg9XUDkdXHMaNnKG+5 m76N7H1lCaV3Nof/2hSygLQ10wNyR0tWmCzYFa0j+Jjgfd2X7dWTbWTegtqRZ4VP4AdO Lx5a3ERkYL0nKJe6/1giY77WT33IacABIhaQnPrY/eC7gjCeG1Zg8RaJNuOdpfBC7jnl fgkZEjWloO3JkQEv6jbGM/snSJ+EiXokQUtdoQcVmr1/5q8qyNuqUWd6UQi110pVrneV UVofRxZuHd7oroJ1syrZg2vmMfCiiZTtejVBtU1jlUOIdX/rxncIWtez+FLQcWi9OJGs gcnw== X-Gm-Message-State: AHYfb5gxxU5d2V7vR4xZc2RIGcU6R2gHROgtvWP9njN9CuhgqE7XZ4hR TmgCGIcU+xHgtRXt X-Google-Smtp-Source: ADKCNb5xdJeshFUcZ++hMmGUxII0z0uqHmZCMldkiuqe6XUEe13RnT+nPkyrppXoWTJx43P9v1wEtw== X-Received: by 10.46.22.21 with SMTP id w21mr2676508ljd.83.1504215321839; Thu, 31 Aug 2017 14:35:21 -0700 (PDT) Received: from fabina.bredbandsbolaget.se (c-287571d5.014-348-6c756e10.cust.bredbandsbolaget.se. [213.113.117.40]) by smtp.gmail.com with ESMTPSA id h5sm146533ljb.55.2017.08.31.14.35.20 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 31 Aug 2017 14:35:21 -0700 (PDT) From: Linus Walleij To: dri-devel@lists.freedesktop.org, Eric Anholt , Daniel Vetter , Jani Nikula , Sean Paul Subject: [PATCH] drm/tve200: Replace custom connector with panel bridge Date: Thu, 31 Aug 2017 23:35:14 +0200 Message-Id: <20170831213514.29267-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.13.5 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170831_143547_822580_44A95A66 X-CRM114-Status: GOOD ( 23.04 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Linus Walleij , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This replaces the custom connector in the TVE200 with the panel bridge helper. As long as we're just using panels and no other bridges, this works just fine. Signed-off-by: Linus Walleij Reviewed-by: Eric Anholt --- drivers/gpu/drm/tve200/Kconfig | 3 +- drivers/gpu/drm/tve200/Makefile | 3 +- drivers/gpu/drm/tve200/tve200_connector.c | 125 ------------------------------ drivers/gpu/drm/tve200/tve200_display.c | 15 ++-- drivers/gpu/drm/tve200/tve200_drm.h | 14 ++-- drivers/gpu/drm/tve200/tve200_drv.c | 66 +++++++++++----- 6 files changed, 63 insertions(+), 163 deletions(-) delete mode 100644 drivers/gpu/drm/tve200/tve200_connector.c diff --git a/drivers/gpu/drm/tve200/Kconfig b/drivers/gpu/drm/tve200/Kconfig index 21d9841ddb88..c5f03bf4570c 100644 --- a/drivers/gpu/drm/tve200/Kconfig +++ b/drivers/gpu/drm/tve200/Kconfig @@ -4,7 +4,8 @@ config DRM_TVE200 depends on CMA depends on ARM || COMPILE_TEST depends on OF - select DRM_PANEL + select DRM_BRIDGE + select DRM_PANEL_BRIDGE select DRM_KMS_HELPER select DRM_KMS_CMA_HELPER select DRM_GEM_CMA_HELPER diff --git a/drivers/gpu/drm/tve200/Makefile b/drivers/gpu/drm/tve200/Makefile index a9dba54f7ee5..6b7a6a1dcbf8 100644 --- a/drivers/gpu/drm/tve200/Makefile +++ b/drivers/gpu/drm/tve200/Makefile @@ -1,5 +1,4 @@ -tve200_drm-y += tve200_connector.o \ - tve200_display.o \ +tve200_drm-y += tve200_display.o \ tve200_drv.o obj-$(CONFIG_DRM_TVE200) += tve200_drm.o diff --git a/drivers/gpu/drm/tve200/tve200_connector.c b/drivers/gpu/drm/tve200/tve200_connector.c deleted file mode 100644 index 5e6c20b57d6d..000000000000 --- a/drivers/gpu/drm/tve200/tve200_connector.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2017 Linus Walleij - * Parts of this file were based on sources as follows: - * - * Copyright (C) 2006-2008 Intel Corporation - * Copyright (C) 2007 Amos Lee - * Copyright (C) 2007 Dave Airlie - * Copyright (C) 2011 Texas Instruments - * Copyright (C) 2017 Eric Anholt - * - * This program is free software and is provided to you under the terms of the - * GNU General Public License version 2 as published by the Free Software - * Foundation, and any use by you of this program is subject to the terms of - * such GNU licence. - */ - -/** - * tve200_drm_connector.c - * Implementation of the connector functions for the Faraday TV Encoder - */ -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "tve200_drm.h" - -static void tve200_connector_destroy(struct drm_connector *connector) -{ - struct tve200_drm_connector *tve200con = - to_tve200_connector(connector); - - if (tve200con->panel) - drm_panel_detach(tve200con->panel); - - drm_connector_unregister(connector); - drm_connector_cleanup(connector); -} - -static enum drm_connector_status tve200_connector_detect(struct drm_connector - *connector, bool force) -{ - struct tve200_drm_connector *tve200con = - to_tve200_connector(connector); - - return (tve200con->panel ? - connector_status_connected : - connector_status_disconnected); -} - -static int tve200_connector_helper_get_modes(struct drm_connector *connector) -{ - struct tve200_drm_connector *tve200con = - to_tve200_connector(connector); - - if (!tve200con->panel) - return 0; - - return drm_panel_get_modes(tve200con->panel); -} - -static const struct drm_connector_funcs connector_funcs = { - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = tve200_connector_destroy, - .detect = tve200_connector_detect, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - -static const struct drm_connector_helper_funcs connector_helper_funcs = { - .get_modes = tve200_connector_helper_get_modes, -}; - -/* - * Walks the OF graph to find the panel node and then asks DRM to look - * up the panel. - */ -static struct drm_panel *tve200_get_panel(struct device *dev) -{ - struct device_node *endpoint, *panel_node; - struct device_node *np = dev->of_node; - struct drm_panel *panel; - - endpoint = of_graph_get_next_endpoint(np, NULL); - if (!endpoint) { - dev_err(dev, "no endpoint to fetch panel\n"); - return NULL; - } - - /* Don't proceed if we have an endpoint but no panel_node tied to it */ - panel_node = of_graph_get_remote_port_parent(endpoint); - of_node_put(endpoint); - if (!panel_node) { - dev_err(dev, "no valid panel node\n"); - return NULL; - } - - panel = of_drm_find_panel(panel_node); - of_node_put(panel_node); - - return panel; -} - -int tve200_connector_init(struct drm_device *dev) -{ - struct tve200_drm_dev_private *priv = dev->dev_private; - struct tve200_drm_connector *tve200con = &priv->connector; - struct drm_connector *connector = &tve200con->connector; - - drm_connector_init(dev, connector, &connector_funcs, - DRM_MODE_CONNECTOR_DPI); - drm_connector_helper_add(connector, &connector_helper_funcs); - - tve200con->panel = tve200_get_panel(dev->dev); - if (tve200con->panel) - drm_panel_attach(tve200con->panel, connector); - - return 0; -} diff --git a/drivers/gpu/drm/tve200/tve200_display.c b/drivers/gpu/drm/tve200/tve200_display.c index 37fb333331f3..cfdffc15a2ce 100644 --- a/drivers/gpu/drm/tve200/tve200_display.c +++ b/drivers/gpu/drm/tve200/tve200_display.c @@ -127,7 +127,7 @@ static void tve200_display_enable(struct drm_simple_display_pipe *pipe, struct tve200_drm_dev_private *priv = drm->dev_private; const struct drm_display_mode *mode = &cstate->mode; struct drm_framebuffer *fb = plane->state->fb; - struct drm_connector *connector = &priv->connector.connector; + struct drm_connector *connector = priv->connector; u32 format = fb->format->format; u32 ctrl1 = 0; @@ -215,13 +215,9 @@ static void tve200_display_enable(struct drm_simple_display_pipe *pipe, ctrl1 |= TVE200_TVEEN; - drm_panel_prepare(priv->connector.panel); - /* Turn it on */ writel(ctrl1, priv->regs + TVE200_CTRL); - drm_panel_enable(priv->connector.panel); - drm_crtc_vblank_on(crtc); } @@ -233,13 +229,9 @@ void tve200_display_disable(struct drm_simple_display_pipe *pipe) drm_crtc_vblank_off(crtc); - drm_panel_disable(priv->connector.panel); - /* Disable and Power Down */ writel(0, priv->regs + TVE200_CTRL); - drm_panel_unprepare(priv->connector.panel); - clk_disable_unprepare(priv->clk); } @@ -336,9 +328,12 @@ int tve200_display_init(struct drm_device *drm) ret = drm_simple_display_pipe_init(drm, &priv->pipe, &tve200_display_funcs, formats, ARRAY_SIZE(formats), - &priv->connector.connector); + priv->connector); if (ret) return ret; + /* We need the encoder to attach the bridge */ + priv->encoder = &priv->pipe.encoder; + return 0; } diff --git a/drivers/gpu/drm/tve200/tve200_drm.h b/drivers/gpu/drm/tve200/tve200_drm.h index f00fc47a6bd1..c7acfaa1a2c5 100644 --- a/drivers/gpu/drm/tve200/tve200_drm.h +++ b/drivers/gpu/drm/tve200/tve200_drm.h @@ -95,16 +95,18 @@ #include #include - -struct tve200_drm_connector { - struct drm_connector connector; - struct drm_panel *panel; -}; +#include +#include +#include +#include struct tve200_drm_dev_private { struct drm_device *drm; - struct tve200_drm_connector connector; + struct drm_connector *connector; + struct drm_encoder *encoder; + struct drm_panel *panel; + struct drm_bridge *bridge; struct drm_simple_display_pipe pipe; struct drm_fbdev_cma *fbdev; diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c index fe742106db4e..c22644692a88 100644 --- a/drivers/gpu/drm/tve200/tve200_drv.c +++ b/drivers/gpu/drm/tve200/tve200_drv.c @@ -47,6 +47,8 @@ #include #include #include +#include +#include #include "tve200_drm.h" @@ -62,6 +64,8 @@ static int tve200_modeset_init(struct drm_device *dev) { struct drm_mode_config *mode_config; struct tve200_drm_dev_private *priv = dev->dev_private; + struct drm_panel *panel; + struct drm_bridge *bridge; int ret = 0; drm_mode_config_init(dev); @@ -72,35 +76,51 @@ static int tve200_modeset_init(struct drm_device *dev) mode_config->min_height = 240; mode_config->max_height = 576; - ret = tve200_connector_init(dev); + ret = drm_of_find_panel_or_bridge(dev->dev->of_node, + 0, 0, &panel, &bridge); + if (ret && ret != -ENODEV) + return ret; + if (panel) { + bridge = drm_panel_bridge_add(panel, + DRM_MODE_CONNECTOR_Unknown); + if (IS_ERR(bridge)) { + ret = PTR_ERR(bridge); + goto out_bridge; + } + } + + ret = tve200_display_init(dev); if (ret) { - dev_err(dev->dev, "Failed to create tve200_drm_connector\n"); - goto out_config; + dev_err(dev->dev, "failed to init display\n"); + goto out_bridge; + } + + if (bridge) { + ret = drm_bridge_attach(priv->encoder, bridge, NULL); + if (ret) + goto out_bridge; } /* - * Don't actually attach if we didn't find a drm_panel - * attached to us. + * TODO: when we are using a different bridge than a panel + * (such as a dumb VGA connector) we need to devise a different + * method to get the connector out of the bridge. */ - if (!priv->connector.panel) { - dev_info(dev->dev, - "deferring due to lack of DRM panel device\n"); - ret = -EPROBE_DEFER; - goto out_config; + if (!panel) { + dev_err(dev->dev, "the bridge is not a panel\n"); + goto out_bridge; } - dev_info(dev->dev, "attached to panel %s\n", - dev_name(priv->connector.panel->dev)); + priv->panel = panel; + priv->connector = panel->connector; + priv->bridge = bridge; - ret = tve200_display_init(dev); - if (ret) { - dev_err(dev->dev, "failed to init display\n"); - goto out_config; - } + dev_info(dev->dev, "attached to panel %s\n", + dev_name(panel->dev)); ret = drm_vblank_init(dev, 1); if (ret) { dev_err(dev->dev, "failed to init vblank\n"); - goto out_config; + goto out_bridge; } drm_mode_config_reset(dev); @@ -115,7 +135,11 @@ static int tve200_modeset_init(struct drm_device *dev) goto finish; -out_config: +out_bridge: + if (panel) + drm_panel_bridge_remove(bridge); + else + drm_bridge_remove(bridge); drm_mode_config_cleanup(dev); finish: return ret; @@ -249,6 +273,10 @@ static int tve200_remove(struct platform_device *pdev) drm_dev_unregister(drm); if (priv->fbdev) drm_fbdev_cma_fini(priv->fbdev); + if (priv->panel) + drm_panel_bridge_remove(priv->bridge); + else + drm_bridge_remove(priv->bridge); drm_mode_config_cleanup(drm); clk_disable_unprepare(priv->pclk); drm_dev_unref(drm);