From patchwork Sat Sep 2 20:07:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 111504 Delivered-To: patch@linaro.org Received: by 10.140.95.112 with SMTP id h103csp2630649qge; Sat, 2 Sep 2017 13:07:24 -0700 (PDT) X-Received: by 10.99.161.26 with SMTP id b26mr7084927pgf.168.1504382844621; Sat, 02 Sep 2017 13:07:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504382844; cv=none; d=google.com; s=arc-20160816; b=cseSCZM2gAn2KCiGCN8OnTdtX3KwmasTm8qliqPyCBUkKqWvXXXx6P4JpEwDk3Rhv2 wzoZ+Vfw4oDIALmgemoRfmsDIxcd+q9pPVyF2djHbfpj4UVpJOVaZVQDNyzI1FfRKEw6 hPsZ4k716bGkXrGhwuhO22RkG10FVdgauLuwUARAxtEcEA5lTLFuwcxafONtKYOYPIbQ i/EGFU2EOxbfCetxUh1HRWAUeOnEFDlH1YvPRLKVy0ocSwl/h8R9k3khev4Xor7DNKy8 lsLcmHwBAcwh9ojET9AdUQ1DIX9WUlnc+EwIwDiQKOT9wYxx4VeE8VnNlro5q3ZF0KPQ focA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:cc:message-id:date:subject:to:from :dkim-signature:delivered-to:arc-authentication-results; bh=7jDhUM1BjoTSzCydrmy0k4yTL6gYyuvKZ41QcM1FK7U=; b=h7ZTkGSej5e6T+Nj7uvrGXIB5OurxzorQcKaTPK8bEJMjdVjkdgtY5MnAASi8x0TcH JArinsChmVehrhlykNgou6ySRj0nvs4UdU7RvLxEPHQBzDPuiq5XSyDqhzP9ncC5+fKu 1E2/+/9T6E7XihQcLze+HAqaQ2GOOvO6P+Uy4wCJJsflJ4+pdsW3/wp+URjZ6grvO1v3 58u++sYEhv1XOMk0dVQHlDDFCc98JVAtaaKij/VdgLOTJJm+Op0grHnNFGUrL/xHWvsr i+tiLdDSGZkeQucU8YmX7YbpIr3g+/MtjKT3rB5yr2xylN4uGGBuPiTOqKD7uZHgLPo3 UFSQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Xf4V2gQU; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [131.252.210.177]) by mx.google.com with ESMTPS id p11si2471857pli.726.2017.09.02.13.07.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 02 Sep 2017 13:07:24 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) client-ip=131.252.210.177; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Xf4V2gQU; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DA0206E091; Sat, 2 Sep 2017 20:07:21 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lf0-x231.google.com (mail-lf0-x231.google.com [IPv6:2a00:1450:4010:c07::231]) by gabe.freedesktop.org (Postfix) with ESMTPS id 99D0B6E08F for ; Sat, 2 Sep 2017 20:07:19 +0000 (UTC) Received: by mail-lf0-x231.google.com with SMTP id a126so9840259lfa.0 for ; Sat, 02 Sep 2017 13:07:19 -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=Ik2TV1MujY2Hq7gOydT35ThjDWdzOYvoNMjDWNc5wSk=; b=Xf4V2gQUUtM09q0LkoA/fVMtNIVmwGvCqdBpsNMPIjj2p1If/BnA3S2qXdCHNm4xV5 S8CVqYE1hBB6FdJ53+3XYisUQX9jLn5vi2WXDkMsNdexh883fgfRqj1Qwx7cuIWiMck1 dwBDFPOH2XE2lN4AWShRG5x0BTjqtC19qZRAM= 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=Ik2TV1MujY2Hq7gOydT35ThjDWdzOYvoNMjDWNc5wSk=; b=PhP8rEYUERQaGdlYndNb1ZHlXUeQ1fUI1Co9WJPEhGN7rHdS9OlvYzxv4Q5D7GQK6Y nl9v3VDP1vukabu1HTx0QuI7hUXIhQoivKtAhkFe96ZFrXjYwp9HgbhMGRz1WDLVE+Tr k5/9BAzcwZ65dznlk9x4DyjrrTnq5u8SDOa/gqKjYFNw3gxPShzcGlEm/1QSHGXNZ8F1 qVoDtIlhzFU5OVtNmdMIC4osacJQZG0Vj+xHf0vtaqwSpAxk6No1kJXmNn8UfkKI5HnI uNcQ7WIoCT7zJeo7NbC+iXl77MoJGj7tyHYx+xzISJ8BDpi2oouuMvy/vO7auaVezWIK HL9Q== X-Gm-Message-State: AHPjjUgHslMwqp/vL7Po4mkpTRSKpAmN/RO8TNKbrNza0M7wcttSF+YH pZ5oVewwUDfqyouQpPQ6BA== X-Google-Smtp-Source: ADKCNb5p7zilPnWIBZuXihYVCMrxRasrvc4P6ljWAc2gmRPinWigUnwHitGQitpXwbkVP9tP2ounNg== X-Received: by 10.25.165.130 with SMTP id o124mr2335816lfe.29.1504382837448; Sat, 02 Sep 2017 13:07:17 -0700 (PDT) Received: from fabina.bredbandsbolaget.se (c-707b71d5.014-348-6c756e10.cust.bredbandsbolaget.se. [213.113.123.112]) by smtp.gmail.com with ESMTPSA id b202sm234343lfg.80.2017.09.02.13.07.16 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 02 Sep 2017 13:07:16 -0700 (PDT) From: Linus Walleij To: dri-devel@lists.freedesktop.org, Eric Anholt , Daniel Vetter , Jani Nikula , Sean Paul Subject: [PATCH v2] drm/tve200: Replace custom connector with panel bridge Date: Sat, 2 Sep 2017 22:07:11 +0200 Message-Id: <20170902200711.29298-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.13.5 Cc: linux-arm-kernel@lists.infradead.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" 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. Reviewed-by: Eric Anholt Signed-off-by: Linus Walleij Acked-by: Daniel Vetter --- ChangeLog v1->v2: - Drop a few surplus #includes - Collect Eric's review tag --- 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 | 10 +-- drivers/gpu/drm/tve200/tve200_drv.c | 66 +++++++++++----- 6 files changed, 59 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..b463624c1f29 100644 --- a/drivers/gpu/drm/tve200/tve200_drm.h +++ b/drivers/gpu/drm/tve200/tve200_drm.h @@ -96,15 +96,13 @@ #include #include -struct tve200_drm_connector { - struct drm_connector connector; - struct drm_panel *panel; -}; - 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);