From patchwork Thu Oct 14 15:26:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 12558797 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 AF53EC433EF for ; Thu, 14 Oct 2021 15:28:25 +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 72B3460F6F for ; Thu, 14 Oct 2021 15:28:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 72B3460F6F 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=2uD1ZVHDUiHBoMV5MV+aqdniZM637bwZf01D6lBuIik=; b=RV1GmiViCEkUvV py05VqWD8SIPeCK4SaYPySfybRd/+iCJ9BI//sZO7OBmcATuVeHviYUMRb8PtB3J9WL8kAiyR/aeJ anCbMhcDTIayyftrVGe3GgnKJ1FkpupGETgonTg5j6825zKRr0AjSueOIaDGI+d/RG5FF15kBlMdq F2WRKK/NbARbq7GJ1u75SUUAlxyiFLexJpgln4Nl6s5dRv7YLDFAotMc2fbEdArTXNcWhsRHTf6dc TetBORst1GMkmPyFvu6HxrvmwcE1mDsAmgZsmIhyS2qx/pUx5cz9Au0gTmwp5BSUFmF5wIIoMOZia UFLViXcrLilGsZg3gQvg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mb2dD-003deV-Gf; Thu, 14 Oct 2021 15:26:55 +0000 Received: from mail-wr1-x435.google.com ([2a00:1450:4864:20::435]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mb2cZ-003dKz-6p for linux-arm-kernel@lists.infradead.org; Thu, 14 Oct 2021 15:26:18 +0000 Received: by mail-wr1-x435.google.com with SMTP id r7so20708434wrc.10 for ; Thu, 14 Oct 2021 08:26:14 -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=A/UD6kbf9y3kSEH44o5tSIzBUQ67nK53eX5Y59IgtSs=; b=P34HjUhkjjM7vHhJKe0dRgGSZQwPHY3HN79wqaabHjRWRd+kHcF17ph1dTmh7ycAWH iZ7oVA90oPTWqC1KdA9viHiCyOhltk1TVWZvo50LTQu80LGqKdmu/CCLAJl9VJbqtfKl RFBJv2jedAvS0H1zJ6Nn8Lbw3C2Jn3IEFVVmXuVH7P4RDk71AibN37Vv5BYGmh7wRTzV Mr20QvCgR+bQO/Y3Dft+qrMhucxN82Kz5K+j/BgFW/9y99+GfgBfrcrCRU9BXzsGhdZT uXWgFzRAZ4TZzQI/zn21GytScKK0+erWt+Gec5iSeS2hwD4PqqRbySscZWKcLi712OQ/ qaKQ== 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=A/UD6kbf9y3kSEH44o5tSIzBUQ67nK53eX5Y59IgtSs=; b=j9lA8SxDkAspmpT2oW4s58TfHWkDwKAZXuYajYEBP7VOHuS6UsO9jawZiEjGpI39zW 7lz7vW5Vi97vTF807OFrqK54D2zwpeOTtdcgZ39jXV2bZzCHVC8zbu6vFeI1ag9cQ4SZ dXHhYzTwitgOCkCy4X0ElIK2J5//YIOV98hDGgG7D0nvCrNjR6njIDNfxdKk0Go79v9w PAfgsM7taaoY30hHu9Q9Koy0eMY9AxQ6kJlwr4AkLnWRBZGiVt+SpwRWs5De8DvWH34k wtYgYnbubBzd4uRwZcNm3s+gi8+Txzf/+0ALUNIet1fD/eKL/AMr2LulNEVlfH8JihjM wX7Q== X-Gm-Message-State: AOAM5301AvgqLis8YP4UsFz6jpleAjXWlyIm5oktArYpM/PugnY5/yj4 oVTTYhn7LHN+4bI30LRG6o60sw== X-Google-Smtp-Source: ABdhPJywinMYzalRdTjhe2vVBQGXKB18TTNLcJD2odD6MDV+5cF2gn9oPeCZXQYmsrzhWIjkyZo93w== X-Received: by 2002:a5d:47cd:: with SMTP id o13mr7565708wrc.85.1634225173222; Thu, 14 Oct 2021 08:26:13 -0700 (PDT) Received: from localhost.localdomain ([2001:861:44c0:66c0:209b:8400:2b80:b4ae]) by smtp.gmail.com with ESMTPSA id k22sm2626790wrd.59.2021.10.14.08.26.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 08:26:12 -0700 (PDT) From: Neil Armstrong To: daniel@ffwll.ch, Laurent.pinchart@ideasonboard.com, robert.foss@linaro.org, jonas@kwiboo.se, jernej.skrabec@gmail.com 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 1/7] drm/bridge: display-connector: implement bus fmts callbacks Date: Thu, 14 Oct 2021 17:26:00 +0200 Message-Id: <20211014152606.2289528-2-narmstrong@baylibre.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211014152606.2289528-1-narmstrong@baylibre.com> References: <20211014152606.2289528-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5079; h=from:subject; bh=07kqi5zzzSZI3ElecWIOO/HwkZFn9DMBCe+0pRu8cJA=; b=owEBbQKS/ZANAwAKAXfc29rIyEnRAcsmYgBhaEt/t/370Lg/hnQqBrBvL/wtk59MM3tbZ0rvz/5N eMloI7WJAjMEAAEKAB0WIQQ9U8YmyFYF/h30LIt33NvayMhJ0QUCYWhLfwAKCRB33NvayMhJ0UqrD/ 4v4xuQX0SlQs0w6df5xkrKK/+gkk4YbBZ86Cfd7zw4s3Iwr4XOZJmp0p73OxA7CoEnLAz1E+NBnBw4 iD+c7wE2ll2b/naUYgoLFwgdehJsLhVIv3iM2N+vdYuM4CqO0xsP1i59FwwAaDK1dVY1l3X5SgeVKv B+s666HTrJYnUzsU608Qo52PD6vFsI3zz0uP8a3hNWxgYDHnJiP4Ms2o+oQTjnXjI41LfWf2ptx379 m3btHxQqgICP0eZsDuyKxbyjiOtoe3c+Sh3ZgpQPyK9o/9cOO2olu9gcMU1d8PY7NqW2nUA5ledYbH kQZf6H6JRGZUP6hvDbuVJ2seoAEaBumNUVMEQU9Nq6Fq7kQ/bP2ppJmycLdtuwVN6wS4I439Zxk4JU rNTYocHgjs9tJV5U2fLPqzM0r9EfOuY8fHmo9kkBKlFbX0CkZ/e/cWbjI50StsiMf5U33VMefWCKmF IqrAGtc8z9MG6HPzfivQinyzxZKZdTB0EOFR7o4R+khNww7zAEqcIZMm8JezS1LHv6MlVqFRNQ0UAf z+AGRjKvZjlrUiqgqbqbrvXfvTxw+njfv3hhe3IMk9jWefaYZmj5C5pbLvjUFhR27/UrxYKuE4c9z5 HNOpnHDAQtcXBn9xcklCTs+nGlR4AO8oQXwX4Y4U/7FPzFAF0QsIFXf3h1Og== 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-20211014_082615_278789_4E0DABD7 X-CRM114-Status: GOOD ( 16.24 ) X-BeenThere: linux-arm-kernel@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-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=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 | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c index 05eb759da6fc..9697ac173157 100644 --- a/drivers/gpu/drm/bridge/display-connector.c +++ b/drivers/gpu/drm/bridge/display-connector.c @@ -14,6 +14,7 @@ #include #include +#include #include struct display_connector { @@ -87,10 +88,97 @@ 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 permits avoiding skipping the negociation 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 return fallback data like done in the bridge function: + * select_bus_fmt_recursive() when atomic_get_input_bus_fmts is not supported. + * This permits avoiding skipping the negociation 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 Thu Oct 14 15:26:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 12558795 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 171B1C433FE for ; Thu, 14 Oct 2021 15:28:10 +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 D97E960F6F for ; Thu, 14 Oct 2021 15:28:09 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org D97E960F6F 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=LpqImSmFLMEDrnakSOhQlGC0/dJ7D3vNG+0RiWEGxU0=; b=VkZ982V9eUGFoh 5D8HxDyM9lk1EivIScUhGBTa4CnAFhVsJ77aoRYo2xiyseFxAqWxVQcQzUUpsYlfoYy0/CgNqyBKZ oWVlDocAjbw2Yz4guICJjEZlnoxXReWc6QgxfRVl8ya+7/qJXNyAWyzOF8IdWS07CntDPJHwOfzkV Vnp4OdeTS1GyDoUJ7xckZPhkqxk/ntdNkoIM7EnIs+tDnLaW9Rx6Sdp8Ys72NKwyun4usVIwGo8fu 0kCrzuqI5OYClamRxS1WjCRAkgq1eIb0MxdSK6rZnRmN6UklB8y3a4sv81UvuQ4b8c2mk9UUIqeBP RCB5FD97iQLfAPK9KD+g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mb2d0-003daA-88; Thu, 14 Oct 2021 15:26:42 +0000 Received: from mail-wr1-x42b.google.com ([2a00:1450:4864:20::42b]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mb2cZ-003dL9-IL for linux-arm-kernel@lists.infradead.org; Thu, 14 Oct 2021 15:26:18 +0000 Received: by mail-wr1-x42b.google.com with SMTP id v17so20645100wrv.9 for ; Thu, 14 Oct 2021 08:26:15 -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=TQyJyeyxugDyeCUhn5i4YMOhGyD1g0TIMIamYKTURg8=; b=aUp3lJkhPh7AP+vd/IxIyLZ9pww2/86fdh30VMRPWAjOPgcYeMdPzrsxZP6sBE00E8 pGgzyLGLmp7zVQ9cUv4mpduzaEXvlUsIaRQ5JV5NYw5sBZgTNhtsBPU8cWCoubF4OfIc We6escDBTXR7ecjOqAG4gkw4+7NGQRUo4+QsAzHDndGtbN1dr1o8V2Z1KEESagi+16Rl 5fOOUoFuqRymwJctDz1xKKLZDd4T60MPavnGIjCNluwnnSLQII3vOnjSlAbJt3b7KJll vQmOM1DfYTWxh5JoOgbb+9xIQpmPQaoVZxhIPK6kR3U8HplWUWWagcbLKHRnB6FdBF16 6gJA== 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=TQyJyeyxugDyeCUhn5i4YMOhGyD1g0TIMIamYKTURg8=; b=WRn251tsYCXFuv83yZWPvd2HD+Hgwz2bWbJcLAu2e+tbsvN/gK+T2A912Y1LGXn8p8 ijR5H2/7y2ofuPI4h5S3zBc8VVfGwhUPrcyrbkedbZzYNrLbmdb/E9B+Fqgi8KO1CJkE MFj7izNyMtBIiuwOUnZBWk1R7soBxcpIMssCFzL0EH8lSVagOUMAjEV+Hxtq+zLQQ1tQ 33NuYuPt/ovXJ5LlvbEhFVDX2kJgyr3ZESbeozMG+7yGX0+O5Kw9DM97uixHUEOKCaqi dLDT05JekGE051eAKnOAx6y3TbD62KNkYEMODa2bXJVwFy9mVDvBMG5r/XTlpY/hNQ4V 5vnQ== X-Gm-Message-State: AOAM533TZUtWAtBFp6tRRbVI0iF4xHpSwif1MyKDfACrP9G+pcddd1p5 ZSBeEwuI3E1qArX9NYt8GOuG9g== X-Google-Smtp-Source: ABdhPJxnLyE8e0XkabFsMCNQvlY0H++PdbAFZrHOuqQqMKmsmbK8aX172SuBdkcJX2Cj9DFX3GNU8g== X-Received: by 2002:adf:bb93:: with SMTP id q19mr7638741wrg.423.1634225174291; Thu, 14 Oct 2021 08:26:14 -0700 (PDT) Received: from localhost.localdomain ([2001:861:44c0:66c0:209b:8400:2b80:b4ae]) by smtp.gmail.com with ESMTPSA id k22sm2626790wrd.59.2021.10.14.08.26.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 08:26:13 -0700 (PDT) From: Neil Armstrong To: daniel@ffwll.ch, Laurent.pinchart@ideasonboard.com 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 2/7] drm/meson: remove useless recursive components matching Date: Thu, 14 Oct 2021 17:26:01 +0200 Message-Id: <20211014152606.2289528-3-narmstrong@baylibre.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211014152606.2289528-1-narmstrong@baylibre.com> References: <20211014152606.2289528-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3111; h=from:subject; bh=hBDX9bpPEmClmGilczb0BvjIpqS0+aaehaCml/3nEUs=; b=owEBbQKS/ZANAwAKAXfc29rIyEnRAcsmYgBhaEt/6ArrByBlXtYa4Vcu1Celjod/sPgyacJsGSYf F+mjdc+JAjMEAAEKAB0WIQQ9U8YmyFYF/h30LIt33NvayMhJ0QUCYWhLfwAKCRB33NvayMhJ0UhTD/ sH5NZJVQx2YWy6sRmd61nqnsAGOSLvKNLmGt8xiRmm0Zb6ckWoeM30vuE14uVqqzR5ikE4cAk/T3jF 7/r1O/KwZkOPSCzUIFpNFuzUPkO2d0DjdyTSbkZFUEmBLmAwGFio3y6BQu8Pa4pURJP0FgXWNVYVye aT5CTX2lGsSJseYDx5JYNt6U71cmF9f78gV4+1PrRmu8s1rto3ltR/8K7WvWcURGAm8ordgWepmS5E 7dj0ZYEWUvKWJLZFePsoHZwXUGBcrSLd4N6AP285F8+1dD7pULchywDPVlue6vJwlfVy+QUJUvwu3j iXKQNRu2FzqliPbcwmbtkymy6kUvBdRKp3WPoRpPZgAdlEzZMklGMm0UiUFICCyKNt8Cwd9a9mYNGu fuOllgCaOoC/cdInuHDEQP3wZdS+m1dlbdFzVPhcYOqSDgtbVGa17Y9DBms8ypC0KWUmIh3TopYHun o3mNZ3G5AOzbil+PIl+oFEef6n9t/9w55rU9m1638cRpZOJknrxAdP8NWUDkV3//J6Ynq4UzVEcWbl H+4OkvqyX+UchzQ+NrfCQssWeD3aF6Vn+17AML3/MN48tFNupMUCvq106yYJeucpiIlDpfx805qymA hXLGWVK/F9bG9qFrA6ImJQW6Otdxc+H9TRc2JpYtS+iSrdbcW7dw6ohCHb/Q== 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-20211014_082615_629899_8380F42D X-CRM114-Status: GOOD ( 16.42 ) X-BeenThere: linux-arm-kernel@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-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=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 --- 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 bc0d60df04ae..b53606d8825f 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -427,46 +427,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); @@ -478,6 +438,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; @@ -492,8 +459,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; + } + + DRM_DEBUG_DRIVER("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 Thu Oct 14 15:26:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 12558801 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 4CDE7C433EF for ; Thu, 14 Oct 2021 15:29:13 +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 134B860FDC for ; Thu, 14 Oct 2021 15:29:13 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 134B860FDC 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=0xedkDWjyHu/OVBCMS6aN6JzDNBYUWFpc3oiV4Cn7yE=; b=MbW6EZijlD3wb6 SPDYYUr8c5K1VvzpNe2usRVNYDWaicM2xieISI2r5OzZaRhXE8PR192VCgFRajiSsTST9QcEAECgQ GPT6OscLMb0sEHMRLeylbZH3haSp+cZn9fTIBYEe4kDMsMnJ0pCakC5EpGtFgTi4a2ZCspc4sluKh NrutIGu3P+AMoZChf+OYxr3KEalWwBAtrDEIqpjNfo5Z05K1HTO7JHO8323hpPDxvoa/z3oMdoTj9 swu1Rx+AGXfTv1T4V6OcorjZhGjhuSn2EoV+5+htx6qpNJMh/QuKvtxYUeYcbMjK6uq5hq1D9ebtM 3o4qmu2T3u9QVrhUrj3A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mb2do-003dvJ-Mo; Thu, 14 Oct 2021 15:27:33 +0000 Received: from mail-wr1-x42b.google.com ([2a00:1450:4864:20::42b]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mb2ca-003dMP-Sg for linux-arm-kernel@lists.infradead.org; Thu, 14 Oct 2021 15:26:25 +0000 Received: by mail-wr1-x42b.google.com with SMTP id k7so20551170wrd.13 for ; Thu, 14 Oct 2021 08:26:16 -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=M0A8vO6K2UaJl8Wh0iIro32K7b9X039mJZAxfPxUb4w=; b=cNeIFDHkJJa3zh12LAbvukYCinFIEE1BbogL70/vnuNC3FfHct4rdsZe7URQgR7r1e YfLaVZVxRX+qt1f2DVvaGww7tH/LXT6+LklZEdW318Dt0RcqWn1ZZV17iqtW9Fb9L0cV 2Z2n3S03lhoF4rR1YEq02zHZrBfqBWa63XEV3eKrnTz9DEkqeFYZehRQo7nLC4E/IzGV KG9miAvTNWUtzFRdiX3KHtQFJvIPn+ude4RRlHH6C+rjIGmRcudfMCKsfGt3iJ0MJtYe dcF9Y1OrJ1Kt0SPRZsKBsKSejHeKSsVA0rwzxf8/aZxyIchMVWFssoOOetrMXjiD2moe Sn5w== 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=M0A8vO6K2UaJl8Wh0iIro32K7b9X039mJZAxfPxUb4w=; b=BmnfrX1Owh08C7Wr7bQL2Octvsc1mx9xyUtWMUH/2FLK+l3MYnsVP9Pd+XNRyIqFKm qlteMpYRTiVdnHM5dAc4loEODmzUDuUnHxs91qbu7I3XAUFfIPfWGjhHX3cwRo32f0oz eSwZmwa6/PP86RG2UwVeiOw8Ak7K7Uwc/V0Xgb9BdBzSVo+1LnN+yomfcpZzWhZed9Kr 175jH4WfrzkJxxQz7dl5/E30RQbtNHjtgA3wK77V2r66BR8eHyf6eEKtMWzT0/xSaar2 jdgqsN2D9Aes1vdeIzPCk4xc4oDx7tgaC+PvxC+IkyBQyszEUozQd5Ers/NdosRDkpuZ jebw== X-Gm-Message-State: AOAM530huwQHlO8KM4X3w/v8chyvohDz0DfP7QVDJnXl+tED2nIqzkCg lc71QgevHO97oLEdOnCjafPSDQ== X-Google-Smtp-Source: ABdhPJwEqyezQJGLbDEbcEChp12DPG+BD0gwvEEVcUOxXl7IE6W87kUzppKThgSsMup25NN+Pw7VTg== X-Received: by 2002:adf:ee8a:: with SMTP id b10mr7498976wro.335.1634225175394; Thu, 14 Oct 2021 08:26:15 -0700 (PDT) Received: from localhost.localdomain ([2001:861:44c0:66c0:209b:8400:2b80:b4ae]) by smtp.gmail.com with ESMTPSA id k22sm2626790wrd.59.2021.10.14.08.26.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 08:26:14 -0700 (PDT) From: Neil Armstrong To: daniel@ffwll.ch, Laurent.pinchart@ideasonboard.com 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 3/7] drm/meson: split out encoder from meson_dw_hdmi Date: Thu, 14 Oct 2021 17:26:02 +0200 Message-Id: <20211014152606.2289528-4-narmstrong@baylibre.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211014152606.2289528-1-narmstrong@baylibre.com> References: <20211014152606.2289528-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=29720; h=from:subject; bh=XObqiZtEhpcWbklPOqVh0yRZE4cymgfUYFI76ln+OsU=; b=owEBbQKS/ZANAwAKAXfc29rIyEnRAcsmYgBhaEt/X6JZhhGESr8pW7aIJGCrArrugDAp8RV93d/e QcBS+hmJAjMEAAEKAB0WIQQ9U8YmyFYF/h30LIt33NvayMhJ0QUCYWhLfwAKCRB33NvayMhJ0aewD/ 48ItnRRKPowFlQNWNtI4AbVvQ9bVrUWYQmNzKr8Df3QHUyKkHRf1DOzZHWAizaDlv9LqJqQF0/YEyo KZebJdz0fKMCcE8YQqZDDUQR4bTUhW76z6qgn7haYQ3cEdYXo/R4nWQwG6G2EDLoHyG+EqaA83S1Ar YhCTxqa7sDri9CaXssDD+BTqRLG/n8r5Egex7Vbw/45c67imKRbmpMmL7APiikxCoaH1p9pyOMY4iF t124HprTq12Si/GZHbEbh8NxyhlLxbde4XuFKYvPGcJOOnaPRL3HssFRwBOuPn8H/EXz7DISHtilXb OFI0gLzh9SuJhj0Nbr+f/358ZwvKquatA3DPIp2xBVRn8qWu0A4CjH0FB6eqei4t7SROZ415YUlvSc rOBjzFqioODTvGFBIFrX+GPFDkyzRD+GNGledfNU4IGzx31/W6LiD6oPnafdMYGasRsgUz0ViKXm2A rcGoXYphYkZdTXkpdvfqGyCQRhWFkZcU229b/ER5yW7I9yaUM1Jv91O4a0p0mkFcrfzGAffZPcqB3E XLll7i+YCEb/Y2OAuj1xw0YAbTcNp4dvUPtPExVQy4jH13P9Iof/DG77gK3vw66Y1f2/ru42BzuqRK RPmr5oTdXF5XYVtpGjkcR9R432rY/Er0oVr17sRpFpf2WP5stbKT6MavpkQQ== 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-20211014_082617_207192_B7F48E82 X-CRM114-Status: GOOD ( 27.23 ) X-BeenThere: linux-arm-kernel@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-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=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, the encoder init uses the simple kms helper and for now the bridge attach flags is 0. The meson dw-hdmi glue is slighly fixed to live without the encoder in the same driver. Signed-off-by: Neil Armstrong --- 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 | 359 +++++++++++++++++++++ drivers/gpu/drm/meson/meson_encoder_hdmi.h | 12 + 5 files changed, 396 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 b53606d8825f..0a28a8e29d63 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" @@ -319,6 +320,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 2ed87cfdd735..c2480b3335ac 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,19 +702,12 @@ 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; struct resource *res; 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"); @@ -1004,7 +723,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)) { @@ -1076,28 +794,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; @@ -1112,15 +813,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..c775a1ab5b1e --- /dev/null +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c @@ -0,0 +1,359 @@ +// 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 + +#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_enable(struct drm_bridge *bridge) +{ + struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); + struct meson_drm *priv = encoder_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_encoder_hdmi_disable(struct drm_bridge *bridge) +{ + struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); + struct meson_drm *priv = encoder_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_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; + + 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 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; + + 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(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_mode_set(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + const struct drm_display_mode *adjusted_mode) +{ + struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); + struct meson_drm *priv = encoder_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 (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)); +} + +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); + + encoder_hdmi->output_bus_fmt = bridge_state->output_bus_cfg.format; + + DRM_DEBUG_DRIVER("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, + .enable = meson_encoder_hdmi_enable, + .disable = meson_encoder_hdmi_disable, + .mode_valid = meson_encoder_hdmi_mode_valid, + .mode_set = meson_encoder_hdmi_mode_set, + .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; + + DRM_DEBUG_DRIVER("\n"); + + 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] + */ + + DRM_DEBUG_DRIVER("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 Thu Oct 14 15:26:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 12558799 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 9E0A8C433F5 for ; Thu, 14 Oct 2021 15:28:53 +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 6E51860E8B for ; Thu, 14 Oct 2021 15:28:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 6E51860E8B 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=4vElPFumsEBzQ7kI3bknrHd4ydKwR7WbOH73DiKFeP4=; b=TKP1MWFtuqoaWo 8VgjAQFiv3NOe/g7hFZby2qSbktCKxruZ21BJCCFGAX2A7XAkTcaTWR3iUcjszuI04UF9DgblMBza AKZr1fJpl73qFA+BOwYST9/a7u6nxQwC0TvQ+8lMEbDSLcWsyJa4lCCjSUzsDHkEJPLbPGhzS9Oj2 NM4Zr6LXKD0Kt/Zzw03+yzuCZhejbV1ErNOIzdIBO+kHkMWNe8uyhHvb/wrlHhdhyQ/1CyzVdhAEh oIUTH+RHtC/un1yTEgyvdHvQ9IqvZpzx9HA51gY0CLOwVBm4AYvPmpB24UMv2A19HOyXAeu2leTQT 900EY0fMcCI4lCJTcNiA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mb2dS-003djl-4L; Thu, 14 Oct 2021 15:27:10 +0000 Received: from mail-wr1-x431.google.com ([2a00:1450:4864:20::431]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mb2cc-003dMm-CU for linux-arm-kernel@lists.infradead.org; Thu, 14 Oct 2021 15:26:21 +0000 Received: by mail-wr1-x431.google.com with SMTP id e12so20715675wra.4 for ; Thu, 14 Oct 2021 08:26:17 -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=xJdt9xqgEepFbtbB1UkquFZ4VDLNOq6El+raZeZWSOM=; b=pt34RyPq6TeilQMWvaHMCBd0p6iBB5mQ8zyO7bsO0z01t93qtPnfhTtxhynXcJCNZI iejhkLmblTXq7J0R4WWX12xrJSxTJW0L0GLzhdteU9CAgzcrwsJlco9WizJRgcsgkMlf 5SSeCrL3ajGsL5O2s7oUzFOnkoSIkFyX4d5TNYLMjAG3Obr8FEN2lK+YUXNF9NydQi1L P39e94inxhD6MtuCe4rImRHiIoHLnIIucIf205t/kkHURxK51E89grzki14Vr/RhGiA5 p+Y1BsN/CDaqCfhOWBrF0dJNqtR+7ZDFhXLL1nhfz0eac2nIjIR7sxin3uJohE6T1QLY x/Lg== 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=xJdt9xqgEepFbtbB1UkquFZ4VDLNOq6El+raZeZWSOM=; b=a/ig4SFfmG6OYSUsAp12+8RNWZ9xKh7m5TAq+gea7ZeWQDiOyHT8YrFlNstKv73sEH 6AbmLvJ6aNzVulpoSu4lYiTBEiCEnVulhjKvgY5UOGp32wtHdstiwtiber9p7bgopcwG uXQS0PL4npyRw4OmpYGm4nUd6gkOPhIrGBQHrcl1q1FfEig7IhuZLBOpdYfYFPE+ATqs m+yisSVIPUpwgM1daRRh2WyQTa8Drst9A4TACreYTCMFMlko6vCA8NI7UOTqzUbVOUpw reaxM8SY3BZgx43Kau9diSk3V8Rvy4i8mj3+9VJLF62vqZ0xsdjm9DV+sixQO1SsUzhO aOMQ== X-Gm-Message-State: AOAM530HZ0KfzTyVnRosukujAjB2IzNULoIdPVwzV5luZ3JqhkOO+QgC K6pRe7xfGlzYrbQg0yRCi+xzHDPbHrtaHA== X-Google-Smtp-Source: ABdhPJwK/ywxZ2fw2tMZOvBzRr4/yRNBMI1ZBNntxWcjpPuqQLTvL/JRBJL2y5JNH7j8BDDkiWNjnA== X-Received: by 2002:adf:aa92:: with SMTP id h18mr7277007wrc.372.1634225176290; Thu, 14 Oct 2021 08:26:16 -0700 (PDT) Received: from localhost.localdomain ([2001:861:44c0:66c0:209b:8400:2b80:b4ae]) by smtp.gmail.com with ESMTPSA id k22sm2626790wrd.59.2021.10.14.08.26.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 08:26:15 -0700 (PDT) From: Neil Armstrong To: daniel@ffwll.ch, Laurent.pinchart@ideasonboard.com, robert.foss@linaro.org, jonas@kwiboo.se, jernej.skrabec@gmail.com 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 4/7] drm/bridge: synopsys: dw-hdmi: also allow interlace on bridge Date: Thu, 14 Oct 2021 17:26:03 +0200 Message-Id: <20211014152606.2289528-5-narmstrong@baylibre.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211014152606.2289528-1-narmstrong@baylibre.com> References: <20211014152606.2289528-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=884; h=from:subject; bh=VqFA57uYRVnBWiC14bz6QM29bBtN5sRjm8xb2MmDNeU=; b=owEBbQKS/ZANAwAKAXfc29rIyEnRAcsmYgBhaEuAk+fmsK54XgR9Ufj2kk92eYhEp32GG1J/nqjJ orc3ih6JAjMEAAEKAB0WIQQ9U8YmyFYF/h30LIt33NvayMhJ0QUCYWhLgAAKCRB33NvayMhJ0VXbD/ sHJAJpjVaCD1jpnUNddl/tWvU1cQ93DRTHgJCZ4Vr+G+868TYNoXo/scludQSH488DVMDjgGBIJy3M 6jK35EeZgBAUAuD1qmSVEe+aawSSejSlM2Lsfem+TqSWohfPnegZ0q1E66Hm3VUWoaECFyJRPW8i/d 24vn91yOmynCdVKzNMndB5roqofG/5fPGZ1aDi74uySqBv4Cn7ZZ7Hg93KLAHVmcF/NvWr8TquzgCW zq5WoxWT+SIHWoqHLW8LAQTzTLzlNlGkAy15eFAE5PK4cSJebUxX9M+Fn8CEzedh8OsnRffzrydbh8 Bk3deAPoxjBKasnYv0xs1/zGc7Ya6Dic/085flzUlDSUjqz8HounBW3Nttrn7+w+wSvl8kgRm2/a+c bEG+nDgyUN/TGEBO45quuzXh7rTcK8aYsjixdqxkrQC3cbI5dXEs/5j8YWIPVFVfujGPCV+8rHy2Oj H1nPVMzDhd1JPMQ/rx+gZXzQ2U8L2DfxgxG5SUNpX+LJfs7yYLrtVG9aYoEj+goPNPU4txlZK9JaFZ Z1I8clZ/y5FdnnYlBF8iv/R5iCw+CGoZJuNCc7uriMIM0hfwTGGxD/RuQDMSlh+WMj8ULonwqM8rHz w6y1ruDofp+/TouykxmSWQSPPjwQvBgpLLPoa3VnSsUV55ANFAqA23zsLhOA== 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-20211014_082618_440251_DCC02D5D X-CRM114-Status: UNSURE ( 9.84 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-arm-kernel@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-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Since we allow interlace on the encoder, also allow it on the bridge so we can allow interlaced modes when using DRM_BRIDGE_ATTACH_NO_CONNECTOR. Signed-off-by: Neil Armstrong Acked-by: Sam Ravnborg --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index f08d0fded61f..62ae63565d3a 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -3413,6 +3413,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, hdmi->bridge.funcs = &dw_hdmi_bridge_funcs; hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD; + hdmi->bridge.interlace_allowed = true; #ifdef CONFIG_OF hdmi->bridge.of_node = pdev->dev.of_node; #endif From patchwork Thu Oct 14 15:26:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 12558807 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 04BBEC433EF for ; Thu, 14 Oct 2021 15:30:53 +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 BF43A60F9E for ; Thu, 14 Oct 2021 15:30:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org BF43A60F9E 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=ys5a8LHf4PqR0HYYLTwkpIZ99UisTd5LeSYAT8O6wsc=; b=myurrqiv0I4tQB UjWIgWjfZ66J8eDHlWM/+ialjDm4HnFmTMQ0+HRMGZNDyZbbU9Pjl+SLWHTJCauRId6VDY2FaxIAn 55Cdm89jKJEjsZ20gSw3QhA2OM3vSHDwDZOQpgWXWnIH/Co4OK3U0LXm2NXoQ7py1lzYBJ69WLKrA vUW40FDrnIvmynVBJnO9KleCEliLS09Pd05ETF17cIvTkUJQvRDmws3qlWjWd5dJ882WI+MeEyfSn KT03vfGL88uTjuUpvTj+jCwcTXrkOhZUH8VWawBO+QLP2E1o7Xud4VJuFe70FNeEJxOEbrUDGppoU CpOvSLnjA76klDjod/OQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mb2fZ-003etk-U7; Thu, 14 Oct 2021 15:29:23 +0000 Received: from mail-ed1-x52a.google.com ([2a00:1450:4864:20::52a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mb2e2-003e5L-CE for linux-arm-kernel@lists.infradead.org; Thu, 14 Oct 2021 15:27:48 +0000 Received: by mail-ed1-x52a.google.com with SMTP id a25so25842916edx.8 for ; Thu, 14 Oct 2021 08:27:45 -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=9uFRAg/cSZ1Ge1wEiYH5jWmFxwS6RH3twCyxI3UBC5c=; b=CegzzxFtb/uayp1+8cDO1U6QxOoeWj31k1k1Z7XOfoo/i5+bHkASQvbn9FvaS6p/uu zyF2bI8Dlz48Ki38g+v8EKeY3wBd7rRxKgwiYxQ4Kdz07k7zJikiY/sVfzPpM96SUP3V 3QBBqZsIfzDufuPB42h2s4XgIMYIla38OL/zrNs4WISrmGbRbXACPpVK24cDsuUAgZTI HyyjlP5dXGMF6a6JmkpWf7Dp6oXf+ckaBDrMhcOglx+Xmv8i3XeahsyJ11Y1teohpSlg oH+mVbvQ+KxcbOFy/khczxq+/xllWkTBcS1Vin7m9JDit2i4TuXJ9m3RQNBHXLkNBCcD geMQ== 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=9uFRAg/cSZ1Ge1wEiYH5jWmFxwS6RH3twCyxI3UBC5c=; b=j4N+Nn5RRyL+d6fCTFY/JDngLlhEEuE7Ai261RISQOQZoNkTfmoft0C7GYBUkv+2O6 sGxpyrGyHcjn4q92rUX9UxgMleWb7F1pDuJ1E3ZUBIRk21zXU5FPEsmxlQZj9KTMGTfn Vzx6hKfENhy/lrY1dzFSrgQfX6czMvVwIkUJpW99JiCLl9di0GCCZqoHzmu6S+GTpcWW 3q65gi9lHHfbr/0JLx/lbBQqpQ6Pc2d2ybSOeIxMtjAAq9YpZQdeba/teNcl3HWBwiKd CeI+cPDG+mDanB0o5Pk1FaRqxpONmolURIQ78xgu+NPzctBpIeRAuPTBb54mxl6oelSD UJ4Q== X-Gm-Message-State: AOAM532W+VjuWVFXnWhk0nsygaGiv/ZPWUvq+xDSIZDkHLLSxlhlKQz/ DQfyN1ZsjOcBDYsDAIdsZ+dbQKRI4cgvzQ== X-Google-Smtp-Source: ABdhPJzpwhH69ZbKantF9xkYUjaz9jOHz93hDwbCoysI7kqMKMlD1YIqvGMp0yv9zTTaW8r/t+xrqw== X-Received: by 2002:adf:9b97:: with SMTP id d23mr7342393wrc.135.1634225177180; Thu, 14 Oct 2021 08:26:17 -0700 (PDT) Received: from localhost.localdomain ([2001:861:44c0:66c0:209b:8400:2b80:b4ae]) by smtp.gmail.com with ESMTPSA id k22sm2626790wrd.59.2021.10.14.08.26.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 08:26:16 -0700 (PDT) From: Neil Armstrong To: daniel@ffwll.ch, Laurent.pinchart@ideasonboard.com 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 5/7] drm/meson: encoder_hdmi: switch to bridge DRM_BRIDGE_ATTACH_NO_CONNECTOR Date: Thu, 14 Oct 2021 17:26:04 +0200 Message-Id: <20211014152606.2289528-6-narmstrong@baylibre.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211014152606.2289528-1-narmstrong@baylibre.com> References: <20211014152606.2289528-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7744; h=from:subject; bh=6i6KMw5kTyiPYblQgBG12n2DEPIZia2mYTPpIOLuziA=; b=owEBbQKS/ZANAwAKAXfc29rIyEnRAcsmYgBhaEuA/2fFsyQw1JOef8WiTXD7UMaSzOoThtR9lJXC d6jt0DCJAjMEAAEKAB0WIQQ9U8YmyFYF/h30LIt33NvayMhJ0QUCYWhLgAAKCRB33NvayMhJ0Z6OD/ 9RP0uaVWA6EnqwnTt5JQMCDaCIBbX6KmvlbMTRxFt5vBaFuFaqSOQGLyxcWBu12Fgn0khi3fl6pfn6 EzZ3iID8xbgAnoSyNj/QMiwOcVVelzuK0xDxlQwH2crdVVgKCulq1lnBi8C2OQ4x7NN3i+e3LevgIk bOBIXUH14xVi0BEhIAy7PbvuQc6/KNN8nNjss+uEQcHH6UbPHtDIxpepVPRdD6rncFOxZ/aqKcEf9F hVYJL3YmBxoQM4rf1mKd0Qqvm+k6j/C/UlIIIlm5KetkfgDYRX7ZfP3VZnGWnQV3ZU2k/hZbKhiQKH DwrSlvYG1yG874xnwPbOZYfD9IJWNHnVNg6YeTeQjleKLBX+Mxg3OUUDM3oOEYuKWe9fK/I+UK/NZQ +TO43vYsrIHrRAi+aaiSvEDPKimW+iHOWowQAYAd+T16PVnzyOsC7Qy8bwYHfzmgc+2UuTEHm9YQ9E CJI0cVudV7KcNl2b7ji82l38K7fBbM9KB/2UGpKXFSeYvHX5jl3k+cBaiRsQwRZJzcbDxtpNYK5qoF sOuQkYZ95JORAPj7xmjqIIudXSF+m934EcvFi0B3AmU2gZQDU4QHwir+xiGc8h9oVeVMRfWKgYEA+S UYc0ZmTALl0aMM9B4JPpKNUT7Bjl6WzJOKAo4m9AdmeJAruU5V6B9laHY5bA== 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-20211014_082746_446474_87A0D445 X-CRM114-Status: GOOD ( 23.59 ) X-BeenThere: linux-arm-kernel@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-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=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 --- 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 c2480b3335ac..933ff63b1ecf 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -805,6 +805,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 c775a1ab5b1e..a4264587d89a 100644 --- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c @@ -14,9 +14,12 @@ #include #include +#include + #include #include #include +#include #include #include #include @@ -34,8 +37,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) \ @@ -50,6 +55,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_enable(struct drm_bridge *bridge) { struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); @@ -284,12 +297,33 @@ 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, .enable = meson_encoder_hdmi_enable, .disable = meson_encoder_hdmi_disable, .mode_valid = meson_encoder_hdmi_mode_valid, .mode_set = meson_encoder_hdmi_mode_set, + .hpd_notify = meson_encoder_hdmi_hpd_notify, .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, @@ -300,6 +334,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; @@ -326,6 +361,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); @@ -342,17 +378,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; + } + DRM_DEBUG_DRIVER("HDMI encoder initialized\n"); return 0; From patchwork Thu Oct 14 15:26:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 12558803 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 599CCC433F5 for ; Thu, 14 Oct 2021 15:29:54 +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 16A9F60EBB for ; Thu, 14 Oct 2021 15:29:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 16A9F60EBB 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=an0eNAaEnRilVcLfRFVK7sSjLKZ5YVZji7L3NK+oe5U=; b=AcyIDxP5tZ+Vhv Cr7UYaI01mP4e07KS3qxKSDRAHlgh9GAo+NDr+eslhTfz4cpDs9lkWPOt/pho9mtnEqP0QyXCpyXN Yke46FtAKZRA2MXG1zb2zrBbmyoxBX0P4l4Y2v8DIBSyt6j0W1rJ2AtWROdihCA2+tRYdtxXLRfbV RmuOBCmSgC9DdU/xfuwH4DiZVi48+ahXDj0ePY1iw5goFS9o+OCOchOgM2g/dRWmdG2wEDwBROXGB jjo7PZU80R5DS0FmonKNpiiKqx3F0/LBVYeZwgjlKB5gCZUFStL71qtJ8tJRASIYA576jgbbMRFt9 LoXq1ERHkL5TXtVAibQw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mb2eO-003eGe-91; Thu, 14 Oct 2021 15:28:09 +0000 Received: from mail-wr1-x434.google.com ([2a00:1450:4864:20::434]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mb2cg-003dOh-5B for linux-arm-kernel@lists.infradead.org; Thu, 14 Oct 2021 15:26:26 +0000 Received: by mail-wr1-x434.google.com with SMTP id e3so20494405wrc.11 for ; Thu, 14 Oct 2021 08:26:19 -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=HZnfkK09uhjWqw+DNrCRghBv6QinaoLIxZDB7Hb28mg=; b=g/NzPc/NwJzQRwO5rPKji2Pmc828XRZBZEsPwsoOqiu6MoG2kscJum00aWzjkVRsp/ Cs+R8hor6ve44wZpLrlW7ah6vBISlyJ1/WrUlSm99Sx5vj8j1i1wPS8xQp3R2G1aeeJ8 6N8C/pLnVuk1XzRvQ7qozezFv0xJSGq5QVlp5Qgl/vJrs3lWJHtqSd6O4R4Oi8NwwKEn VvGQXYZVsWR8P0duXOrP32M+OZ4xOUEDA3phU5fRIvGj9SIOa78wFAtOkUyf5mYcBuYe uMMKAP63GFXzk/Sznq8rb/m8rT1pBZAhi4vvhmj4GCEiyDmHwbOvUwudiPKmVhNV0VvS CyjA== 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=HZnfkK09uhjWqw+DNrCRghBv6QinaoLIxZDB7Hb28mg=; b=zRkiacaoDPrRlFAuQTk0UkBeBuVFW9ah2zMPQuYssYpuefexzgB35byx5gtMg3O9li MQw2LQBFbohdilmUtRJq2Xpke2hJRAr6RQOX38SyyQDDZTAg2cti9Cmx6TYf6a6BcbbN w39gQtUADIwlLHsxUeCYbnfbbQpBfFU9tKJzjCwbsP7NmMFCtJ5lnsi5okvjO7B80jUk QsT1CXHJnLWpfYKhdL3OA5WwOh2bB5osviopnHFcJb+6qGZPewzMXepeKXnEkHVghpbr qVlbBhPfOIqf0KJRBBZjhICko5dIPsu0V6rjZ9kIcvzFe5AU9fXfW+w1MYnK8A3hi3Vk 2bNw== X-Gm-Message-State: AOAM531xjq4a21NPjpJJNwhJxtaIS/wKapVMuMECCjWALHdm5nDkwG7F o43Lqtw5JEkuCKcL2bua/wDWog== X-Google-Smtp-Source: ABdhPJwZoNXIidqiqnHVpBnZZse41KQMw/qtXG047QyO3Dpq8ifkksnDqJ6h9ZZpO8qMpyBKKAn6Cg== X-Received: by 2002:a5d:4d0f:: with SMTP id z15mr7668686wrt.334.1634225178294; Thu, 14 Oct 2021 08:26:18 -0700 (PDT) Received: from localhost.localdomain ([2001:861:44c0:66c0:209b:8400:2b80:b4ae]) by smtp.gmail.com with ESMTPSA id k22sm2626790wrd.59.2021.10.14.08.26.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 08:26:17 -0700 (PDT) From: Neil Armstrong To: daniel@ffwll.ch, Laurent.pinchart@ideasonboard.com 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 6/7] drm/meson: rename venc_cvbs to encoder_cvbs Date: Thu, 14 Oct 2021 17:26:05 +0200 Message-Id: <20211014152606.2289528-7-narmstrong@baylibre.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211014152606.2289528-1-narmstrong@baylibre.com> References: <20211014152606.2289528-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=9494; h=from:subject; bh=FeZfVcXcgSpdb977WidjFbWDVjcPsPKUucXlcKGhFP8=; b=owEBbQKS/ZANAwAKAXfc29rIyEnRAcsmYgBhaEuAtMhFpVoXXFxFzbYa68362S5l7Ul/yhos8IZ/ JjuXh2+JAjMEAAEKAB0WIQQ9U8YmyFYF/h30LIt33NvayMhJ0QUCYWhLgAAKCRB33NvayMhJ0SczD/ 9kTN2vOPqWl7g7i+JwGJl4oXTY4K/yqepY7qk8pqPKfOY4IL3Ps5ECNZXD1fwCcVRahXmmrxAICu5s 60Fugj67QfV6t9tFiCBZapS22olvStUVEwkxnHlb13HB31sEl8TImq41fs1wqogERw+HTLvzJ5sgpX gJnu4xFHo9nbg5H9F80+WCLReX8EBSYf5YZr9yscrXVl93bEBA/F58O+XUGcAE0wRPQciyvHqq37Kw l3SrjQfMhtA1xp0RDysTB0V0YWsz2giO7V6yXh2rfUXAdTFF4GueHeVCKSGc3YpcF1Y8lL93b8jXsq LAV3CQdi36du9EkBEMDL4uiUY2d5+DsDy5V4AE5B0tINU6MgkijwA9ziHJfnw4UBbz0A0/Wy6Fta4i 9yA49epe+8XQSGiA5p4qxmL+MJkWHxphuS9pW6F8oP0L9IDepRIiVUHexf+1EXHLTx6VmjAqmJ2Ym4 Brxo7wdepC4g1dkYtBZi3VKBjPsmIAzd2zyh78BpmeCcLxU6Xo3Jshw4hjI6QHUPW+gAtDOzqzN7TD GQiS+RdxT/H2ZaA/GJivo8RyO0jw0L5A3nWTtuF2u7MHOMmkemZD52vnKCPzarnLRxInZwXcCtZE6R YkHN6YcH4m0+eyk3x9XBNDK821pW+uk1dQJiylq6OwGoGi0XnFdews/PmLmQ== 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-20211014_082622_226396_BE0F149C X-CRM114-Status: GOOD ( 20.43 ) X-BeenThere: linux-arm-kernel@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-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=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 --- 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 0a28a8e29d63..d07d302ce4a6 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" @@ -308,7 +308,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 Thu Oct 14 15:26:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 12558805 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 4B0A4C433F5 for ; Thu, 14 Oct 2021 15:30:12 +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 164C760F9E for ; Thu, 14 Oct 2021 15:30:12 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 164C760F9E 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=PAJUUq9HEWevqb8mzf2tce0Hb+DiOEnaTOIbareMpOU=; b=ZZ6+pOLkUzkzIe LTPxyTCXNp1mEtFeuG3hEwX49s2A2YK5o/DkrWrUZIerMkT1RNWgiQp7MKApjoAwKOliLDIaZpj2I ALZ/XL81PHkXv4ggkJX0AyYae0zEgPFOk3Lpfq2rRWpeURdRU2GvlA7LzakzbL/Q/mgFLy0cqu8+j KXkqcNMsCxFnj8+D+dyvc9H//W+lLlTQZ5hQe+PgHxePoVZwaF45K3WkRA5JVfPyspHxqK5x9Mwtk wYLyNxIpz65i8Icl/cjexvJ1VvyKk9mtp5K0u4m+hRiAVsGJ51qyos8bQMIM5yODLUbzpPbgqLgEM eGul4K1O3dUgF3WeDGVw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mb2eq-003eWz-Ch; Thu, 14 Oct 2021 15:28:36 +0000 Received: from mail-wr1-x434.google.com ([2a00:1450:4864:20::434]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mb2cg-003dPV-5P for linux-arm-kernel@lists.infradead.org; Thu, 14 Oct 2021 15:26:28 +0000 Received: by mail-wr1-x434.google.com with SMTP id e12so20716231wra.4 for ; Thu, 14 Oct 2021 08:26:20 -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=c94TXJUU9Tn5Br00ptQarYNibinITrqp1MJiXWZUIJU=; b=14XacjbBkZaME+xCLEdSax/U5zpDQeLqh7gNIqTN2ZuKCqmkTEIn2sQNF1t60Umsyw rykCOWAqvIFez9pLl82PTsWjkcwugIxDh9aLGjZBuMTtXd1OGVv0I+b6DVM4IEHBCzu7 yk7UmfzBHMN0QABAu5/nElNLZ6QfrGQekwQwJZEZUaK/Kmc4vQmF9V5BVdQYa8UqLonB mkLO4YJwr4Pv+79HMlCJAILB/vK5vrnyyheSdSQ78OY+iTRpaT+nG5MvD/jwAWUfxLv9 DIUqI35bp42tD+bvsiShYTsNnJUxN7wtMdEQzwvR+HbVWWL4CpEd7KwfCzAzIVPaXKac AR5A== 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=c94TXJUU9Tn5Br00ptQarYNibinITrqp1MJiXWZUIJU=; b=VDCy4HiMzuFiS+M/JNSz+ntXCilRsRnDrqEFPmhKxAaED8pPCVVqRpglyzPdAoXoXZ nMLJ5VagAERNm0ooPo+y9mBsMGdlgbZi7/NDezTWmnARd5qHb29VNBBbVpFbsh23me08 QClsywAH5fuknCfGeXxx1ztnMU6lNIA01IoRyodsJ1l0jXJjkbfXg82Dzz3aXm69fAii rcZ6h9mfBU04vdUVuzDEFY0fEYHAkTpBVXF8lxiaIk9JddTAOcQTfDHFB0pu5JCLToNw P0m1Eire/3YzpGty+Gbr7jVvIrQgTMcd4+BcG2K9uD2VTjMoDbMC3qU26pnIhssKuTYs s3xQ== X-Gm-Message-State: AOAM531PQ1rbrgw6a/d0nbIGpj/NPw76UfpEj30zApA89kqPFgrb8KCE qV2GENH1UTRGOywCW+s5uClqLA== X-Google-Smtp-Source: ABdhPJwbAIl/G9Vvg9EDmTf5st6qJ9/7+rVtHD/s1W7j3fv7YlrZ00juRyfjffGoLWyBWQgqMmMm2w== X-Received: by 2002:a1c:29c2:: with SMTP id p185mr20071328wmp.43.1634225179181; Thu, 14 Oct 2021 08:26:19 -0700 (PDT) Received: from localhost.localdomain ([2001:861:44c0:66c0:209b:8400:2b80:b4ae]) by smtp.gmail.com with ESMTPSA id k22sm2626790wrd.59.2021.10.14.08.26.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 08:26:18 -0700 (PDT) From: Neil Armstrong To: daniel@ffwll.ch, Laurent.pinchart@ideasonboard.com 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 7/7] drm/meson: encoder_cvbs: switch to bridge with ATTACH_NO_CONNECTOR Date: Thu, 14 Oct 2021 17:26:06 +0200 Message-Id: <20211014152606.2289528-8-narmstrong@baylibre.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211014152606.2289528-1-narmstrong@baylibre.com> References: <20211014152606.2289528-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=10509; h=from:subject; bh=KCHKpDSUauSGGy0CAW8huADDJq10sL56KJUwfhOuo9Y=; b=owEBbQKS/ZANAwAKAXfc29rIyEnRAcsmYgBhaEuAQdh5GZ47uzc7qfa90gniMaahg1dOSAn7TAko oxIO+GqJAjMEAAEKAB0WIQQ9U8YmyFYF/h30LIt33NvayMhJ0QUCYWhLgAAKCRB33NvayMhJ0aCSEA CfmobsOMHngkWrpqm5G+/r7LPzvZ63Y7ggiz2e6mVd400koeRaBSqtGba+Q8p9pjzcFv/JL1lWicWW nYQdrOpt1mKXX/4LZ3lZ6Te45h50ZuD8l2SUBolPtnI5dnMy8UHOhpj7I6oZDT8HFTS5zoOnwFkV/P CJHZjtLjYo8moQAx9QVg5Co98ULO+/n9OJ6nS9V7/QPlthnJ3kDrtXqrmeHjm76x3kZ0BbxH7TpHAo X76ZKeAuvXhxzM8wDQuSE4xZHB01YZ4bM+g/k1YwvUrV6fU7iDZ1IOpkMWHrQdXIIbIsotPLH0DdOP Mk2DNPiEbSQMVhZt0ak3bkY/rQ5yoxyP8DW3GUHE62xNzV/N2FxVvLvga32YcSVIHnjcR/DzTULCtu Zr0tI3JUMkWZ3WDkjFZxskuYz4oLsLWuclqpgEdMEoY6F6Ulamcn0zNUgTjiuZfOvV55VJqhbdgfTH HLA4y+H6uWFOkUQXzFTkLL/zontlIO6E9fVnmROvPNhEAnzMWujFuVStwW8H1cOG8eGIZkm8FYO83c CtVf6XSBv4geJMZ3Ku7Xlp7u0HCpD1ln3R5iNNf6XwPgksgqDvZA7wPfwx1SBBIxGeCJyU9M1dNgCq BhHX5toXUty3H45GTaOcTQWtCAFJ5/dEOFjZYfgaNxjdp1gFWjx+kJCINcwg== 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-20211014_082622_264955_9341EF73 X-CRM114-Status: GOOD ( 18.39 ) X-BeenThere: linux-arm-kernel@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-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=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 --- drivers/gpu/drm/meson/meson_encoder_cvbs.c | 178 +++++++++------------ 1 file changed, 79 insertions(+), 99 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c index 01024c5f610c..0b974667cf55 100644 --- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c +++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c @@ -13,6 +13,9 @@ #include #include +#include +#include +#include #include #include #include @@ -30,14 +33,14 @@ struct meson_encoder_cvbs { struct drm_encoder encoder; - struct drm_connector connector; + struct drm_bridge bridge; + struct drm_bridge *next_bridge; + struct drm_connector *connector; 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,21 +84,18 @@ 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 drm_display_mode *mode; @@ -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, -}; - -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, -}; + if (meson_cvbs_get_mode(mode)) + return MODE_OK; -/* 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,10 +137,10 @@ 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_disable(struct drm_bridge *bridge) { 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; /* Disable CVBS VDAC */ @@ -175,10 +153,10 @@ static void meson_encoder_cvbs_encoder_disable(struct drm_encoder *encoder) } } -static void meson_encoder_cvbs_encoder_enable(struct drm_encoder *encoder) +static void meson_encoder_cvbs_enable(struct drm_bridge *bridge) { 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; /* VDAC0 source is not from ATV */ @@ -198,13 +176,13 @@ 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_mode_set(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + const struct drm_display_mode *adjusted_mode) { 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) { @@ -218,76 +196,78 @@ static void meson_encoder_cvbs_encoder_mode_set(struct drm_encoder *encoder, } } -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, + .enable = meson_encoder_cvbs_enable, + .disable = meson_encoder_cvbs_disable, + .mode_valid = meson_encoder_cvbs_mode_valid, + .mode_set = meson_encoder_cvbs_mode_set, + .get_modes = meson_encoder_cvbs_get_modes, + .atomic_check = meson_encoder_cvbs_atomic_check, }; -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; + meson_encoder_cvbs->encoder.possible_crtcs = BIT(0); - /* Encoder */ - - drm_encoder_helper_add(encoder, &meson_encoder_cvbs_encoder_helper_funcs); - - 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 */ + meson_encoder_cvbs->connector = drm_bridge_connector_init(priv->drm, + &meson_encoder_cvbs->encoder); + if (IS_ERR(meson_encoder_cvbs->connector)) { + dev_err(priv->dev, "Unable to create CVBS bridge connector\n"); + return PTR_ERR(meson_encoder_cvbs->connector); + } + drm_connector_attach_encoder(meson_encoder_cvbs->connector, + &meson_encoder_cvbs->encoder); return 0; }