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: 111444 Delivered-To: patch@linaro.org Received: by 10.140.95.112 with SMTP id h103csp100563qge; Thu, 31 Aug 2017 14:35:57 -0700 (PDT) X-Received: by 10.84.238.199 with SMTP id l7mr4186817pln.346.1504215357316; Thu, 31 Aug 2017 14:35:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504215357; cv=none; d=google.com; s=arc-20160816; b=kuBt23cZlh+2/uK2P3fngbxZCf3Vev1ED+oLoSHVhm0xpLte/EjXaAFRPcGj7UgqE6 0MmSboXgq1H7Z1vPh8JQdjVFEwiAlFRhGYPPM0KrmuHaxBaNqVG74mJ4+n4Chwe5MP01 VImJHhEXMOJMuJSrv5FvyPqODA52Wxpl8ea49BaELT8a/Ia3332ad9tyC429PUNruBnh 0sQR43hh8X+ikS+fTm7lzSdkugSZepfkUZW9YuGMP1r9rC0t1h7+YChzIM/EswAFrwy9 phheKjme8imEMtv0gz4j2iEI9dmf+WNlgLVAImnQyEgHkv+GmDrrX9oPc8PY6Gn1nO2i eYKA== 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=HMJ5Z9nia9MsSxreoefuGO23hfGeeAuK1oalcJcN3cY=; b=iVASGONF2QvuVn60LTXNueEg86Zc/8FYLdwGRE21iT8DGS0RXjoDJbQNqLOaiOmKVQ zfCQlzPiKAzmcUmXsgoEdFAQ6jxthipLcJ0X74XhHJlcHMOB8jJnCXRxDwqaPoGZVtDz uAhVvax+dvYr8xtACC5swX1WjzZrEyC9XeHody1QpBW7xbTo+kxLB1vnea+XtUA4IVH8 qnaRKuecG0LMadPxT/McoulqG6f87Aa52THqryCypf6QvJGwiEpoX6vdYWhEd88DPZJy lhHFMGdhX5EINiRveUWKi+4P4YDzKZ1kJwng0K3/uJcf80JeEgDdkvQxh+ug5HFohbbv BfzQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=IlrpblUB; 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 64si482044plb.209.2017.08.31.14.35.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 31 Aug 2017 14:35:57 -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=IlrpblUB; 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 7ECFC6E785; Thu, 31 Aug 2017 21:35:25 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lf0-x22d.google.com (mail-lf0-x22d.google.com [IPv6:2a00:1450:4010:c07::22d]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1B9046E785 for ; Thu, 31 Aug 2017 21:35:23 +0000 (UTC) Received: by mail-lf0-x22d.google.com with SMTP id a126so3302243lfa.0 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=mzwKyjyZk9AZIUFDClXaZXUl6QCWoLFw6SI//z1fEJt5gX1KCFtx+0i6+nsMRNy0r5 9emrHuMPgeARASu6GbNB5+XSOA2hiHWBKlNPQPZeCAAPrcWwdR1Wx+qDEFWb4NHZXnDZ ehmYEEbnxKcxduzJjVjQSgTtCEyPKwU3Ka+0bOrs70IJjhEAYZBufkr3H+4zi6looTmn 71ToamtB1OQ31iJXzmfhSSUj4Hn22TXC6h6etvKF3G0ijI1xKyd25jyyiWdHNeX1+y+J LVkTK9FW3sEnMXoG9C9+eLBZGpM99DO+O/ruAR5FfL6ifuobfHghsAwlh44jwHwI77dx 3M9g== X-Gm-Message-State: AHYfb5hUmgwiuAMSwvw4nhw1RXSHeyenC0Q4U70FBLiQoDmX99utNVIB dOB+QNg/U3DJUcCMf4byrQ== 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 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. 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);