From patchwork Wed Oct 20 12:39:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 12572279 X-Patchwork-Delegate: neil.armstrong@linaro.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B0ABC433F5 for ; Wed, 20 Oct 2021 12:40:30 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3772961372 for ; Wed, 20 Oct 2021 12:40:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 3772961372 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=EmN9DlbiAMHisFN/XWLuGEvxnCTVUI4LkjKhdqCAP9A=; b=uH6eakha86XKHr 0GteqW1VFRTL4xDzRO3IIHpF0rM5uruMX8vYu0oDQz/1agJPIHxsypX6hN7bJHlJiZG9wc6IzCNZL TWg9OCMDgfShnmzpKh0DNMGzsw/g6HTr7PC+gqUP2XQqoAlsq57OUiMIt8b/UZk/iHGn5WRPgWyRm hpflnTJzvPLwTnftXbSyWJdOVy4qwYgLiT1E21Kl1keB2EFEiXYnDjHP81kfRkXRRNLVO/+5ZJIIu 0mwOwouhPY0kkfyI+r7OKIjkZPUHZup+lrHVJcG08BQYITEL1S4XE1H3naNR84tVjnlZg/TdIBdH2 /NVmnyZ7nzqbHwTOE7cg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdAtN-004V3b-ND; Wed, 20 Oct 2021 12:40:25 +0000 Received: from mail-wm1-x335.google.com ([2a00:1450:4864:20::335]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdAsq-004UnG-R6 for linux-amlogic@lists.infradead.org; Wed, 20 Oct 2021 12:39:56 +0000 Received: by mail-wm1-x335.google.com with SMTP id d198-20020a1c1dcf000000b00322f53b9b89so9943395wmd.0 for ; Wed, 20 Oct 2021 05:39:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=uNc+IrE+4SO33Ds9wqRQl0pqGwosqKnED8f9gFIZ4qQ=; b=sbcmiTisBHNPWCJCNj0ZEFL6T6yazKdDkenqxBK+vGcmvMPGyKGuEDdRczr5hN49G8 iTuJGRGgV4mNoOOi9jvAhQ8muFgKizP3rPwNBDanoSJdLWjNybTypdX8ZvHTwi2QZWND hWDU88N5I1VvHg52AWu0k1q4RT+AsTnyKLY2s+IIVt0F8H338KChTYxU9eWHqH2ggL5f xtYpNiGUccgoVVFcAgPktyYBIarMDEVLshmCVXI/eQbWpviuGsJSc+aRf5PSnyiXmF5l LQ/WGg9nZkhXqqAlNbOqNSxPDP4UVtALg21uGLl7mK3/O4wfT9AKTX3aG2yR3WU3TGn9 R0fA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=uNc+IrE+4SO33Ds9wqRQl0pqGwosqKnED8f9gFIZ4qQ=; b=5zpKrmOVdBmJbRv1qTIufS+4gO8QfBCaNe2xln7ORAYQhNYDtSPMIQhpG++o2AB7YR tfjskd+x5vrWP82rvdtLBw/X3Izg8KFRhXRJk3WRES3ENZ7E+S+KcrPOnaSFwQGcoMvM EIKEEonCt/nvi77fbnlbH3ltA0V2cPzj2NiQOOdidoQVcXjFuivK3sQQ2MBMQF6mx1Gh KC60Or1mZUOcA2bg8kQt4Uzkc8AtY4FutbpDDIVn42HvkdFfROn0PH3tWypMwW0BI62e zGEsfeZYC9oHA3KrF+cixrgSjWklnQ33AE2LIKly7xGV8G4otZL8y4gzJX/naAtAEzUT Lxdw== X-Gm-Message-State: AOAM530Xbr43IDa179fFuhXwrmxp8lpC9S3DqqvyljFKLI5+LAuYDFsx y112SpAmqgdgcPnrcpIpssFKjQ== X-Google-Smtp-Source: ABdhPJyfZenXNQXewRr9MrYXS1oHuTUvJJDaaL3WIBEzrGcuL8a1CKoWn41lbZIItQcqXIisJs5d9g== X-Received: by 2002:a5d:58ca:: with SMTP id o10mr52164130wrf.358.1634733591429; Wed, 20 Oct 2021 05:39:51 -0700 (PDT) Received: from localhost.localdomain ([2001:861:44c0:66c0:d31f:1512:8915:e439]) by smtp.gmail.com with ESMTPSA id b19sm5342680wmj.9.2021.10.20.05.39.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Oct 2021 05:39:51 -0700 (PDT) From: Neil Armstrong To: daniel@ffwll.ch, Laurent.pinchart@ideasonboard.com, sam@ravnborg.org Cc: martin.blumenstingl@googlemail.com, dri-devel@lists.freedesktop.org, linux-amlogic@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Neil Armstrong Subject: [PATCH v3 1/6] drm/bridge: display-connector: implement bus fmts callbacks Date: Wed, 20 Oct 2021 14:39:42 +0200 Message-Id: <20211020123947.2585572-2-narmstrong@baylibre.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211020123947.2585572-1-narmstrong@baylibre.com> References: <20211020123947.2585572-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5053; h=from:subject; bh=ZaTrpeiEqqaaclH17vTiRNAhyUGCyF81N0KiKn9lflo=; b=owEBbQKS/ZANAwAKAXfc29rIyEnRAcsmYgBhcA34Cdfjx5c+XeC3VOSgmFhN4Wi6IIA5tNLXd6l9 J94s5laJAjMEAAEKAB0WIQQ9U8YmyFYF/h30LIt33NvayMhJ0QUCYXAN+AAKCRB33NvayMhJ0dRoEA DDbIoGBmTMHXzmDKf2phe1k3efBjyW65XCjnPlwIcdCalhqUuzI7/uGmbSAg2HlHb1wY50I8tdblcb klAd7dzufsoPB0EnPN0mtiR3SBlPkcluR9aC2M7lJHEvo4kIk5OfLiM76yNxdvUOxo2N3rccsxusnm ZZ8m8HOpTcbXjE/XYg450Drq6wLQFf4N/dNM60JkpRyM2fduZNxjuloL564R3rnOPbM/cB8o2JkYQG 4xU4FdnQwfpxgNEPnE1pe3V8LFl+8yfBx0/4igtnbTFNwOukgtGUWjvY7GkeiDaTMaMKRLDJ/QAiXr cRsJ0tmF+wm3ayo+6dTpjCctypEB+SvUOoenlfvCJf6Jw86j42g2fkozV3xGMX2hsh0F/JrMkAbJqM mXkqUAO+nzA9Y4+sWHDRbTtqcqT/zLzrGC7oSF3wBjYk2TFTF0iSPnG0/t6gDLehk6N/28RzT3xhZB jC48h9zKJlTSwFhOrFK+37x+aZOdpuu+kABUJt6gAV/lrPULKdPa0iR6Oyw83JQqNJFnT/rB7geaX7 Vgh8Pmmfz1G0Ap1G4kz9ZhEhAPORqsHwSXHaLkNut0fkWD0N6BSLRLUrbpm4TR2eGFkqxpSZ18nMA4 VzlVm0oa2xAt0u4jKLUPBGhNj9B0vQ2HDnb04M9r5fFi9xB7m8yu/ILIwtuQ== X-Developer-Key: i=narmstrong@baylibre.com; a=openpgp; fpr=89EC3D058446217450F22848169AB7B1A4CFF8AE X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211020_053952_909755_3D2E5D89 X-CRM114-Status: GOOD ( 15.32 ) X-BeenThere: linux-amlogic@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-amlogic" Errors-To: linux-amlogic-bounces+linux-amlogic=archiver.kernel.org@lists.infradead.org Since this bridge is tied to the connector, it acts like a passthrough, so concerning the output & input bus formats, either pass the bus formats from the previous bridge or return fallback data like done in the bridge function: drm_atomic_bridge_chain_select_bus_fmts() & select_bus_fmt_recursive. This permits avoiding skipping the negociation if the remaining bridge chain has all the bits in place. Without this bus fmt negociation breaks on drm/meson HDMI pipeline when attaching dw-hdmi with DRM_BRIDGE_ATTACH_NO_CONNECTOR, because the last bridge of the display-connector doesn't implement buf fmt callbacks and MEDIA_BUS_FMT_FIXED is used leading to select an unsupported default bus format from dw-hdmi. Signed-off-by: Neil Armstrong Reviewed-by: Sam Ravnborg --- drivers/gpu/drm/bridge/display-connector.c | 86 ++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c index 847a0dce7f1d..d24f5b90feab 100644 --- a/drivers/gpu/drm/bridge/display-connector.c +++ b/drivers/gpu/drm/bridge/display-connector.c @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -87,10 +88,95 @@ static struct edid *display_connector_get_edid(struct drm_bridge *bridge, return drm_get_edid(connector, conn->bridge.ddc); } +/* + * Since this bridge is tied to the connector, it acts like a passthrough, + * so concerning the output bus formats, either pass the bus formats from the + * previous bridge or return fallback data like done in the bridge function: + * drm_atomic_bridge_chain_select_bus_fmts(). + * This supports negotiation if the bridge chain has all bits in place. + */ +static u32 *display_connector_get_output_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + unsigned int *num_output_fmts) +{ + struct drm_bridge *prev_bridge = drm_bridge_get_prev_bridge(bridge); + struct drm_bridge_state *prev_bridge_state; + + if (!prev_bridge || !prev_bridge->funcs->atomic_get_output_bus_fmts) { + struct drm_connector *conn = conn_state->connector; + u32 *out_bus_fmts; + + *num_output_fmts = 1; + out_bus_fmts = kmalloc(sizeof(*out_bus_fmts), GFP_KERNEL); + if (!out_bus_fmts) + return NULL; + + if (conn->display_info.num_bus_formats && + conn->display_info.bus_formats) + out_bus_fmts[0] = conn->display_info.bus_formats[0]; + else + out_bus_fmts[0] = MEDIA_BUS_FMT_FIXED; + + return out_bus_fmts; + } + + prev_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, + prev_bridge); + + return prev_bridge->funcs->atomic_get_output_bus_fmts(prev_bridge, prev_bridge_state, + crtc_state, conn_state, + num_output_fmts); +} + +/* + * Since this bridge is tied to the connector, it acts like a passthrough, + * so concerning the input bus formats, either pass the bus formats from the + * previous bridge or MEDIA_BUS_FMT_FIXED (like select_bus_fmt_recursive()) + * when atomic_get_input_bus_fmts is not supported. + * This supports negotiation if the bridge chain has all bits in place. + */ +static u32 *display_connector_get_input_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + struct drm_bridge *prev_bridge = drm_bridge_get_prev_bridge(bridge); + struct drm_bridge_state *prev_bridge_state; + + if (!prev_bridge || !prev_bridge->funcs->atomic_get_input_bus_fmts) { + u32 *in_bus_fmts; + + *num_input_fmts = 1; + in_bus_fmts = kmalloc(sizeof(*in_bus_fmts), GFP_KERNEL); + if (!in_bus_fmts) + return NULL; + + in_bus_fmts[0] = MEDIA_BUS_FMT_FIXED; + + return in_bus_fmts; + } + + prev_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, + prev_bridge); + + return prev_bridge->funcs->atomic_get_input_bus_fmts(prev_bridge, prev_bridge_state, + crtc_state, conn_state, output_fmt, + num_input_fmts); +} + static const struct drm_bridge_funcs display_connector_bridge_funcs = { .attach = display_connector_attach, .detect = display_connector_detect, .get_edid = display_connector_get_edid, + .atomic_get_output_bus_fmts = display_connector_get_output_bus_fmts, + .atomic_get_input_bus_fmts = display_connector_get_input_bus_fmts, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, }; static irqreturn_t display_connector_hpd_irq(int irq, void *arg) From patchwork Wed Oct 20 12:39:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 12572281 X-Patchwork-Delegate: neil.armstrong@linaro.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 24853C433EF for ; Wed, 20 Oct 2021 12:40:31 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E2F7061372 for ; Wed, 20 Oct 2021 12:40:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org E2F7061372 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=iOrOSbK+5xdJ2JGHl+57+YxaPZYdycFFk1cjxNfgibo=; b=HtB9Zj62HikWGX WU4xgAtR9jxHboQ6RyOxWg70CjK2cpYG6MrJkANemwIIAUISkPNGNNOM44btccK4RGPsX39GxHqwC l5FBbE0phJFMHadW3c8Nf1OJP+sWJD8CnnmMmcqSoNJBJ1Z+GW/JfAyKUJa18o4HounIXceVtLo9x dki0W5K5JX8sHereQd/g+3+9nsEs2lILdpEh5YgAL2QZBsCCfT4ke7sDSr1JpVaoj3xVrf1rrjYFt b761257+XA7M82xD8stdIjM6gK5TSSZlYcSwtSDj9VOR8HlBbPxjRnMuUB58u95Gd+MFfM6QvPfpm DRfJxh4qDAZ94C364tJA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdAtO-004V4C-Ls; Wed, 20 Oct 2021 12:40:26 +0000 Received: from mail-wm1-x330.google.com ([2a00:1450:4864:20::330]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdAsr-004Uny-Mq for linux-amlogic@lists.infradead.org; Wed, 20 Oct 2021 12:39:56 +0000 Received: by mail-wm1-x330.google.com with SMTP id u8-20020a05600c440800b0030d90076dabso4917673wmn.1 for ; Wed, 20 Oct 2021 05:39:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PrIMbe0cgeUgVskjVfxjc1cVVmfypfzeebevv5kx8mA=; b=Pr+dAUu/mCPN3ilMBfuPs7ptSAUMXt4BI+qeV09Iz2k7tIuYTum21jbIoYwZ6u8Inh 4F55yX2JqRgcxu5ICOWiLuVt0mIHSOj6NCBB7Vz14sR2vOUhWRxiN9K2RNbIxG3PXl53 qLWNetxF3ND0aAgWBfbS7lXorjHyXLAuKCYhfycmjEDhsgbXA3add3r3ZC777/JZo+EO 7zLvCizmox2FVdnJXKvjnN24f+3Lehb6Nc2bqbs0qmZ2E0q+yhl7Bw1fDW0mmtb7AzhT J60ReiHtGiNG19/06agfLC+UaACu4sGFSmlaqfzD89Zpb4VykuCDnTPzNPhZ9618edIR ePCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PrIMbe0cgeUgVskjVfxjc1cVVmfypfzeebevv5kx8mA=; b=sqZ/nr4VhgC9tozDtEF7bOHNacXCI+Nemkeqp+E6QXQAVZZxIPGKJlayxmxAFGfyhI QZ0omQuxj2Q44f/hxGI46IYwG1eUkc1e94Lh5sm2eqjCbAZfmPwfhAXgr6Lw+njdenkG 7oAQhS6CP4Mw8TwSiz7IiQCXX44nE+ZRNCqniqvykTvr4JStvnNw3fiMjpuiYcYtu0NP BztE4IYzzx6GHpjFiJ0EFndM8mkCb1m2JJS+57s+lcXm/m38MhX0QMpcFV8p0TWWxrFZ D7tbopl6ajAX3SD7Z+/I67agSpUYDPC9ht6N5v3vkaFoa3VyrdrbOhjh+MaPvhHSj9Qk bCjw== X-Gm-Message-State: AOAM532LHAO1eeImUAQYH/ZE8Bf/yI9i0iqVHVtFC6wOjXF+c4odcEBs +jnuGOmP8A/Hr+U0dB0o5lG9Yg== X-Google-Smtp-Source: ABdhPJw0ShkRNi7rCxTUF0MorfZe7tSZ4dB3eodpanL/TUpOCwYs0O8C7f3sSF9eQweH3me9fwjScA== X-Received: by 2002:a05:600c:3584:: with SMTP id p4mr13080991wmq.168.1634733592440; Wed, 20 Oct 2021 05:39:52 -0700 (PDT) Received: from localhost.localdomain ([2001:861:44c0:66c0:d31f:1512:8915:e439]) by smtp.gmail.com with ESMTPSA id b19sm5342680wmj.9.2021.10.20.05.39.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Oct 2021 05:39:51 -0700 (PDT) From: Neil Armstrong To: daniel@ffwll.ch, Laurent.pinchart@ideasonboard.com, sam@ravnborg.org Cc: martin.blumenstingl@googlemail.com, dri-devel@lists.freedesktop.org, linux-amlogic@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Neil Armstrong Subject: [PATCH v3 2/6] drm/meson: remove useless recursive components matching Date: Wed, 20 Oct 2021 14:39:43 +0200 Message-Id: <20211020123947.2585572-3-narmstrong@baylibre.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211020123947.2585572-1-narmstrong@baylibre.com> References: <20211020123947.2585572-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3222; h=from:subject; bh=CN3FLP6iVU76e0yAYMgWdH+jRNt14KgdTlQZc0OHMOE=; b=owEBbQKS/ZANAwAKAXfc29rIyEnRAcsmYgBhcA34OiTZV2ZFtMy96i9yZnB9GrMijV1zFNrHEcyb umLfJSqJAjMEAAEKAB0WIQQ9U8YmyFYF/h30LIt33NvayMhJ0QUCYXAN+AAKCRB33NvayMhJ0ZzyD/ 4lhR8faDJpilegWriDDzuq5KGRjumsjn/WlbNZjCPoOqaj+pn5KXfsZzw9R7Eeup7ZqYyCAQOcIvcs oQmvtld62wlHcTSHBs8/6Z3xpYnDKqOsIO/94wSJss0kEwrNAr6JHKn/wtboC7Qsnj+46QaOdCQF4v mOK6oirD8VIkza0RIJhQeu/QvEE6Rl5e6pEhGBO4eCO8eJy3sgyxaDT6Q3qzCc88F9LBZ67X+KkWdV S9MRl29/bLsI/x6KXJqWirHBBS2gCn5HhicMfbUnQ2NAYE4BWL2QKpXAj0N1FQnd5XCE1vR3Znm4no tdYmAuvLL6TsdSCI7SB5FKe0fCRjczKHFwUcD4zUZ2UlsnUhGoemIYk2nCZ6UjUbpPPwkg8eN0DjJA wu3fAkTt8pVC9fXPDxRh0v+MwLMQUoz3KmruRkZrnm6b7hUDGtj11YQTnk2iHwijm3+HYl8T3tBumY 7gT6EUrp67O+/H/0sq5qZMc4q3xAX+1yqyQfdvnyaI2qUfvRhwDdiXLthxrZE80YL3vG3W9UN3yk+V I7Gwl8sJpzKTevNhBIYUvvQh8a1BMyiAFUKT20Zu1YRAAK4YJA4yo/RYmnazb7L2J9wwPFNRaMQD2e yJf218RosAh/v0ryiddosAwhMw0/Pp5jshuGAwJG5SKTO2uOXh6eNmshvxRg== X-Developer-Key: i=narmstrong@baylibre.com; a=openpgp; fpr=89EC3D058446217450F22848169AB7B1A4CFF8AE X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211020_053953_770869_CA11E624 X-CRM114-Status: GOOD ( 15.22 ) X-BeenThere: linux-amlogic@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-amlogic" Errors-To: linux-amlogic-bounces+linux-amlogic=archiver.kernel.org@lists.infradead.org The initial design was recursive to cover all port/endpoints, but only the first layer of endpoints should be covered by the components list. This also breaks the MIPI-DSI init/bridge attach sequence, thus only parse the first endpoints instead of recursing. Signed-off-by: Neil Armstrong Acked-by: Sam Ravnborg Acked-by: Martin Blumenstingl --- drivers/gpu/drm/meson/meson_drv.c | 62 +++++++++++-------------------- 1 file changed, 21 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 7f41a33592c8..97ebc07357bb 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -426,46 +426,6 @@ static int compare_of(struct device *dev, void *data) return dev->of_node == data; } -/* Possible connectors nodes to ignore */ -static const struct of_device_id connectors_match[] = { - { .compatible = "composite-video-connector" }, - { .compatible = "svideo-connector" }, - { .compatible = "hdmi-connector" }, - { .compatible = "dvi-connector" }, - {} -}; - -static int meson_probe_remote(struct platform_device *pdev, - struct component_match **match, - struct device_node *parent, - struct device_node *remote) -{ - struct device_node *ep, *remote_node; - int count = 1; - - /* If node is a connector, return and do not add to match table */ - if (of_match_node(connectors_match, remote)) - return 1; - - component_match_add(&pdev->dev, match, compare_of, remote); - - for_each_endpoint_of_node(remote, ep) { - remote_node = of_graph_get_remote_port_parent(ep); - if (!remote_node || - remote_node == parent || /* Ignore parent endpoint */ - !of_device_is_available(remote_node)) { - of_node_put(remote_node); - continue; - } - - count += meson_probe_remote(pdev, match, remote, remote_node); - - of_node_put(remote_node); - } - - return count; -} - static void meson_drv_shutdown(struct platform_device *pdev) { struct meson_drm *priv = dev_get_drvdata(&pdev->dev); @@ -477,6 +437,13 @@ static void meson_drv_shutdown(struct platform_device *pdev) drm_atomic_helper_shutdown(priv->drm); } +/* Possible connectors nodes to ignore */ +static const struct of_device_id connectors_match[] = { + { .compatible = "composite-video-connector" }, + { .compatible = "svideo-connector" }, + {} +}; + static int meson_drv_probe(struct platform_device *pdev) { struct component_match *match = NULL; @@ -491,8 +458,21 @@ static int meson_drv_probe(struct platform_device *pdev) continue; } - count += meson_probe_remote(pdev, &match, np, remote); + /* If an analog connector is detected, count it as an output */ + if (of_match_node(connectors_match, remote)) { + ++count; + of_node_put(remote); + continue; + } + + dev_dbg(&pdev->dev, "parent %pOF remote match add %pOF parent %s\n", + np, remote, dev_name(&pdev->dev)); + + component_match_add(&pdev->dev, &match, compare_of, remote); + of_node_put(remote); + + ++count; } if (count && !match) From patchwork Wed Oct 20 12:39:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 12572285 X-Patchwork-Delegate: neil.armstrong@linaro.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1F09C433F5 for ; Wed, 20 Oct 2021 12:41:02 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A872061355 for ; Wed, 20 Oct 2021 12:41:02 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org A872061355 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=n+UJfgn1XD/sXOsl89uhM330p0QvWA5E87s2flBC1sk=; b=hG9rMfffX4TASm WknL3/AloqjfOr0euugGiL4+ILafPn8WgQjHg1112sC2Ol0fGC2LN+27rmZHf3cvOFX+rT8oHSA05 Sdvjh5DNYe7Xd03Z8X1LVA4P7dXRdwEm2vH7W7Uf7/CujZ7brVyh1c3zDGpOx3l/eT/4ir18xD9xm rSN+HQXcDsPf8MuxsbjuCq9do7RvZRcriDGcOyMbiFU1ZMBcS6xqk6dEKVKbjIp6+mht81M7nsnsq yLuYiR4+Ve2m63oyCut6XhnEiZM9XqdGneLExheu5o/+Aq+ceukX5hsY/9cYZ6TYh0iP9aPeE452R 2+w7hIAd+MbdB80he0IQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdAts-004VIr-HZ; Wed, 20 Oct 2021 12:40:56 +0000 Received: from mail-wm1-x32d.google.com ([2a00:1450:4864:20::32d]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdAst-004Uoc-7f for linux-amlogic@lists.infradead.org; Wed, 20 Oct 2021 12:40:00 +0000 Received: by mail-wm1-x32d.google.com with SMTP id g79-20020a1c2052000000b00323023159e1so1369604wmg.2 for ; Wed, 20 Oct 2021 05:39:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=bQbDhrcuncIAmx9g3WxjNrfMdCtfsNrpu9zkEekYc4s=; b=JWvrIjOOp9/DuvyHvNh3nzLwS1t+FFCEc96XOqMURlsgqTpFO/YhPwUkxo5xxgOn7A 4C87wyskM58AccOO7KHJBWG50LKOZ8wHuv9G9AD7XSaHNhX99JGMfxV9l9ri0zxMsJMZ Mvk+XKWrZBOeM/LCpQPo6Xn1RODvCFifDTUKp2/RbvPDG0zdi+7wfTXIyCoR+imujFgh HinlyH+nW35eIPFbrebEbjkKVMA7+dkYR0+jP4hZZyX//iGcmEnDnGWBvd/fKNnJuX/P 7hDs9Ci2YILDHOjwajP1lBN2gc3elZaykYH3sHbRKeAOEcxSLckcOJNdu+0vx9a+Uzhi XEGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=bQbDhrcuncIAmx9g3WxjNrfMdCtfsNrpu9zkEekYc4s=; b=E92i2tW/BzcE6Bbe9AtRvxxObiyQ4Jr1FEtiYrELHI0Q1FydOpbbqLEz9X46+GCYfT yqUbJ3SJDauiAar2dkvGODsC5EXlVAkfWjLMusdtdYKJ8p8YuQRB661+Jgfqi+vzySyG Embe3VhdCf0TMpsCfxCXWoDLGeL9pPO0degUjuJZS9scTunUTF0noLwy6LD5dZDn3F07 7b/iw5SYtOVdxi8+UPQBQ/FzGsbPgKk7FOy+/ZKQiSqhOAx8ppGpQHbqSrXxJDehlCpk 98aqxdQAsZaQzEvAI1yJRB35LOYWEHjTnec0huTk7xUY3bdhrs4vrGZ+Mzf23SgnlDIz c5pw== X-Gm-Message-State: AOAM533fUqAovx0nCZEAeKM6NLLnLCf/oIkcNSjGHed97299EyqMxCM+ 9QBNTx/aR0z9nqwOxXbOOVbvAw== X-Google-Smtp-Source: ABdhPJyBbXcOKHUD75FGSsUNvYkZhPJ9Sg+dhKuqE4r79lF+D3EkMZK0P0FWQUbXCq75jTC7R04Yxw== X-Received: by 2002:a7b:c5d8:: with SMTP id n24mr13675063wmk.51.1634733593610; Wed, 20 Oct 2021 05:39:53 -0700 (PDT) Received: from localhost.localdomain ([2001:861:44c0:66c0:d31f:1512:8915:e439]) by smtp.gmail.com with ESMTPSA id b19sm5342680wmj.9.2021.10.20.05.39.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Oct 2021 05:39:53 -0700 (PDT) From: Neil Armstrong To: daniel@ffwll.ch, Laurent.pinchart@ideasonboard.com, sam@ravnborg.org Cc: martin.blumenstingl@googlemail.com, dri-devel@lists.freedesktop.org, linux-amlogic@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Neil Armstrong Subject: [PATCH v3 3/6] drm/meson: split out encoder from meson_dw_hdmi Date: Wed, 20 Oct 2021 14:39:44 +0200 Message-Id: <20211020123947.2585572-4-narmstrong@baylibre.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211020123947.2585572-1-narmstrong@baylibre.com> References: <20211020123947.2585572-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=30349; h=from:subject; bh=Ynt/9+rk7FMummkeFCBXPMcWIDDEfrLjm5c6525s4MQ=; b=owEBbQKS/ZANAwAKAXfc29rIyEnRAcsmYgBhcA34iaTEBQuEVmH5pi1wd4mzmNT2hU6v3smdK/DG tS0ROMmJAjMEAAEKAB0WIQQ9U8YmyFYF/h30LIt33NvayMhJ0QUCYXAN+AAKCRB33NvayMhJ0ccND/ 4neIiSNe2pCGdNE6IKc6IMnRZVyET0k/Z1l3IxjkBApmcjBQEvUYAu3KA7Cuuc+kft3AkiHckqpw2F HM/qeKelq6Ab7rCbedgh9g3jwLPgAZbSRl5yidyrRFHF1PM6FFZZYE9/bxCECG8Oo+Wsh1lYjSby77 mqmzfMN/4Y6Z58pU/ah+DklkbIFzo+l6RHXWZ6qoF37XhMvhkZjOXWqxQ22CePxkHpUm/HFkgXwT2z +UI5E6mGalqHMW5wwBJHxiJ2vFvqsH8Mjg3vT64I6h7Q8BK0SsxjKXhkf3HKOex4OJwvzXdkkolwik zWcZssgUK8P5r/PHOvbq7H9cCT+oh0GnsDpuM7n0ZaNiig0o00x6QfUdFtiZgKI5GuUGJKWddG3YEd stJCwJxHbdMWTYFbuxJU/pZ6uRaga8AshDgdaLnfuT8coyjpjhb8Y5jMHFL+ivOyjyMOKg/3ajYEQT qdYcyLCFySTwjwv0ebbygQtQ/BFX+WGKUYXfjhi9Bu5rDPHbvvljg5PEu1TC9rkM18eIwUNlQsebE/ EcI+L3sf2xy4NeHGl64w/T1tdphG77R9YfShFoSk4moj3+O1wX5LL1X7d5HNWkS3WM98QmBOG1NtTE /TbfzYdO0brtHIKpPBgrlkFUv8mHZKyF/sud4Z+fLdJoPahgxHf81Mt5tjXA== X-Developer-Key: i=narmstrong@baylibre.com; a=openpgp; fpr=89EC3D058446217450F22848169AB7B1A4CFF8AE X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211020_053955_422395_278F48B0 X-CRM114-Status: GOOD ( 26.80 ) X-BeenThere: linux-amlogic@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-amlogic" Errors-To: linux-amlogic-bounces+linux-amlogic=archiver.kernel.org@lists.infradead.org This moves all the non-DW-HDMI code where it should be: an encoder in the drm/meson core driver. The bridge functions are copied as-is, except: - the encoder init uses the simple kms helper - the mode_set has been moved to atomic_enable() - debug prints are converted to dev_debg() For now the bridge attach flags is 0, DRM_BRIDGE_ATTACH_NO_CONNECTOR will be handled later. The meson dw-hdmi glue is slightly fixed to live without the encoder in the same driver. Signed-off-by: Neil Armstrong Acked-by: Sam Ravnborg Acked-by: Martin Blumenstingl --- drivers/gpu/drm/meson/Makefile | 1 + drivers/gpu/drm/meson/meson_drv.c | 5 + drivers/gpu/drm/meson/meson_dw_hdmi.c | 341 ++----------------- drivers/gpu/drm/meson/meson_encoder_hdmi.c | 369 +++++++++++++++++++++ drivers/gpu/drm/meson/meson_encoder_hdmi.h | 12 + 5 files changed, 406 insertions(+), 322 deletions(-) create mode 100644 drivers/gpu/drm/meson/meson_encoder_hdmi.c create mode 100644 drivers/gpu/drm/meson/meson_encoder_hdmi.h diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile index 28a519cdf66b..523fce45f16b 100644 --- a/drivers/gpu/drm/meson/Makefile +++ b/drivers/gpu/drm/meson/Makefile @@ -2,6 +2,7 @@ meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_venc_cvbs.o meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_overlay.o meson-drm-y += meson_rdma.o meson_osd_afbcd.o +meson-drm-y += meson_encoder_hdmi.o obj-$(CONFIG_DRM_MESON) += meson-drm.o obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 97ebc07357bb..0978b440f336 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -32,6 +32,7 @@ #include "meson_osd_afbcd.h" #include "meson_registers.h" #include "meson_venc_cvbs.h" +#include "meson_encoder_hdmi.h" #include "meson_viu.h" #include "meson_vpp.h" #include "meson_rdma.h" @@ -318,6 +319,10 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) } } + ret = meson_encoder_hdmi_init(priv); + if (ret) + goto free_drm; + ret = meson_plane_create(priv); if (ret) goto free_drm; diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 0afbd1e70bfc..fb540a503efe 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -22,14 +22,11 @@ #include #include -#include #include #include "meson_drv.h" #include "meson_dw_hdmi.h" #include "meson_registers.h" -#include "meson_vclk.h" -#include "meson_venc.h" #define DRIVER_NAME "meson-dw-hdmi" #define DRIVER_DESC "Amlogic Meson HDMI-TX DRM driver" @@ -135,8 +132,6 @@ struct meson_dw_hdmi_data { }; struct meson_dw_hdmi { - struct drm_encoder encoder; - struct drm_bridge bridge; struct dw_hdmi_plat_data dw_plat_data; struct meson_drm *priv; struct device *dev; @@ -148,12 +143,8 @@ struct meson_dw_hdmi { struct regulator *hdmi_supply; u32 irq_stat; struct dw_hdmi *hdmi; - unsigned long output_bus_fmt; + struct drm_bridge *bridge; }; -#define encoder_to_meson_dw_hdmi(x) \ - container_of(x, struct meson_dw_hdmi, encoder) -#define bridge_to_meson_dw_hdmi(x) \ - container_of(x, struct meson_dw_hdmi, bridge) static inline int dw_hdmi_is_compatible(struct meson_dw_hdmi *dw_hdmi, const char *compat) @@ -295,14 +286,14 @@ static inline void dw_hdmi_dwc_write_bits(struct meson_dw_hdmi *dw_hdmi, /* Setup PHY bandwidth modes */ static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi, - const struct drm_display_mode *mode) + const struct drm_display_mode *mode, + bool mode_is_420) { struct meson_drm *priv = dw_hdmi->priv; unsigned int pixel_clock = mode->clock; /* For 420, pixel clock is half unlike venc clock */ - if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) - pixel_clock /= 2; + if (mode_is_420) pixel_clock /= 2; if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) { @@ -374,68 +365,25 @@ static inline void meson_dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi) mdelay(2); } -static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, - const struct drm_display_mode *mode) -{ - struct meson_drm *priv = dw_hdmi->priv; - int vic = drm_match_cea_mode(mode); - unsigned int phy_freq; - unsigned int vclk_freq; - unsigned int venc_freq; - unsigned int hdmi_freq; - - vclk_freq = mode->clock; - - /* For 420, pixel clock is half unlike venc clock */ - if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) - vclk_freq /= 2; - - /* TMDS clock is pixel_clock * 10 */ - phy_freq = vclk_freq * 10; - - if (!vic) { - meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, phy_freq, - vclk_freq, vclk_freq, vclk_freq, false); - return; - } - - /* 480i/576i needs global pixel doubling */ - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - vclk_freq *= 2; - - venc_freq = vclk_freq; - hdmi_freq = vclk_freq; - - /* VENC double pixels for 1080i, 720p and YUV420 modes */ - if (meson_venc_hdmi_venc_repeat(vic) || - dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) - venc_freq *= 2; - - vclk_freq = max(venc_freq, hdmi_freq); - - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - venc_freq /= 2; - - DRM_DEBUG_DRIVER("vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n", - phy_freq, vclk_freq, venc_freq, hdmi_freq, - priv->venc.hdmi_use_enci); - - meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, phy_freq, vclk_freq, - venc_freq, hdmi_freq, priv->venc.hdmi_use_enci); -} - static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, const struct drm_display_info *display, const struct drm_display_mode *mode) { struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; + bool is_hdmi2_sink = display->hdmi.scdc.supported; struct meson_drm *priv = dw_hdmi->priv; unsigned int wr_clk = readl_relaxed(priv->io_base + _REG(VPU_HDMI_SETTING)); + bool mode_is_420 = false; DRM_DEBUG_DRIVER("\"%s\" div%d\n", mode->name, mode->clock > 340000 ? 40 : 10); + if (drm_mode_is_420_only(display, mode) || + (!is_hdmi2_sink && + drm_mode_is_420_also(display, mode))) + mode_is_420 = true; + /* Enable clocks */ regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); @@ -457,8 +405,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12)); /* TMDS pattern setup */ - if (mode->clock > 340000 && - dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_YUV8_1X24) { + if (mode->clock > 340000 && !mode_is_420) { dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, 0); dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23, @@ -476,7 +423,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x2); /* Setup PHY parameters */ - meson_hdmi_phy_setup_mode(dw_hdmi, mode); + meson_hdmi_phy_setup_mode(dw_hdmi, mode, mode_is_420); /* Setup PHY */ regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, @@ -622,214 +569,15 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id) dw_hdmi_setup_rx_sense(dw_hdmi->hdmi, hpd_connected, hpd_connected); - drm_helper_hpd_irq_event(dw_hdmi->encoder.dev); + drm_helper_hpd_irq_event(dw_hdmi->bridge->dev); + drm_bridge_hpd_notify(dw_hdmi->bridge, + hpd_connected ? connector_status_connected + : connector_status_disconnected); } return IRQ_HANDLED; } -static enum drm_mode_status -dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, - const struct drm_display_info *display_info, - const struct drm_display_mode *mode) -{ - struct meson_dw_hdmi *dw_hdmi = data; - struct meson_drm *priv = dw_hdmi->priv; - bool is_hdmi2_sink = display_info->hdmi.scdc.supported; - unsigned int phy_freq; - unsigned int vclk_freq; - unsigned int venc_freq; - unsigned int hdmi_freq; - int vic = drm_match_cea_mode(mode); - enum drm_mode_status status; - - DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode)); - - /* If sink does not support 540MHz, reject the non-420 HDMI2 modes */ - if (display_info->max_tmds_clock && - mode->clock > display_info->max_tmds_clock && - !drm_mode_is_420_only(display_info, mode) && - !drm_mode_is_420_also(display_info, mode)) - return MODE_BAD; - - /* Check against non-VIC supported modes */ - if (!vic) { - status = meson_venc_hdmi_supported_mode(mode); - if (status != MODE_OK) - return status; - - return meson_vclk_dmt_supported_freq(priv, mode->clock); - /* Check against supported VIC modes */ - } else if (!meson_venc_hdmi_supported_vic(vic)) - return MODE_BAD; - - vclk_freq = mode->clock; - - /* For 420, pixel clock is half unlike venc clock */ - if (drm_mode_is_420_only(display_info, mode) || - (!is_hdmi2_sink && - drm_mode_is_420_also(display_info, mode))) - vclk_freq /= 2; - - /* TMDS clock is pixel_clock * 10 */ - phy_freq = vclk_freq * 10; - - /* 480i/576i needs global pixel doubling */ - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - vclk_freq *= 2; - - venc_freq = vclk_freq; - hdmi_freq = vclk_freq; - - /* VENC double pixels for 1080i, 720p and YUV420 modes */ - if (meson_venc_hdmi_venc_repeat(vic) || - drm_mode_is_420_only(display_info, mode) || - (!is_hdmi2_sink && - drm_mode_is_420_also(display_info, mode))) - venc_freq *= 2; - - vclk_freq = max(venc_freq, hdmi_freq); - - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - venc_freq /= 2; - - dev_dbg(dw_hdmi->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n", - __func__, phy_freq, vclk_freq, venc_freq, hdmi_freq); - - return meson_vclk_vic_supported_freq(priv, phy_freq, vclk_freq); -} - -/* Encoder */ - -static const u32 meson_dw_hdmi_out_bus_fmts[] = { - MEDIA_BUS_FMT_YUV8_1X24, - MEDIA_BUS_FMT_UYYVYY8_0_5X24, -}; - -static void meson_venc_hdmi_encoder_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); -} - -static const struct drm_encoder_funcs meson_venc_hdmi_encoder_funcs = { - .destroy = meson_venc_hdmi_encoder_destroy, -}; - -static u32 * -meson_venc_hdmi_encoder_get_inp_bus_fmts(struct drm_bridge *bridge, - struct drm_bridge_state *bridge_state, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state, - u32 output_fmt, - unsigned int *num_input_fmts) -{ - u32 *input_fmts = NULL; - int i; - - *num_input_fmts = 0; - - for (i = 0 ; i < ARRAY_SIZE(meson_dw_hdmi_out_bus_fmts) ; ++i) { - if (output_fmt == meson_dw_hdmi_out_bus_fmts[i]) { - *num_input_fmts = 1; - input_fmts = kcalloc(*num_input_fmts, - sizeof(*input_fmts), - GFP_KERNEL); - if (!input_fmts) - return NULL; - - input_fmts[0] = output_fmt; - - break; - } - } - - return input_fmts; -} - -static int meson_venc_hdmi_encoder_atomic_check(struct drm_bridge *bridge, - struct drm_bridge_state *bridge_state, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) -{ - struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge); - - dw_hdmi->output_bus_fmt = bridge_state->output_bus_cfg.format; - - DRM_DEBUG_DRIVER("output_bus_fmt %lx\n", dw_hdmi->output_bus_fmt); - - return 0; -} - -static void meson_venc_hdmi_encoder_disable(struct drm_bridge *bridge) -{ - struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge); - struct meson_drm *priv = dw_hdmi->priv; - - DRM_DEBUG_DRIVER("\n"); - - writel_bits_relaxed(0x3, 0, - priv->io_base + _REG(VPU_HDMI_SETTING)); - - writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); - writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); -} - -static void meson_venc_hdmi_encoder_enable(struct drm_bridge *bridge) -{ - struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge); - struct meson_drm *priv = dw_hdmi->priv; - - DRM_DEBUG_DRIVER("%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP"); - - if (priv->venc.hdmi_use_enci) - writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); - else - writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); -} - -static void meson_venc_hdmi_encoder_mode_set(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - const struct drm_display_mode *adjusted_mode) -{ - struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge); - struct meson_drm *priv = dw_hdmi->priv; - int vic = drm_match_cea_mode(mode); - unsigned int ycrcb_map = VPU_HDMI_OUTPUT_CBYCR; - bool yuv420_mode = false; - - DRM_DEBUG_DRIVER("\"%s\" vic %d\n", mode->name, vic); - - if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) { - ycrcb_map = VPU_HDMI_OUTPUT_CRYCB; - yuv420_mode = true; - } - - /* VENC + VENC-DVI Mode setup */ - meson_venc_hdmi_mode_set(priv, vic, ycrcb_map, yuv420_mode, mode); - - /* VCLK Set clock */ - dw_hdmi_set_vclk(dw_hdmi, mode); - - if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) - /* Setup YUV420 to HDMI-TX, no 10bit diphering */ - writel_relaxed(2 | (2 << 2), - priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); - else - /* Setup YUV444 to HDMI-TX, no 10bit diphering */ - writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); -} - -static const struct drm_bridge_funcs meson_venc_hdmi_encoder_bridge_funcs = { - .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, - .atomic_get_input_bus_fmts = meson_venc_hdmi_encoder_get_inp_bus_fmts, - .atomic_reset = drm_atomic_helper_bridge_reset, - .atomic_check = meson_venc_hdmi_encoder_atomic_check, - .enable = meson_venc_hdmi_encoder_enable, - .disable = meson_venc_hdmi_encoder_disable, - .mode_set = meson_venc_hdmi_encoder_mode_set, -}; - /* DW HDMI Regmap */ static int meson_dw_hdmi_reg_read(void *context, unsigned int reg, @@ -876,28 +624,6 @@ static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = { .dwc_write = dw_hdmi_g12a_dwc_write, }; -static bool meson_hdmi_connector_is_available(struct device *dev) -{ - struct device_node *ep, *remote; - - /* HDMI Connector is on the second port, first endpoint */ - ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, 0); - if (!ep) - return false; - - /* If the endpoint node exists, consider it enabled */ - remote = of_graph_get_remote_port(ep); - if (remote) { - of_node_put(ep); - return true; - } - - of_node_put(ep); - of_node_put(remote); - - return false; -} - static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi) { struct meson_drm *priv = meson_dw_hdmi->priv; @@ -976,18 +702,11 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, struct drm_device *drm = data; struct meson_drm *priv = drm->dev_private; struct dw_hdmi_plat_data *dw_plat_data; - struct drm_bridge *next_bridge; - struct drm_encoder *encoder; int irq; int ret; DRM_DEBUG_DRIVER("\n"); - if (!meson_hdmi_connector_is_available(dev)) { - dev_info(drm->dev, "HDMI Output connector not available\n"); - return -ENODEV; - } - match = of_device_get_match_data(&pdev->dev); if (!match) { dev_err(&pdev->dev, "failed to get match data\n"); @@ -1003,7 +722,6 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, meson_dw_hdmi->dev = dev; meson_dw_hdmi->data = match; dw_plat_data = &meson_dw_hdmi->dw_plat_data; - encoder = &meson_dw_hdmi->encoder; meson_dw_hdmi->hdmi_supply = devm_regulator_get_optional(dev, "hdmi"); if (IS_ERR(meson_dw_hdmi->hdmi_supply)) { @@ -1074,28 +792,11 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, return ret; } - /* Encoder */ - - ret = drm_encoder_init(drm, encoder, &meson_venc_hdmi_encoder_funcs, - DRM_MODE_ENCODER_TMDS, "meson_hdmi"); - if (ret) { - dev_err(priv->dev, "Failed to init HDMI encoder\n"); - return ret; - } - - meson_dw_hdmi->bridge.funcs = &meson_venc_hdmi_encoder_bridge_funcs; - drm_bridge_attach(encoder, &meson_dw_hdmi->bridge, NULL, 0); - - encoder->possible_crtcs = BIT(0); - meson_dw_hdmi_init(meson_dw_hdmi); - DRM_DEBUG_DRIVER("encoder initialized\n"); - /* Bridge / Connector */ dw_plat_data->priv_data = meson_dw_hdmi; - dw_plat_data->mode_valid = dw_hdmi_mode_valid; dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops; dw_plat_data->phy_name = "meson_dw_hdmi_phy"; dw_plat_data->phy_data = meson_dw_hdmi; @@ -1110,15 +811,11 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, platform_set_drvdata(pdev, meson_dw_hdmi); - meson_dw_hdmi->hdmi = dw_hdmi_probe(pdev, - &meson_dw_hdmi->dw_plat_data); + meson_dw_hdmi->hdmi = dw_hdmi_probe(pdev, &meson_dw_hdmi->dw_plat_data); if (IS_ERR(meson_dw_hdmi->hdmi)) return PTR_ERR(meson_dw_hdmi->hdmi); - next_bridge = of_drm_find_bridge(pdev->dev.of_node); - if (next_bridge) - drm_bridge_attach(encoder, next_bridge, - &meson_dw_hdmi->bridge, 0); + meson_dw_hdmi->bridge = of_drm_find_bridge(pdev->dev.of_node); DRM_DEBUG_DRIVER("HDMI controller initialized\n"); diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c new file mode 100644 index 000000000000..2e73e19d8887 --- /dev/null +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c @@ -0,0 +1,369 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2016 BayLibre, SAS + * Author: Neil Armstrong + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "meson_drv.h" +#include "meson_registers.h" +#include "meson_vclk.h" +#include "meson_venc.h" + +struct meson_encoder_hdmi { + struct drm_encoder encoder; + struct drm_bridge bridge; + struct drm_bridge *next_bridge; + struct meson_drm *priv; + unsigned long output_bus_fmt; +}; + +#define bridge_to_meson_encoder_hdmi(x) \ + container_of(x, struct meson_encoder_hdmi, bridge) + +static int meson_encoder_hdmi_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) +{ + struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); + + return drm_bridge_attach(bridge->encoder, encoder_hdmi->next_bridge, + &encoder_hdmi->bridge, flags); +} + +static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi, + const struct drm_display_mode *mode) +{ + struct meson_drm *priv = encoder_hdmi->priv; + int vic = drm_match_cea_mode(mode); + unsigned int phy_freq; + unsigned int vclk_freq; + unsigned int venc_freq; + unsigned int hdmi_freq; + + vclk_freq = mode->clock; + + /* For 420, pixel clock is half unlike venc clock */ + if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) + vclk_freq /= 2; + + /* TMDS clock is pixel_clock * 10 */ + phy_freq = vclk_freq * 10; + + if (!vic) { + meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, phy_freq, + vclk_freq, vclk_freq, vclk_freq, false); + return; + } + + /* 480i/576i needs global pixel doubling */ + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + vclk_freq *= 2; + + venc_freq = vclk_freq; + hdmi_freq = vclk_freq; + + /* VENC double pixels for 1080i, 720p and YUV420 modes */ + if (meson_venc_hdmi_venc_repeat(vic) || + encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) + venc_freq *= 2; + + vclk_freq = max(venc_freq, hdmi_freq); + + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + venc_freq /= 2; + + dev_dbg(priv->dev, "vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n", + phy_freq, vclk_freq, venc_freq, hdmi_freq, + priv->venc.hdmi_use_enci); + + meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, phy_freq, vclk_freq, + venc_freq, hdmi_freq, priv->venc.hdmi_use_enci); +} + +static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *display_info, + const struct drm_display_mode *mode) +{ + struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); + struct meson_drm *priv = encoder_hdmi->priv; + bool is_hdmi2_sink = display_info->hdmi.scdc.supported; + unsigned int phy_freq; + unsigned int vclk_freq; + unsigned int venc_freq; + unsigned int hdmi_freq; + int vic = drm_match_cea_mode(mode); + enum drm_mode_status status; + + dev_dbg(priv->dev, "Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode)); + + /* If sink does not support 540MHz, reject the non-420 HDMI2 modes */ + if (display_info->max_tmds_clock && + mode->clock > display_info->max_tmds_clock && + !drm_mode_is_420_only(display_info, mode) && + !drm_mode_is_420_also(display_info, mode)) + return MODE_BAD; + + /* Check against non-VIC supported modes */ + if (!vic) { + status = meson_venc_hdmi_supported_mode(mode); + if (status != MODE_OK) + return status; + + return meson_vclk_dmt_supported_freq(priv, mode->clock); + /* Check against supported VIC modes */ + } else if (!meson_venc_hdmi_supported_vic(vic)) + return MODE_BAD; + + vclk_freq = mode->clock; + + /* For 420, pixel clock is half unlike venc clock */ + if (drm_mode_is_420_only(display_info, mode) || + (!is_hdmi2_sink && + drm_mode_is_420_also(display_info, mode))) + vclk_freq /= 2; + + /* TMDS clock is pixel_clock * 10 */ + phy_freq = vclk_freq * 10; + + /* 480i/576i needs global pixel doubling */ + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + vclk_freq *= 2; + + venc_freq = vclk_freq; + hdmi_freq = vclk_freq; + + /* VENC double pixels for 1080i, 720p and YUV420 modes */ + if (meson_venc_hdmi_venc_repeat(vic) || + drm_mode_is_420_only(display_info, mode) || + (!is_hdmi2_sink && + drm_mode_is_420_also(display_info, mode))) + venc_freq *= 2; + + vclk_freq = max(venc_freq, hdmi_freq); + + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + venc_freq /= 2; + + dev_dbg(priv->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n", + __func__, phy_freq, vclk_freq, venc_freq, hdmi_freq); + + return meson_vclk_vic_supported_freq(priv, phy_freq, vclk_freq); +} + +static void meson_encoder_hdmi_atomic_enable(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state) +{ + struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); + struct drm_atomic_state *state = bridge_state->base.state; + unsigned int ycrcb_map = VPU_HDMI_OUTPUT_CBYCR; + struct meson_drm *priv = encoder_hdmi->priv; + struct drm_connector_state *conn_state; + const struct drm_display_mode *mode; + struct drm_crtc_state *crtc_state; + struct drm_connector *connector; + bool yuv420_mode = false; + int vic; + + connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); + if (WARN_ON(!connector)) + return; + + conn_state = drm_atomic_get_new_connector_state(state, connector); + if (WARN_ON(!conn_state)) + return; + + crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); + if (WARN_ON(!crtc_state)) + return; + + mode = &crtc_state->adjusted_mode; + + vic = drm_match_cea_mode(mode); + + dev_dbg(priv->dev, "\"%s\" vic %d\n", mode->name, vic); + + if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) { + ycrcb_map = VPU_HDMI_OUTPUT_CRYCB; + yuv420_mode = true; + } + + /* VENC + VENC-DVI Mode setup */ + meson_venc_hdmi_mode_set(priv, vic, ycrcb_map, yuv420_mode, mode); + + /* VCLK Set clock */ + meson_encoder_hdmi_set_vclk(encoder_hdmi, mode); + + if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) + /* Setup YUV420 to HDMI-TX, no 10bit diphering */ + writel_relaxed(2 | (2 << 2), + priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); + else + /* Setup YUV444 to HDMI-TX, no 10bit diphering */ + writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); + + dev_dbg(priv->dev, "%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP"); + + if (priv->venc.hdmi_use_enci) + writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); + else + writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); +} + +static void meson_encoder_hdmi_atomic_disable(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state) +{ + struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); + struct meson_drm *priv = encoder_hdmi->priv; + + writel_bits_relaxed(0x3, 0, + priv->io_base + _REG(VPU_HDMI_SETTING)); + + writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); + writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); +} + +static const u32 meson_encoder_hdmi_out_bus_fmts[] = { + MEDIA_BUS_FMT_YUV8_1X24, + MEDIA_BUS_FMT_UYYVYY8_0_5X24, +}; + +static u32 * +meson_encoder_hdmi_get_inp_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + u32 *input_fmts = NULL; + int i; + + *num_input_fmts = 0; + + for (i = 0 ; i < ARRAY_SIZE(meson_encoder_hdmi_out_bus_fmts) ; ++i) { + if (output_fmt == meson_encoder_hdmi_out_bus_fmts[i]) { + *num_input_fmts = 1; + input_fmts = kcalloc(*num_input_fmts, + sizeof(*input_fmts), + GFP_KERNEL); + if (!input_fmts) + return NULL; + + input_fmts[0] = output_fmt; + + break; + } + } + + return input_fmts; +} + +static int meson_encoder_hdmi_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); + struct drm_connector_state *old_conn_state = + drm_atomic_get_old_connector_state(conn_state->state, conn_state->connector); + struct meson_drm *priv = encoder_hdmi->priv; + + encoder_hdmi->output_bus_fmt = bridge_state->output_bus_cfg.format; + + dev_dbg(priv->dev, "output_bus_fmt %lx\n", encoder_hdmi->output_bus_fmt); + + if (!drm_connector_atomic_hdr_metadata_equal(old_conn_state, conn_state)) + crtc_state->mode_changed = true; + + return 0; +} + +static const struct drm_bridge_funcs meson_encoder_hdmi_bridge_funcs = { + .attach = meson_encoder_hdmi_attach, + .mode_valid = meson_encoder_hdmi_mode_valid, + .atomic_enable = meson_encoder_hdmi_atomic_enable, + .atomic_disable = meson_encoder_hdmi_atomic_disable, + .atomic_get_input_bus_fmts = meson_encoder_hdmi_get_inp_bus_fmts, + .atomic_check = meson_encoder_hdmi_atomic_check, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, +}; + +int meson_encoder_hdmi_init(struct meson_drm *priv) +{ + struct meson_encoder_hdmi *meson_encoder_hdmi; + struct device_node *remote; + int ret; + + meson_encoder_hdmi = devm_kzalloc(priv->dev, sizeof(*meson_encoder_hdmi), GFP_KERNEL); + if (!meson_encoder_hdmi) + return -ENOMEM; + + /* HDMI Transceiver Bridge */ + remote = of_graph_get_remote_node(priv->dev->of_node, 1, 0); + if (!remote) { + dev_err(priv->dev, "HDMI transceiver device is disabled"); + return 0; + } + + meson_encoder_hdmi->next_bridge = of_drm_find_bridge(remote); + if (!meson_encoder_hdmi->next_bridge) { + dev_err(priv->dev, "Failed to find HDMI transceiver bridge\n"); + return -EPROBE_DEFER; + } + + /* HDMI Encoder Bridge */ + meson_encoder_hdmi->bridge.funcs = &meson_encoder_hdmi_bridge_funcs; + meson_encoder_hdmi->bridge.of_node = priv->dev->of_node; + meson_encoder_hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; + + drm_bridge_add(&meson_encoder_hdmi->bridge); + + meson_encoder_hdmi->priv = priv; + + /* Encoder */ + ret = drm_simple_encoder_init(priv->drm, &meson_encoder_hdmi->encoder, + DRM_MODE_ENCODER_TMDS); + if (ret) { + dev_err(priv->dev, "Failed to init HDMI encoder: %d\n", ret); + return ret; + } + + meson_encoder_hdmi->encoder.possible_crtcs = BIT(0); + + /* Attach HDMI Encoder Bridge to Encoder */ + ret = drm_bridge_attach(&meson_encoder_hdmi->encoder, &meson_encoder_hdmi->bridge, NULL, 0); + if (ret) { + dev_err(priv->dev, "Failed to attach bridge: %d\n", ret); + return ret; + } + + /* + * We should have now in place: + * encoder->[hdmi encoder bridge]->[dw-hdmi bridge]->[dw-hdmi connector] + */ + + dev_dbg(priv->dev, "HDMI encoder initialized\n"); + + return 0; +} diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.h b/drivers/gpu/drm/meson/meson_encoder_hdmi.h new file mode 100644 index 000000000000..ed19494f0956 --- /dev/null +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2021 BayLibre, SAS + * Author: Neil Armstrong + */ + +#ifndef __MESON_ENCODER_HDMI_H +#define __MESON_ENCODER_HDMI_H + +int meson_encoder_hdmi_init(struct meson_drm *priv); + +#endif /* __MESON_ENCODER_HDMI_H */ From patchwork Wed Oct 20 12:39:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 12572283 X-Patchwork-Delegate: neil.armstrong@linaro.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AF036C433F5 for ; Wed, 20 Oct 2021 12:40:47 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 70BF961374 for ; Wed, 20 Oct 2021 12:40:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 70BF961374 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=OJY95lbBNxU/WBe/bgS82AhiJj6iFHxi+5PmUQ12PjE=; b=2o9KgYpF9b2Q0V t4tm74jTEIYRP7S2kvWf0GwooMeikKnUribsZCHRMUVazh9hcdaMcpnlSBzvC5qq9wmzHc8eR30qT qXgFDPOxh25/YKlT333ykR7YtySnz0414DnzNTmw6T3RBuhCHXH038JI+mC/Kas51rlZbnoFRaaWE I69jGffCNzkmmk1CwHKfs4VhA1WBIvSWTXItEsUKLYsn0rRlWYwzYR5YDPy7hKIijFJkko/CTty7b p+U8cZvs765GUA2MhIdPbSNI5xP42oaLx5TcXkI+rL1hA0f5w6fOAAjY2OtZ2M0C9VqX4U0XwNVLG x9hB280C/0DVrsiXGGlA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdAte-004VBl-LM; Wed, 20 Oct 2021 12:40:42 +0000 Received: from mail-wm1-x32c.google.com ([2a00:1450:4864:20::32c]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdAsu-004Up9-5v for linux-amlogic@lists.infradead.org; Wed, 20 Oct 2021 12:39:59 +0000 Received: by mail-wm1-x32c.google.com with SMTP id 77-20020a1c0450000000b0030da2439b21so1423143wme.0 for ; Wed, 20 Oct 2021 05:39:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=jiinvX9tI54x5SLHabqig93k3uxlHlswuN5uX6BjTl4=; b=k5UJoCfc3a/ChUJjErZfsDE8CKzm6N1fY3KZCcE+x9SM4PJtVoKiMTE8LxbCXuqEDu 962iwEHAGITJdGE/dTJSDTc3qyJI4LUHb3I8VGKLt0YlO0/pDvIkL69Zx19tFLAaB8B7 yG6hwqqSfqSkhlpKMOAfoQIibydJGoflr2P8R2RGgbXPXMemPP3coqYgm3CwQd2Rqine c4CCOUkkv0SXRiCS6w+PyIko8zdz7fab2FlGWUjVYk/U/NDLM/Z2wazFXVjlrPp7yQOi sINAbs5kzcx2hlnfNlCL8VitkpBjYONyV0eeJJoEQ/BOrCf2BwXfBIuX5wAVrlPJr4Cq Jstw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jiinvX9tI54x5SLHabqig93k3uxlHlswuN5uX6BjTl4=; b=21W2viYM18SrEDnl4aVyL85mr/NP5Hhu42h2fRYFYOqPGBA0T5mPArwZawcANnjxO1 88MwtqupQn2CUWvR+Pkt7mC3/CC+kb7HGUZF0QChhGTdKf6kKEG+R4V+29xUCNNOy/QN j/zkzrVyTjXnPg8VB2PThwvUAGgEBoSX/XYsDc4kIpuQ8vBcXtu8r8U3tcT0Crk/NFRm t/agxKl23lidFQiCzAyKpTREn9oxwTza91O1rEDk64y+9Bn7bLMeNuKx8Mbgbkd7j64u SN/Se9OzCp5TV69bSBlJ7fI95A31qJvaFPTXvKWaoYj1l6Axl4SMNpxatvn23z1Ril8X PWmw== X-Gm-Message-State: AOAM532gtQQxjF+WFbsUmmZkBFNIPfaF8FnXdtwd5xOg+uHeWIsad3ot BY2OzyY29HeemBolznDbqRALJw== X-Google-Smtp-Source: ABdhPJyyKUKrwhSsBZgPAXOgJOxVvlmh9Bd+6kJ0Stkse4IyS+1nIdvnlzOUf6uPInyUF0hX5w67Pg== X-Received: by 2002:a05:600c:ac1:: with SMTP id c1mr13165308wmr.99.1634733594743; Wed, 20 Oct 2021 05:39:54 -0700 (PDT) Received: from localhost.localdomain ([2001:861:44c0:66c0:d31f:1512:8915:e439]) by smtp.gmail.com with ESMTPSA id b19sm5342680wmj.9.2021.10.20.05.39.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Oct 2021 05:39:54 -0700 (PDT) From: Neil Armstrong To: daniel@ffwll.ch, Laurent.pinchart@ideasonboard.com, sam@ravnborg.org Cc: martin.blumenstingl@googlemail.com, dri-devel@lists.freedesktop.org, linux-amlogic@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Neil Armstrong Subject: [PATCH v3 4/6] drm/meson: encoder_hdmi: switch to bridge DRM_BRIDGE_ATTACH_NO_CONNECTOR Date: Wed, 20 Oct 2021 14:39:45 +0200 Message-Id: <20211020123947.2585572-5-narmstrong@baylibre.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211020123947.2585572-1-narmstrong@baylibre.com> References: <20211020123947.2585572-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7653; h=from:subject; bh=JOkvQc81RnmaBjsJV0Kp9WcWJQhhemCUWGOjLkWHtaM=; b=owEBbQKS/ZANAwAKAXfc29rIyEnRAcsmYgBhcA34U8iBkJMESB5V1Wa2HiE7z3yk0tVHj/l4NxES PySwWm+JAjMEAAEKAB0WIQQ9U8YmyFYF/h30LIt33NvayMhJ0QUCYXAN+AAKCRB33NvayMhJ0ZnLD/ 44Z9N66wFWxCpak3SrBMgk3yzHp3oCU1WEPBErCGZjLVDdlv4WlrvXRZsY/6hYRuC0/8OpzhMTSDvG RwN03XrHCeYWsjx4dVDgvztkoJIG1v579U+j3i4OlvQVccWmg9RfYNgoxLWXoF405HzPmjOa2NLLmA 2ABEInBUiUkzaDJqXmbzqj7zbl3SSWOWUoaUGGFE65MajknYTfkT1PBgUjXBv+9FOCZsRCV5Q/ijb6 g2pyxcoyzdOCuBCnRAYkjLOnJNyMITQ0TeNE3yjB657N4afE6e4PwOMpNNzzkAaSnobtIc/vh8HOCa BKpJhoPogz7Dq6N0jMhP8OpzgITZPIHvdZoeMR7sKIoxF/fe/YOwzyaDdmC8QG8+D+kx/QU95a4CNG NCFjml+UBlcOu4G1qEMkWmT2onZT47EDF07xDPNwGjgRu9V2eGHskwmNouufSmF18NMClr/FVwWDby YOenVjFwTZXh8Qtn/m/UyuGsN/GrPGbkWjBQ8NaP56qRN31OCx7wP20LNf2SfspJMJEUHu1C8IYvV1 p+yQaz4YlKjarm+/nzlBff0uG4CzwBYpBe6gg4jNEWM2KjrUXIX1Rw6cThOSUHG19k1rLm+MKGyp7y r3KOtvjLx4yppsu2azYhgt2LmwZWhXeFQmqnc00JMShbGsfKr81UxkZxBDug== X-Developer-Key: i=narmstrong@baylibre.com; a=openpgp; fpr=89EC3D058446217450F22848169AB7B1A4CFF8AE X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211020_053956_281796_8FB3BE08 X-CRM114-Status: GOOD ( 22.83 ) X-BeenThere: linux-amlogic@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-amlogic" Errors-To: linux-amlogic-bounces+linux-amlogic=archiver.kernel.org@lists.infradead.org This implements the necessary change to no more use the embedded connector in dw-hdmi and use the dedicated bridge connector driver by passing DRM_BRIDGE_ATTACH_NO_CONNECTOR to the bridge attach call. The necessary connector properties are added to handle the same functionalities as the embedded dw-hdmi connector, i.e. the HDR metadata, the CEC notifier & other flags. The dw-hdmi output_port is set to 1 in order to look for a connector next bridge in order to get DRM_BRIDGE_ATTACH_NO_CONNECTOR working. Signed-off-by: Neil Armstrong Acked-by: Sam Ravnborg Acked-by: Martin Blumenstingl --- drivers/gpu/drm/meson/Kconfig | 2 + drivers/gpu/drm/meson/meson_dw_hdmi.c | 1 + drivers/gpu/drm/meson/meson_encoder_hdmi.c | 81 +++++++++++++++++++++- 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig index 9f9281dd49f8..a4e1ed96e5e8 100644 --- a/drivers/gpu/drm/meson/Kconfig +++ b/drivers/gpu/drm/meson/Kconfig @@ -6,9 +6,11 @@ config DRM_MESON select DRM_KMS_HELPER select DRM_KMS_CMA_HELPER select DRM_GEM_CMA_HELPER + select DRM_DISPLAY_CONNECTOR select VIDEOMODE_HELPERS select REGMAP_MMIO select MESON_CANVAS + select CEC_CORE if CEC_NOTIFIER config DRM_MESON_DW_HDMI tristate "HDMI Synopsys Controller support for Amlogic Meson Display" diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index fb540a503efe..5cd2b2ebbbd3 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -803,6 +803,7 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709; dw_plat_data->ycbcr_420_allowed = true; dw_plat_data->disable_cec = true; + dw_plat_data->output_port = 1; if (dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxm-dw-hdmi") || diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c index 2e73e19d8887..156cb43735f7 100644 --- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c @@ -14,8 +14,11 @@ #include #include +#include + #include #include +#include #include #include #include @@ -33,8 +36,10 @@ struct meson_encoder_hdmi { struct drm_encoder encoder; struct drm_bridge bridge; struct drm_bridge *next_bridge; + struct drm_connector *connector; struct meson_drm *priv; unsigned long output_bus_fmt; + struct cec_notifier *cec_notifier; }; #define bridge_to_meson_encoder_hdmi(x) \ @@ -49,6 +54,14 @@ static int meson_encoder_hdmi_attach(struct drm_bridge *bridge, &encoder_hdmi->bridge, flags); } +static void meson_encoder_hdmi_detach(struct drm_bridge *bridge) +{ + struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); + + cec_notifier_conn_unregister(encoder_hdmi->cec_notifier); + encoder_hdmi->cec_notifier = NULL; +} + static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi, const struct drm_display_mode *mode) { @@ -297,9 +310,30 @@ static int meson_encoder_hdmi_atomic_check(struct drm_bridge *bridge, return 0; } +static void meson_encoder_hdmi_hpd_notify(struct drm_bridge *bridge, + enum drm_connector_status status) +{ + struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); + struct edid *edid; + + if (!encoder_hdmi->cec_notifier) + return; + + if (status == connector_status_connected) { + edid = drm_bridge_get_edid(encoder_hdmi->next_bridge, encoder_hdmi->connector); + if (!edid) + return; + + cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid); + } else + cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier); +} + static const struct drm_bridge_funcs meson_encoder_hdmi_bridge_funcs = { .attach = meson_encoder_hdmi_attach, + .detach = meson_encoder_hdmi_detach, .mode_valid = meson_encoder_hdmi_mode_valid, + .hpd_notify = meson_encoder_hdmi_hpd_notify, .atomic_enable = meson_encoder_hdmi_atomic_enable, .atomic_disable = meson_encoder_hdmi_atomic_disable, .atomic_get_input_bus_fmts = meson_encoder_hdmi_get_inp_bus_fmts, @@ -312,6 +346,7 @@ static const struct drm_bridge_funcs meson_encoder_hdmi_bridge_funcs = { int meson_encoder_hdmi_init(struct meson_drm *priv) { struct meson_encoder_hdmi *meson_encoder_hdmi; + struct platform_device *pdev; struct device_node *remote; int ret; @@ -336,6 +371,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv) meson_encoder_hdmi->bridge.funcs = &meson_encoder_hdmi_bridge_funcs; meson_encoder_hdmi->bridge.of_node = priv->dev->of_node; meson_encoder_hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; + meson_encoder_hdmi->bridge.interlace_allowed = true; drm_bridge_add(&meson_encoder_hdmi->bridge); @@ -352,17 +388,58 @@ int meson_encoder_hdmi_init(struct meson_drm *priv) meson_encoder_hdmi->encoder.possible_crtcs = BIT(0); /* Attach HDMI Encoder Bridge to Encoder */ - ret = drm_bridge_attach(&meson_encoder_hdmi->encoder, &meson_encoder_hdmi->bridge, NULL, 0); + ret = drm_bridge_attach(&meson_encoder_hdmi->encoder, &meson_encoder_hdmi->bridge, NULL, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); if (ret) { dev_err(priv->dev, "Failed to attach bridge: %d\n", ret); return ret; } + /* Initialize & attach Bridge Connector */ + meson_encoder_hdmi->connector = drm_bridge_connector_init(priv->drm, + &meson_encoder_hdmi->encoder); + if (IS_ERR(meson_encoder_hdmi->connector)) { + dev_err(priv->dev, "Unable to create HDMI bridge connector\n"); + return PTR_ERR(meson_encoder_hdmi->connector); + } + drm_connector_attach_encoder(meson_encoder_hdmi->connector, + &meson_encoder_hdmi->encoder); + /* * We should have now in place: - * encoder->[hdmi encoder bridge]->[dw-hdmi bridge]->[dw-hdmi connector] + * encoder->[hdmi encoder bridge]->[dw-hdmi bridge]->[display connector bridge]->[display connector] */ + /* + * drm_connector_attach_max_bpc_property() requires the + * connector to have a state. + */ + drm_atomic_helper_connector_reset(meson_encoder_hdmi->connector); + + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL) || + meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || + meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + drm_connector_attach_hdr_output_metadata_property(meson_encoder_hdmi->connector); + + drm_connector_attach_max_bpc_property(meson_encoder_hdmi->connector, 8, 8); + + /* Handle this here until handled by drm_bridge_connector_init() */ + meson_encoder_hdmi->connector->ycbcr_420_allowed = true; + + pdev = of_find_device_by_node(remote); + if (pdev) { + struct cec_connector_info conn_info; + struct cec_notifier *notifier; + + cec_fill_conn_info_from_drm(&conn_info, meson_encoder_hdmi->connector); + + notifier = cec_notifier_conn_register(&pdev->dev, NULL, &conn_info); + if (!notifier) + return -ENOMEM; + + meson_encoder_hdmi->cec_notifier = notifier; + } + dev_dbg(priv->dev, "HDMI encoder initialized\n"); return 0; From patchwork Wed Oct 20 12:39:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 12572287 X-Patchwork-Delegate: neil.armstrong@linaro.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 10AF8C433EF for ; Wed, 20 Oct 2021 12:41:29 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BCC4F61355 for ; Wed, 20 Oct 2021 12:41:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org BCC4F61355 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=dpEHLMRVb3UjnWisIPDFK9/bI+kQ9lDTz6jk3rTWSgM=; b=3EmPMhxGm3EhKh QVaq1PDIWUHk3yTg4zH5MdDCOUXtYSOJHosNlkTPwDrOo4gCcQgjWP9Zj19AN96beYFhUnlnV2VwY jWb1gdPx/TmIYq8g7F+qVLgBuijt58FnTLDGb4CiZM/B7UNfA68S1A1kV7+0j2dIXfdSMAshj32pI eHhoMOP8/LpaU9tjKjmaMX9odONed8JYF5VLtLy4wngwSXbS7Ca7qLeEhlS2VtPpejVH1UIJWdVDf lV0IdHvlRKF4TMQC/HJd4WL26UdoI9pQZobetOid4YN3EyZLVnHbSoR3rmkVc+vspH0c31bZrQv8L xIMi5A+w0Ek+Yj61Rcgg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdAuK-004VYA-3K; Wed, 20 Oct 2021 12:41:24 +0000 Received: from mail-wm1-x330.google.com ([2a00:1450:4864:20::330]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdAsv-004UqF-BD for linux-amlogic@lists.infradead.org; Wed, 20 Oct 2021 12:40:02 +0000 Received: by mail-wm1-x330.google.com with SMTP id g39so14532188wmp.3 for ; Wed, 20 Oct 2021 05:39:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=326SLwtQzES2hKKjA5RUtlRW9fb//6GCXyVhIKw2U9A=; b=Ni60kIWwHrOkCcMYZVaWhiO88VNILnqaXduVOWnXrGMLFZgleJ59/fpcCSCTs3N9bQ Gzn2hay9cLpV/G6UQ/k3aSiZF/y8ZU9ayfHOYuhj+iA/ixAgZM6UC223i8mUrxGabCs0 EOKlbq9IJW3WPH09sOz8CaZOZz8J6Vd6q+uKPrc+T1L4cP8AVMqI9jvKkdSNY7x6D3FW KUw19l1VwQhJNgtPqb0R3iqoU4Ai2B8vKk9NylXENNLInOCza34v8bEBpAKS4uOyaesU 7wxtKeTCoArUGNUKSwa0TPnKDCItOuChSkUHcOU6ZlJEsI/oo+8HLc9AtbvVX540232T eUAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=326SLwtQzES2hKKjA5RUtlRW9fb//6GCXyVhIKw2U9A=; b=erKIR0hrFNIEkLyvVAYeLmeYjdDzTQnE8B3H6NjtNcnaDWz6m1n/oOww0HBXeGF/5l clCOpDAGgCWi89CY7ySTOamhmZ3goIRovnDxfj9K6GxnQAW0N1TrSRyPHKkuSbHvCxK1 uXlcEaDLrHoAjYrP5p6R8yNjn0LlyI7E0+p9bGcuNq3iiWM0+VymMRTwXQLHjdVeGZsE iv7G7kXbgkY57rxyFOGRJ6csd1EQVn7S8XK/ucQnfe3/Fupm/TFWpYNILijUw2uJFdbn 5/gTcJfBHzG073RQ+v0YI2euX7SyhNPykiWD/po3yHg5zyL87Q0ph4bj3LNlJSXN1GpO /aWA== X-Gm-Message-State: AOAM530I693s6+STbjSclUXiMkqLet2AeArUL+1sKELGOqfM/o14FpBp UVvuOkU/8YIN/mCDVhe603JPSpkJOM/iFw== X-Google-Smtp-Source: ABdhPJxvmIEsttfH1+nt8uAOIN9xvKFHk51uxHMYTHiM+PyXu4ZkqdgfBXl+OQajjFgwa03WzCVjhA== X-Received: by 2002:a1c:e906:: with SMTP id q6mr13509042wmc.126.1634733595967; Wed, 20 Oct 2021 05:39:55 -0700 (PDT) Received: from localhost.localdomain ([2001:861:44c0:66c0:d31f:1512:8915:e439]) by smtp.gmail.com with ESMTPSA id b19sm5342680wmj.9.2021.10.20.05.39.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Oct 2021 05:39:55 -0700 (PDT) From: Neil Armstrong To: daniel@ffwll.ch, Laurent.pinchart@ideasonboard.com, sam@ravnborg.org Cc: martin.blumenstingl@googlemail.com, dri-devel@lists.freedesktop.org, linux-amlogic@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Neil Armstrong Subject: [PATCH v3 5/6] drm/meson: rename venc_cvbs to encoder_cvbs Date: Wed, 20 Oct 2021 14:39:46 +0200 Message-Id: <20211020123947.2585572-6-narmstrong@baylibre.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211020123947.2585572-1-narmstrong@baylibre.com> References: <20211020123947.2585572-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=9605; h=from:subject; bh=O0XW2nrHQ+cAOx1/yhSNCSabduVbNxlUGFgrwYwQklc=; b=owEBbQKS/ZANAwAKAXfc29rIyEnRAcsmYgBhcA347XUZkTgPulTyfsQGamNZBeQCEWUfMCySaK8J 7a3ti5KJAjMEAAEKAB0WIQQ9U8YmyFYF/h30LIt33NvayMhJ0QUCYXAN+AAKCRB33NvayMhJ0clTEA CWb+VNl7i1btlvQR9bJR1mXE8fFslqXNfChDo6y84i/MIN2HEsE9aJUbnr/mHTNlMuqlcKi2yHUCVr UKfZSfs1LfpLIIXfK4zbcK/4CGnV0P+N3w8gDjtDlrioa6Jyy7GAf+E+NA5v4O8ol1d+s3qNlQat4V 5l37XE+iT3FF2GZTTl9Pd8CdoGgae86mTk231YqIXxpH+YxZ7iRhF9XA2JBXnxVN70V+hYfIXnaGFD skdYs0jcGmjAL/yX1+lvzoyj4FkhC65pjqP06AJAEpYGSumGTwvmSyiYj3cMVtvVHRoeY5NUdgT509 ybM0kuJufSGH+JyJXQO+goI8h/GWMW2q9kQ6ohtFb/YX5t2GFflv5kdQSRYW0LRDvs4lIO0tO5tHHJ mDKNtQCnoPFqofUexloczC74KTNrZ0roVy1WMWgRICaNZIUQ7i8vWFyHKFwCHUtTlJQ6SzC+4hFa3/ xg/HnAbO6/gL+z2k1I/GKiW54y1oGy++Kns8cLI1KP7VUiehLgd0lfLd8nmIXDWer9KxZObbBLp1ml GNK/7Qz6+wX2WTDO4UF/eGtpacGhNNjKMGPlTeNCiPaaDtZE2pGV9SyyAzKKslcUofJrgYdlWA8WdV +V/sIVm2nIzv7221IPhV+iMS+JsQAFtKbc3aBWhuA06/2cfKpT0qNa9Z0zlA== X-Developer-Key: i=narmstrong@baylibre.com; a=openpgp; fpr=89EC3D058446217450F22848169AB7B1A4CFF8AE X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211020_053957_461972_DA73EBCB X-CRM114-Status: GOOD ( 19.13 ) X-BeenThere: linux-amlogic@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-amlogic" Errors-To: linux-amlogic-bounces+linux-amlogic=archiver.kernel.org@lists.infradead.org Rename the cvbs encoder to match the newly introduced meson_encoder_hdmi. Signed-off-by: Neil Armstrong Acked-by: Sam Ravnborg Acked-by: Martin Blumenstingl --- drivers/gpu/drm/meson/Makefile | 2 +- drivers/gpu/drm/meson/meson_drv.c | 4 +- ...meson_venc_cvbs.c => meson_encoder_cvbs.c} | 78 +++++++++---------- ...meson_venc_cvbs.h => meson_encoder_cvbs.h} | 2 +- 4 files changed, 43 insertions(+), 43 deletions(-) rename drivers/gpu/drm/meson/{meson_venc_cvbs.c => meson_encoder_cvbs.c} (74%) rename drivers/gpu/drm/meson/{meson_venc_cvbs.h => meson_encoder_cvbs.h} (92%) diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile index 523fce45f16b..3afa31bdc950 100644 --- a/drivers/gpu/drm/meson/Makefile +++ b/drivers/gpu/drm/meson/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_venc_cvbs.o +meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_encoder_cvbs.o meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_overlay.o meson-drm-y += meson_rdma.o meson_osd_afbcd.o meson-drm-y += meson_encoder_hdmi.o diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 0978b440f336..80f1d439841a 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -31,7 +31,7 @@ #include "meson_plane.h" #include "meson_osd_afbcd.h" #include "meson_registers.h" -#include "meson_venc_cvbs.h" +#include "meson_encoder_cvbs.h" #include "meson_encoder_hdmi.h" #include "meson_viu.h" #include "meson_vpp.h" @@ -307,7 +307,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) /* Encoder Initialization */ - ret = meson_venc_cvbs_create(priv); + ret = meson_encoder_cvbs_init(priv); if (ret) goto free_drm; diff --git a/drivers/gpu/drm/meson/meson_venc_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c similarity index 74% rename from drivers/gpu/drm/meson/meson_venc_cvbs.c rename to drivers/gpu/drm/meson/meson_encoder_cvbs.c index f1747fde1fe0..01024c5f610c 100644 --- a/drivers/gpu/drm/meson/meson_venc_cvbs.c +++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c @@ -20,7 +20,7 @@ #include "meson_registers.h" #include "meson_vclk.h" -#include "meson_venc_cvbs.h" +#include "meson_encoder_cvbs.h" /* HHI VDAC Registers */ #define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */ @@ -28,16 +28,16 @@ #define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */ #define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbe offset in data sheet */ -struct meson_venc_cvbs { +struct meson_encoder_cvbs { struct drm_encoder encoder; struct drm_connector connector; struct meson_drm *priv; }; -#define encoder_to_meson_venc_cvbs(x) \ - container_of(x, struct meson_venc_cvbs, encoder) +#define encoder_to_meson_encoder_cvbs(x) \ + container_of(x, struct meson_encoder_cvbs, encoder) -#define connector_to_meson_venc_cvbs(x) \ - container_of(x, struct meson_venc_cvbs, connector) +#define connector_to_meson_encoder_cvbs(x) \ + container_of(x, struct meson_encoder_cvbs, connector) /* Supported Modes */ @@ -140,16 +140,16 @@ struct drm_connector_helper_funcs meson_cvbs_connector_helper_funcs = { /* Encoder */ -static void meson_venc_cvbs_encoder_destroy(struct drm_encoder *encoder) +static void meson_encoder_cvbs_encoder_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); } -static const struct drm_encoder_funcs meson_venc_cvbs_encoder_funcs = { - .destroy = meson_venc_cvbs_encoder_destroy, +static const struct drm_encoder_funcs meson_encoder_cvbs_encoder_funcs = { + .destroy = meson_encoder_cvbs_encoder_destroy, }; -static int meson_venc_cvbs_encoder_atomic_check(struct drm_encoder *encoder, +static int meson_encoder_cvbs_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { @@ -159,11 +159,11 @@ static int meson_venc_cvbs_encoder_atomic_check(struct drm_encoder *encoder, return -EINVAL; } -static void meson_venc_cvbs_encoder_disable(struct drm_encoder *encoder) +static void meson_encoder_cvbs_encoder_disable(struct drm_encoder *encoder) { - struct meson_venc_cvbs *meson_venc_cvbs = - encoder_to_meson_venc_cvbs(encoder); - struct meson_drm *priv = meson_venc_cvbs->priv; + struct meson_encoder_cvbs *meson_encoder_cvbs = + encoder_to_meson_encoder_cvbs(encoder); + struct meson_drm *priv = meson_encoder_cvbs->priv; /* Disable CVBS VDAC */ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { @@ -175,11 +175,11 @@ static void meson_venc_cvbs_encoder_disable(struct drm_encoder *encoder) } } -static void meson_venc_cvbs_encoder_enable(struct drm_encoder *encoder) +static void meson_encoder_cvbs_encoder_enable(struct drm_encoder *encoder) { - struct meson_venc_cvbs *meson_venc_cvbs = - encoder_to_meson_venc_cvbs(encoder); - struct meson_drm *priv = meson_venc_cvbs->priv; + struct meson_encoder_cvbs *meson_encoder_cvbs = + encoder_to_meson_encoder_cvbs(encoder); + struct meson_drm *priv = meson_encoder_cvbs->priv; /* VDAC0 source is not from ATV */ writel_bits_relaxed(VENC_VDAC_SEL_ATV_DMD, 0, @@ -198,14 +198,14 @@ static void meson_venc_cvbs_encoder_enable(struct drm_encoder *encoder) } } -static void meson_venc_cvbs_encoder_mode_set(struct drm_encoder *encoder, +static void meson_encoder_cvbs_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { const struct meson_cvbs_mode *meson_mode = meson_cvbs_get_mode(mode); - struct meson_venc_cvbs *meson_venc_cvbs = - encoder_to_meson_venc_cvbs(encoder); - struct meson_drm *priv = meson_venc_cvbs->priv; + struct meson_encoder_cvbs *meson_encoder_cvbs = + encoder_to_meson_encoder_cvbs(encoder); + struct meson_drm *priv = meson_encoder_cvbs->priv; if (meson_mode) { meson_venci_cvbs_mode_set(priv, meson_mode->enci); @@ -219,14 +219,14 @@ static void meson_venc_cvbs_encoder_mode_set(struct drm_encoder *encoder, } static const struct drm_encoder_helper_funcs - meson_venc_cvbs_encoder_helper_funcs = { - .atomic_check = meson_venc_cvbs_encoder_atomic_check, - .disable = meson_venc_cvbs_encoder_disable, - .enable = meson_venc_cvbs_encoder_enable, - .mode_set = meson_venc_cvbs_encoder_mode_set, + meson_encoder_cvbs_encoder_helper_funcs = { + .atomic_check = meson_encoder_cvbs_encoder_atomic_check, + .disable = meson_encoder_cvbs_encoder_disable, + .enable = meson_encoder_cvbs_encoder_enable, + .mode_set = meson_encoder_cvbs_encoder_mode_set, }; -static bool meson_venc_cvbs_connector_is_available(struct meson_drm *priv) +static bool meson_encoder_cvbs_connector_is_available(struct meson_drm *priv) { struct device_node *remote; @@ -238,27 +238,27 @@ static bool meson_venc_cvbs_connector_is_available(struct meson_drm *priv) return true; } -int meson_venc_cvbs_create(struct meson_drm *priv) +int meson_encoder_cvbs_init(struct meson_drm *priv) { struct drm_device *drm = priv->drm; - struct meson_venc_cvbs *meson_venc_cvbs; + struct meson_encoder_cvbs *meson_encoder_cvbs; struct drm_connector *connector; struct drm_encoder *encoder; int ret; - if (!meson_venc_cvbs_connector_is_available(priv)) { + if (!meson_encoder_cvbs_connector_is_available(priv)) { dev_info(drm->dev, "CVBS Output connector not available\n"); return 0; } - meson_venc_cvbs = devm_kzalloc(priv->dev, sizeof(*meson_venc_cvbs), + meson_encoder_cvbs = devm_kzalloc(priv->dev, sizeof(*meson_encoder_cvbs), GFP_KERNEL); - if (!meson_venc_cvbs) + if (!meson_encoder_cvbs) return -ENOMEM; - meson_venc_cvbs->priv = priv; - encoder = &meson_venc_cvbs->encoder; - connector = &meson_venc_cvbs->connector; + meson_encoder_cvbs->priv = priv; + encoder = &meson_encoder_cvbs->encoder; + connector = &meson_encoder_cvbs->connector; /* Connector */ @@ -276,10 +276,10 @@ int meson_venc_cvbs_create(struct meson_drm *priv) /* Encoder */ - drm_encoder_helper_add(encoder, &meson_venc_cvbs_encoder_helper_funcs); + drm_encoder_helper_add(encoder, &meson_encoder_cvbs_encoder_helper_funcs); - ret = drm_encoder_init(drm, encoder, &meson_venc_cvbs_encoder_funcs, - DRM_MODE_ENCODER_TVDAC, "meson_venc_cvbs"); + ret = drm_encoder_init(drm, encoder, &meson_encoder_cvbs_encoder_funcs, + DRM_MODE_ENCODER_TVDAC, "meson_encoder_cvbs"); if (ret) { dev_err(priv->dev, "Failed to init CVBS encoder\n"); return ret; diff --git a/drivers/gpu/drm/meson/meson_venc_cvbs.h b/drivers/gpu/drm/meson/meson_encoder_cvbs.h similarity index 92% rename from drivers/gpu/drm/meson/meson_venc_cvbs.h rename to drivers/gpu/drm/meson/meson_encoder_cvbs.h index ab7f76ba469c..61d9d183ce7f 100644 --- a/drivers/gpu/drm/meson/meson_venc_cvbs.h +++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.h @@ -24,6 +24,6 @@ struct meson_cvbs_mode { /* Modes supported by the CVBS output */ extern struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT]; -int meson_venc_cvbs_create(struct meson_drm *priv); +int meson_encoder_cvbs_init(struct meson_drm *priv); #endif /* __MESON_VENC_CVBS_H */ From patchwork Wed Oct 20 12:39:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 12572289 X-Patchwork-Delegate: neil.armstrong@linaro.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3075DC433F5 for ; Wed, 20 Oct 2021 12:42:00 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E91306103D for ; Wed, 20 Oct 2021 12:41:59 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org E91306103D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=/qt85v0E009ZNTS1zGS8oPE2yUAczupZgqTjTqB31bY=; b=5C+U1+nPyomQZa 8K+kIAujI9dG9QqZNYvSVL3GS7lj50oR32ELx0d08QIPe9oW89oS8j+nUf94AxfRupi/bb2qGAAE9 WowOrGImXzIMzf7rsa1C3pzxR2vhe9RUn/M3H0GU0WRf9brI/O0MYmrznnbTo6iB/+S+qIXhGJrdo vI9jesUOQW3dAxCUaGVK4SwYW7pcsnf29cMD72xWwH+pwFj4M9qj0NZslrwWKvE5lzwImPcwZ2eA2 GcsMJebAJxSJNepH+64qFADzMF0GPHLYRZhegnJg8cf0Y7MwjoKQVGs5ofxY4WkyTZwJ3rk4bR3wk uMpesStvHc8qxxhrdNfQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdAun-004Vol-P5; Wed, 20 Oct 2021 12:41:53 +0000 Received: from mail-wm1-x333.google.com ([2a00:1450:4864:20::333]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdAsw-004UrJ-Sv for linux-amlogic@lists.infradead.org; Wed, 20 Oct 2021 12:40:03 +0000 Received: by mail-wm1-x333.google.com with SMTP id 67-20020a1c1946000000b0030d4c90fa87so9906743wmz.2 for ; Wed, 20 Oct 2021 05:39:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/IFVpxHHJMHARIjdjaFpebNjFZaqu9DmMEXQC6d8lb8=; b=fQfz2s+GIjH1uU5O3aV4gRZQgQlDTXAi3ZHtBRiY0MWbjfbwsRPV+HHvL9uhEVivX9 CusCd4St2091KB5+whbMAidQabmHVLFWq6yDodC8C5aIAJMexkIZ0zLfs4G60dxLgLzA k2kMj+jdh/ZQUyfK3LR5Fx3N6G8+vNi0HurSQ/XMUvwuZOZNoAvc0mFG0vBIzMiCmI3o ax7U2UjMfzDwTd1PyUTy7MRTlCVioTf8F2V0Kfg6qfDro8eiix7YE8053M0EfJtdKYbL rDWDqVlnJqHk3dyoQmLCuiuCLuF3uJ4QPJN0b7m4ooHGJmCKxrDmhWVZQ03zFwx6WNTn Eq4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/IFVpxHHJMHARIjdjaFpebNjFZaqu9DmMEXQC6d8lb8=; b=W0k8eFvTvJDsfIOYxLRcJO0aTNeN+NWyXtbJwUuKPaP37u3+ikwWVA/oHPEJPxS6rc wKAqC01aDXwyjElKvYhQClAAvgCB1vNxSAAWVWg6UcGgqBTUF0Q/hcxBoVy5Z2qysSE0 EoX7dxLFKs2bd1v1d71lFKezozwmkY5GenHF2C+ifBGAKlWaz7rqHl2duo+BqDo33HR0 C6VlRitRPTP01+d3qTGB0H4uxUBiDokR4qJzhb3kTJazHo9l9ZaUJNsOb6OEiuP9MgaV sZmR3pjkaknnhpd4io6Kv6cLrvGB3TCOLdHM+95dvz9+4aXD7E3+I0ub4Z+L4WjDu/nR P+mg== X-Gm-Message-State: AOAM532K/hiEH6lffM+GJo1nLAubfVyjZNR2JdXmwTKFre1XeKu0pwBT 54xmCeS9qIfrLaxCRZqVPdZvwA== X-Google-Smtp-Source: ABdhPJx5PaHHkfj44R0jHo5Eflv7DvAaCo43R50VoGhU9CgRj98KJuZdQp4to6o81FLwm3sGVufnQA== X-Received: by 2002:a05:600c:378d:: with SMTP id o13mr8404439wmr.41.1634733597149; Wed, 20 Oct 2021 05:39:57 -0700 (PDT) Received: from localhost.localdomain ([2001:861:44c0:66c0:d31f:1512:8915:e439]) by smtp.gmail.com with ESMTPSA id b19sm5342680wmj.9.2021.10.20.05.39.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Oct 2021 05:39:56 -0700 (PDT) From: Neil Armstrong To: daniel@ffwll.ch, Laurent.pinchart@ideasonboard.com, sam@ravnborg.org Cc: martin.blumenstingl@googlemail.com, dri-devel@lists.freedesktop.org, linux-amlogic@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Neil Armstrong Subject: [PATCH v3 6/6] drm/meson: encoder_cvbs: switch to bridge with ATTACH_NO_CONNECTOR Date: Wed, 20 Oct 2021 14:39:47 +0200 Message-Id: <20211020123947.2585572-7-narmstrong@baylibre.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211020123947.2585572-1-narmstrong@baylibre.com> References: <20211020123947.2585572-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=12904; h=from:subject; bh=OlNNTmN8nosYoeNKPBE53UzuRFb9R4pSq4LSfrZKnuU=; b=owEBbQKS/ZANAwAKAXfc29rIyEnRAcsmYgBhcA34ftCu2bQYD9BgERzGjB8Kv6U3gZ6EYg3Pbf2X sOB7GZyJAjMEAAEKAB0WIQQ9U8YmyFYF/h30LIt33NvayMhJ0QUCYXAN+AAKCRB33NvayMhJ0T5pD/ 9V1YFO4VRnw1txSSTLIOCukxA5xMFCG60fCaPJKrz3SP2K9mbvjgNMDv64J0wWNnNi+hYI3MoHJgYe HlGiUG6pVI2hoG1knDcD0xnBCme/yQos+D1VWlyytThYS5KgEjspl4xJd0bMzpKFHr1t/DEYTQQNUR KtS1ZBv/j/4s5eywzX/P9MBcMkiuhpa4E+RPUy7/7bNae57Bjr/Ajci060PWGGBgCoiu68NB2I8+sR A3uMg2N8pCxOZMlN0b9RYsrBplRtWjYIfr9Q2TsSqTWiPEhs+H/dYMwD2OsHhVnLDo1enrVKD7Me2V 0qHvTxM6S+CZMASm4Zx6+2cv8VOlXcigjDc/jp1pOXU5nP5F83i8l1K2qJyXnrQoDKFWGygy9pQq8X rPtga2U+6sWdqojR3EkcwcKjEE4tTmextefuqctUigRGb52VC5wwgf5cBOUGee1Va3+HjELeDCMCPM 51Gh8zI/NTfwPqmro8fTcItx1r6F3Lm1yTZF/Fz58ueDgbdfOvjTW5hPekC2ZfIb8+HX5ltqcae0kq E7p3W2gzt98B6j6TApYZWTayN6V4cWbHBk8pPGYqa0i7uJ9k30ZT2GF6daCgHi3WlYewoFG/c2Hl8k yuMSdLVacNYwGHLeooKtZGj6rYURnvHyDbuzqKy5u1d0x1ECNPhmTCTDFOOg== X-Developer-Key: i=narmstrong@baylibre.com; a=openpgp; fpr=89EC3D058446217450F22848169AB7B1A4CFF8AE X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211020_053958_962617_0A9F6D9B X-CRM114-Status: GOOD ( 18.86 ) X-BeenThere: linux-amlogic@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-amlogic" Errors-To: linux-amlogic-bounces+linux-amlogic=archiver.kernel.org@lists.infradead.org Drop the local connector and move all callback to bridge funcs in order to leverage the generic CVBS diplay connector. This will also permit adding custom cvbs connectors for ADC based HPD detection on some Amlogic SoC based boards. Signed-off-by: Neil Armstrong Acked-by: Sam Ravnborg Acked-by: Martin Blumenstingl --- drivers/gpu/drm/meson/meson_encoder_cvbs.c | 241 ++++++++++----------- 1 file changed, 116 insertions(+), 125 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c index 01024c5f610c..fd8db97ba8ba 100644 --- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c +++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c @@ -13,10 +13,12 @@ #include #include +#include +#include #include #include #include -#include +#include #include "meson_registers.h" #include "meson_vclk.h" @@ -30,14 +32,13 @@ struct meson_encoder_cvbs { struct drm_encoder encoder; - struct drm_connector connector; + struct drm_bridge bridge; + struct drm_bridge *next_bridge; struct meson_drm *priv; }; -#define encoder_to_meson_encoder_cvbs(x) \ - container_of(x, struct meson_encoder_cvbs, encoder) -#define connector_to_meson_encoder_cvbs(x) \ - container_of(x, struct meson_encoder_cvbs, connector) +#define bridge_to_meson_encoder_cvbs(x) \ + container_of(x, struct meson_encoder_cvbs, bridge) /* Supported Modes */ @@ -81,32 +82,31 @@ meson_cvbs_get_mode(const struct drm_display_mode *req_mode) return NULL; } -/* Connector */ - -static void meson_cvbs_connector_destroy(struct drm_connector *connector) +static int meson_encoder_cvbs_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) { - drm_connector_cleanup(connector); -} + struct meson_encoder_cvbs *meson_encoder_cvbs = + bridge_to_meson_encoder_cvbs(bridge); -static enum drm_connector_status -meson_cvbs_connector_detect(struct drm_connector *connector, bool force) -{ - /* FIXME: Add load-detect or jack-detect if possible */ - return connector_status_connected; + return drm_bridge_attach(bridge->encoder, meson_encoder_cvbs->next_bridge, + &meson_encoder_cvbs->bridge, flags); } -static int meson_cvbs_connector_get_modes(struct drm_connector *connector) +static int meson_encoder_cvbs_get_modes(struct drm_bridge *bridge, + struct drm_connector *connector) { - struct drm_device *dev = connector->dev; + struct meson_encoder_cvbs *meson_encoder_cvbs = + bridge_to_meson_encoder_cvbs(bridge); + struct meson_drm *priv = meson_encoder_cvbs->priv; struct drm_display_mode *mode; int i; for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) { struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i]; - mode = drm_mode_duplicate(dev, &meson_mode->mode); + mode = drm_mode_duplicate(priv->drm, &meson_mode->mode); if (!mode) { - DRM_ERROR("Failed to create a new display mode\n"); + dev_err(priv->dev, "Failed to create a new display mode\n"); return 0; } @@ -116,40 +116,18 @@ static int meson_cvbs_connector_get_modes(struct drm_connector *connector) return i; } -static int meson_cvbs_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) +static int meson_encoder_cvbs_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *display_info, + const struct drm_display_mode *mode) { - /* Validate the modes added in get_modes */ - return MODE_OK; -} - -static const struct drm_connector_funcs meson_cvbs_connector_funcs = { - .detect = meson_cvbs_connector_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = meson_cvbs_connector_destroy, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; + if (meson_cvbs_get_mode(mode)) + return MODE_OK; -static const -struct drm_connector_helper_funcs meson_cvbs_connector_helper_funcs = { - .get_modes = meson_cvbs_connector_get_modes, - .mode_valid = meson_cvbs_connector_mode_valid, -}; - -/* Encoder */ - -static void meson_encoder_cvbs_encoder_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); + return MODE_BAD; } -static const struct drm_encoder_funcs meson_encoder_cvbs_encoder_funcs = { - .destroy = meson_encoder_cvbs_encoder_destroy, -}; - -static int meson_encoder_cvbs_encoder_atomic_check(struct drm_encoder *encoder, +static int meson_encoder_cvbs_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { @@ -159,27 +137,40 @@ static int meson_encoder_cvbs_encoder_atomic_check(struct drm_encoder *encoder, return -EINVAL; } -static void meson_encoder_cvbs_encoder_disable(struct drm_encoder *encoder) +static void meson_encoder_cvbs_atomic_enable(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state) { - struct meson_encoder_cvbs *meson_encoder_cvbs = - encoder_to_meson_encoder_cvbs(encoder); - struct meson_drm *priv = meson_encoder_cvbs->priv; + struct meson_encoder_cvbs *encoder_cvbs = bridge_to_meson_encoder_cvbs(bridge); + struct drm_atomic_state *state = bridge_state->base.state; + struct meson_drm *priv = encoder_cvbs->priv; + const struct meson_cvbs_mode *meson_mode; + struct drm_connector_state *conn_state; + struct drm_crtc_state *crtc_state; + struct drm_connector *connector; - /* Disable CVBS VDAC */ - if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { - regmap_write(priv->hhi, HHI_VDAC_CNTL0_G12A, 0); - regmap_write(priv->hhi, HHI_VDAC_CNTL1_G12A, 0); - } else { - regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0); - regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8); - } -} + connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); + if (WARN_ON(!connector)) + return; -static void meson_encoder_cvbs_encoder_enable(struct drm_encoder *encoder) -{ - struct meson_encoder_cvbs *meson_encoder_cvbs = - encoder_to_meson_encoder_cvbs(encoder); - struct meson_drm *priv = meson_encoder_cvbs->priv; + conn_state = drm_atomic_get_new_connector_state(state, connector); + if (WARN_ON(!conn_state)) + return; + + crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); + if (WARN_ON(!crtc_state)) + return; + + meson_mode = meson_cvbs_get_mode(&crtc_state->adjusted_mode); + if (WARN_ON(!meson_mode)) + return; + + meson_venci_cvbs_mode_set(priv, meson_mode->enci); + + /* Setup 27MHz vclk2 for ENCI and VDAC */ + meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, + MESON_VCLK_CVBS, MESON_VCLK_CVBS, + MESON_VCLK_CVBS, MESON_VCLK_CVBS, + true); /* VDAC0 source is not from ATV */ writel_bits_relaxed(VENC_VDAC_SEL_ATV_DMD, 0, @@ -198,96 +189,96 @@ static void meson_encoder_cvbs_encoder_enable(struct drm_encoder *encoder) } } -static void meson_encoder_cvbs_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) +static void meson_encoder_cvbs_atomic_disable(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state) { - const struct meson_cvbs_mode *meson_mode = meson_cvbs_get_mode(mode); struct meson_encoder_cvbs *meson_encoder_cvbs = - encoder_to_meson_encoder_cvbs(encoder); + bridge_to_meson_encoder_cvbs(bridge); struct meson_drm *priv = meson_encoder_cvbs->priv; - if (meson_mode) { - meson_venci_cvbs_mode_set(priv, meson_mode->enci); - - /* Setup 27MHz vclk2 for ENCI and VDAC */ - meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, - MESON_VCLK_CVBS, MESON_VCLK_CVBS, - MESON_VCLK_CVBS, MESON_VCLK_CVBS, - true); + /* Disable CVBS VDAC */ + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { + regmap_write(priv->hhi, HHI_VDAC_CNTL0_G12A, 0); + regmap_write(priv->hhi, HHI_VDAC_CNTL1_G12A, 0); + } else { + regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0); + regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8); } } -static const struct drm_encoder_helper_funcs - meson_encoder_cvbs_encoder_helper_funcs = { - .atomic_check = meson_encoder_cvbs_encoder_atomic_check, - .disable = meson_encoder_cvbs_encoder_disable, - .enable = meson_encoder_cvbs_encoder_enable, - .mode_set = meson_encoder_cvbs_encoder_mode_set, +static const struct drm_bridge_funcs meson_encoder_cvbs_bridge_funcs = { + .attach = meson_encoder_cvbs_attach, + .mode_valid = meson_encoder_cvbs_mode_valid, + .get_modes = meson_encoder_cvbs_get_modes, + .atomic_enable = meson_encoder_cvbs_atomic_enable, + .atomic_disable = meson_encoder_cvbs_atomic_disable, + .atomic_check = meson_encoder_cvbs_atomic_check, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, }; -static bool meson_encoder_cvbs_connector_is_available(struct meson_drm *priv) -{ - struct device_node *remote; - - remote = of_graph_get_remote_node(priv->dev->of_node, 0, 0); - if (!remote) - return false; - - of_node_put(remote); - return true; -} - int meson_encoder_cvbs_init(struct meson_drm *priv) { struct drm_device *drm = priv->drm; struct meson_encoder_cvbs *meson_encoder_cvbs; struct drm_connector *connector; - struct drm_encoder *encoder; + struct device_node *remote; int ret; - if (!meson_encoder_cvbs_connector_is_available(priv)) { + meson_encoder_cvbs = devm_kzalloc(priv->dev, sizeof(*meson_encoder_cvbs), GFP_KERNEL); + if (!meson_encoder_cvbs) + return -ENOMEM; + + /* CVBS Connector Bridge */ + remote = of_graph_get_remote_node(priv->dev->of_node, 0, 0); + if (!remote) { dev_info(drm->dev, "CVBS Output connector not available\n"); return 0; } - meson_encoder_cvbs = devm_kzalloc(priv->dev, sizeof(*meson_encoder_cvbs), - GFP_KERNEL); - if (!meson_encoder_cvbs) - return -ENOMEM; + meson_encoder_cvbs->next_bridge = of_drm_find_bridge(remote); + if (!meson_encoder_cvbs->next_bridge) { + dev_err(priv->dev, "Failed to find CVBS Connector bridge\n"); + return -EPROBE_DEFER; + } - meson_encoder_cvbs->priv = priv; - encoder = &meson_encoder_cvbs->encoder; - connector = &meson_encoder_cvbs->connector; + /* CVBS Encoder Bridge */ + meson_encoder_cvbs->bridge.funcs = &meson_encoder_cvbs_bridge_funcs; + meson_encoder_cvbs->bridge.of_node = priv->dev->of_node; + meson_encoder_cvbs->bridge.type = DRM_MODE_CONNECTOR_Composite; + meson_encoder_cvbs->bridge.ops = DRM_BRIDGE_OP_MODES; + meson_encoder_cvbs->bridge.interlace_allowed = true; - /* Connector */ + drm_bridge_add(&meson_encoder_cvbs->bridge); - drm_connector_helper_add(connector, - &meson_cvbs_connector_helper_funcs); + meson_encoder_cvbs->priv = priv; - ret = drm_connector_init(drm, connector, &meson_cvbs_connector_funcs, - DRM_MODE_CONNECTOR_Composite); + /* Encoder */ + ret = drm_simple_encoder_init(priv->drm, &meson_encoder_cvbs->encoder, + DRM_MODE_ENCODER_TVDAC); if (ret) { - dev_err(priv->dev, "Failed to init CVBS connector\n"); + dev_err(priv->dev, "Failed to init CVBS encoder: %d\n", ret); return ret; } - connector->interlace_allowed = 1; - - /* Encoder */ - - drm_encoder_helper_add(encoder, &meson_encoder_cvbs_encoder_helper_funcs); + meson_encoder_cvbs->encoder.possible_crtcs = BIT(0); - ret = drm_encoder_init(drm, encoder, &meson_encoder_cvbs_encoder_funcs, - DRM_MODE_ENCODER_TVDAC, "meson_encoder_cvbs"); + /* Attach CVBS Encoder Bridge to Encoder */ + ret = drm_bridge_attach(&meson_encoder_cvbs->encoder, &meson_encoder_cvbs->bridge, NULL, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); if (ret) { - dev_err(priv->dev, "Failed to init CVBS encoder\n"); + dev_err(priv->dev, "Failed to attach bridge: %d\n", ret); return ret; } - encoder->possible_crtcs = BIT(0); - - drm_connector_attach_encoder(connector, encoder); + /* Initialize & attach Bridge Connector */ + connector = drm_bridge_connector_init(priv->drm, &meson_encoder_cvbs->encoder); + if (IS_ERR(connector)) { + dev_err(priv->dev, "Unable to create CVBS bridge connector\n"); + return PTR_ERR(connector); + } + drm_connector_attach_encoder(connector, &meson_encoder_cvbs->encoder); return 0; }