From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1F0E7ECAAA1 for ; Mon, 19 Sep 2022 16:59:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230225AbiISQ7v (ORCPT ); Mon, 19 Sep 2022 12:59:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43038 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229709AbiISQ7r (ORCPT ); Mon, 19 Sep 2022 12:59:47 -0400 Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7CDE31263C for ; Mon, 19 Sep 2022 09:59:46 -0700 (PDT) Received: by mail-ed1-x534.google.com with SMTP id y8so98023edc.10 for ; Mon, 19 Sep 2022 09:59:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=VIAi0nNwF0EQ4Ycv099voA35UIwgAD/zCbxE9L3eFBQ=; b=R+qQPnPqizqQy0t3jkiLKwfr4K4/dgarwPfFttzlNb43E4o78izHqlKaHUTtF5L0aX U2rW7VDjsEC3GyuX7FFwe1iKr1B4FC7xjZcFh06+y0ryXl2F/GrkLLm1obnIhZPXlqL7 hPJoE+3Rb00pJAWDNwRcizomgd5BsFP4RIF3WmuztmNQRO3lPH435EjKkezKb6JjjiFm +D7J3psGA0bhm1mdY2z/1oZ4WG2QYmi+YfIloXmbs1HtYN7LY1dMPOfFPG5+1SH3EjLd 6WQPNGdX5ebzgk8mDgJXkf0TTio5UuUFR8R/cQCrHXJKjw3iFhqEji1Adg9w2agMIAih tkmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=VIAi0nNwF0EQ4Ycv099voA35UIwgAD/zCbxE9L3eFBQ=; b=Iua4qnpAP+F8bMjyrCjQJjQ6u3QjPy+aqnZKiadlMEyDqVIWSEWfi0Vpj0JtpFzQV2 iWchHUUjguLXilE/e/QI7rBd84ivUhPwH8MoXi2OLzcWTiMFDihC42WowEOCeBxiKZc/ oAVQAeBEWh/6yHin+qGBbs1HfSHH5XVDpzQOaomsITAvpicBij5xC7Z+gDRbA8z1R+9l PkirYNfRlHR1K0E7TBDq9De1tkI66Z7oksITGmoDcQv7Pq4PJQY91WH134lUf6w0++0T F2Z2D/iIBvG9PVWhBIQ1M1h4ch5TCPtid8GeKs1FioH5rnfl9tEV8JbTQzH4hEiY8hQH AYAA== X-Gm-Message-State: ACrzQf1+2iV1w1imufvzfpS0aTYMk3g+xkIaeLn1tc1Cb8sEs1V8zElc I16/UpNPYvR83Hor7AwqTW+plA== X-Google-Smtp-Source: AMsMyM4FWcGqIb04fz++aRLharY4kKuVTi0otIV+l0WpEp9ORTAl2Z/yp1vEqg/lPBMW1Gcd0sxy3w== X-Received: by 2002:aa7:c585:0:b0:453:e1c6:7dc6 with SMTP id g5-20020aa7c585000000b00453e1c67dc6mr6810316edq.245.1663606785020; Mon, 19 Sep 2022 09:59:45 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.09.59.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 09:59:44 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:55:59 +0200 Subject: [PATCH v1 01/17] dt-bindings: clk: mediatek: Add MT8195 DPI clocks MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-1-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Pablo Sun Expand dt-bindings slot for VDOSYS1 of MT8195. This clock is required by the DPI1 hardware and is a downstream of the HDMI pixel clock. Signed-off-by: Pablo Sun Signed-off-by: Guillaume Ranquet Reviewed-by: Mattijs Korpershoek diff --git a/include/dt-bindings/clock/mt8195-clk.h b/include/dt-bindings/c= lock/mt8195-clk.h index 95cf812a0b37..d70d017ad69c 100644 Acked-by: Krzysztof Kozlowski --- a/include/dt-bindings/clock/mt8195-clk.h +++ b/include/dt-bindings/clock/mt8195-clk.h @@ -859,6 +859,8 @@ #define CLK_VDO1_DPINTF 47 #define CLK_VDO1_DISP_MONITOR_DPINTF 48 #define CLK_VDO1_26M_SLOW 49 -#define CLK_VDO1_NR_CLK 50 +#define CLK_VDO1_DPI1_HDMI 50 +#define CLK_VDO1_NR_CLK 51 + =20 #endif /* _DT_BINDINGS_CLK_MT8195_H */ --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 280E1ECAAA1 for ; Mon, 19 Sep 2022 16:59:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230256AbiISQ7z (ORCPT ); Mon, 19 Sep 2022 12:59:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43094 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230174AbiISQ7s (ORCPT ); Mon, 19 Sep 2022 12:59:48 -0400 Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C135911459 for ; Mon, 19 Sep 2022 09:59:47 -0700 (PDT) Received: by mail-ed1-x534.google.com with SMTP id 29so159809edv.2 for ; Mon, 19 Sep 2022 09:59:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=pe51xvlTzoxvP1PkLEmQi5YJGHaBQkqHjYX/h+KRrX4=; b=B+X1p1fH4JpGs34rfSwYzzSHzwu5qnL83GcremhYxa34LPTfzyuT54Qx4NkUrP80pu pQuuF2QUVoy7vzZV3h6TrERow//gfDL5XfrnuPPuhc+B4RHI2qc+3ex/jWKQ63RA0DfF hBB0zWcx0Lk6XvWHsF7Jch4RHJgIiSY2LK6gxuWKN/rgLWdkiQ6mLPjpWh4cz4AHHPtT pC4zGQhthMR+WPSyxbXBMc3qQw3YfboFI7Q7Yy9Bgo6ddHWkCSfutvSn4/NE2FUgXx1e NM29wYa2a+PX3vs2XgVJk1y+K5rnO2tGCxRjBGuogh3F3cFoZXeNpiG1Tcq1hcgaNJxd w1+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=pe51xvlTzoxvP1PkLEmQi5YJGHaBQkqHjYX/h+KRrX4=; b=aa6k5pZFs+BtgwlSeOOd7gK1UAF7gE3VSr77CnwSf29hF+FcoZZv1t98xjjZQb/L31 06BVGvHZfK2cawIitylErKuTXkOE5AzUS7e4qr/e+8BDCVyyKoaRQSMNZbpr9u/adp/I pj6xVeeWvwkx3wIhONJsObTk0FhNnQVoQlOrlSvyW9YtaXXLtfaBiZ9Hb02vpEaSiGIl ncSgGwe7CY5Gts1HP5bQ3v0KcVoEgQGpgVslok4z4r7AeV23Rc8J2zS14YupvtbEsmlK OVFE1fxD4aYiHURBQgziWOQHJeKK2MXnkYlVwiYQh6qhgBRjIMFtyTMItdCmLWTgQnXw AE8A== X-Gm-Message-State: ACrzQf2mdVOk0U4HupQzGca4UU4t6zJbdLG2JapMND8L7u0e5h50pBTv +hE7g/cx596idVfVSw9wSbgT/w== X-Google-Smtp-Source: AMsMyM4Kcqj7iaeTFSgnPboPDJcmYDvSGBzBAfopbwGlsGHAlwhMCX86GfBtADSsZGEx5aSm5j7eEQ== X-Received: by 2002:a05:6402:2b8b:b0:43a:5475:f1ae with SMTP id fj11-20020a0564022b8b00b0043a5475f1aemr16246555edb.363.1663606787204; Mon, 19 Sep 2022 09:59:47 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.09.59.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 09:59:46 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:00 +0200 Subject: [PATCH v1 02/17] clk: mediatek: add VDOSYS1 clock MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-2-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Pablo Sun Add the clock gate definition for the DPI1 hardware in VDOSYS1. The parent clock "hdmi_txpll" is already defined in `mt8195.dtsi`. Signed-off-by: Pablo Sun Signed-off-by: Guillaume Ranquet diff --git a/drivers/clk/mediatek/clk-mt8195-vdo1.c b/drivers/clk/mediatek/= clk-mt8195-vdo1.c index d54d7726d186..835335b9d87b 100644 Reviewed-by: Chen-Yu Tsai --- a/drivers/clk/mediatek/clk-mt8195-vdo1.c +++ b/drivers/clk/mediatek/clk-mt8195-vdo1.c @@ -34,6 +34,12 @@ static const struct mtk_gate_regs vdo1_3_cg_regs =3D { .sta_ofs =3D 0x140, }; =20 +static const struct mtk_gate_regs vdo1_4_cg_regs =3D { + .set_ofs =3D 0x400, + .clr_ofs =3D 0x400, + .sta_ofs =3D 0x400, +}; + #define GATE_VDO1_0(_id, _name, _parent, _shift) \ GATE_MTK(_id, _name, _parent, &vdo1_0_cg_regs, _shift, &mtk_clk_gate_ops_= setclr) =20 @@ -50,6 +56,9 @@ static const struct mtk_gate_regs vdo1_3_cg_regs =3D { #define GATE_VDO1_3(_id, _name, _parent, _shift) \ GATE_MTK(_id, _name, _parent, &vdo1_3_cg_regs, _shift, &mtk_clk_gate_ops_= setclr) =20 +#define GATE_VDO1_4(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &vdo1_4_cg_regs, _shift, &mtk_clk_gate_ops_= no_setclr_inv) + static const struct mtk_gate vdo1_clks[] =3D { /* VDO1_0 */ GATE_VDO1_0(CLK_VDO1_SMI_LARB2, "vdo1_smi_larb2", "top_vpp", 0), @@ -107,6 +116,8 @@ static const struct mtk_gate vdo1_clks[] =3D { GATE_VDO1_2(CLK_VDO1_DISP_MONITOR_DPINTF, "vdo1_disp_monitor_dpintf", "to= p_vpp", 17), /* VDO1_3 */ GATE_VDO1_3(CLK_VDO1_26M_SLOW, "vdo1_26m_slow", "clk26m", 8), + /* VDO1_4 */ + GATE_VDO1_4(CLK_VDO1_DPI1_HDMI, "vdo1_dpi1_hdmi", "hdmi_txpll", 0), }; =20 static int clk_mt8195_vdo1_probe(struct platform_device *pdev) --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A095AECAAA1 for ; Mon, 19 Sep 2022 17:00:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230280AbiISQ77 (ORCPT ); Mon, 19 Sep 2022 12:59:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43210 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230206AbiISQ7u (ORCPT ); Mon, 19 Sep 2022 12:59:50 -0400 Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [IPv6:2a00:1450:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA9A613CC9 for ; Mon, 19 Sep 2022 09:59:49 -0700 (PDT) Received: by mail-ed1-x52d.google.com with SMTP id z97so112889ede.8 for ; Mon, 19 Sep 2022 09:59:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=7xDk5BrXibXgfT99ckwNvMekh76xOPeNv/4FsaCfh58=; b=CEZJ9TEVferg0ulxXwdUEbWib2zYhw9Tir5LaamEXUe9UQabtpHUZ7t39RbS4S85HC x9PFzpX7wALrVEGjd5qyae6tIH2bK+BZxA3AsOGG5SLe8GtLeXrWR5PdxeYfhkGL8zz6 4aQbHNr7a6hYGMtek5NqaK1fsiK/TphfUjeSfIXBdpM51CKKKEWyLmeQpmyv0FJfOOKB 18XYmYWBK0IEwGn7H7CTG9n/4b/wl9y9Ex4FAUHaHxrhTxfMVImS7y1QRGtXw5/va7SX FYVEq7OHlcwL2JOG2/A0K17XMaMH2dmNtlQw3PM5ptekzTUaKbzqovvSlmYzThYg57/r AsXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=7xDk5BrXibXgfT99ckwNvMekh76xOPeNv/4FsaCfh58=; b=isNZ1dG3Y39voysnni2dF3h91lY9sSviO9uYgR8Ln4GG+FpRzYvwdksWFTxT2KKAlS pid+MbkIXynZg3XFVlgDnoWhPJWKjvVOgM5Y5o2m2h4rdbeVRyUBKqpCVIcuIPQB5Mdm LIgPHCsbhjXFmgwb/gMOAt2YmJXiKrmzux+drhaCaScWi+evq8cOmxfPTuwHBEVV0E0M uRnLHO/dqeloWtU7yWo+XdD0FRx0nBZdMyi68ayQ1IIXkKG+96KYRfe0FbL1KwKFghsc 6fhflVSdrNeNKStZMhdb/kxEg8h70GFoIusWRcGRaimsf+X8TYQq94/iNheQLfvvf6Li hSAA== X-Gm-Message-State: ACrzQf3GJ5fysyLT9gTOhtkDAcky3NeZhx5N6pDyPMGuWeLZuDpX5Ou5 yyUueK1u+5R669epMG+iTYuFJQ== X-Google-Smtp-Source: AMsMyM5gxGj7vc60+sBilG3OlczkPRO2uGjBc+la49BQKMmf9aIyceQBVlL/fz7uc0yOaSZjotbdPQ== X-Received: by 2002:a05:6402:493:b0:445:b5f0:7a0f with SMTP id k19-20020a056402049300b00445b5f07a0fmr16348159edv.120.1663606789339; Mon, 19 Sep 2022 09:59:49 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.09.59.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 09:59:49 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:01 +0200 Subject: [PATCH v1 03/17] dt-bindings: phy: mediatek: hdmi-phy: Add mt8195 compatible MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-3-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add a compatible for the HDMI PHY on MT8195 Signed-off-by: Guillaume Ranquet diff --git a/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml b= /Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml index 0d94950b84ca..71c75a11e189 100644 Acked-by: Krzysztof Kozlowski --- a/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml +++ b/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml @@ -28,6 +28,7 @@ properties: - const: mediatek,mt2701-hdmi-phy - const: mediatek,mt2701-hdmi-phy - const: mediatek,mt8173-hdmi-phy + - const: mediatek,mt8195-hdmi-phy =20 reg: maxItems: 1 --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 88024ECAAA1 for ; Mon, 19 Sep 2022 17:00:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230371AbiISRAM (ORCPT ); Mon, 19 Sep 2022 13:00:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44058 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230292AbiISRAC (ORCPT ); Mon, 19 Sep 2022 13:00:02 -0400 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BFB241D0C7 for ; Mon, 19 Sep 2022 09:59:52 -0700 (PDT) Received: by mail-ej1-x631.google.com with SMTP id y3so180865ejc.1 for ; Mon, 19 Sep 2022 09:59:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=69nrv/BKayymEj9f70cbXjRoS8M413ZGsp2FP8B+6Cc=; b=2ZDgXmtX7kBtwoUAyxz8rI/gnLo1usAqRIcFp//WkgUEpHJhCUTPn56LV4nSD4vc96 4ADNXslH3B5Shd0LcD3JYJ/7M2ZPxpmYvmlBYDwnciQmIb+dd8rT5emdFWvOx80yejKt MMM8QfLsaPoNoAkDCdmmVoQB2LnGEf+DCqPv8SpIhTDkZiFUJpu0OAbbaTMsM6wKYWVG lg3lGETEKJf+8OgeAlqZ+L88vbRecsFHARHMiEUM2ZXJKQC9sUEXHYWN4IGWITGu4Cvj f6wMQhd6qOjwNEIuq/p2LxdNHcLGhBDZkGkNOuxddNG8AASoFiH/teUXDgyW9sEztL18 s+mQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=69nrv/BKayymEj9f70cbXjRoS8M413ZGsp2FP8B+6Cc=; b=UtbDF3DAiL9aiNXCL2y3lV4aH43yEdNV8OM3o3hzKew38AoGb0aYD8AvNI3epRMYpH qfLpX0umfpSG+Qgjp9eXzqIKotJ1KfUPb/D51a7MP2IKUpFfB2GwV2LRJ7iYG/NmMcit Zj6lOOrhC8aJyiae5t8mPo5WzgaCkQRE4gPAPExvaJ66Ou+lMe11qW+ylbw8CbUsfZmX 3UsZfmSAZBiBMu1qqjs5iheR0o0yXkItLdiYOjetmMcB2qd/FpcKjdaOgBy2n/Dtw0+4 s91EevTGxkP3QkwQvomSHie2nct1xMqezl4d9k/eq1aXumEzMBYwLVa7wiEcntRwWsim fmUw== X-Gm-Message-State: ACrzQf3lFoSoi619cAfofmM3PNBb/kkg+UjGKl0C9USSLvmiL/8UlyPD 8BUPDTw/4NZpkN0EbtsxNtlY2A== X-Google-Smtp-Source: AMsMyM6XlPFlhgC04B9QuW2zwPNOCYiGRhmcbXp9t18fVx3nugtxHUNV8fsXdbf/C+/TYrDgfmHhoA== X-Received: by 2002:a17:907:7b9a:b0:778:adc1:1b0b with SMTP id ne26-20020a1709077b9a00b00778adc11b0bmr13092811ejc.569.1663606791165; Mon, 19 Sep 2022 09:59:51 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.09.59.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 09:59:50 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:02 +0200 Subject: [PATCH v1 04/17] dt-bindings: display: mediatek: add MT8195 hdmi bindings MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-4-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add mt8195 SoC bindings for hdmi and hdmi-ddc Make port1 optional for mt8195 as it only supports HDMI tx for now. Requires a ddc-i2c-bus phandle. Requires a power-domains phandle. Signed-off-by: Guillaume Ranquet diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,hd= mi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.= yaml index bdaf0b51e68c..abb231a0694b 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.yaml @@ -21,6 +21,10 @@ properties: - mediatek,mt7623-hdmi - mediatek,mt8167-hdmi - mediatek,mt8173-hdmi + - mediatek,mt8195-hdmi + + clocks: true + clock-names: true =20 reg: maxItems: 1 @@ -28,20 +32,6 @@ properties: interrupts: maxItems: 1 =20 - clocks: - items: - - description: Pixel Clock - - description: HDMI PLL - - description: Bit Clock - - description: S/PDIF Clock - - clock-names: - items: - - const: pixel - - const: pll - - const: bclk - - const: spdif - phys: maxItems: 1 =20 @@ -58,6 +48,16 @@ properties: description: | phandle link and register offset to the system configuration registe= rs. =20 + ddc-i2c-bus: + $ref: '/schemas/types.yaml#/definitions/phandle' + description: Phandle to the ddc-i2c device + + power-domains: + description: + A phandle and PM domain specifier as defined by bindings + of the power controller specified by phandle. See + Documentation/devicetree/bindings/power/power-domain.yaml for detail= s. + ports: $ref: /schemas/graph.yaml#/properties/ports =20 @@ -76,7 +76,6 @@ properties: =20 required: - port@0 - - port@1 =20 required: - compatible @@ -86,9 +85,55 @@ required: - clock-names - phys - phy-names - - mediatek,syscon-hdmi - ports =20 +allOf: + - if: + properties: + compatible: + contains: + const: mediatek,mt8195-hdmi + then: + properties: + clocks: + items: + - description: APB + - description: HDCP + - description: HDCP 24M + - description: Split HDMI + clock-names: + items: + - const: hdmi_apb_sel + - const: hdcp_sel + - const: hdcp24_sel + - const: split_hdmi + + required: + - power-domains + - ddc-i2c-bus + else: + properties: + clocks: + items: + - description: Pixel Clock + - description: HDMI PLL + - description: Bit Clock + - description: S/PDIF Clock + + clock-names: + items: + - const: pixel + - const: pll + - const: bclk + - const: spdif + + ports: + required: + - port@1 + + required: + - mediatek,syscon-hdmi + additionalProperties: false =20 examples: diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mt= 8195-hdmi-ddc.yaml b/Documentation/devicetree/bindings/display/mediatek/med= iatek,mt8195-hdmi-ddc.yaml new file mode 100644 index 000000000000..3c80bcebe6d3 --- /dev/null +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hd= mi-ddc.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi-d= dc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek HDMI DDC Device Tree Bindings for mt8195 + +maintainers: + - CK Hu + - Jitao shi + +description: | + The HDMI DDC i2c controller is used to interface with the HDMI DDC pins. + +properties: + compatible: + enum: + - mediatek,mt8195-hdmi-ddc + + clocks: + maxItems: 1 + + clock-names: + items: + - const: ddc-i2c + +required: + - compatible + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + #include + hdmiddc0: ddc_i2c { + compatible =3D "mediatek,mt8195-hdmi-ddc"; + clocks =3D <&clk26m>; + clock-names =3D "ddc-i2c"; + }; + +... --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF589ECAAA1 for ; Mon, 19 Sep 2022 17:00:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230342AbiISRAR (ORCPT ); Mon, 19 Sep 2022 13:00:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44058 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230313AbiISRAI (ORCPT ); Mon, 19 Sep 2022 13:00:08 -0400 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A315432DB9 for ; Mon, 19 Sep 2022 09:59:54 -0700 (PDT) Received: by mail-ej1-x635.google.com with SMTP id a26so142812ejc.4 for ; Mon, 19 Sep 2022 09:59:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=luoO1LxKDmftX99eiF83qZnJXT6xOXQyVnCCkkwkdZ0=; b=vgqXPnwJfBaDfi4hVLCviUh3Gx+X6JzI45XAKLuOUe2h2jHSiPiCAyLXcxsC8P5RX8 mta4oVeCIoH7ljc8WQ1ufUbqSXG+JeHfF2n9XlW25tLQG4BNAEXLcv/BfM/5Qqh31CDw dR5uoEZ+9CPX1nLrigQUnUFhp01iu2MqLIRhZV16zhGCpSUSc08x0yl1LIhZI0j6ubo/ HNz7tWo0DAhRyZ/1LM/TVbEnEjGa33dBNjwTlf0gOpW2f6h9k30WlZMJIu93SnWPW4JS 69GS6lI/fA7OAzCXcd8Bgc13gq5urO9ok5789REso4IcaVC2cs4G6s6RHxENYewjNzam 9RBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=luoO1LxKDmftX99eiF83qZnJXT6xOXQyVnCCkkwkdZ0=; b=OmK4vdWc/lwAdn8GRrlQeje09Ek4eKUBy0gkbw3OAVp2Hard/e79bBych3Qg9vrqCh wRMzoN2oQ/elm5iXo/oiXgBR1gIsI5Zm3FmZjL/uzxCj3CpdZhue0C2yF2iQ+itZQ+OX GdvC4BhsNTZjRaStqwpFl7SJ4WdJNPGxA+e0+377C3j97gId7efm5FXdOfER7F98TWV6 mbfQXVzWULU9uQMdHPYT1i1egl7M+iOs5kwrTWogOV4qPXQLtcFYL5FXLcnI1nZOcvHq YsZqWGKD8QiSaTURBzj0sPcQAjn8GVEWLde4pj3iBnk7KbN9XTGMLGlVqmamLfTRz3RD Z6vQ== X-Gm-Message-State: ACrzQf2Mfa5mGkGMIS9bmt/Hgo+mdpkIaoWxyNmIxRTRm+AlgrfSbDhs QjybHrlk3028jytyiwrHyCOPxQ== X-Google-Smtp-Source: AMsMyM5rnDUnukBVd+yEqOxJIHItyo96vhlvjjoScLMZLrhi/dI2zDekSyBitbbTOdXRgSb4OzTwlg== X-Received: by 2002:a17:906:da86:b0:740:7120:c6e6 with SMTP id xh6-20020a170906da8600b007407120c6e6mr13618036ejb.44.1663606793008; Mon, 19 Sep 2022 09:59:53 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.09.59.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 09:59:52 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:03 +0200 Subject: [PATCH v1 05/17] drm/mediatek: hdmi: use a syscon/regmap instead of iomem MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-5-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org To prepare support for newer chips that need to share their address range with a dedicated ddc driver, move to a syscon. Signed-off-by: Guillaume Ranquet diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek= /mtk_hdmi.c index 3196189429bc..5cd05d4fe1a9 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -172,7 +172,7 @@ struct mtk_hdmi { u32 ibias_up; struct regmap *sys_regmap; unsigned int sys_offset; - void __iomem *regs; + struct regmap *regs; enum hdmi_colorspace csp; struct hdmi_audio_param aud_param; bool audio_enable; @@ -188,44 +188,29 @@ static inline struct mtk_hdmi *hdmi_ctx_from_bridge(s= truct drm_bridge *b) return container_of(b, struct mtk_hdmi, bridge); } =20 -static u32 mtk_hdmi_read(struct mtk_hdmi *hdmi, u32 offset) +static int mtk_hdmi_read(struct mtk_hdmi *hdmi, u32 offset, u32 *val) { - return readl(hdmi->regs + offset); + return regmap_read(hdmi->regs, offset, val); } =20 static void mtk_hdmi_write(struct mtk_hdmi *hdmi, u32 offset, u32 val) { - writel(val, hdmi->regs + offset); + regmap_write(hdmi->regs, offset, val); } =20 static void mtk_hdmi_clear_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bit= s) { - void __iomem *reg =3D hdmi->regs + offset; - u32 tmp; - - tmp =3D readl(reg); - tmp &=3D ~bits; - writel(tmp, reg); + regmap_clear_bits(hdmi->regs, offset, bits); } =20 static void mtk_hdmi_set_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits) { - void __iomem *reg =3D hdmi->regs + offset; - u32 tmp; - - tmp =3D readl(reg); - tmp |=3D bits; - writel(tmp, reg); + regmap_set_bits(hdmi->regs, offset, bits); } =20 static void mtk_hdmi_mask(struct mtk_hdmi *hdmi, u32 offset, u32 val, u32 = mask) { - void __iomem *reg =3D hdmi->regs + offset; - u32 tmp; - - tmp =3D readl(reg); - tmp =3D (tmp & ~mask) | (val & mask); - writel(tmp, reg); + regmap_update_bits(hdmi->regs, offset, mask, val); } =20 static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black) @@ -474,7 +459,7 @@ static void mtk_hdmi_hw_aud_set_i2s_fmt(struct mtk_hdmi= *hdmi, { u32 val; =20 - val =3D mtk_hdmi_read(hdmi, GRL_CFG0); + mtk_hdmi_read(hdmi, GRL_CFG0, &val); val &=3D ~(CFG0_W_LENGTH_MASK | CFG0_I2S_MODE_MASK); =20 switch (i2s_fmt) { @@ -566,7 +551,7 @@ static void mtk_hdmi_hw_aud_set_input_type(struct mtk_h= dmi *hdmi, { u32 val; =20 - val =3D mtk_hdmi_read(hdmi, GRL_CFG1); + mtk_hdmi_read(hdmi, GRL_CFG1, &val); if (input_type =3D=3D HDMI_AUD_INPUT_I2S && (val & CFG1_SPDIF) =3D=3D CFG1_SPDIF) { val &=3D ~CFG1_SPDIF; @@ -597,7 +582,7 @@ static void mtk_hdmi_hw_aud_src_reenable(struct mtk_hdm= i *hdmi) { u32 val; =20 - val =3D mtk_hdmi_read(hdmi, GRL_MIX_CTRL); + mtk_hdmi_read(hdmi, GRL_MIX_CTRL, &val); if (val & MIX_CTRL_SRC_EN) { val &=3D ~MIX_CTRL_SRC_EN; mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val); @@ -611,7 +596,7 @@ static void mtk_hdmi_hw_aud_src_disable(struct mtk_hdmi= *hdmi) { u32 val; =20 - val =3D mtk_hdmi_read(hdmi, GRL_MIX_CTRL); + mtk_hdmi_read(hdmi, GRL_MIX_CTRL, &val); val &=3D ~MIX_CTRL_SRC_EN; mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val); mtk_hdmi_write(hdmi, GRL_SHIFT_L1, 0x00); @@ -622,7 +607,7 @@ static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *h= dmi, { u32 val; =20 - val =3D mtk_hdmi_read(hdmi, GRL_CFG5); + mtk_hdmi_read(hdmi, GRL_CFG5, &val); val &=3D CFG5_CD_RATIO_MASK; =20 switch (mclk) { @@ -1428,7 +1413,6 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *h= dmi, struct device_node *cec_np, *remote, *i2c_np; struct platform_device *cec_pdev; struct regmap *regmap; - struct resource *mem; int ret; =20 ret =3D mtk_hdmi_get_all_clk(hdmi, np); @@ -1474,8 +1458,7 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *h= dmi, } hdmi->sys_regmap =3D regmap; =20 - mem =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); - hdmi->regs =3D devm_ioremap_resource(dev, mem); + hdmi->regs =3D syscon_node_to_regmap(dev->of_node); if (IS_ERR(hdmi->regs)) { ret =3D PTR_ERR(hdmi->regs); goto put_device; --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 272B4ECAAA1 for ; Mon, 19 Sep 2022 17:00:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230346AbiISRAT (ORCPT ); Mon, 19 Sep 2022 13:00:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230321AbiISRAI (ORCPT ); Mon, 19 Sep 2022 13:00:08 -0400 Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [IPv6:2a00:1450:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A1DE133350 for ; Mon, 19 Sep 2022 09:59:55 -0700 (PDT) Received: by mail-ed1-x52d.google.com with SMTP id z97so113272ede.8 for ; Mon, 19 Sep 2022 09:59:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=5y6U/O2cW1kp0MEYYlgdcRumC1g8PUdg2NEss+CEK4Y=; b=u9o63LTxFa7L0qIFlEApgQkRIlw0NFfFQtW1Vdw4ql0gk0AkcKQUA308pxM1LeQsTV ealEEZUUQ1Hoc26qB9doB91p2dMDciChIfhr5efax2uEJls/dFAHbvg72hGqyPc2ZCli /jtjFI0iCGSTOGhwM0REsrlbCu6NmyGmUve8aAOWWow0ddGpbjiYETkTphqQ7chs719p i4s1mpSRVVmRqL3N3loAyHeDe/c22M5IQRRGBjhk0zhNR088zfQCYCghvg7Gf0yjBkOV jWYjrMsnDxopS6FaQY3glD94bxQViwhQjaECJnwkS+0NUaZXxlVdW4g7EbcdNq8ZdMwI t5Jw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=5y6U/O2cW1kp0MEYYlgdcRumC1g8PUdg2NEss+CEK4Y=; b=2GneoJDRGDZY2P4aBPNIfpRfr4RL/uATKU3qW2UUaQ4G23uEms1mhaGqI4NTGo6JuK kb/orwqPk2ytEf8uktXcfoeEkLCF3h1xwbinoAeECnO/pxvIoVNOk0NL+miVU0iio3xO fhEKkMmWbdo+Qix3kppbsHUcEiZLUGVbFUPwr7EbaHIX3wzB54f3BJGPykvduWEiRU3P NDxr8bkQ4wBfvyJrtDiVlGTKI+Jnu8THEfFsuxRu/p+ooJ6f/B5hICeF+27saSIY0Hcu HoDuUiYbZKT4T6PwNrxn83FFQoClAG//YO/zkx+dPdvb+yjvq9doAII4VFvml7g4igft 0tBQ== X-Gm-Message-State: ACrzQf12dejLO7do+BexTThK0+56xqe7L3qK48CxeuNGEWubWhxyS5LY /0ESWgMhnJ7QvV/zLwv40Ku3hQ== X-Google-Smtp-Source: AMsMyM4z9QtWkhNsKkQaCij9zXzUMc6vE8fa01Z3HxRTpUioaFewUxAHVAEU609+mICb4RrhgGgc5A== X-Received: by 2002:aa7:da97:0:b0:452:bea2:5200 with SMTP id q23-20020aa7da97000000b00452bea25200mr16562187eds.341.1663606794718; Mon, 19 Sep 2022 09:59:54 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.09.59.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 09:59:54 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:04 +0200 Subject: [PATCH v1 06/17] dt-bindings: mediatek: set the hdmi to be compatible with syscon MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-6-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In order to share register with a dedicated ddc driver, set the hdmi compatible to syscon. Signed-off-by: Guillaume Ranquet diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,hd= mi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.= yaml index abb231a0694b..86297b7eb7f7 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.yaml @@ -16,12 +16,14 @@ description: | =20 properties: compatible: - enum: - - mediatek,mt2701-hdmi - - mediatek,mt7623-hdmi - - mediatek,mt8167-hdmi - - mediatek,mt8173-hdmi - - mediatek,mt8195-hdmi + items: + - enum: + - mediatek,mt2701-hdmi + - mediatek,mt7623-hdmi + - mediatek,mt8167-hdmi + - mediatek,mt8173-hdmi + - const: syscon + =20 clocks: true clock-names: true @@ -142,7 +144,7 @@ examples: #include #include hdmi0: hdmi@14025000 { - compatible =3D "mediatek,mt8173-hdmi"; + compatible =3D "mediatek,mt8173-hdmi", "syscon"; reg =3D <0x14025000 0x400>; interrupts =3D ; clocks =3D <&mmsys CLK_MM_HDMI_PIXEL>, diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts= /mediatek/mt8173.dtsi index 7640b5158ff9..3e7a0f406631 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -1306,7 +1306,7 @@ od@14023000 { }; =20 hdmi0: hdmi@14025000 { - compatible =3D "mediatek,mt8173-hdmi"; + compatible =3D "mediatek,mt8173-hdmi", "syscon"; reg =3D <0 0x14025000 0 0x400>; interrupts =3D ; clocks =3D <&mmsys CLK_MM_HDMI_PIXEL>, --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DEF1DECAAD3 for ; Mon, 19 Sep 2022 17:00:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230420AbiISRAY (ORCPT ); Mon, 19 Sep 2022 13:00:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44566 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230344AbiISRAK (ORCPT ); Mon, 19 Sep 2022 13:00:10 -0400 Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8E26C3343D for ; Mon, 19 Sep 2022 09:59:58 -0700 (PDT) Received: by mail-ed1-x534.google.com with SMTP id y8so98860edc.10 for ; Mon, 19 Sep 2022 09:59:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=ION6izdHywigVEdYyM+mFhzmU0aXOyUlxucDQ5PX8Pc=; b=Z2/g4WcEN2ELwY7ETNq4WHUE2b2aNn4SXtWXCCIeDfoYqSSqFPxQjLSdvZXbbVZj8F NH4jE9sabKHaMu+Ioe3ehB8fu6Zggn810zEjUqZjJ/N0gfQUaIiFSNdbeW+2y6tZvWpy huF08wuOMD/I2Tacd2Dd3Z1cvjELdKZS4TA/M6zIJJcLNUiGpX9mqNoiMN2N6wtXSa9E TbZyoWF0CMnXJHVHwIF2H9bYSUse5jIXR7ocDooUB3HJXCaS9aumI67rrkLeKc3LsVeg UkJu2984qy6b/GYcbx+8cuSoQquA/fz3bPbJBqRtVw9BpLvDBv6u4Wiy1l2PM5kpicbj WQEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=ION6izdHywigVEdYyM+mFhzmU0aXOyUlxucDQ5PX8Pc=; b=6EM7Hse7EMM6dQ3sin/WBaYBHi36k+NWX6My/Eo1He5ZixMH3n+T4b7ovbzb7AgOgg 6fz5QYMvSQMO/Q/MJLRwUZ+ysGakGVghKAsuRw75ccaX5N1MUXiXgJ3Bxk+51M12qp2s XMajWfoBaUo4Xk7frMkvZWZR8yBd+S31RjDi9PxdXvVrm5oyZ/WABGNlYZK7y+RPziv5 E4SnQuaqTQ4bnKR8ON2tngRGQUfDzXPqTbKJv8WLhdoovTojlhw0Ekw78JeiePN+M36I nBnu6yclrg4IKKXtbswRADpralE9UzPgq4RKyuVrFMMB6GwMVmXj2hSJFBe07wzhkQFA GEtg== X-Gm-Message-State: ACrzQf0aC5bgOGEkiV9+SV/CRIqA75/jUMXAysGS+jqk6eWs3GMc0Jrg DP9ZUgZEXcLaukamiCLG1Ip6ehEeiB5hcg== X-Google-Smtp-Source: AMsMyM4YCLwWXN205BrufbnSb5q3wN0qYtmddYN6Na498B3RYkEVDUJL/iHLAHigeI/zKhJOkw3jyw== X-Received: by 2002:a05:6402:402a:b0:449:2ae0:aa9a with SMTP id d42-20020a056402402a00b004492ae0aa9amr16781610eda.420.1663606797605; Mon, 19 Sep 2022 09:59:57 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.09.59.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 09:59:57 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:05 +0200 Subject: [PATCH v1 07/17] drm/mediatek: extract common functions from the mtk hdmi driver MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-7-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Create a common "framework" that can be used to add support for different hdmi IPs within the mediatek range of products. Signed-off-by: Guillaume Ranquet diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/M= akefile index d4d193f60271..008ec69da67b 100644 --- a/drivers/gpu/drm/mediatek/Makefile +++ b/drivers/gpu/drm/mediatek/Makefile @@ -22,7 +22,8 @@ obj-$(CONFIG_DRM_MEDIATEK) +=3D mediatek-drm.o =20 mediatek-drm-hdmi-objs :=3D mtk_cec.o \ mtk_hdmi.o \ - mtk_hdmi_ddc.o + mtk_hdmi_ddc.o \ + mtk_hdmi_common.o \ =20 obj-$(CONFIG_DRM_MEDIATEK_HDMI) +=3D mediatek-drm-hdmi.o =20 diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek= /mtk_hdmi.c index 5cd05d4fe1a9..837d36ec4d64 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -32,187 +32,18 @@ #include =20 #include "mtk_cec.h" -#include "mtk_hdmi.h" #include "mtk_hdmi_regs.h" +#include "mtk_hdmi_common.h" =20 #define NCTS_BYTES 7 =20 -enum mtk_hdmi_clk_id { - MTK_HDMI_CLK_HDMI_PIXEL, - MTK_HDMI_CLK_HDMI_PLL, - MTK_HDMI_CLK_AUD_BCLK, - MTK_HDMI_CLK_AUD_SPDIF, - MTK_HDMI_CLK_COUNT +const char * const mtk_hdmi_clk_names_mt8183[MTK_MT8183_HDMI_CLK_COUNT] = =3D { + [MTK_MT8183_HDMI_CLK_HDMI_PIXEL] =3D "pixel", + [MTK_MT8183_HDMI_CLK_HDMI_PLL] =3D "pll", + [MTK_MT8183_HDMI_CLK_AUD_BCLK] =3D "bclk", + [MTK_MT8183_HDMI_CLK_AUD_SPDIF] =3D "spdif", }; =20 -enum hdmi_aud_input_type { - HDMI_AUD_INPUT_I2S =3D 0, - HDMI_AUD_INPUT_SPDIF, -}; - -enum hdmi_aud_i2s_fmt { - HDMI_I2S_MODE_RJT_24BIT =3D 0, - HDMI_I2S_MODE_RJT_16BIT, - HDMI_I2S_MODE_LJT_24BIT, - HDMI_I2S_MODE_LJT_16BIT, - HDMI_I2S_MODE_I2S_24BIT, - HDMI_I2S_MODE_I2S_16BIT -}; - -enum hdmi_aud_mclk { - HDMI_AUD_MCLK_128FS, - HDMI_AUD_MCLK_192FS, - HDMI_AUD_MCLK_256FS, - HDMI_AUD_MCLK_384FS, - HDMI_AUD_MCLK_512FS, - HDMI_AUD_MCLK_768FS, - HDMI_AUD_MCLK_1152FS, -}; - -enum hdmi_aud_channel_type { - HDMI_AUD_CHAN_TYPE_1_0 =3D 0, - HDMI_AUD_CHAN_TYPE_1_1, - HDMI_AUD_CHAN_TYPE_2_0, - HDMI_AUD_CHAN_TYPE_2_1, - HDMI_AUD_CHAN_TYPE_3_0, - HDMI_AUD_CHAN_TYPE_3_1, - HDMI_AUD_CHAN_TYPE_4_0, - HDMI_AUD_CHAN_TYPE_4_1, - HDMI_AUD_CHAN_TYPE_5_0, - HDMI_AUD_CHAN_TYPE_5_1, - HDMI_AUD_CHAN_TYPE_6_0, - HDMI_AUD_CHAN_TYPE_6_1, - HDMI_AUD_CHAN_TYPE_7_0, - HDMI_AUD_CHAN_TYPE_7_1, - HDMI_AUD_CHAN_TYPE_3_0_LRS, - HDMI_AUD_CHAN_TYPE_3_1_LRS, - HDMI_AUD_CHAN_TYPE_4_0_CLRS, - HDMI_AUD_CHAN_TYPE_4_1_CLRS, - HDMI_AUD_CHAN_TYPE_6_1_CS, - HDMI_AUD_CHAN_TYPE_6_1_CH, - HDMI_AUD_CHAN_TYPE_6_1_OH, - HDMI_AUD_CHAN_TYPE_6_1_CHR, - HDMI_AUD_CHAN_TYPE_7_1_LH_RH, - HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR, - HDMI_AUD_CHAN_TYPE_7_1_LC_RC, - HDMI_AUD_CHAN_TYPE_7_1_LW_RW, - HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD, - HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS, - HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS, - HDMI_AUD_CHAN_TYPE_7_1_CS_CH, - HDMI_AUD_CHAN_TYPE_7_1_CS_OH, - HDMI_AUD_CHAN_TYPE_7_1_CS_CHR, - HDMI_AUD_CHAN_TYPE_7_1_CH_OH, - HDMI_AUD_CHAN_TYPE_7_1_CH_CHR, - HDMI_AUD_CHAN_TYPE_7_1_OH_CHR, - HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR, - HDMI_AUD_CHAN_TYPE_6_0_CS, - HDMI_AUD_CHAN_TYPE_6_0_CH, - HDMI_AUD_CHAN_TYPE_6_0_OH, - HDMI_AUD_CHAN_TYPE_6_0_CHR, - HDMI_AUD_CHAN_TYPE_7_0_LH_RH, - HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR, - HDMI_AUD_CHAN_TYPE_7_0_LC_RC, - HDMI_AUD_CHAN_TYPE_7_0_LW_RW, - HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD, - HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS, - HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS, - HDMI_AUD_CHAN_TYPE_7_0_CS_CH, - HDMI_AUD_CHAN_TYPE_7_0_CS_OH, - HDMI_AUD_CHAN_TYPE_7_0_CS_CHR, - HDMI_AUD_CHAN_TYPE_7_0_CH_OH, - HDMI_AUD_CHAN_TYPE_7_0_CH_CHR, - HDMI_AUD_CHAN_TYPE_7_0_OH_CHR, - HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR, - HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS, - HDMI_AUD_CHAN_TYPE_UNKNOWN =3D 0xFF -}; - -enum hdmi_aud_channel_swap_type { - HDMI_AUD_SWAP_LR, - HDMI_AUD_SWAP_LFE_CC, - HDMI_AUD_SWAP_LSRS, - HDMI_AUD_SWAP_RLS_RRS, - HDMI_AUD_SWAP_LR_STATUS, -}; - -struct hdmi_audio_param { - enum hdmi_audio_coding_type aud_codec; - enum hdmi_audio_sample_size aud_sampe_size; - enum hdmi_aud_input_type aud_input_type; - enum hdmi_aud_i2s_fmt aud_i2s_fmt; - enum hdmi_aud_mclk aud_mclk; - enum hdmi_aud_channel_type aud_input_chan_type; - struct hdmi_codec_params codec_params; -}; - -struct mtk_hdmi_conf { - bool tz_disabled; - bool cea_modes_only; - unsigned long max_mode_clock; -}; - -struct mtk_hdmi { - struct drm_bridge bridge; - struct drm_bridge *next_bridge; - struct drm_connector *curr_conn;/* current connector (only valid when 'en= abled') */ - struct device *dev; - const struct mtk_hdmi_conf *conf; - struct phy *phy; - struct device *cec_dev; - struct i2c_adapter *ddc_adpt; - struct clk *clk[MTK_HDMI_CLK_COUNT]; - struct drm_display_mode mode; - bool dvi_mode; - u32 min_clock; - u32 max_clock; - u32 max_hdisplay; - u32 max_vdisplay; - u32 ibias; - u32 ibias_up; - struct regmap *sys_regmap; - unsigned int sys_offset; - struct regmap *regs; - enum hdmi_colorspace csp; - struct hdmi_audio_param aud_param; - bool audio_enable; - bool powered; - bool enabled; - hdmi_codec_plugged_cb plugged_cb; - struct device *codec_dev; - struct mutex update_plugged_status_lock; -}; - -static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b) -{ - return container_of(b, struct mtk_hdmi, bridge); -} - -static int mtk_hdmi_read(struct mtk_hdmi *hdmi, u32 offset, u32 *val) -{ - return regmap_read(hdmi->regs, offset, val); -} - -static void mtk_hdmi_write(struct mtk_hdmi *hdmi, u32 offset, u32 val) -{ - regmap_write(hdmi->regs, offset, val); -} - -static void mtk_hdmi_clear_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bit= s) -{ - regmap_clear_bits(hdmi->regs, offset, bits); -} - -static void mtk_hdmi_set_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits) -{ - regmap_set_bits(hdmi->regs, offset, bits); -} - -static void mtk_hdmi_mask(struct mtk_hdmi *hdmi, u32 offset, u32 val, u32 = mask) -{ - regmap_update_bits(hdmi->regs, offset, mask, val); -} - static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black) { mtk_hdmi_mask(hdmi, VIDEO_CFG_4, black ? GEN_RGB : NORMAL_PATH, @@ -825,14 +656,14 @@ static int mtk_hdmi_video_change_vpll(struct mtk_hdmi= *hdmi, u32 clock) int ret; =20 /* The DPI driver already should have set TVDPLL to the correct rate */ - ret =3D clk_set_rate(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL], clock); + ret =3D clk_set_rate(hdmi->clk[MTK_MT8183_HDMI_CLK_HDMI_PLL], clock); if (ret) { dev_err(hdmi->dev, "Failed to set PLL to %u Hz: %d\n", clock, ret); return ret; } =20 - rate =3D clk_get_rate(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL]); + rate =3D clk_get_rate(hdmi->clk[MTK_MT8183_HDMI_CLK_HDMI_PLL]); =20 if (DIV_ROUND_CLOSEST(rate, 1000) !=3D DIV_ROUND_CLOSEST(clock, 1000)) dev_warn(hdmi->dev, "Want PLL %u Hz, got %lu Hz\n", clock, @@ -857,7 +688,6 @@ static void mtk_hdmi_video_set_display_mode(struct mtk_= hdmi *hdmi, mtk_hdmi_hw_msic_setting(hdmi, mode); } =20 - static void mtk_hdmi_aud_set_input(struct mtk_hdmi *hdmi) { enum hdmi_aud_channel_type chan_type; @@ -948,56 +778,6 @@ static int mtk_hdmi_aud_output_config(struct mtk_hdmi = *hdmi, return 0; } =20 -static int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi, - struct drm_display_mode *mode) -{ - struct hdmi_avi_infoframe frame; - u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; - ssize_t err; - - err =3D drm_hdmi_avi_infoframe_from_display_mode(&frame, - hdmi->curr_conn, mode); - if (err < 0) { - dev_err(hdmi->dev, - "Failed to get AVI infoframe from mode: %zd\n", err); - return err; - } - - err =3D hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); - if (err < 0) { - dev_err(hdmi->dev, "Failed to pack AVI infoframe: %zd\n", err); - return err; - } - - mtk_hdmi_hw_send_info_frame(hdmi, buffer, sizeof(buffer)); - return 0; -} - -static int mtk_hdmi_setup_spd_infoframe(struct mtk_hdmi *hdmi, - const char *vendor, - const char *product) -{ - struct hdmi_spd_infoframe frame; - u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_SPD_INFOFRAME_SIZE]; - ssize_t err; - - err =3D hdmi_spd_infoframe_init(&frame, vendor, product); - if (err < 0) { - dev_err(hdmi->dev, "Failed to initialize SPD infoframe: %zd\n", - err); - return err; - } - - err =3D hdmi_spd_infoframe_pack(&frame, buffer, sizeof(buffer)); - if (err < 0) { - dev_err(hdmi->dev, "Failed to pack SDP infoframe: %zd\n", err); - return err; - } - - mtk_hdmi_hw_send_info_frame(hdmi, buffer, sizeof(buffer)); - return 0; -} - static int mtk_hdmi_setup_audio_infoframe(struct mtk_hdmi *hdmi) { struct hdmi_audio_infoframe frame; @@ -1054,7 +834,7 @@ static int mtk_hdmi_setup_vendor_specific_infoframe(st= ruct mtk_hdmi *hdmi, return 0; } =20 -static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi) +void mtk_hdmi_output_init_mt8183(struct mtk_hdmi *hdmi) { struct hdmi_audio_param *aud_param =3D &hdmi->aud_param; =20 @@ -1065,8 +845,6 @@ static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi) aud_param->aud_i2s_fmt =3D HDMI_I2S_MODE_I2S_24BIT; aud_param->aud_mclk =3D HDMI_AUD_MCLK_128FS; aud_param->aud_input_chan_type =3D HDMI_AUD_CHAN_TYPE_2_0; - - return 0; } =20 static void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi) @@ -1123,49 +901,28 @@ static int mtk_hdmi_output_set_display_mode(struct m= tk_hdmi *hdmi, return 0; } =20 -static const char * const mtk_hdmi_clk_names[MTK_HDMI_CLK_COUNT] =3D { - [MTK_HDMI_CLK_HDMI_PIXEL] =3D "pixel", - [MTK_HDMI_CLK_HDMI_PLL] =3D "pll", - [MTK_HDMI_CLK_AUD_BCLK] =3D "bclk", - [MTK_HDMI_CLK_AUD_SPDIF] =3D "spdif", -}; - -static int mtk_hdmi_get_all_clk(struct mtk_hdmi *hdmi, - struct device_node *np) -{ - int i; - - for (i =3D 0; i < ARRAY_SIZE(mtk_hdmi_clk_names); i++) { - hdmi->clk[i] =3D of_clk_get_by_name(np, - mtk_hdmi_clk_names[i]); - if (IS_ERR(hdmi->clk[i])) - return PTR_ERR(hdmi->clk[i]); - } - return 0; -} - -static int mtk_hdmi_clk_enable_audio(struct mtk_hdmi *hdmi) +int mtk_hdmi_clk_enable_audio_mt8183(struct mtk_hdmi *hdmi) { int ret; =20 - ret =3D clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_AUD_BCLK]); + ret =3D clk_prepare_enable(hdmi->clk[MTK_MT8183_HDMI_CLK_AUD_BCLK]); if (ret) return ret; =20 - ret =3D clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_AUD_SPDIF]); + ret =3D clk_prepare_enable(hdmi->clk[MTK_MT8183_HDMI_CLK_AUD_SPDIF]); if (ret) goto err; =20 return 0; err: - clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_BCLK]); + clk_disable_unprepare(hdmi->clk[MTK_MT8183_HDMI_CLK_AUD_BCLK]); return ret; } =20 -static void mtk_hdmi_clk_disable_audio(struct mtk_hdmi *hdmi) +void mtk_hdmi_clk_disable_audio_mt8183(struct mtk_hdmi *hdmi) { - clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_BCLK]); - clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_SPDIF]); + clk_disable_unprepare(hdmi->clk[MTK_MT8183_HDMI_CLK_AUD_BCLK]); + clk_disable_unprepare(hdmi->clk[MTK_MT8183_HDMI_CLK_AUD_SPDIF]); } =20 static enum drm_connector_status @@ -1250,21 +1007,6 @@ static enum drm_connector_status mtk_hdmi_bridge_det= ect(struct drm_bridge *bridg return mtk_hdmi_detect(hdmi); } =20 -static struct edid *mtk_hdmi_bridge_get_edid(struct drm_bridge *bridge, - struct drm_connector *connector) -{ - struct mtk_hdmi *hdmi =3D hdmi_ctx_from_bridge(bridge); - struct edid *edid; - - if (!hdmi->ddc_adpt) - return NULL; - edid =3D drm_get_edid(connector, hdmi->ddc_adpt); - if (!edid) - return NULL; - hdmi->dvi_mode =3D !drm_detect_monitor_audio(edid); - return edid; -} - static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { @@ -1289,13 +1031,6 @@ static int mtk_hdmi_bridge_attach(struct drm_bridge = *bridge, return 0; } =20 -static bool mtk_hdmi_bridge_mode_fixup(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - static void mtk_hdmi_bridge_atomic_disable(struct drm_bridge *bridge, struct drm_bridge_state *old_bridge_state) { @@ -1305,8 +1040,8 @@ static void mtk_hdmi_bridge_atomic_disable(struct drm= _bridge *bridge, return; =20 phy_power_off(hdmi->phy); - clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_HDMI_PIXEL]); - clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL]); + clk_disable_unprepare(hdmi->clk[MTK_MT8183_HDMI_CLK_HDMI_PIXEL]); + clk_disable_unprepare(hdmi->clk[MTK_MT8183_HDMI_CLK_HDMI_PLL]); =20 hdmi->curr_conn =3D NULL; =20 @@ -1327,28 +1062,6 @@ static void mtk_hdmi_bridge_atomic_post_disable(stru= ct drm_bridge *bridge, hdmi->powered =3D false; } =20 -static void mtk_hdmi_bridge_mode_set(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - const struct drm_display_mode *adjusted_mode) -{ - struct mtk_hdmi *hdmi =3D hdmi_ctx_from_bridge(bridge); - - dev_dbg(hdmi->dev, "cur info: name:%s, hdisplay:%d\n", - adjusted_mode->name, adjusted_mode->hdisplay); - dev_dbg(hdmi->dev, "hsync_start:%d,hsync_end:%d, htotal:%d", - adjusted_mode->hsync_start, adjusted_mode->hsync_end, - adjusted_mode->htotal); - dev_dbg(hdmi->dev, "hskew:%d, vdisplay:%d\n", - adjusted_mode->hskew, adjusted_mode->vdisplay); - dev_dbg(hdmi->dev, "vsync_start:%d, vsync_end:%d, vtotal:%d", - adjusted_mode->vsync_start, adjusted_mode->vsync_end, - adjusted_mode->vtotal); - dev_dbg(hdmi->dev, "vscan:%d, flag:%d\n", - adjusted_mode->vscan, adjusted_mode->flags); - - drm_mode_copy(&hdmi->mode, adjusted_mode); -} - static void mtk_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge, struct drm_bridge_state *old_state) { @@ -1360,36 +1073,32 @@ static void mtk_hdmi_bridge_atomic_pre_enable(struc= t drm_bridge *bridge, hdmi->powered =3D true; } =20 -static void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi, - struct drm_display_mode *mode) -{ - mtk_hdmi_setup_audio_infoframe(hdmi); - mtk_hdmi_setup_avi_infoframe(hdmi, mode); - mtk_hdmi_setup_spd_infoframe(hdmi, "mediatek", "On-chip HDMI"); - if (mode->flags & DRM_MODE_FLAG_3D_MASK) - mtk_hdmi_setup_vendor_specific_infoframe(hdmi, mode); -} - static void mtk_hdmi_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_bridge_state *old_state) { struct drm_atomic_state *state =3D old_state->base.state; struct mtk_hdmi *hdmi =3D hdmi_ctx_from_bridge(bridge); + u8 buffer_spd[HDMI_INFOFRAME_SIZE(SPD)]; + u8 buffer_avi[HDMI_INFOFRAME_SIZE(AVI)]; =20 /* Retrieve the connector through the atomic state. */ hdmi->curr_conn =3D drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); =20 mtk_hdmi_output_set_display_mode(hdmi, &hdmi->mode); - clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL]); - clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PIXEL]); + clk_prepare_enable(hdmi->clk[MTK_MT8183_HDMI_CLK_HDMI_PLL]); + clk_prepare_enable(hdmi->clk[MTK_MT8183_HDMI_CLK_HDMI_PIXEL]); phy_power_on(hdmi->phy); - mtk_hdmi_send_infoframe(hdmi, &hdmi->mode); + mtk_hdmi_setup_audio_infoframe(hdmi); + mtk_hdmi_send_infoframe(hdmi, buffer_spd, sizeof(buffer_spd), + buffer_avi, sizeof(buffer_avi), &hdmi->mode); + if (hdmi->mode.flags & DRM_MODE_FLAG_3D_MASK) + mtk_hdmi_setup_vendor_specific_infoframe(hdmi, &hdmi->mode); =20 hdmi->enabled =3D true; } =20 -static const struct drm_bridge_funcs mtk_hdmi_bridge_funcs =3D { +const struct drm_bridge_funcs mtk_mt8183_hdmi_bridge_funcs =3D { .mode_valid =3D mtk_hdmi_bridge_mode_valid, .atomic_duplicate_state =3D drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state =3D drm_atomic_helper_bridge_destroy_state, @@ -1405,105 +1114,6 @@ static const struct drm_bridge_funcs mtk_hdmi_bridg= e_funcs =3D { .get_edid =3D mtk_hdmi_bridge_get_edid, }; =20 -static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, - struct platform_device *pdev) -{ - struct device *dev =3D &pdev->dev; - struct device_node *np =3D dev->of_node; - struct device_node *cec_np, *remote, *i2c_np; - struct platform_device *cec_pdev; - struct regmap *regmap; - int ret; - - ret =3D mtk_hdmi_get_all_clk(hdmi, np); - if (ret) { - if (ret !=3D -EPROBE_DEFER) - dev_err(dev, "Failed to get clocks: %d\n", ret); - - return ret; - } - - /* The CEC module handles HDMI hotplug detection */ - cec_np =3D of_get_compatible_child(np->parent, "mediatek,mt8173-cec"); - if (!cec_np) { - dev_err(dev, "Failed to find CEC node\n"); - return -EINVAL; - } - - cec_pdev =3D of_find_device_by_node(cec_np); - if (!cec_pdev) { - dev_err(hdmi->dev, "Waiting for CEC device %pOF\n", - cec_np); - of_node_put(cec_np); - return -EPROBE_DEFER; - } - of_node_put(cec_np); - hdmi->cec_dev =3D &cec_pdev->dev; - - /* - * The mediatek,syscon-hdmi property contains a phandle link to the - * MMSYS_CONFIG device and the register offset of the HDMI_SYS_CFG - * registers it contains. - */ - regmap =3D syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi"); - ret =3D of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1, - &hdmi->sys_offset); - if (IS_ERR(regmap)) - ret =3D PTR_ERR(regmap); - if (ret) { - dev_err(dev, - "Failed to get system configuration registers: %d\n", - ret); - goto put_device; - } - hdmi->sys_regmap =3D regmap; - - hdmi->regs =3D syscon_node_to_regmap(dev->of_node); - if (IS_ERR(hdmi->regs)) { - ret =3D PTR_ERR(hdmi->regs); - goto put_device; - } - - remote =3D of_graph_get_remote_node(np, 1, 0); - if (!remote) { - ret =3D -EINVAL; - goto put_device; - } - - if (!of_device_is_compatible(remote, "hdmi-connector")) { - hdmi->next_bridge =3D of_drm_find_bridge(remote); - if (!hdmi->next_bridge) { - dev_err(dev, "Waiting for external bridge\n"); - of_node_put(remote); - ret =3D -EPROBE_DEFER; - goto put_device; - } - } - - i2c_np =3D of_parse_phandle(remote, "ddc-i2c-bus", 0); - if (!i2c_np) { - dev_err(dev, "Failed to find ddc-i2c-bus node in %pOF\n", - remote); - of_node_put(remote); - ret =3D -EINVAL; - goto put_device; - } - of_node_put(remote); - - hdmi->ddc_adpt =3D of_find_i2c_adapter_by_node(i2c_np); - of_node_put(i2c_np); - if (!hdmi->ddc_adpt) { - dev_err(dev, "Failed to get ddc i2c adapter by node\n"); - ret =3D -EINVAL; - goto put_device; - } - - return 0; -put_device: - put_device(hdmi->cec_dev); - return ret; -} - /* * HDMI audio codec callbacks */ @@ -1649,175 +1259,9 @@ static const struct hdmi_codec_ops mtk_hdmi_audio_c= odec_ops =3D { .no_capture_mute =3D 1, }; =20 -static int mtk_hdmi_register_audio_driver(struct device *dev) -{ - struct mtk_hdmi *hdmi =3D dev_get_drvdata(dev); - struct hdmi_codec_pdata codec_data =3D { - .ops =3D &mtk_hdmi_audio_codec_ops, - .max_i2s_channels =3D 2, - .i2s =3D 1, - .data =3D hdmi, - }; - struct platform_device *pdev; - - pdev =3D platform_device_register_data(dev, HDMI_CODEC_DRV_NAME, - PLATFORM_DEVID_AUTO, &codec_data, - sizeof(codec_data)); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - - DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME); - return 0; -} - -static int mtk_drm_hdmi_probe(struct platform_device *pdev) -{ - struct mtk_hdmi *hdmi; - struct device *dev =3D &pdev->dev; - int ret; - - hdmi =3D devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); - if (!hdmi) - return -ENOMEM; - - hdmi->dev =3D dev; - hdmi->conf =3D of_device_get_match_data(dev); - - ret =3D mtk_hdmi_dt_parse_pdata(hdmi, pdev); - if (ret) - return ret; - - hdmi->phy =3D devm_phy_get(dev, "hdmi"); - if (IS_ERR(hdmi->phy)) { - ret =3D PTR_ERR(hdmi->phy); - dev_err(dev, "Failed to get HDMI PHY: %d\n", ret); - return ret; - } - - mutex_init(&hdmi->update_plugged_status_lock); - platform_set_drvdata(pdev, hdmi); - - ret =3D mtk_hdmi_output_init(hdmi); - if (ret) { - dev_err(dev, "Failed to initialize hdmi output\n"); - return ret; - } - - ret =3D mtk_hdmi_register_audio_driver(dev); - if (ret) { - dev_err(dev, "Failed to register audio driver: %d\n", ret); - return ret; - } - - hdmi->bridge.funcs =3D &mtk_hdmi_bridge_funcs; - hdmi->bridge.of_node =3D pdev->dev.of_node; - hdmi->bridge.ops =3D DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID - | DRM_BRIDGE_OP_HPD; - hdmi->bridge.type =3D DRM_MODE_CONNECTOR_HDMIA; - drm_bridge_add(&hdmi->bridge); - - ret =3D mtk_hdmi_clk_enable_audio(hdmi); - if (ret) { - dev_err(dev, "Failed to enable audio clocks: %d\n", ret); - goto err_bridge_remove; - } - - return 0; - -err_bridge_remove: - drm_bridge_remove(&hdmi->bridge); - return ret; -} - -static int mtk_drm_hdmi_remove(struct platform_device *pdev) -{ - struct mtk_hdmi *hdmi =3D platform_get_drvdata(pdev); - - drm_bridge_remove(&hdmi->bridge); - mtk_hdmi_clk_disable_audio(hdmi); - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int mtk_hdmi_suspend(struct device *dev) -{ - struct mtk_hdmi *hdmi =3D dev_get_drvdata(dev); - - mtk_hdmi_clk_disable_audio(hdmi); - - return 0; -} - -static int mtk_hdmi_resume(struct device *dev) -{ - struct mtk_hdmi *hdmi =3D dev_get_drvdata(dev); - int ret =3D 0; - - ret =3D mtk_hdmi_clk_enable_audio(hdmi); - if (ret) { - dev_err(dev, "hdmi resume failed!\n"); - return ret; - } - - return 0; -} -#endif -static SIMPLE_DEV_PM_OPS(mtk_hdmi_pm_ops, - mtk_hdmi_suspend, mtk_hdmi_resume); - -static const struct mtk_hdmi_conf mtk_hdmi_conf_mt2701 =3D { - .tz_disabled =3D true, -}; - -static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8167 =3D { - .max_mode_clock =3D 148500, - .cea_modes_only =3D true, -}; - -static const struct of_device_id mtk_drm_hdmi_of_ids[] =3D { - { .compatible =3D "mediatek,mt2701-hdmi", - .data =3D &mtk_hdmi_conf_mt2701, - }, - { .compatible =3D "mediatek,mt8167-hdmi", - .data =3D &mtk_hdmi_conf_mt8167, - }, - { .compatible =3D "mediatek,mt8173-hdmi", - }, - {} -}; -MODULE_DEVICE_TABLE(of, mtk_drm_hdmi_of_ids); - -static struct platform_driver mtk_hdmi_driver =3D { - .probe =3D mtk_drm_hdmi_probe, - .remove =3D mtk_drm_hdmi_remove, - .driver =3D { - .name =3D "mediatek-drm-hdmi", - .of_match_table =3D mtk_drm_hdmi_of_ids, - .pm =3D &mtk_hdmi_pm_ops, - }, -}; - -static struct platform_driver * const mtk_hdmi_drivers[] =3D { - &mtk_hdmi_ddc_driver, - &mtk_cec_driver, - &mtk_hdmi_driver, -}; - -static int __init mtk_hdmitx_init(void) -{ - return platform_register_drivers(mtk_hdmi_drivers, - ARRAY_SIZE(mtk_hdmi_drivers)); -} - -static void __exit mtk_hdmitx_exit(void) +void set_hdmi_codec_pdata_mt8183(struct hdmi_codec_pdata *codec_data) { - platform_unregister_drivers(mtk_hdmi_drivers, - ARRAY_SIZE(mtk_hdmi_drivers)); + codec_data->ops =3D &mtk_hdmi_audio_codec_ops; + codec_data->max_i2s_channels =3D 2; + codec_data->i2s =3D 1; } - -module_init(mtk_hdmitx_init); -module_exit(mtk_hdmitx_exit); - -MODULE_AUTHOR("Jie Qiu "); -MODULE_DESCRIPTION("MediaTek HDMI Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.h b/drivers/gpu/drm/mediatek= /mtk_hdmi.h index 472bf141c92b..45a6ff1fb7d7 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.h +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.h @@ -6,9 +6,25 @@ #ifndef _MTK_HDMI_CTRL_H #define _MTK_HDMI_CTRL_H =20 +struct mtk_hdmi; struct platform_driver; =20 extern struct platform_driver mtk_cec_driver; extern struct platform_driver mtk_hdmi_ddc_driver; +extern const struct drm_bridge_funcs mtk_mt8183_hdmi_bridge_funcs; =20 +void mtk_hdmi_output_init_mt8183(struct mtk_hdmi *hdmi); +void mtk_hdmi_clk_disable_audio_mt8183(struct mtk_hdmi *hdmi); +int mtk_hdmi_clk_enable_audio_mt8183(struct mtk_hdmi *hdmi); +void set_hdmi_codec_pdata_mt8183(struct hdmi_codec_pdata *codec_data); + +enum mtk_hdmi_clk_id_mt8183 { + MTK_MT8183_HDMI_CLK_HDMI_PIXEL, + MTK_MT8183_HDMI_CLK_HDMI_PLL, + MTK_MT8183_HDMI_CLK_AUD_BCLK, + MTK_MT8183_HDMI_CLK_AUD_SPDIF, + MTK_MT8183_HDMI_CLK_COUNT, +}; + +extern const char * const mtk_hdmi_clk_names_mt8183[MTK_MT8183_HDMI_CLK_CO= UNT]; #endif /* _MTK_HDMI_CTRL_H */ diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/m= ediatek/mtk_hdmi_common.c new file mode 100644 index 000000000000..bfcca6f8b839 --- /dev/null +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c @@ -0,0 +1,433 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2014 MediaTek Inc. + * Copyright (c) 2022 BayLibre, SAS + * Author: Jie Qiu + */ +#include "mtk_hdmi_common.h" + +struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b) +{ + return container_of(b, struct mtk_hdmi, bridge); +} + +int mtk_hdmi_read(struct mtk_hdmi *hdmi, u32 offset, u32 *val) +{ + return regmap_read(hdmi->regs, offset, val); +} + +void mtk_hdmi_write(struct mtk_hdmi *hdmi, u32 offset, u32 val) +{ + regmap_write(hdmi->regs, offset, val); +} + +void mtk_hdmi_clear_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits) +{ + regmap_clear_bits(hdmi->regs, offset, bits); +} + +void mtk_hdmi_set_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits) +{ + regmap_set_bits(hdmi->regs, offset, bits); +} + +void mtk_hdmi_mask(struct mtk_hdmi *hdmi, u32 offset, u32 val, u32 mask) +{ + regmap_update_bits(hdmi->regs, offset, mask, val); +} + +int mtk_hdmi_setup_spd_infoframe(struct mtk_hdmi *hdmi, u8 *buffer, size_t= bufsz, + const char *vendor, const char *product) +{ + struct hdmi_spd_infoframe frame; + ssize_t err; + + err =3D hdmi_spd_infoframe_init(&frame, vendor, product); + if (err < 0) { + dev_err(hdmi->dev, "Failed to initialize SPD infoframe: %zd\n", + err); + return err; + } + + err =3D hdmi_spd_infoframe_pack(&frame, buffer, bufsz); + if (err < 0) { + dev_err(hdmi->dev, "Failed to pack SDP infoframe: %zd\n", err); + return err; + } + + return 0; +} + +int mtk_hdmi_get_all_clk(struct mtk_hdmi *hdmi, struct device_node *np, + const char *const *mtk_hdmi_clk_names, size_t num_clocks) +{ + int i; + + for (i =3D 0; i < num_clocks; i++) { + hdmi->clk[i] =3D of_clk_get_by_name(np, mtk_hdmi_clk_names[i]); + dev_err(hdmi->dev, "Getting clk name: %s\n", mtk_hdmi_clk_names[i]); + + if (IS_ERR(hdmi->clk[i])) + return PTR_ERR(hdmi->clk[i]); + } + + return 0; +} + +struct edid *mtk_hdmi_bridge_get_edid(struct drm_bridge *bridge, + struct drm_connector *connector) +{ + struct mtk_hdmi *hdmi =3D hdmi_ctx_from_bridge(bridge); + struct edid *edid; + + if (!hdmi->ddc_adpt) + return NULL; + edid =3D drm_get_edid(connector, hdmi->ddc_adpt); + if (!edid) + return NULL; + return edid; +} + +bool mtk_hdmi_bridge_mode_fixup(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +void +mtk_hdmi_bridge_mode_set(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + const struct drm_display_mode *adjusted_mode) +{ + struct mtk_hdmi *hdmi =3D hdmi_ctx_from_bridge(bridge); + + drm_mode_copy(&hdmi->mode, adjusted_mode); +} + +int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi, u8 *buffer, size_t= bufsz, + struct drm_display_mode *mode) +{ + struct hdmi_avi_infoframe frame; + ssize_t err; + + err =3D drm_hdmi_avi_infoframe_from_display_mode(&frame, &hdmi->conn, + mode); + + if (err < 0) { + dev_err(hdmi->dev, + "Failed to get AVI infoframe from mode: %zd\n", err); + return err; + } + + err =3D hdmi_avi_infoframe_pack(&frame, buffer, bufsz); + + if (err < 0) { + dev_err(hdmi->dev, "Failed to pack AVI infoframe: %zd\n", err); + return err; + } + + return 0; +} + +void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi, u8 *buffer_spd, size_t= bufsz_spd, + u8 *buffer_avi, size_t bufsz_avi, struct drm_display_mode *mode) +{ + mtk_hdmi_setup_avi_infoframe(hdmi, buffer_avi, bufsz_avi, mode); + mtk_hdmi_setup_spd_infoframe(hdmi, buffer_spd, bufsz_spd, "mediatek", "On= -chip HDMI"); +} + +int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct platform_device = *pdev, + const char *const *clk_names, size_t num_clocks) +{ + struct device *dev =3D &pdev->dev; + struct device_node *np =3D dev->of_node; + struct device_node *cec_np, *remote, *i2c_np; + struct platform_device *cec_pdev; + struct regmap *regmap; + struct resource *mem; + int ret; + + ret =3D mtk_hdmi_get_all_clk(hdmi, np, clk_names, num_clocks); + if (ret) { + dev_err(dev, "Failed to get all clks\n"); + return ret; + } + + /* The CEC module handles HDMI hotplug detection */ + cec_np =3D of_get_compatible_child(np->parent, "mediatek,mt8173-cec"); + if (!cec_np) { + dev_err(dev, "Failed to find CEC node\n"); + return -EINVAL; + } + + cec_pdev =3D of_find_device_by_node(cec_np); + if (!cec_pdev) { + dev_err(hdmi->dev, "Waiting for CEC device %pOF\n", cec_np); + of_node_put(cec_np); + return -EPROBE_DEFER; + } + of_node_put(cec_np); + hdmi->cec_dev =3D &cec_pdev->dev; + /* + * The mediatek,syscon-hdmi property contains a phandle link to the + * MMSYS_CONFIG device and the register offset of the HDMI_SYS_CFG + * registers it contains. + */ + regmap =3D syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi"); + ret =3D of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1, &hdmi->= sys_offset); + if (IS_ERR(regmap)) + ret =3D PTR_ERR(regmap); + if (ret) { + dev_err(dev, "Failed to get system configuration registers: %d\n", ret); + goto put_device; + } + hdmi->sys_regmap =3D regmap; + + mem =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + ret =3D -ENOMEM; + goto put_device; + } + + hdmi->regs =3D syscon_node_to_regmap(dev->of_node); + if (IS_ERR(hdmi->regs)) { + ret =3D PTR_ERR(hdmi->regs); + goto put_device; + } + + remote =3D of_graph_get_remote_node(np, 1, 0); + if (!remote) { + ret =3D -EINVAL; + goto put_device; + } + + if (!of_device_is_compatible(remote, "hdmi-connector")) { + hdmi->next_bridge =3D of_drm_find_bridge(remote); + if (!hdmi->next_bridge) { + dev_err(dev, "Waiting for external bridge\n"); + of_node_put(remote); + ret =3D -EPROBE_DEFER; + goto put_device; + } + } + + i2c_np =3D of_parse_phandle(remote, "ddc-i2c-bus", 0); + if (!i2c_np) { + of_node_put(pdev->dev.of_node); + dev_err(dev, "Failed to find ddc-i2c-bus"); + ret =3D -EINVAL; + goto put_device; + } + + hdmi->ddc_adpt =3D of_find_i2c_adapter_by_node(i2c_np); + of_node_put(i2c_np); + if (!hdmi->ddc_adpt) { + dev_err(dev, "Failed to get ddc i2c adapter by node"); + ret =3D -EPROBE_DEFER; + goto put_device; + } + + return 0; +put_device: + put_device(hdmi->cec_dev); + return ret; +} + +static int mtk_hdmi_register_audio_driver(struct device *dev) +{ + struct platform_device *pdev; + struct mtk_hdmi *hdmi =3D dev_get_drvdata(dev); + struct hdmi_codec_pdata codec_data =3D { + .data =3D hdmi, + }; + + if (hdmi->conf->set_hdmi_codec_pdata) + hdmi->conf->set_hdmi_codec_pdata(&codec_data); + + pdev =3D platform_device_register_data(dev, HDMI_CODEC_DRV_NAME, + PLATFORM_DEVID_AUTO, &codec_data, + sizeof(codec_data)); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME); + return 0; +} + +int mtk_drm_hdmi_probe(struct platform_device *pdev) +{ + struct mtk_hdmi *hdmi; + struct device *dev =3D &pdev->dev; + int ret; + + hdmi =3D devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); + if (!hdmi) + return -ENOMEM; + + hdmi->dev =3D dev; + hdmi->conf =3D of_device_get_match_data(dev); + + hdmi->clk =3D devm_kcalloc(dev, hdmi->conf->num_clocks, sizeof(struct clk= *), + GFP_KERNEL); + + hdmi->phy =3D devm_phy_get(dev, "hdmi"); + if (IS_ERR(hdmi->phy)) { + ret =3D PTR_ERR(hdmi->phy); + dev_err(dev, "Failed to get HDMI PHY: %d\n", ret); + return ret; + } + + ret =3D mtk_hdmi_dt_parse_pdata(hdmi, pdev, hdmi->conf->mtk_hdmi_clock_na= mes, + hdmi->conf->num_clocks); + + if (ret) + return ret; + + platform_set_drvdata(pdev, hdmi); + + if (hdmi->conf->mtk_hdmi_output_init) + hdmi->conf->mtk_hdmi_output_init(hdmi); + + hdmi->bridge.funcs =3D hdmi->conf->bridge_funcs; + + hdmi->bridge.ops =3D DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRID= GE_OP_HPD; + hdmi->bridge.type =3D DRM_MODE_CONNECTOR_HDMIA; + hdmi->bridge.of_node =3D pdev->dev.of_node; + drm_bridge_add(&hdmi->bridge); + + ret =3D mtk_hdmi_register_audio_driver(dev); + + if (ret) + return ret; + + return 0; +} + +int mtk_drm_hdmi_remove(struct platform_device *pdev) +{ + struct mtk_hdmi *hdmi =3D platform_get_drvdata(pdev); + + drm_bridge_remove(&hdmi->bridge); + + if (hdmi->conf->mtk_hdmi_clk_disable) + hdmi->conf->mtk_hdmi_clk_disable(hdmi); + + i2c_put_adapter(hdmi->ddc_adpt); + + return 0; +} + +static const struct mtk_hdmi_conf mtk_hdmi_conf_mt2701 =3D { + .tz_disabled =3D true, + .bridge_funcs =3D &mtk_mt8183_hdmi_bridge_funcs, + .mtk_hdmi_output_init =3D mtk_hdmi_output_init_mt8183, + .mtk_hdmi_clk_disable =3D mtk_hdmi_clk_disable_audio_mt8183, + .mtk_hdmi_clk_enable =3D mtk_hdmi_clk_enable_audio_mt8183, + .set_hdmi_codec_pdata =3D set_hdmi_codec_pdata_mt8183, + .mtk_hdmi_clock_names =3D mtk_hdmi_clk_names_mt8183, + .num_clocks =3D MTK_MT8183_HDMI_CLK_COUNT, +}; + +static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8167 =3D { + .max_mode_clock =3D 148500, + .cea_modes_only =3D true, + .bridge_funcs =3D &mtk_mt8183_hdmi_bridge_funcs, + .mtk_hdmi_output_init =3D mtk_hdmi_output_init_mt8183, + .mtk_hdmi_clk_disable =3D mtk_hdmi_clk_disable_audio_mt8183, + .mtk_hdmi_clk_enable =3D mtk_hdmi_clk_enable_audio_mt8183, + .set_hdmi_codec_pdata =3D set_hdmi_codec_pdata_mt8183, + .mtk_hdmi_clock_names =3D mtk_hdmi_clk_names_mt8183, + .num_clocks =3D MTK_MT8183_HDMI_CLK_COUNT, +}; + +static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8173 =3D { + .bridge_funcs =3D &mtk_mt8183_hdmi_bridge_funcs, + .mtk_hdmi_output_init =3D mtk_hdmi_output_init_mt8183, + .mtk_hdmi_clk_disable =3D mtk_hdmi_clk_disable_audio_mt8183, + .mtk_hdmi_clk_enable =3D mtk_hdmi_clk_enable_audio_mt8183, + .set_hdmi_codec_pdata =3D set_hdmi_codec_pdata_mt8183, + .mtk_hdmi_clock_names =3D mtk_hdmi_clk_names_mt8183, + .num_clocks =3D MTK_MT8183_HDMI_CLK_COUNT, +}; + +static const struct of_device_id mtk_drm_hdmi_of_ids[] =3D { + { .compatible =3D "mediatek,mt2701-hdmi", + .data =3D &mtk_hdmi_conf_mt2701, + }, + { .compatible =3D "mediatek,mt8167-hdmi", + .data =3D &mtk_hdmi_conf_mt8167, + }, + { .compatible =3D "mediatek,mt8173-hdmi", + .data =3D &mtk_hdmi_conf_mt8173, + }, + {} +}; +MODULE_DEVICE_TABLE(of, mtk_drm_hdmi_of_ids); + +#ifdef CONFIG_PM_SLEEP +static __maybe_unused int mtk_hdmi_suspend(struct device *dev) +{ + struct mtk_hdmi *hdmi =3D dev_get_drvdata(dev); + + if (hdmi->conf->mtk_hdmi_clk_disable) + hdmi->conf->mtk_hdmi_clk_disable(hdmi); + + return 0; +} + +static __maybe_unused int mtk_hdmi_resume(struct device *dev) +{ + int ret; + struct mtk_hdmi *hdmi =3D dev_get_drvdata(dev); + + dev_dbg(dev, "hdmi resume success!\n"); + + if (hdmi->conf->mtk_hdmi_clk_enable) { + ret =3D hdmi->conf->mtk_hdmi_clk_enable(hdmi); + if (ret) + dev_err(dev, "hdmi resume failed!\n"); + } + + return ret; +} +#endif + +static SIMPLE_DEV_PM_OPS(mtk_hdmi_pm_ops, + mtk_hdmi_suspend, mtk_hdmi_resume); + +static struct platform_driver mtk_hdmi_driver =3D { + .probe =3D mtk_drm_hdmi_probe, + .remove =3D mtk_drm_hdmi_remove, + .driver =3D { + .name =3D "mediatek-drm-hdmi", + .of_match_table =3D mtk_drm_hdmi_of_ids, + .pm =3D &mtk_hdmi_pm_ops, + }, +}; + +static struct platform_driver * const mtk_hdmi_drivers[] =3D { + &mtk_hdmi_ddc_driver, + &mtk_cec_driver, + &mtk_hdmi_driver, +}; + +static int __init mtk_hdmitx_init(void) +{ + return platform_register_drivers(mtk_hdmi_drivers, + ARRAY_SIZE(mtk_hdmi_drivers)); +} + +static void __exit mtk_hdmitx_exit(void) +{ + platform_unregister_drivers(mtk_hdmi_drivers, + ARRAY_SIZE(mtk_hdmi_drivers)); +} + +module_init(mtk_hdmitx_init); +module_exit(mtk_hdmitx_exit); + +MODULE_AUTHOR("Jie Qiu "); +MODULE_AUTHOR("Can Zeng "); +MODULE_DESCRIPTION("MediaTek HDMI Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h b/drivers/gpu/drm/m= ediatek/mtk_hdmi_common.h new file mode 100644 index 000000000000..7452bea91f9e --- /dev/null +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h @@ -0,0 +1,221 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 MediaTek Inc. + * Copyright (c) 2022 BayLibre, SAS + */ + +#ifndef _MTK_HDMI_COMMON_H +#define _MTK_HDMI_COMMON_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mtk_cec.h" +#include "mtk_hdmi.h" + +struct mtk_hdmi_conf { + bool tz_disabled; + bool cea_modes_only; + unsigned long max_mode_clock; + const struct drm_bridge_funcs *bridge_funcs; + void (*mtk_hdmi_output_init)(struct mtk_hdmi *hdmi); + void (*mtk_hdmi_clk_disable)(struct mtk_hdmi *hdmi); + int (*mtk_hdmi_clk_enable)(struct mtk_hdmi *hdmi); + void (*set_hdmi_codec_pdata)(struct hdmi_codec_pdata *codec_data); + const char *const *mtk_hdmi_clock_names; + int num_clocks; +}; + +enum hdmi_color_depth { HDMI_8_BIT, HDMI_10_BIT, HDMI_12_BIT, HDMI_16_BIT = }; + +enum hdmi_aud_input_type { + HDMI_AUD_INPUT_I2S =3D 0, + HDMI_AUD_INPUT_SPDIF, +}; + +enum hdmi_aud_i2s_fmt { + HDMI_I2S_MODE_RJT_24BIT =3D 0, + HDMI_I2S_MODE_RJT_16BIT, + HDMI_I2S_MODE_LJT_24BIT, + HDMI_I2S_MODE_LJT_16BIT, + HDMI_I2S_MODE_I2S_24BIT, + HDMI_I2S_MODE_I2S_16BIT +}; + +enum hdmi_aud_mclk { + HDMI_AUD_MCLK_128FS, + HDMI_AUD_MCLK_192FS, + HDMI_AUD_MCLK_256FS, + HDMI_AUD_MCLK_384FS, + HDMI_AUD_MCLK_512FS, + HDMI_AUD_MCLK_768FS, + HDMI_AUD_MCLK_1152FS, +}; + +enum hdmi_aud_channel_type { + HDMI_AUD_CHAN_TYPE_1_0 =3D 0, + HDMI_AUD_CHAN_TYPE_1_1, + HDMI_AUD_CHAN_TYPE_2_0, + HDMI_AUD_CHAN_TYPE_2_1, + HDMI_AUD_CHAN_TYPE_3_0, + HDMI_AUD_CHAN_TYPE_3_1, + HDMI_AUD_CHAN_TYPE_4_0, + HDMI_AUD_CHAN_TYPE_4_1, + HDMI_AUD_CHAN_TYPE_5_0, + HDMI_AUD_CHAN_TYPE_5_1, + HDMI_AUD_CHAN_TYPE_6_0, + HDMI_AUD_CHAN_TYPE_6_1, + HDMI_AUD_CHAN_TYPE_7_0, + HDMI_AUD_CHAN_TYPE_7_1, + HDMI_AUD_CHAN_TYPE_3_0_LRS, + HDMI_AUD_CHAN_TYPE_3_1_LRS, + HDMI_AUD_CHAN_TYPE_4_0_CLRS, + HDMI_AUD_CHAN_TYPE_4_1_CLRS, + HDMI_AUD_CHAN_TYPE_6_1_CS, + HDMI_AUD_CHAN_TYPE_6_1_CH, + HDMI_AUD_CHAN_TYPE_6_1_OH, + HDMI_AUD_CHAN_TYPE_6_1_CHR, + HDMI_AUD_CHAN_TYPE_7_1_LH_RH, + HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR, + HDMI_AUD_CHAN_TYPE_7_1_LC_RC, + HDMI_AUD_CHAN_TYPE_7_1_LW_RW, + HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD, + HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS, + HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS, + HDMI_AUD_CHAN_TYPE_7_1_CS_CH, + HDMI_AUD_CHAN_TYPE_7_1_CS_OH, + HDMI_AUD_CHAN_TYPE_7_1_CS_CHR, + HDMI_AUD_CHAN_TYPE_7_1_CH_OH, + HDMI_AUD_CHAN_TYPE_7_1_CH_CHR, + HDMI_AUD_CHAN_TYPE_7_1_OH_CHR, + HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR, + HDMI_AUD_CHAN_TYPE_6_0_CS, + HDMI_AUD_CHAN_TYPE_6_0_CH, + HDMI_AUD_CHAN_TYPE_6_0_OH, + HDMI_AUD_CHAN_TYPE_6_0_CHR, + HDMI_AUD_CHAN_TYPE_7_0_LH_RH, + HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR, + HDMI_AUD_CHAN_TYPE_7_0_LC_RC, + HDMI_AUD_CHAN_TYPE_7_0_LW_RW, + HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD, + HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS, + HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS, + HDMI_AUD_CHAN_TYPE_7_0_CS_CH, + HDMI_AUD_CHAN_TYPE_7_0_CS_OH, + HDMI_AUD_CHAN_TYPE_7_0_CS_CHR, + HDMI_AUD_CHAN_TYPE_7_0_CH_OH, + HDMI_AUD_CHAN_TYPE_7_0_CH_CHR, + HDMI_AUD_CHAN_TYPE_7_0_OH_CHR, + HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR, + HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS, + HDMI_AUD_CHAN_TYPE_UNKNOWN =3D 0xFF +}; + +enum hdmi_aud_channel_swap_type { + HDMI_AUD_SWAP_LR, + HDMI_AUD_SWAP_LFE_CC, + HDMI_AUD_SWAP_LSRS, + HDMI_AUD_SWAP_RLS_RRS, + HDMI_AUD_SWAP_LR_STATUS, +}; + +enum hdmi_hpd_state { + HDMI_PLUG_OUT =3D 0, + HDMI_PLUG_IN_AND_SINK_POWER_ON, + HDMI_PLUG_IN_ONLY, +}; + +struct hdmi_audio_param { + enum hdmi_audio_coding_type aud_codec; + enum hdmi_audio_sample_size aud_sampe_size; + enum hdmi_aud_input_type aud_input_type; + enum hdmi_aud_i2s_fmt aud_i2s_fmt; + enum hdmi_aud_mclk aud_mclk; + enum hdmi_aud_channel_type aud_input_chan_type; + struct hdmi_codec_params codec_params; +}; + +struct mtk_hdmi { + struct drm_bridge bridge; + struct drm_connector conn; + struct device *dev; + const struct mtk_hdmi_conf *conf; + struct phy *phy; + struct i2c_adapter *ddc_adpt; + struct clk **clk; + struct drm_display_mode mode; + bool dvi_mode; + struct regmap *sys_regmap; + unsigned int sys_offset; + struct regmap *regs; + u64 support_csp_depth; + u64 set_csp_depth; + enum hdmi_colorspace csp; + enum hdmi_color_depth color_depth; + enum hdmi_colorimetry colorimtery; + enum hdmi_extended_colorimetry extended_colorimetry; + enum hdmi_quantization_range quantization_range; + enum hdmi_ycc_quantization_range ycc_quantization_range; + + bool powered; + bool enabled; + unsigned int hdmi_irq; + enum hdmi_hpd_state hpd; + + bool hdmi_enabled; + bool power_clk_enabled; + bool irq_registered; + + /* Audio */ + struct hdmi_audio_param aud_param; + bool audio_enable; + + struct drm_connector *curr_conn;/* current connector (only valid when 'en= abled') */ + struct mutex update_plugged_status_lock; + struct device *cec_dev; + struct device *codec_dev; + hdmi_codec_plugged_cb plugged_cb; + struct drm_bridge *next_bridge; +}; + +struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b); +int mtk_hdmi_read(struct mtk_hdmi *hdmi, u32 offset, u32 *val); +void mtk_hdmi_write(struct mtk_hdmi *hdmi, u32 offset, u32 val); +void mtk_hdmi_clear_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits); +void mtk_hdmi_set_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits); +void mtk_hdmi_mask(struct mtk_hdmi *hdmi, u32 offset, u32 val, u32 mask); +int mtk_hdmi_setup_spd_infoframe(struct mtk_hdmi *hdmi, u8 *buffer, size_t= bufsz, + const char *vendor, const char *product); +void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi, u8 *buffer_spd, size_t= bufsz_spd, + u8 *buffer_avi, size_t bufsz_avi, struct drm_display_mode *mode); +int mtk_hdmi_get_all_clk(struct mtk_hdmi *hdmi, struct device_node *np, + const char *const *clk_names, size_t num_clocks); +struct edid *mtk_hdmi_bridge_get_edid(struct drm_bridge *bridge, + struct drm_connector *connector); +bool mtk_hdmi_bridge_mode_fixup(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); +void mtk_hdmi_bridge_mode_set(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + const struct drm_display_mode *adjusted_mode); +int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, + struct platform_device *pdev, const char *const *clk_names, size_t = num_clocks); +int mtk_drm_hdmi_probe(struct platform_device *pdev); +int mtk_drm_hdmi_remove(struct platform_device *pdev); + +#endif //_MTK_HDMI_COMMON_H --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2ADC9ECAAA1 for ; Mon, 19 Sep 2022 17:00:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230292AbiISRAp (ORCPT ); Mon, 19 Sep 2022 13:00:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44704 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230370AbiISRAM (ORCPT ); Mon, 19 Sep 2022 13:00:12 -0400 Received: from mail-ej1-x62f.google.com (mail-ej1-x62f.google.com [IPv6:2a00:1450:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CBEB333A3D for ; Mon, 19 Sep 2022 10:00:01 -0700 (PDT) Received: by mail-ej1-x62f.google.com with SMTP id 13so156672ejn.3 for ; Mon, 19 Sep 2022 10:00:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=HLkgjmfUQZXrBufYXmW5V+FjpCBTnrnJRl8bPfgjGi0=; b=iCp4PRqRut8ldEn6iFDY5780nxcwQxypuEqbmfTvfX+LeaUV0TBlilns6GCWIlnwrq CiunYZfYC1IndkJR3gnSQ4FcJF4TiUnJYlWWbk6h+p035qcTxa1oHPK+O+pAuXcCXMw1 LMpjCRzZR/vSqVIB7Ng/g+wzpRJhyDQ1tAyyRG6ag7jXkiGaWcAQBDPrZHK6tIPuir3i FJelQbDn/dhuzkO0e0r6jNWMX2zLGGvK8DS59YGysg/RVD7XXX6JNM7WRoaEE5ppbj+r FD+ecJG4zoLcLkbU/ZVidIhIdeppq99UGS7J0oDwTXyZQkt5err89RZjpn5BCdJ5atTZ F5jQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=HLkgjmfUQZXrBufYXmW5V+FjpCBTnrnJRl8bPfgjGi0=; b=u84P0iPBOUtucnxhlMulYGq5GpEqWMyPS7GasMnfCUhQo4B+Dmsxc21ncdEJ2pgHWn fVmYJeUkoPEQ/UwyZwHFr7obvgZzRYUT/e58NmD4Pm0mxMPc4z7u9wSvbil8p2Kx2Yr4 SXh/Ll/ICwmb/ENhaCEz4nx+tbZlR1yjV4L5Sw5xBDWCALQFxsDxSGG82bK58IHyBKMW eYSGri699j1/RwG0lJT/e7PiuRs2BJo4cqrqndcyUYmL9+rVIPVdyjrfQAsUkO7Y5pii kRWsUB4IURkx73mFMBmsmhs1NtXZid2xJRvk87cqhxRDtuHcvnq/lS5seWCk90TTbUDV 0SSQ== X-Gm-Message-State: ACrzQf2cvgXfuT68iKCwpooxiH522JYXv/m9wfrvnSiKpquQUo6cwj1b w/PeFLa6MyDbOHcEI3yTPI1VzQ== X-Google-Smtp-Source: AMsMyM68qjQqULpZ/BI4lE6+kDmd0BZAyqrmHiJF5y5T8zzA2DF8Y6DbzBptf6WxEg9nnyn2opsPwQ== X-Received: by 2002:a17:907:7b93:b0:770:1d4f:4de9 with SMTP id ne19-20020a1709077b9300b007701d4f4de9mr13596890ejc.201.1663606799750; Mon, 19 Sep 2022 09:59:59 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.09.59.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 09:59:59 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:06 +0200 Subject: [PATCH v1 08/17] drm/mediatek: hdmi: add cec flag MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-8-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add a flag to indicate support for cec. Signed-off-by: Guillaume Ranquet diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/m= ediatek/mtk_hdmi_common.c index bfcca6f8b839..86653ebaacfd 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c @@ -154,35 +154,38 @@ int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, st= ruct platform_device *pdev, return ret; } =20 - /* The CEC module handles HDMI hotplug detection */ - cec_np =3D of_get_compatible_child(np->parent, "mediatek,mt8173-cec"); - if (!cec_np) { - dev_err(dev, "Failed to find CEC node\n"); - return -EINVAL; - } + if (hdmi->conf->has_cec) { + /* The CEC module handles HDMI hotplug detection */ + cec_np =3D of_get_compatible_child(np->parent, "mediatek,mt8173-cec"); + if (!cec_np) { + dev_err(dev, "Failed to find CEC node\n"); + return -EINVAL; + } =20 - cec_pdev =3D of_find_device_by_node(cec_np); - if (!cec_pdev) { - dev_err(hdmi->dev, "Waiting for CEC device %pOF\n", cec_np); + cec_pdev =3D of_find_device_by_node(cec_np); + if (!cec_pdev) { + dev_err(hdmi->dev, "Waiting for CEC device %pOF\n", cec_np); + of_node_put(cec_np); + return -EPROBE_DEFER; + } of_node_put(cec_np); - return -EPROBE_DEFER; - } - of_node_put(cec_np); - hdmi->cec_dev =3D &cec_pdev->dev; - /* - * The mediatek,syscon-hdmi property contains a phandle link to the - * MMSYS_CONFIG device and the register offset of the HDMI_SYS_CFG - * registers it contains. - */ - regmap =3D syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi"); - ret =3D of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1, &hdmi->= sys_offset); - if (IS_ERR(regmap)) - ret =3D PTR_ERR(regmap); - if (ret) { - dev_err(dev, "Failed to get system configuration registers: %d\n", ret); - goto put_device; + hdmi->cec_dev =3D &cec_pdev->dev; + /* + * The mediatek,syscon-hdmi property contains a phandle link to the + * MMSYS_CONFIG device and the register offset of the HDMI_SYS_CFG + * registers it contains. + */ + regmap =3D syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi"); + ret =3D of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1, &hdmi-= >sys_offset); + if (IS_ERR(regmap)) + ret =3D PTR_ERR(regmap); + if (ret) { + dev_err(dev, + "Failed to get system configuration registers: %d\n", ret); + goto put_device; + } + hdmi->sys_regmap =3D regmap; } - hdmi->sys_regmap =3D regmap; =20 mem =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { @@ -230,7 +233,8 @@ int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, stru= ct platform_device *pdev, =20 return 0; put_device: - put_device(hdmi->cec_dev); + if (hdmi->conf->has_cec) + put_device(hdmi->cec_dev); return ret; } =20 @@ -320,6 +324,7 @@ int mtk_drm_hdmi_remove(struct platform_device *pdev) =20 static const struct mtk_hdmi_conf mtk_hdmi_conf_mt2701 =3D { .tz_disabled =3D true, + .has_cec =3D true, .bridge_funcs =3D &mtk_mt8183_hdmi_bridge_funcs, .mtk_hdmi_output_init =3D mtk_hdmi_output_init_mt8183, .mtk_hdmi_clk_disable =3D mtk_hdmi_clk_disable_audio_mt8183, @@ -332,6 +337,7 @@ static const struct mtk_hdmi_conf mtk_hdmi_conf_mt2701 = =3D { static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8167 =3D { .max_mode_clock =3D 148500, .cea_modes_only =3D true, + .has_cec =3D true, .bridge_funcs =3D &mtk_mt8183_hdmi_bridge_funcs, .mtk_hdmi_output_init =3D mtk_hdmi_output_init_mt8183, .mtk_hdmi_clk_disable =3D mtk_hdmi_clk_disable_audio_mt8183, diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h b/drivers/gpu/drm/m= ediatek/mtk_hdmi_common.h index 7452bea91f9e..921bde150e11 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h @@ -31,6 +31,7 @@ struct mtk_hdmi_conf { bool tz_disabled; bool cea_modes_only; + bool has_cec; unsigned long max_mode_clock; const struct drm_bridge_funcs *bridge_funcs; void (*mtk_hdmi_output_init)(struct mtk_hdmi *hdmi); --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A55B7C6FA91 for ; Mon, 19 Sep 2022 17:01:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230378AbiISRBB (ORCPT ); Mon, 19 Sep 2022 13:01:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44754 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230456AbiISRAl (ORCPT ); Mon, 19 Sep 2022 13:00:41 -0400 Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com [IPv6:2a00:1450:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A2B78371AC for ; Mon, 19 Sep 2022 10:00:04 -0700 (PDT) Received: by mail-ej1-x629.google.com with SMTP id 13so156979ejn.3 for ; Mon, 19 Sep 2022 10:00:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=g8hZh96h7kcVe0FwyV/2fd9otBYm0/NItAoi3rrV5Yw=; b=xLxEGxkLE9ts8PrWjFZFQCdOiglt2QkS+aUCn873bVHln5LsU0bvqAVn5LFP05/Yyr Q3qRpEst57E9SGRzI8qpwLl2n81lnV7mXZ8ciDQ4f+3wWKaYsFb2M2yp0JVu14Rkzx4t imIkYqSNoVVEaxFbAdujyag9f5p4E4p5mOkIQP3u5LxjGS3mUDhFyoxzELq+k/uubc9L MZrTbOobCprscw8nBrp+kaWxRcV20dNkKLyny7J28BijqGfXNFdD0jNIoHenj01MLEvJ CyJJL8ZP5n7MOZGHu2N9lqRQedIinPzfrVndKqNhcJdYpXLaOzgQFoR/WoFNLT2htXpU HC6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=g8hZh96h7kcVe0FwyV/2fd9otBYm0/NItAoi3rrV5Yw=; b=A5n2be5WVvo7/UT8/6wSd4Wrr73OlnwJa3T/3aa6AZS1KjbPtUjmsKkM2RUVX/7Dnh ee8ti5hPCAHKdeTPZNiXDxjVsGH8yQ2AZ6Uvg6/W1OCEJ/WBkV2JPur6UNVjNSF70MXk CQTPy0d9di6oLbX0w/rYt6PxUAMUPw0XKE0bGJhPTc5rJhxYZRpVUpcLxXNrpLa5kUy0 KIeS87JrI/VbuTdkQQJawsEaj5vsenCOKJcydmzrBvRV+JAXo8AU+tiU5w7d8GAVA9pw SNcOR69fkhf9i1RXalLm3wBGMrPJmEwYS6D0fj1TFKzsFteOCJP9dopt11IUBwY+L6Nv QQIA== X-Gm-Message-State: ACrzQf1doOwr1YiUTQj8P9axCparyI1uMhmIxH04HMKrR23HUoQs9sOv qc4+4O4+j9CJaotAWvSMTSljEQ== X-Google-Smtp-Source: AMsMyM4DJI7JfhQLtMN2LYTOhc8B3W1+i58GmxhTOF/MVrCsnqMqyiepx3Iq5rhTvArkC9ga2QF9Xg== X-Received: by 2002:a17:907:1ded:b0:76f:af8f:942e with SMTP id og45-20020a1709071ded00b0076faf8f942emr13451537ejc.120.1663606802567; Mon, 19 Sep 2022 10:00:02 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.09.59.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 10:00:01 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:07 +0200 Subject: [PATCH v1 09/17] drm/mediatek: hdmi: add connector flag MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-9-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add a flag to indicate support for an external connector Signed-off-by: Guillaume Ranquet diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/m= ediatek/mtk_hdmi_common.c index 86653ebaacfd..30407603d693 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c @@ -199,20 +199,22 @@ int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, st= ruct platform_device *pdev, goto put_device; } =20 - remote =3D of_graph_get_remote_node(np, 1, 0); - if (!remote) { - ret =3D -EINVAL; - goto put_device; - } - - if (!of_device_is_compatible(remote, "hdmi-connector")) { - hdmi->next_bridge =3D of_drm_find_bridge(remote); - if (!hdmi->next_bridge) { - dev_err(dev, "Waiting for external bridge\n"); - of_node_put(remote); - ret =3D -EPROBE_DEFER; + if (hdmi->conf->has_connector) { + remote =3D of_graph_get_remote_node(np, 1, 0); + if (!remote) { + ret =3D -EINVAL; goto put_device; } + + if (!of_device_is_compatible(remote, "hdmi-connector")) { + hdmi->next_bridge =3D of_drm_find_bridge(remote); + if (!hdmi->next_bridge) { + dev_err(dev, "Waiting for external bridge\n"); + of_node_put(remote); + ret =3D -EPROBE_DEFER; + goto put_device; + } + } } =20 i2c_np =3D of_parse_phandle(remote, "ddc-i2c-bus", 0); @@ -325,6 +327,7 @@ int mtk_drm_hdmi_remove(struct platform_device *pdev) static const struct mtk_hdmi_conf mtk_hdmi_conf_mt2701 =3D { .tz_disabled =3D true, .has_cec =3D true, + .has_connector =3D true, .bridge_funcs =3D &mtk_mt8183_hdmi_bridge_funcs, .mtk_hdmi_output_init =3D mtk_hdmi_output_init_mt8183, .mtk_hdmi_clk_disable =3D mtk_hdmi_clk_disable_audio_mt8183, @@ -338,6 +341,7 @@ static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8167 = =3D { .max_mode_clock =3D 148500, .cea_modes_only =3D true, .has_cec =3D true, + .has_connector =3D true, .bridge_funcs =3D &mtk_mt8183_hdmi_bridge_funcs, .mtk_hdmi_output_init =3D mtk_hdmi_output_init_mt8183, .mtk_hdmi_clk_disable =3D mtk_hdmi_clk_disable_audio_mt8183, diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h b/drivers/gpu/drm/m= ediatek/mtk_hdmi_common.h index 921bde150e11..62a14435be69 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h @@ -32,6 +32,7 @@ struct mtk_hdmi_conf { bool tz_disabled; bool cea_modes_only; bool has_cec; + bool has_connector; unsigned long max_mode_clock; const struct drm_bridge_funcs *bridge_funcs; void (*mtk_hdmi_output_init)(struct mtk_hdmi *hdmi); --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 66E57ECAAA1 for ; Mon, 19 Sep 2022 17:01:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230495AbiISRA5 (ORCPT ); Mon, 19 Sep 2022 13:00:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44664 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230258AbiISRA1 (ORCPT ); Mon, 19 Sep 2022 13:00:27 -0400 Received: from mail-ej1-x634.google.com (mail-ej1-x634.google.com [IPv6:2a00:1450:4864:20::634]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 276F13D58C for ; Mon, 19 Sep 2022 10:00:06 -0700 (PDT) Received: by mail-ej1-x634.google.com with SMTP id r18so52561eja.11 for ; Mon, 19 Sep 2022 10:00:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=7ewVwlqmSZNgETsEvZqoFNhQps11G0ZAn5b60e+kwmE=; b=ltJHkE9qpYoLEDSN5DAx3cZgruYpelRbpwQcuaGdFUMLM3WJOSSnmHPjq0mpUqr1/z gQmz4aIu1+C2XCgAurWgLJcYErvdR4pZCHRjigSIHMdLj1hHPhb1eZ0uKCN3yalxK9qu GQSLKUQSOH+ZG7+yYGBOCRSOxQjRklDOiAYlzLZkIXtvsZWEgeOzyAm7yN5N0KoblI5a Chf8ShDsXCqZKzCoTAj9MlcgaigL68bvRigo9a2jipo46Rdg4R3ClF/1eroZSV1j3O6z CgcSBUC0Z9qbQQR/6dtC3LdupnvTBwtPW3JXZNgAEGC0PifQtmrhh69LHGp9uY59knMO qdZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=7ewVwlqmSZNgETsEvZqoFNhQps11G0ZAn5b60e+kwmE=; b=ir+YLnp8KfG06hYvXyQbOcf5uYE9udxaGl6u213Exca44joQ3r1SmijK4RVcHK8Jom rfCuqFmJQSholha6aDeJIKhmQlwvVjz9zQiZGZG/1b0ukmmafYiKgdIHvYN9RWH6Y7FA VKIKq/0pvRKGN7lZsxbFUqeONvMXwP2ZYoGJuyk+OdXd9cvAQxcGt/2TCb5RkEZ4AT5N V+XYwvrf/CfVFTurN2fqid7EkBXTrNOidu9Qhq4eMCDiazRTJvrEYvP3C1BnhdvxVA/s hJijy0ofkN5scovbW79DRj8As8nQUFAoeNwc3RyxZihWP5aSBVkjUpbkx1A785CoVsft 0Tsw== X-Gm-Message-State: ACrzQf361QDCRhcCi11cMDef2eEprsVTnJZsvJ81kSx42xvQ8qDMeyC9 FuFMiAgw5KsXNZbPzUveUK1dyA== X-Google-Smtp-Source: AMsMyM67IRRVMY+Suw0izTU3sRzUSrYIHC8PsOPjPY/v4kIJUR1V+xpsamXrdF60dn5nXvO6vgqnpA== X-Received: by 2002:a17:907:72d5:b0:77d:5d01:4f4f with SMTP id du21-20020a17090772d500b0077d5d014f4fmr13945767ejc.285.1663606804603; Mon, 19 Sep 2022 10:00:04 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.10.00.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 10:00:04 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:08 +0200 Subject: [PATCH v1 10/17] drm/mediatek: hdmi: add frame_colorimetry flag MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-10-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add a flag to indicate support for frame colorimetry. Signed-off-by: Guillaume Ranquet diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/m= ediatek/mtk_hdmi_common.c index 30407603d693..9fe086e2cd7c 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c @@ -120,6 +120,17 @@ int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi= , u8 *buffer, size_t bufsz return err; } =20 + if (hdmi->conf->has_frame_colorimetry) { + frame.colorimetry =3D hdmi->colorimtery; + if (frame.colorimetry =3D=3D HDMI_COLORIMETRY_EXTENDED) + frame.extended_colorimetry =3D hdmi->extended_colorimetry; + + /* quantiation range:limited or full */ + if (frame.colorspace =3D=3D HDMI_COLORSPACE_RGB) + frame.quantization_range =3D hdmi->quantization_range; + else + frame.ycc_quantization_range =3D hdmi->ycc_quantization_range; + } err =3D hdmi_avi_infoframe_pack(&frame, buffer, bufsz); =20 if (err < 0) { diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h b/drivers/gpu/drm/m= ediatek/mtk_hdmi_common.h index 62a14435be69..75a9b62dccee 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h @@ -33,6 +33,7 @@ struct mtk_hdmi_conf { bool cea_modes_only; bool has_cec; bool has_connector; + bool has_frame_colorimetry; unsigned long max_mode_clock; const struct drm_bridge_funcs *bridge_funcs; void (*mtk_hdmi_output_init)(struct mtk_hdmi *hdmi); --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29638ECAAD3 for ; Mon, 19 Sep 2022 17:01:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230523AbiISRBP (ORCPT ); Mon, 19 Sep 2022 13:01:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44802 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230465AbiISRAn (ORCPT ); Mon, 19 Sep 2022 13:00:43 -0400 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 96CDB3DBF8 for ; Mon, 19 Sep 2022 10:00:10 -0700 (PDT) Received: by mail-ej1-x631.google.com with SMTP id r18so53100eja.11 for ; Mon, 19 Sep 2022 10:00:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=L8k9UV7FGU5BrNNCawy5rQEU61bvky5QP6A4hYtAEjc=; b=ygPhEfyPj2sSwF4DlqCIF4IFJYfssL9pjiFAw7xZhIHOr+Q3ho/DQ5j9/clgSaYMO8 guUXmc2g7bai5XyICb2elEMtBVYd6WRjCdJ1x5exDxku7Y7UMfnT5SfDnT3TTSi9Pj2b wSfCxW/1xke3iXKmMZIgk0xBsFH4Cq+IbuzR5YAIF8h2Jo+7KwsJ1Ov4AdorOogO3Y4r b0jh7WzktQ3nPLtAa3FNX4mOxxF+MWP5tyam5cBYy4h09CRdiopjMYD41UUhH2pD8YEd SdTVa/kO2Pm2dkdXU7uMm24vlNvPmBuy5NCXB8wR5ah98dfN+ADdZPWU3JA6sUXtjhRo Ogaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=L8k9UV7FGU5BrNNCawy5rQEU61bvky5QP6A4hYtAEjc=; b=fO26Lvfi5O6f/prd689rnbXHfEW3QHoYN0kcd1pEYyZpS/z64bOfsRmSCmo4Cr36h9 1kvaixYlLcCD2uuPnS+t19WKYwaCG7Ho+DjKrCQVNRuu2QE7MAx+EuZcFQJ/jO/UyZVW +xs2OYWMRu8sj+KkSiqnlXYVmN0DzHsSv3uO7DaXxOVYTHY9y5dvuUHNAPJBzJYRXc2G /V6S8qfHJ92ZJax1nl09P6RDmzOGfYYReNAoFJFCGHwDyUHki6X5DlRA1hwBWFG7uOug fSrEs/LdTyhEb8T+QeCoRs07F6RZ5My8nHTkfekwySuXuomoCJS09IlhJjqvzkAavDLa 7b7g== X-Gm-Message-State: ACrzQf26vtp2lumucfPWQ18OUF1mqcX9iCxSbjgYAGsmm4BPzCs9LW4t +rJZvTrwE8zQUGgktkJLH9KFZg== X-Google-Smtp-Source: AMsMyM4kSI9msnEhGRxo9MiqPrU2GU82X68pWSFTuliXpy3qPt8qwS7qd8Q3jfmgwrLbbcKmdkk6wg== X-Received: by 2002:a17:906:6a0f:b0:779:2fc:9a51 with SMTP id qw15-20020a1709066a0f00b0077902fc9a51mr13764982ejc.101.1663606808300; Mon, 19 Sep 2022 10:00:08 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.10.00.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 10:00:07 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:09 +0200 Subject: [PATCH v1 11/17] drm/mediatek: hdmi: add mt8195 support MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-11-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Adds hdmi and hdmi-ddc support for mt8195. Signed-off-by: Guillaume Ranquet diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/M= akefile index 008ec69da67b..f1ef6c8ae2b8 100644 --- a/drivers/gpu/drm/mediatek/Makefile +++ b/drivers/gpu/drm/mediatek/Makefile @@ -24,6 +24,8 @@ mediatek-drm-hdmi-objs :=3D mtk_cec.o \ mtk_hdmi.o \ mtk_hdmi_ddc.o \ mtk_hdmi_common.o \ + mtk_mt8195_hdmi.o \ + mtk_mt8195_hdmi_ddc.o \ =20 obj-$(CONFIG_DRM_MEDIATEK_HDMI) +=3D mediatek-drm-hdmi.o =20 diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/m= ediatek/mtk_hdmi_common.c index 9fe086e2cd7c..f6bfe6c1c0be 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c @@ -226,14 +226,22 @@ int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, st= ruct platform_device *pdev, goto put_device; } } - } =20 - i2c_np =3D of_parse_phandle(remote, "ddc-i2c-bus", 0); - if (!i2c_np) { - of_node_put(pdev->dev.of_node); - dev_err(dev, "Failed to find ddc-i2c-bus"); - ret =3D -EINVAL; - goto put_device; + i2c_np =3D of_parse_phandle(remote, "ddc-i2c-bus", 0); + if (!i2c_np) { + of_node_put(pdev->dev.of_node); + dev_err(dev, "Failed to find ddc-i2c-bus"); + ret =3D -EINVAL; + goto put_device; + } + } else { + i2c_np =3D of_parse_phandle(pdev->dev.of_node, "ddc-i2c-bus", 0); + if (!i2c_np) { + of_node_put(pdev->dev.of_node); + dev_err(dev, "Failed to find ddc-i2c-bus"); + ret =3D -EINVAL; + goto put_device; + } } =20 hdmi->ddc_adpt =3D of_find_i2c_adapter_by_node(i2c_np); @@ -372,6 +380,17 @@ static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8173= =3D { .num_clocks =3D MTK_MT8183_HDMI_CLK_COUNT, }; =20 +static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8195 =3D { + .has_frame_colorimetry =3D true, + .bridge_funcs =3D &mtk_mt8195_hdmi_bridge_funcs, + .mtk_hdmi_output_init =3D mtk_hdmi_output_init_mt8195, + .mtk_hdmi_clk_disable =3D mtk_hdmi_clk_disable_mt8195, + .mtk_hdmi_clk_enable =3D mtk_hdmi_clk_enable_mt8195, + .set_hdmi_codec_pdata =3D set_hdmi_codec_pdata_mt8195, + .mtk_hdmi_clock_names =3D mtk_hdmi_clk_names_mt8195, + .num_clocks =3D MTK_MT8195_HDMI_CLK_COUNT, +}; + static const struct of_device_id mtk_drm_hdmi_of_ids[] =3D { { .compatible =3D "mediatek,mt2701-hdmi", .data =3D &mtk_hdmi_conf_mt2701, @@ -382,6 +401,9 @@ static const struct of_device_id mtk_drm_hdmi_of_ids[] = =3D { { .compatible =3D "mediatek,mt8173-hdmi", .data =3D &mtk_hdmi_conf_mt8173, }, + { .compatible =3D "mediatek,mt8195-hdmi", + .data =3D &mtk_hdmi_conf_mt8195, + }, {} }; MODULE_DEVICE_TABLE(of, mtk_drm_hdmi_of_ids); @@ -430,6 +452,7 @@ static struct platform_driver mtk_hdmi_driver =3D { static struct platform_driver * const mtk_hdmi_drivers[] =3D { &mtk_hdmi_ddc_driver, &mtk_cec_driver, + &mtk_hdmi_mt8195_ddc_driver, &mtk_hdmi_driver, }; =20 diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h b/drivers/gpu/drm/m= ediatek/mtk_hdmi_common.h index 75a9b62dccee..737306611fb9 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h @@ -27,6 +27,7 @@ =20 #include "mtk_cec.h" #include "mtk_hdmi.h" +#include "mtk_mt8195_hdmi.h" =20 struct mtk_hdmi_conf { bool tz_disabled; diff --git a/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c b/drivers/gpu/drm/m= ediatek/mtk_mt8195_hdmi.c new file mode 100644 index 000000000000..39e07a6dd490 --- /dev/null +++ b/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c @@ -0,0 +1,1387 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Copyright (c) 2022 BayLibre, SAS + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "mtk_drm_crtc.h" +#include "mtk_hdmi_common.h" +#include "mtk_mt8195_hdmi.h" +#include "mtk_mt8195_hdmi_regs.h" + +#define RGB444_8bit BIT(0) +#define RGB444_10bit BIT(1) +#define RGB444_12bit BIT(2) +#define RGB444_16bit BIT(3) + +#define YCBCR444_8bit BIT(4) +#define YCBCR444_10bit BIT(5) +#define YCBCR444_12bit BIT(6) +#define YCBCR444_16bit BIT(7) + +#define YCBCR422_8bit_NO_SUPPORT BIT(8) +#define YCBCR422_10bit_NO_SUPPORT BIT(9) +#define YCBCR422_12bit BIT(10) +#define YCBCR422_16bit_NO_SUPPORT BIT(11) + +#define YCBCR420_8bit BIT(12) +#define YCBCR420_10bit BIT(13) +#define YCBCR420_12bit BIT(14) +#define YCBCR420_16bit BIT(15) + +#define BYTES_TO_UINT32(msb, b1, b2, lsb) = \ + ((((msb) & 0xff) << 24) + (((b1) & 0xff) << 16) + (((b2) & 0xff) << 8) + = \ + (((lsb) & 0xff))) + +const char *const mtk_hdmi_clk_names_mt8195[MTK_MT8195_HDMI_CLK_COUNT] =3D= { + [MTK_MT8195_HDIM_HDCP_SEL] =3D "hdcp_sel", + [MTK_MT8195_HDMI_HDCP_24M_SEL] =3D "hdcp24_sel", + [MTK_MT8195_HDMI_VPP_SPLIT_HDMI] =3D "split_hdmi", +}; + +static inline struct mtk_hdmi *hdmi_ctx_from_conn(struct drm_connector *c) +{ + return container_of(c, struct mtk_hdmi, conn); +} + +static inline void mtk_hdmi_clr_all_int_status(struct mtk_hdmi *hdmi) +{ + /*clear all tx irq*/ + mtk_hdmi_write(hdmi, TOP_INT_CLR00, 0xffffffff); + mtk_hdmi_write(hdmi, TOP_INT_CLR00, 0x00000000); + mtk_hdmi_write(hdmi, TOP_INT_CLR01, 0xffffffff); + mtk_hdmi_write(hdmi, TOP_INT_CLR01, 0x00000000); +} + +static inline void mtk_hdmi_disable_all_int(struct mtk_hdmi *hdmi) +{ + /*disable all tx irq*/ + mtk_hdmi_write(hdmi, TOP_INT_MASK00, 0x00000000); + mtk_hdmi_write(hdmi, TOP_INT_MASK01, 0x00000000); +} + +static inline void mtk_hdmi_en_hdcp_reauth_int(struct mtk_hdmi *hdmi, + bool enable) +{ + if (enable) + mtk_hdmi_mask(hdmi, TOP_INT_MASK00, + HDCP2X_RX_REAUTH_REQ_DDCM_INT_UNMASK, + HDCP2X_RX_REAUTH_REQ_DDCM_INT_UNMASK); + else + mtk_hdmi_mask(hdmi, TOP_INT_MASK00, + HDCP2X_RX_REAUTH_REQ_DDCM_INT_MASK, + HDCP2X_RX_REAUTH_REQ_DDCM_INT_UNMASK); +} + +static inline void mtk_hdmi_enable_hpd_pord_irq(struct mtk_hdmi *hdmi, + bool enable) +{ + if (enable) + mtk_hdmi_mask(hdmi, TOP_INT_MASK00, 0x0000000f, 0x0000000f); + else + mtk_hdmi_mask(hdmi, TOP_INT_MASK00, 0x00000000, 0x0000000f); +} + +static inline void mtk_hdmi_clr_htplg_pord_irq(struct mtk_hdmi *hdmi) +{ + mtk_hdmi_mask(hdmi, TOP_INT_CLR00, 0x0000000f, 0x0000000f); + mtk_hdmi_mask(hdmi, TOP_INT_CLR00, 0x00000000, 0x0000000f); +} + +static inline void mtk_hdmi_set_sw_hpd(struct mtk_hdmi *hdmi, bool high) +{ + if (high) + mtk_hdmi_mask(hdmi, HDMITX_CONFIG, 0x1 << HDMITX_SW_HPD_SHIFT, + HDMITX_SW_HPD); + else + mtk_hdmi_mask(hdmi, HDMITX_CONFIG, 0x0 << HDMITX_SW_HPD_SHIFT, + HDMITX_SW_HPD); +} + +static inline void mtk_hdmi_force_hdcp_hpd(struct mtk_hdmi *hdmi) +{ + /* force HDCP HPD to 1*/ + mtk_hdmi_mask(hdmi, HDCP2X_CTRL_0, HDCP2X_HPD_OVR, HDCP2X_HPD_OVR); + mtk_hdmi_mask(hdmi, HDCP2X_CTRL_0, HDCP2X_HPD_SW, HDCP2X_HPD_SW); +} + +static void mtk_hdmi_disable_hdcp_encrypt(struct mtk_hdmi *hdmi) +{ + mtk_hdmi_mask(hdmi, HDCP2X_CTRL_0, 0x0 << HDCP2X_ENCRYPT_EN_SHIFT, + HDCP2X_ENCRYPT_EN); + mtk_hdmi_mask(hdmi, HDCP1X_CTRL, 0x0 << HDCP1X_ENC_EN_SHIFT, + HDCP1X_ENC_EN); +} + +static void mtk_hdmi_yuv420_downsample(struct mtk_hdmi *hdmi, bool enable) +{ + if (enable) { + mtk_hdmi_mask(hdmi, HDMITX_CONFIG, + HDMI_YUV420_MODE | HDMITX_SW_HPD, + HDMI_YUV420_MODE | HDMITX_SW_HPD); + mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG, + C444_C422_CONFIG_ENABLE, C444_C422_CONFIG_ENABLE); + mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG, + C422_C420_CONFIG_ENABLE, C422_C420_CONFIG_ENABLE); + mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG, 0, + C422_C420_CONFIG_BYPASS); + mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG, + C422_C420_CONFIG_OUT_CB_OR_CR, + C422_C420_CONFIG_OUT_CB_OR_CR); + mtk_hdmi_mask(hdmi, VID_OUT_FORMAT, + OUTPUT_FORMAT_DEMUX_420_ENABLE, + OUTPUT_FORMAT_DEMUX_420_ENABLE); + } else { + mtk_hdmi_mask(hdmi, HDMITX_CONFIG, 0 | HDMITX_SW_HPD, + HDMI_YUV420_MODE | HDMITX_SW_HPD); + mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG, 0, + C444_C422_CONFIG_ENABLE); + mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG, 0, + C422_C420_CONFIG_ENABLE); + mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG, + C422_C420_CONFIG_BYPASS, C422_C420_CONFIG_BYPASS); + mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG, 0, + C422_C420_CONFIG_OUT_CB_OR_CR); + mtk_hdmi_mask(hdmi, VID_OUT_FORMAT, 0, + OUTPUT_FORMAT_DEMUX_420_ENABLE); + } +} + +static bool mtk_hdmi_tmds_over_340M(struct mtk_hdmi *hdmi) +{ + unsigned long pixel_clk, tmds_clk; + + pixel_clk =3D hdmi->mode.clock * 1000; + + /* TMDS clk frequency */ + if (hdmi->color_depth =3D=3D HDMI_8_BIT) + tmds_clk =3D pixel_clk; + else if (hdmi->color_depth =3D=3D HDMI_10_BIT) + tmds_clk =3D pixel_clk * 5 / 4; + else if (hdmi->color_depth =3D=3D HDMI_12_BIT) + tmds_clk =3D pixel_clk * 3 / 2; + else if (hdmi->color_depth =3D=3D HDMI_16_BIT) + tmds_clk =3D pixel_clk * 2; + else + /* Invalid color_depth */ + return false; + + if (tmds_clk >=3D 340000000 && hdmi->csp !=3D HDMI_COLORSPACE_YUV420) + return true; + + return false; +} + +static inline void mtk_hdmi_enable_scrambling(struct mtk_hdmi *hdmi, + bool enable) +{ + usleep_range(100, 150); + + if (enable) + mtk_hdmi_mask(hdmi, TOP_CFG00, SCR_ON | HDMI2_ON, + SCR_ON | HDMI2_ON); + else + mtk_hdmi_mask(hdmi, TOP_CFG00, SCR_OFF | HDMI2_OFF, + SCR_ON | HDMI2_ON); +} + +static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black) +{ + if (black) + mtk_hdmi_mask(hdmi, TOP_VMUTE_CFG1, REG_VMUTE_EN, REG_VMUTE_EN); + else + mtk_hdmi_mask(hdmi, TOP_VMUTE_CFG1, 0, REG_VMUTE_EN); +} + +static void mtk_hdmi_hw_reset(struct mtk_hdmi *hdmi) +{ + mtk_hdmi_mask(hdmi, HDMITX_CONFIG, 0x0 << HDMITX_SW_RSTB_SHIFT, + HDMITX_SW_RSTB); + udelay(5); + mtk_hdmi_mask(hdmi, HDMITX_CONFIG, 0x1 << HDMITX_SW_RSTB_SHIFT, + HDMITX_SW_RSTB); +} + +static void mtk_hdmi_enable_hdmi_mode(struct mtk_hdmi *hdmi, bool enable) +{ + if (enable) + mtk_hdmi_mask(hdmi, TOP_CFG00, HDMI_MODE_HDMI, HDMI_MODE_HDMI); + else + mtk_hdmi_mask(hdmi, TOP_CFG00, HDMI_MODE_DVI, HDMI_MODE_HDMI); +} + +static bool mtk_hdmi_sink_is_hdmi_device(struct mtk_hdmi *hdmi) +{ + if (hdmi->dvi_mode) + return false; + else + return true; +} + +static void mtk_hdmi_set_deep_color(struct mtk_hdmi *hdmi, bool is_hdmi_si= nk) +{ + unsigned int deep_color =3D 0; + + /* ycbcr422 12bit no deep color */ + if (hdmi->csp =3D=3D HDMI_COLORSPACE_YUV422) { + deep_color =3D DEEPCOLOR_MODE_8BIT; + } else { + switch (hdmi->color_depth) { + case HDMI_8_BIT: + deep_color =3D DEEPCOLOR_MODE_8BIT; + break; + case HDMI_10_BIT: + deep_color =3D DEEPCOLOR_MODE_10BIT; + break; + case HDMI_12_BIT: + deep_color =3D DEEPCOLOR_MODE_12BIT; + break; + case HDMI_16_BIT: + deep_color =3D DEEPCOLOR_MODE_16BIT; + break; + default: + WARN(1, "Unssupported color depth %d\n", + hdmi->color_depth); + } + } + + mtk_hdmi_mask(hdmi, TOP_CFG00, deep_color, DEEPCOLOR_MODE_MASKBIT); + + /* GCP */ + mtk_hdmi_mask(hdmi, TOP_CFG00, 0, DEEPCOLOR_PAT_EN); + if (is_hdmi_sink && deep_color !=3D DEEPCOLOR_MODE_8BIT) + mtk_hdmi_mask(hdmi, TOP_MISC_CTLR, DEEP_COLOR_ADD, + DEEP_COLOR_ADD); + else + mtk_hdmi_mask(hdmi, TOP_MISC_CTLR, 0, DEEP_COLOR_ADD); +} + +static void mtk_hdmi_hw_audio_infoframe(struct mtk_hdmi *hdmi, u8 *buffer, + u8 len) +{ + enum hdmi_infoframe_type frame_type; + u8 frame_ver; + u8 frame_len; + u8 checksum; + + frame_type =3D buffer[0]; + frame_ver =3D buffer[1]; + frame_len =3D buffer[2]; + checksum =3D buffer[3]; + + mtk_hdmi_mask(hdmi, TOP_INFO_EN, AUD_DIS_WR | AUD_DIS, + AUD_EN_WR | AUD_EN); + mtk_hdmi_mask(hdmi, TOP_INFO_RPT, AUD_RPT_DIS, AUD_RPT_EN); + + mtk_hdmi_write(hdmi, TOP_AIF_HEADER, + BYTES_TO_UINT32(0, frame_len, frame_ver, frame_type)); + mtk_hdmi_write(hdmi, TOP_AIF_PKT00, + BYTES_TO_UINT32(buffer[6], buffer[5], buffer[4], + buffer[3])); + mtk_hdmi_write(hdmi, TOP_AIF_PKT01, + BYTES_TO_UINT32(0, 0, buffer[8], buffer[7])); + mtk_hdmi_write(hdmi, TOP_AIF_PKT02, 0); + mtk_hdmi_write(hdmi, TOP_AIF_PKT03, 0); + mtk_hdmi_mask(hdmi, TOP_INFO_RPT, AUD_RPT_EN, AUD_RPT_EN); + mtk_hdmi_mask(hdmi, TOP_INFO_EN, AUD_EN_WR | AUD_EN, + AUD_EN_WR | AUD_EN); +} + +static void mtk_hdmi_hw_avi_infoframe(struct mtk_hdmi *hdmi, u8 *buffer, u= 8 len) +{ + mtk_hdmi_mask(hdmi, TOP_INFO_EN, AVI_DIS_WR | AVI_DIS, + AVI_EN_WR | AVI_EN); + mtk_hdmi_mask(hdmi, TOP_INFO_RPT, AVI_RPT_DIS, AVI_RPT_EN); + + mtk_hdmi_write(hdmi, TOP_AVI_HEADER, + BYTES_TO_UINT32(0, buffer[2], buffer[1], buffer[0])); + + mtk_hdmi_write(hdmi, TOP_AVI_PKT00, + BYTES_TO_UINT32(buffer[6], buffer[5], buffer[4], + buffer[3])); + + mtk_hdmi_write(hdmi, TOP_AVI_PKT01, + BYTES_TO_UINT32(0, buffer[9], buffer[8], buffer[7])); + + mtk_hdmi_write(hdmi, TOP_AVI_PKT02, + BYTES_TO_UINT32(buffer[13], buffer[12], buffer[11], + buffer[10])); + + mtk_hdmi_write(hdmi, TOP_AVI_PKT03, + BYTES_TO_UINT32(0, buffer[16], buffer[15], buffer[14])); + + mtk_hdmi_write(hdmi, TOP_AVI_PKT04, 0); + mtk_hdmi_write(hdmi, TOP_AVI_PKT05, 0); + + mtk_hdmi_mask(hdmi, TOP_INFO_RPT, AVI_RPT_EN, AVI_RPT_EN); + mtk_hdmi_mask(hdmi, TOP_INFO_EN, AVI_EN_WR | AVI_EN, + AVI_EN_WR | AVI_EN); +} + +static void mtk_hdmi_hw_spd_infoframe(struct mtk_hdmi *hdmi, u8 *buffer, u= 8 len) +{ + mtk_hdmi_mask(hdmi, TOP_INFO_EN, SPD_DIS_WR | SPD_DIS, + SPD_EN_WR | SPD_EN); + mtk_hdmi_mask(hdmi, TOP_INFO_RPT, SPD_RPT_DIS, SPD_RPT_EN); + + mtk_hdmi_write(hdmi, TOP_SPDIF_HEADER, + BYTES_TO_UINT32(0, buffer[2], buffer[1], buffer[0])); + + mtk_hdmi_write(hdmi, TOP_SPDIF_PKT00, + BYTES_TO_UINT32(buffer[6], buffer[5], buffer[4], buffer[3])); + + mtk_hdmi_write(hdmi, TOP_SPDIF_PKT01, + BYTES_TO_UINT32(0, buffer[9], buffer[8], buffer[7])); + + mtk_hdmi_write(hdmi, TOP_SPDIF_PKT02, + BYTES_TO_UINT32(buffer[13], buffer[12], buffer[11], buffer[10])); + + mtk_hdmi_write(hdmi, TOP_SPDIF_PKT03, + BYTES_TO_UINT32(0, buffer[16], buffer[15], buffer[14])); + + mtk_hdmi_write(hdmi, TOP_SPDIF_PKT04, + BYTES_TO_UINT32(buffer[20], buffer[19], buffer[18], buffer[17])); + + mtk_hdmi_write(hdmi, TOP_SPDIF_PKT05, + BYTES_TO_UINT32(0, buffer[23], buffer[22], buffer[21])); + + mtk_hdmi_write(hdmi, TOP_SPDIF_PKT06, + BYTES_TO_UINT32(buffer[27], buffer[26], buffer[25], buffer[24])); + + mtk_hdmi_write(hdmi, TOP_SPDIF_PKT07, + BYTES_TO_UINT32(0, 0, 0, buffer[28])); + + mtk_hdmi_mask(hdmi, TOP_INFO_RPT, SPD_RPT_EN, SPD_RPT_EN); + mtk_hdmi_mask(hdmi, TOP_INFO_EN, SPD_EN_WR | SPD_EN, + SPD_EN_WR | SPD_EN); +} + +static int mtk_hdmi_setup_audio_infoframe(struct mtk_hdmi *hdmi) +{ + struct hdmi_codec_params *params =3D &hdmi->aud_param.codec_params; + struct hdmi_audio_infoframe frame; + u8 buffer[14]; + ssize_t err; + + memcpy(&frame, ¶ms->cea, sizeof(struct hdmi_audio_infoframe)); + + err =3D hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer)); + if (err < 0) + return err; + + mtk_hdmi_hw_audio_infoframe(hdmi, buffer, sizeof(buffer)); + return 0; +} + +static void mtk_hdmi_hw_send_aud_packet(struct mtk_hdmi *hdmi, bool enable) +{ + if (enable) + mtk_hdmi_mask(hdmi, AIP_TXCTRL, 0, AUD_PACKET_DROP); + else + mtk_hdmi_mask(hdmi, AIP_TXCTRL, AUD_PACKET_DROP, + AUD_PACKET_DROP); +} + +static inline void mtk_hdmi_hw_send_av_mute(struct mtk_hdmi *hdmi) +{ + /*GCP packet */ + mtk_hdmi_mask(hdmi, TOP_CFG01, 0, CP_CLR_MUTE_EN); + mtk_hdmi_mask(hdmi, TOP_CFG01, 0, CP_SET_MUTE_EN); + mtk_hdmi_mask(hdmi, TOP_INFO_RPT, 0, CP_RPT_EN); + mtk_hdmi_mask(hdmi, TOP_INFO_EN, 0, CP_EN | CP_EN_WR); + + mtk_hdmi_mask(hdmi, TOP_CFG01, 0, CP_CLR_MUTE_EN); + mtk_hdmi_mask(hdmi, TOP_CFG01, CP_SET_MUTE_EN, CP_SET_MUTE_EN); + mtk_hdmi_mask(hdmi, TOP_INFO_RPT, CP_RPT_EN, CP_RPT_EN); + mtk_hdmi_mask(hdmi, TOP_INFO_EN, CP_EN | CP_EN_WR, CP_EN | CP_EN_WR); +} + +static inline void mtk_hdmi_hw_send_av_unmute(struct mtk_hdmi *hdmi) +{ + /*GCP packet */ + mtk_hdmi_mask(hdmi, TOP_CFG01, 0, CP_CLR_MUTE_EN); + mtk_hdmi_mask(hdmi, TOP_CFG01, 0, CP_SET_MUTE_EN); + mtk_hdmi_mask(hdmi, TOP_INFO_RPT, 0, CP_RPT_EN); + mtk_hdmi_mask(hdmi, TOP_INFO_EN, 0, CP_EN | CP_EN_WR); + + mtk_hdmi_mask(hdmi, TOP_CFG01, CP_CLR_MUTE_EN, CP_CLR_MUTE_EN); + mtk_hdmi_mask(hdmi, TOP_CFG01, 0, CP_SET_MUTE_DIS); + mtk_hdmi_mask(hdmi, TOP_INFO_RPT, CP_RPT_EN, CP_RPT_EN); + mtk_hdmi_mask(hdmi, TOP_INFO_EN, CP_EN | CP_EN_WR, CP_EN | CP_EN_WR); +} + +static void mtk_hdmi_hw_ncts_enable(struct mtk_hdmi *hdmi, bool enable) +{ + unsigned int data; + + mtk_hdmi_read(hdmi, AIP_CTRL, &data); + + if (enable) + data |=3D CTS_SW_SEL; + else + data &=3D ~CTS_SW_SEL; + + mtk_hdmi_write(hdmi, AIP_CTRL, data); +} + +static void mtk_hdmi_hw_aud_set_channel_status(struct mtk_hdmi *hdmi, + u8 *channel_status) +{ + /* actually, only the first 5 or 7 bytes of Channel Status + * contain useful information + */ + mtk_hdmi_write(hdmi, AIP_I2S_CHST0, + BYTES_TO_UINT32(channel_status[3], channel_status[2], + channel_status[1], channel_status[0])); + mtk_hdmi_write(hdmi, AIP_I2S_CHST1, + BYTES_TO_UINT32(0, channel_status[6], channel_status[5], + channel_status[4])); +} + +struct hdmi_acr_n { + unsigned int clock; + unsigned int n[3]; +}; + +/* Recommended N values from HDMI specification, tables 7-1 to 7-3 */ +static const struct hdmi_acr_n hdmi_rec_n_table[] =3D { + /* Clock, N: 32kHz 44.1kHz 48kHz */ + { 25175, { 4576, 7007, 6864 } }, + { 74176, { 11648, 17836, 11648 } }, + { 148352, { 11648, 8918, 5824 } }, + { 296703, { 5824, 4459, 5824 } }, + { 297000, { 3072, 4704, 5120 } }, + { 0, { 4096, 6272, 6144 } }, /* all other TMDS clocks */ +}; + +/** + * hdmi_recommended_n() - Return N value recommended by HDMI specification + * @freq: audio sample rate in Hz + * @clock: rounded TMDS clock in kHz + */ +static int hdmi_recommended_n(unsigned int freq, unsigned int clock) +{ + const struct hdmi_acr_n *recommended; + unsigned int i; + + for (i =3D 0; i < ARRAY_SIZE(hdmi_rec_n_table) - 1; i++) { + if (clock =3D=3D hdmi_rec_n_table[i].clock) + break; + } + + if (i =3D=3D ARRAY_SIZE(hdmi_rec_n_table)) + return -EINVAL; + + recommended =3D hdmi_rec_n_table + i; + + switch (freq) { + case 32000: + return recommended->n[0]; + case 44100: + return recommended->n[1]; + case 48000: + return recommended->n[2]; + case 88200: + return recommended->n[1] * 2; + case 96000: + return recommended->n[2] * 2; + case 176400: + return recommended->n[1] * 4; + case 192000: + return recommended->n[2] * 4; + default: + return (128 * freq) / 1000; + } +} + +static unsigned int hdmi_mode_clock_to_hz(unsigned int clock) +{ + switch (clock) { + case 25175: + return 25174825; /* 25.2/1.001 MHz */ + case 74176: + return 74175824; /* 74.25/1.001 MHz */ + case 148352: + return 148351648; /* 148.5/1.001 MHz */ + case 296703: + return 296703297; /* 297/1.001 MHz */ + default: + return clock * 1000; + } +} + +static unsigned int hdmi_expected_cts(unsigned int audio_sample_rate, + unsigned int tmds_clock, unsigned int n) +{ + return DIV_ROUND_CLOSEST_ULL((u64)hdmi_mode_clock_to_hz(tmds_clock) * n, + 128 * audio_sample_rate); +} + +static void mtk_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, + unsigned int sample_rate, + unsigned int clock) +{ + unsigned int ncts; + int n; + + n =3D hdmi_recommended_n(sample_rate, clock); + + if (n =3D=3D -EINVAL) { + DRM_ERROR("Invalid sample rate: %u\n", sample_rate); + return; + } + + ncts =3D hdmi_expected_cts(sample_rate, clock, n); + mtk_hdmi_write(hdmi, AIP_N_VAL, n); + mtk_hdmi_write(hdmi, AIP_CTS_SVAL, ncts); +} + +static void mtk_hdmi_aud_enable_packet(struct mtk_hdmi *hdmi, bool enable) +{ + mtk_hdmi_hw_send_aud_packet(hdmi, enable); +} + +static void mtk_hdmi_aud_on_off_hw_ncts(struct mtk_hdmi *hdmi, bool on) +{ + mtk_hdmi_hw_ncts_enable(hdmi, on); +} + +static void mtk_hdmi_audio_dsd_config(struct mtk_hdmi *hdmi, + unsigned char chnum, bool dsd_bypass) +{ + mtk_hdmi_mask(hdmi, AIP_CTRL, DSD_EN, SPDIF_EN | DSD_EN | HBRA_ON); + mtk_hdmi_mask(hdmi, AIP_TXCTRL, DSD_MUTE_DATA, DSD_MUTE_DATA); + if (dsd_bypass) + mtk_hdmi_write(hdmi, TOP_AUD_MAP, 0x75316420); + else + mtk_hdmi_write(hdmi, TOP_AUD_MAP, 0x04230150); + + mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, 0, I2S2DSD_EN); +} + +static inline void mtk_hdmi_hw_i2s_fifo_map(struct mtk_hdmi *hdmi, + unsigned int fifo_mapping) +{ + mtk_hdmi_mask(hdmi, AIP_I2S_CTRL, fifo_mapping, + FIFO3_MAP | FIFO2_MAP | FIFO1_MAP | FIFO0_MAP); +} + +static inline void mtk_hdmi_hw_i2s_ch_number(struct mtk_hdmi *hdmi, + unsigned int chnum) +{ + mtk_hdmi_mask(hdmi, AIP_CTRL, chnum << I2S_EN_SHIFT, I2S_EN); +} + +static void mtk_hdmi_hw_i2s_ch_mapping(struct mtk_hdmi *hdmi, + unsigned char chnum, + unsigned char mapping) +{ + unsigned int bdata; + + switch (chnum) { + case 2: + bdata =3D 0x1; + break; + case 3: + bdata =3D 0x3; + break; + case 6: + if (mapping =3D=3D 0x0E) { + bdata =3D 0xf; + break; + } + fallthrough; + case 5: + bdata =3D 0x7; + break; + case 7: + case 8: + bdata =3D 0xf; + break; + default: + bdata =3D 0x1; + } + + mtk_hdmi_hw_i2s_fifo_map(hdmi, (MAP_SD3 << 6) | (MAP_SD2 << 4) | + (MAP_SD1 << 2) | (MAP_SD0 << 0)); + mtk_hdmi_hw_i2s_ch_number(hdmi, bdata); + + if (chnum =3D=3D 2) + mtk_hdmi_mask(hdmi, AIP_TXCTRL, LAYOUT0, LAYOUT1); + else + mtk_hdmi_mask(hdmi, AIP_TXCTRL, LAYOUT1, LAYOUT1); +} + +static void mtk_hdmi_i2s_data_fmt(struct mtk_hdmi *hdmi, unsigned char fmt) +{ + unsigned int u4Data; + + mtk_hdmi_read(hdmi, AIP_I2S_CTRL, &u4Data); + u4Data &=3D ~(WS_HIGH | I2S_1ST_BIT_NOSHIFT | JUSTIFY_RIGHT); + + switch (fmt) { + case HDMI_I2S_MODE_RJT_24BIT: + case HDMI_I2S_MODE_RJT_16BIT: + u4Data |=3D (WS_HIGH | I2S_1ST_BIT_NOSHIFT | JUSTIFY_RIGHT); + u4Data |=3D (WS_HIGH | I2S_1ST_BIT_NOSHIFT | JUSTIFY_RIGHT); + break; + + case HDMI_I2S_MODE_LJT_24BIT: + case HDMI_I2S_MODE_LJT_16BIT: + u4Data |=3D (WS_HIGH | I2S_1ST_BIT_NOSHIFT); + u4Data |=3D (WS_HIGH | I2S_1ST_BIT_NOSHIFT); + break; + + case HDMI_I2S_MODE_I2S_24BIT: + case HDMI_I2S_MODE_I2S_16BIT: + default: + break; + } + mtk_hdmi_write(hdmi, AIP_I2S_CTRL, u4Data); +} + +static inline void mtk_hdmi_i2s_sck_edge(struct mtk_hdmi *hdmi, + unsigned int edge) +{ + mtk_hdmi_mask(hdmi, AIP_I2S_CTRL, edge, SCK_EDGE_RISE); +} + +static inline void mtk_hdmi_i2s_cbit_order(struct mtk_hdmi *hdmi, + unsigned int cbit) +{ + mtk_hdmi_mask(hdmi, AIP_I2S_CTRL, cbit, CBIT_ORDER_SAME); +} + +static inline void mtk_hdmi_i2s_vbit(struct mtk_hdmi *hdmi, unsigned int v= bit) +{ + mtk_hdmi_mask(hdmi, AIP_I2S_CTRL, vbit, VBIT_COM); +} + +static inline void mtk_hdmi_i2s_data_direction(struct mtk_hdmi *hdmi, + unsigned int data_dir) +{ + mtk_hdmi_mask(hdmi, AIP_I2S_CTRL, data_dir, DATA_DIR_LSB); +} + +static inline void mtk_hdmi_hw_audio_type(struct mtk_hdmi *hdmi, + unsigned int spdif_i2s) +{ + mtk_hdmi_mask(hdmi, AIP_CTRL, spdif_i2s << SPDIF_EN_SHIFT, SPDIF_EN); +} + +static unsigned char mtk_hdmi_get_i2s_ch_mapping(struct mtk_hdmi *hdmi, + unsigned char channel_type) +{ + unsigned char channelmap =3D 0x00; + + switch (channel_type) { + case HDMI_AUD_CHAN_TYPE_1_1: + case HDMI_AUD_CHAN_TYPE_2_1: + channelmap =3D 0x01; + break; + + case HDMI_AUD_CHAN_TYPE_3_0: + channelmap =3D 0x02; + break; + + case HDMI_AUD_CHAN_TYPE_3_1: + channelmap =3D 0x03; + break; + + case HDMI_AUD_CHAN_TYPE_3_0_LRS: + case HDMI_AUD_CHAN_TYPE_4_0: + channelmap =3D 0x08; + break; + + case HDMI_AUD_CHAN_TYPE_5_1: + channelmap =3D 0x0B; + break; + + case HDMI_AUD_CHAN_TYPE_4_1_CLRS: + case HDMI_AUD_CHAN_TYPE_6_0: + case HDMI_AUD_CHAN_TYPE_6_0_CS: + case HDMI_AUD_CHAN_TYPE_6_0_CH: + case HDMI_AUD_CHAN_TYPE_6_0_OH: + case HDMI_AUD_CHAN_TYPE_6_0_CHR: + channelmap =3D 0x0E; + break; + + case HDMI_AUD_CHAN_TYPE_1_0: + case HDMI_AUD_CHAN_TYPE_2_0: + case HDMI_AUD_CHAN_TYPE_3_1_LRS: + case HDMI_AUD_CHAN_TYPE_4_1: + case HDMI_AUD_CHAN_TYPE_5_0: + case HDMI_AUD_CHAN_TYPE_4_0_CLRS: + case HDMI_AUD_CHAN_TYPE_6_1: + case HDMI_AUD_CHAN_TYPE_6_1_CS: + case HDMI_AUD_CHAN_TYPE_6_1_CH: + case HDMI_AUD_CHAN_TYPE_6_1_OH: + case HDMI_AUD_CHAN_TYPE_6_1_CHR: + case HDMI_AUD_CHAN_TYPE_7_0: + case HDMI_AUD_CHAN_TYPE_7_0_LH_RH: + case HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR: + case HDMI_AUD_CHAN_TYPE_7_0_LC_RC: + case HDMI_AUD_CHAN_TYPE_7_0_LW_RW: + case HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD: + case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS: + case HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS: + case HDMI_AUD_CHAN_TYPE_7_0_CS_CH: + case HDMI_AUD_CHAN_TYPE_7_0_CS_OH: + case HDMI_AUD_CHAN_TYPE_7_0_CS_CHR: + case HDMI_AUD_CHAN_TYPE_7_0_CH_OH: + case HDMI_AUD_CHAN_TYPE_7_0_CH_CHR: + case HDMI_AUD_CHAN_TYPE_7_0_OH_CHR: + case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR: + case HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS: + case HDMI_AUD_CHAN_TYPE_7_1: + case HDMI_AUD_CHAN_TYPE_7_1_LH_RH: + case HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR: + case HDMI_AUD_CHAN_TYPE_7_1_LC_RC: + case HDMI_AUD_CHAN_TYPE_7_1_LW_RW: + case HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD: + case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS: + case HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS: + case HDMI_AUD_CHAN_TYPE_7_1_CS_CH: + case HDMI_AUD_CHAN_TYPE_7_1_CS_OH: + case HDMI_AUD_CHAN_TYPE_7_1_CS_CHR: + case HDMI_AUD_CHAN_TYPE_7_1_CH_OH: + case HDMI_AUD_CHAN_TYPE_7_1_CH_CHR: + case HDMI_AUD_CHAN_TYPE_7_1_OH_CHR: + case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR: + channelmap =3D 0x00; + break; + } + + return channelmap; +} + +static inline void mtk_hdmi_hw_i2s_ch_swap(struct mtk_hdmi *hdmi, + unsigned char swapbit) +{ + mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, swapbit << 20, 0x0F << 20); +} + +static void mtk_hdmi_hbr_config(struct mtk_hdmi *hdmi, bool dsd_bypass) +{ + if (dsd_bypass) { + mtk_hdmi_mask(hdmi, AIP_CTRL, HBRA_ON, + SPDIF_EN | DSD_EN | HBRA_ON); + mtk_hdmi_mask(hdmi, AIP_CTRL, I2S_EN, I2S_EN); + } else { + mtk_hdmi_mask(hdmi, AIP_CTRL, SPDIF_EN, + SPDIF_EN | DSD_EN | HBRA_ON); + mtk_hdmi_mask(hdmi, AIP_CTRL, SPDIF_INTERNAL_MODULE, + SPDIF_INTERNAL_MODULE); + mtk_hdmi_mask(hdmi, AIP_CTRL, HBR_FROM_SPDIF, HBR_FROM_SPDIF); + mtk_hdmi_mask(hdmi, AIP_CTRL, CTS_CAL_N4, CTS_CAL_N4); + } +} + +static inline void mtk_hdmi_hw_spdif_config(struct mtk_hdmi *hdmi) +{ + mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, WR_1UI_UNLOCK, WR_1UI_LOCK); + mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, FS_UNOVERRIDE, FS_OVERRIDE_WRITE); + mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, WR_2UI_UNLOCK, WR_2UI_LOCK); + mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, 0x4 << MAX_1UI_WRITE_SHIFT, + MAX_1UI_WRITE); + mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, 0x9 << MAX_2UI_WRITE_SHIFT, + MAX_2UI_WRITE); + mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, 0x4 << AUD_ERR_THRESH_SHIFT, + AUD_ERR_THRESH); + mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, I2S2DSD_EN, I2S2DSD_EN); +} + +static void mtk_hdmi_aud_set_input(struct mtk_hdmi *hdmi) +{ + unsigned char ChMapping; + + mtk_hdmi_write(hdmi, TOP_AUD_MAP, + C_SD7 + C_SD6 + C_SD5 + C_SD4 + C_SD3 + C_SD2 + C_SD1 + + C_SD0); + mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, 0, 0x0F << 20); + mtk_hdmi_mask(hdmi, AIP_CTRL, 0, + SPDIF_EN | DSD_EN | HBRA_ON | CTS_CAL_N4 | + HBR_FROM_SPDIF | SPDIF_INTERNAL_MODULE); + mtk_hdmi_mask(hdmi, AIP_TXCTRL, 0, DSD_MUTE_DATA | LAYOUT1); + + if (hdmi->aud_param.aud_input_type =3D=3D HDMI_AUD_INPUT_I2S) { + if (hdmi->aud_param.aud_codec =3D=3D HDMI_AUDIO_CODING_TYPE_DSD) { + mtk_hdmi_audio_dsd_config(hdmi, hdmi->aud_param.codec_params.channels, = 0); + mtk_hdmi_hw_i2s_ch_mapping(hdmi, hdmi->aud_param.codec_params.channels,= 1); + } else { + mtk_hdmi_i2s_data_fmt(hdmi, hdmi->aud_param.aud_i2s_fmt); + mtk_hdmi_i2s_sck_edge(hdmi, SCK_EDGE_RISE); + mtk_hdmi_i2s_cbit_order(hdmi, CBIT_ORDER_SAME); + mtk_hdmi_i2s_vbit(hdmi, VBIT_PCM); + mtk_hdmi_i2s_data_direction(hdmi, DATA_DIR_MSB); + mtk_hdmi_hw_audio_type(hdmi, HDMI_AUD_INPUT_I2S); + ChMapping =3D mtk_hdmi_get_i2s_ch_mapping(hdmi, hdmi->aud_param.aud_inp= ut_chan_type); + mtk_hdmi_hw_i2s_ch_mapping(hdmi, hdmi->aud_param.codec_params.channels,= ChMapping); + mtk_hdmi_hw_i2s_ch_swap(hdmi, LFE_CC_SWAP); + } + } else { + if (hdmi->aud_param.aud_input_type =3D=3D HDMI_AUD_INPUT_SPDIF && + (hdmi->aud_param.aud_codec =3D=3D + HDMI_AUDIO_CODING_TYPE_DTS_HD || + hdmi->aud_param.aud_codec =3D=3D + HDMI_AUDIO_CODING_TYPE_MLP) && + hdmi->aud_param.codec_params.sample_rate =3D=3D 768000) { + mtk_hdmi_hbr_config(hdmi, false); + } else { + mtk_hdmi_hw_spdif_config(hdmi); + mtk_hdmi_hw_i2s_ch_mapping(hdmi, 2, 0); + } + } +} + +static void mtk_hdmi_aud_set_sw_ncts(struct mtk_hdmi *hdmi, + struct drm_display_mode *display_mode) +{ + unsigned int sample_rate =3D hdmi->aud_param.codec_params.sample_rate; + + mtk_hdmi_aud_on_off_hw_ncts(hdmi, false); + + mtk_hdmi_hw_aud_set_ncts(hdmi, sample_rate, display_mode->clock); +} + +static inline void mtk_hdmi_hw_audio_input_enable(struct mtk_hdmi *hdmi, + unsigned int enable) +{ + if (enable) + mtk_hdmi_mask(hdmi, AIP_CTRL, AUD_IN_EN, AUD_IN_EN); + else + mtk_hdmi_mask(hdmi, AIP_CTRL, 0x0 << AUD_IN_EN_SHIFT, + AUD_IN_EN); +} + +static void mtk_hdmi_aip_ctrl_init(struct mtk_hdmi *hdmi) +{ + mtk_hdmi_mask(hdmi, AIP_CTRL, + AUD_SEL_OWRT | NO_MCLK_CTSGEN_SEL | CTS_REQ_EN, + AUD_SEL_OWRT | NO_MCLK_CTSGEN_SEL | MCLK_EN | CTS_REQ_EN); + mtk_hdmi_mask(hdmi, AIP_TPI_CTRL, TPI_AUDIO_LOOKUP_DIS, + TPI_AUDIO_LOOKUP_EN); +} + +static void mtk_hdmi_audio_reset(struct mtk_hdmi *hdmi, bool rst) +{ + if (rst) + mtk_hdmi_mask(hdmi, AIP_TXCTRL, + RST4AUDIO | RST4AUDIO_FIFO | RST4AUDIO_ACR, + RST4AUDIO | RST4AUDIO_FIFO | RST4AUDIO_ACR); + else + mtk_hdmi_mask(hdmi, AIP_TXCTRL, 0, + RST4AUDIO | RST4AUDIO_FIFO | RST4AUDIO_ACR); +} + +static void mtk_hdmi_aud_output_config(struct mtk_hdmi *hdmi, + struct drm_display_mode *display_mode) +{ + mtk_hdmi_aud_enable_packet(hdmi, false); + mtk_hdmi_audio_reset(hdmi, true); + mtk_hdmi_aip_ctrl_init(hdmi); + mtk_hdmi_aud_set_input(hdmi); + mtk_hdmi_hw_aud_set_channel_status(hdmi, hdmi->aud_param.codec_params.iec= .status); + mtk_hdmi_setup_audio_infoframe(hdmi); + mtk_hdmi_hw_audio_input_enable(hdmi, true); + mtk_hdmi_audio_reset(hdmi, false); + mtk_hdmi_aud_set_sw_ncts(hdmi, display_mode); + usleep_range(25, 50); + mtk_hdmi_aud_on_off_hw_ncts(hdmi, true); + mtk_hdmi_aud_enable_packet(hdmi, true); +} + +void mtk_hdmi_output_init_mt8195(struct mtk_hdmi *hdmi) +{ + struct hdmi_audio_param *aud_param =3D &hdmi->aud_param; + + aud_param->aud_codec =3D HDMI_AUDIO_CODING_TYPE_PCM; + aud_param->aud_sampe_size =3D HDMI_AUDIO_SAMPLE_SIZE_16; + aud_param->aud_input_type =3D HDMI_AUD_INPUT_I2S; + aud_param->aud_i2s_fmt =3D HDMI_I2S_MODE_I2S_24BIT; + aud_param->aud_mclk =3D HDMI_AUD_MCLK_128FS; + aud_param->aud_input_chan_type =3D HDMI_AUD_CHAN_TYPE_2_0; + + hdmi->hpd =3D HDMI_PLUG_OUT; + hdmi->set_csp_depth =3D RGB444_8bit; + hdmi->csp =3D HDMI_COLORSPACE_RGB; + hdmi->color_depth =3D HDMI_8_BIT; + hdmi->colorimtery =3D HDMI_COLORIMETRY_NONE; + hdmi->extended_colorimetry =3D HDMI_EXTENDED_COLORIMETRY_RESERVED; + hdmi->quantization_range =3D HDMI_QUANTIZATION_RANGE_DEFAULT; + hdmi->ycc_quantization_range =3D HDMI_YCC_QUANTIZATION_RANGE_LIMITED; +} + +static void mtk_hdmi_reset_colorspace_setting(struct mtk_hdmi *hdmi) +{ + hdmi->set_csp_depth =3D RGB444_8bit; + hdmi->csp =3D HDMI_COLORSPACE_RGB; + hdmi->color_depth =3D HDMI_8_BIT; + hdmi->colorimtery =3D HDMI_COLORIMETRY_NONE; + hdmi->extended_colorimetry =3D HDMI_EXTENDED_COLORIMETRY_RESERVED; + hdmi->quantization_range =3D HDMI_QUANTIZATION_RANGE_DEFAULT; + hdmi->ycc_quantization_range =3D HDMI_YCC_QUANTIZATION_RANGE_LIMITED; +} + +static void mtk_hdmi_change_video_resolution(struct mtk_hdmi *hdmi) +{ + bool is_over_340M =3D false; + bool is_hdmi_sink =3D false; + + mtk_hdmi_hw_reset(hdmi); + mtk_hdmi_set_sw_hpd(hdmi, true); + usleep_range(2, 5); + + mtk_hdmi_write(hdmi, HDCP_TOP_CTRL, 0x0); + mtk_hdmi_en_hdcp_reauth_int(hdmi, true); + mtk_hdmi_enable_hpd_pord_irq(hdmi, true); + mtk_hdmi_force_hdcp_hpd(hdmi); + + is_hdmi_sink =3D mtk_hdmi_sink_is_hdmi_device(hdmi); + mtk_hdmi_set_deep_color(hdmi, is_hdmi_sink); + mtk_hdmi_enable_hdmi_mode(hdmi, is_hdmi_sink); + + usleep_range(5, 10); + mtk_hdmi_hw_vid_black(hdmi, true); + mtk_hdmi_hw_send_av_unmute(hdmi); + + mtk_hdmi_mask(hdmi, TOP_CFG01, NULL_PKT_VSYNC_HIGH_EN, + NULL_PKT_VSYNC_HIGH_EN | NULL_PKT_EN); + + is_over_340M =3D mtk_hdmi_tmds_over_340M(hdmi); + mtk_hdmi_enable_scrambling(hdmi, is_over_340M); + + if (hdmi->csp =3D=3D HDMI_COLORSPACE_YUV420) + mtk_hdmi_yuv420_downsample(hdmi, true); + else + mtk_hdmi_yuv420_downsample(hdmi, false); +} + +static void mtk_hdmi_output_set_display_mode(struct mtk_hdmi *hdmi, + struct drm_display_mode *mode) +{ + int ret; + union phy_configure_opts opts =3D { + .dp =3D { .link_rate =3D hdmi->mode.clock * 1000 } + }; + + ret =3D phy_configure(hdmi->phy, &opts); + if (ret) + dev_err(hdmi->dev, "Setting clock=3D%d failed: %d", mode->clock, ret); + + mtk_hdmi_change_video_resolution(hdmi); + mtk_hdmi_aud_output_config(hdmi, mode); +} + +int mtk_hdmi_clk_enable_mt8195(struct mtk_hdmi *hdmi) +{ + int ret; + + ret =3D clk_prepare_enable(hdmi->clk[MTK_MT8195_HDIM_HDCP_SEL]); + if (ret) + return ret; + ret =3D clk_prepare_enable(hdmi->clk[MTK_MT8195_HDMI_HDCP_24M_SEL]); + if (ret) + return ret; + ret =3D clk_prepare_enable(hdmi->clk[MTK_MT8195_HDMI_VPP_SPLIT_HDMI]); + + return ret; +} + +void mtk_hdmi_clk_disable_mt8195(struct mtk_hdmi *hdmi) +{ + clk_disable_unprepare(hdmi->clk[MTK_MT8195_HDIM_HDCP_SEL]); + clk_disable_unprepare(hdmi->clk[MTK_MT8195_HDMI_HDCP_24M_SEL]); + clk_disable_unprepare(hdmi->clk[MTK_MT8195_HDMI_VPP_SPLIT_HDMI]); +} + +static void mtk_hdmi_hpd_event(enum hdmi_hpd_state hpd, struct device *dev) +{ + struct mtk_hdmi *hdmi =3D dev_get_drvdata(dev); + + if (hdmi && hdmi->bridge.encoder && hdmi->bridge.encoder->dev) + drm_helper_hpd_irq_event(hdmi->bridge.encoder->dev); +} + +static enum hdmi_hpd_state mtk_hdmi_hpd_pord_status(struct mtk_hdmi *hdmi) +{ + unsigned int hpd_status; + + mtk_hdmi_read(hdmi, HPD_DDC_STATUS, &hpd_status); + if ((hpd_status & (HPD_PIN_STA | PORD_PIN_STA)) =3D=3D + (HPD_PIN_STA | PORD_PIN_STA)) + return HDMI_PLUG_IN_AND_SINK_POWER_ON; + else if ((hpd_status & (HPD_PIN_STA | PORD_PIN_STA)) =3D=3D PORD_PIN_STA) + return HDMI_PLUG_IN_ONLY; + else + return HDMI_PLUG_OUT; +} + +static irqreturn_t mtk_hdmi_isr(int irq, void *arg) +{ + struct mtk_hdmi *hdmi =3D arg; + unsigned int int_status; + int ret =3D IRQ_HANDLED; + + mtk_hdmi_read(hdmi, TOP_INT_STA00, &int_status); + + /* handle hpd interrupt */ + if (int_status & (PORD_F_INT_STA | PORD_R_INT_STA | HTPLG_F_INT_STA | + HTPLG_R_INT_STA)) { + mtk_hdmi_enable_hpd_pord_irq(hdmi, false); + mtk_hdmi_clr_htplg_pord_irq(hdmi); + ret =3D IRQ_WAKE_THREAD; + } + + /*clear all tx irq*/ + mtk_hdmi_clr_all_int_status(hdmi); + + return ret; +} + +static irqreturn_t mtk_hdmi_hpd_work_handle(int irq, void *arg) +{ + struct mtk_hdmi *hdmi =3D arg; + enum hdmi_hpd_state hpd; + + hpd =3D mtk_hdmi_hpd_pord_status(hdmi); + if (hpd !=3D hdmi->hpd) { + hdmi->hpd =3D hpd; + mtk_hdmi_hpd_event(hpd, hdmi->dev); + } + + mtk_hdmi_enable_hpd_pord_irq(hdmi, true); + return IRQ_HANDLED; +} + +static int mtk_hdmi_enable_disable(struct mtk_hdmi *hdmi, bool enable) +{ + int ret; + + if (enable && !hdmi->hdmi_enabled) { + if (!hdmi->power_clk_enabled) { + /* power domain on */ + ret =3D pm_runtime_get_sync(hdmi->dev); + + /* clk on */ + mtk_hdmi_clk_enable_mt8195(hdmi); + hdmi->power_clk_enabled =3D true; + } + + if (!hdmi->irq_registered) { + /* disable all tx interrupts */ + mtk_hdmi_disable_all_int(hdmi); + /* request irq */ + hdmi->hdmi_irq =3D + irq_of_parse_and_map(hdmi->dev->of_node, 0); + ret =3D request_threaded_irq(hdmi->hdmi_irq, mtk_hdmi_isr, + mtk_hdmi_hpd_work_handle, + IRQF_TRIGGER_HIGH, "hdmiirq", + hdmi); + hdmi->irq_registered =3D true; + /* enable hpd interrupt */ + mtk_hdmi_set_sw_hpd(hdmi, true); + mtk_hdmi_enable_hpd_pord_irq(hdmi, true); + } + + } else if (!enable && hdmi->hdmi_enabled) { + if (hdmi->irq_registered) { + /* free irq */ + free_irq(hdmi->hdmi_irq, NULL); + hdmi->irq_registered =3D false; + } + + if (hdmi->power_clk_enabled) { + /* clk disable */ + mtk_hdmi_clk_disable_mt8195(hdmi); + /* power domain off */ + ret =3D pm_runtime_put_sync(hdmi->dev); + hdmi->power_clk_enabled =3D false; + } + } + + hdmi->hdmi_enabled =3D enable; + + return 0; +} + +static const struct drm_prop_enum_list csp_depth_props[] =3D { + { __builtin_ffs(RGB444_8bit), "RGB444_8bit" }, + { __builtin_ffs(RGB444_10bit), "RGB444_10bit" }, + { __builtin_ffs(RGB444_12bit), "RGB444_10bit" }, + { __builtin_ffs(RGB444_16bit), "RGB444_16bit" }, + { __builtin_ffs(YCBCR444_8bit), "YCBCR444_8bit" }, + { __builtin_ffs(YCBCR444_10bit), "YCBCR444_10bit" }, + { __builtin_ffs(YCBCR444_12bit), "YCBCR444_12bit" }, + { __builtin_ffs(YCBCR444_16bit), "YCBCR444_16bit" }, + { __builtin_ffs(YCBCR422_8bit_NO_SUPPORT), "YCBCR422_8bit_NO_SUPPORT" }, + { __builtin_ffs(YCBCR422_10bit_NO_SUPPORT), + "YCBCR422_10bit_NO_SUPPORT" }, + { __builtin_ffs(YCBCR422_12bit), "YCBCR422_12bit" }, + { __builtin_ffs(YCBCR422_16bit_NO_SUPPORT), + "YCBCR422_16bit_NO_SUPPORT" }, + { __builtin_ffs(YCBCR420_8bit), "YCBCR420_8bit" }, + { __builtin_ffs(YCBCR420_10bit), "YCBCR420_10bit" }, + { __builtin_ffs(YCBCR420_12bit), "YCBCR420_12bit" }, + { __builtin_ffs(YCBCR420_16bit), "YCBCR420_16bit" }, +}; + +static void mtk_hdmi_convert_colorspace_depth(struct mtk_hdmi *hdmi) +{ + switch (hdmi->set_csp_depth) { + case RGB444_8bit: + hdmi->csp =3D HDMI_COLORSPACE_RGB; + hdmi->color_depth =3D HDMI_8_BIT; + break; + case RGB444_10bit: + hdmi->csp =3D HDMI_COLORSPACE_RGB; + hdmi->color_depth =3D HDMI_10_BIT; + break; + case RGB444_12bit: + hdmi->csp =3D HDMI_COLORSPACE_RGB; + hdmi->color_depth =3D HDMI_12_BIT; + break; + case RGB444_16bit: + hdmi->csp =3D HDMI_COLORSPACE_RGB; + hdmi->color_depth =3D HDMI_16_BIT; + break; + case YCBCR444_8bit: + hdmi->csp =3D HDMI_COLORSPACE_YUV444; + hdmi->color_depth =3D HDMI_8_BIT; + break; + case YCBCR444_10bit: + hdmi->csp =3D HDMI_COLORSPACE_YUV444; + hdmi->color_depth =3D HDMI_10_BIT; + break; + case YCBCR444_12bit: + hdmi->csp =3D HDMI_COLORSPACE_YUV444; + hdmi->color_depth =3D HDMI_12_BIT; + break; + case YCBCR444_16bit: + hdmi->csp =3D HDMI_COLORSPACE_YUV444; + hdmi->color_depth =3D HDMI_16_BIT; + break; + case YCBCR422_12bit: + hdmi->csp =3D HDMI_COLORSPACE_YUV422; + hdmi->color_depth =3D HDMI_12_BIT; + break; + case YCBCR420_8bit: + hdmi->csp =3D HDMI_COLORSPACE_YUV420; + hdmi->color_depth =3D HDMI_8_BIT; + break; + case YCBCR420_10bit: + hdmi->csp =3D HDMI_COLORSPACE_YUV420; + hdmi->color_depth =3D HDMI_10_BIT; + break; + case YCBCR420_12bit: + hdmi->csp =3D HDMI_COLORSPACE_YUV420; + hdmi->color_depth =3D HDMI_12_BIT; + break; + case YCBCR420_16bit: + hdmi->csp =3D HDMI_COLORSPACE_YUV420; + hdmi->color_depth =3D HDMI_16_BIT; + break; + default: + + hdmi->csp =3D HDMI_COLORSPACE_RGB; + hdmi->color_depth =3D HDMI_8_BIT; + } +} + +static int mtk_hdmi_conn_get_modes(struct drm_connector *conn) +{ + struct mtk_hdmi *hdmi =3D hdmi_ctx_from_conn(conn); + struct edid *edid; + int ret; + + if (!hdmi->ddc_adpt) + return -ENODEV; + + edid =3D drm_get_edid(conn, hdmi->ddc_adpt); + if (!edid) + return -ENODEV; + + hdmi->dvi_mode =3D !drm_detect_hdmi_monitor(edid); + + drm_connector_update_edid_property(conn, edid); + + ret =3D drm_add_edid_modes(conn, edid); + + kfree(edid); + + return ret; +} + +static int mtk_hdmi_conn_mode_valid(struct drm_connector *conn, + struct drm_display_mode *mode) +{ + if (mode->clock < 27000) + return MODE_CLOCK_LOW; + if (mode->clock > 594000) + return MODE_CLOCK_HIGH; + + return drm_mode_validate_size(mode, 0x1fff, 0x1fff); +} + +static struct drm_encoder *mtk_hdmi_conn_best_enc(struct drm_connector *co= nn) +{ + struct mtk_hdmi *hdmi =3D hdmi_ctx_from_conn(conn); + + return hdmi->bridge.encoder; +} + +static const struct drm_connector_helper_funcs mtk_hdmi_connector_helper_f= uncs =3D { + .get_modes =3D mtk_hdmi_conn_get_modes, + .mode_valid =3D mtk_hdmi_conn_mode_valid, + .best_encoder =3D mtk_hdmi_conn_best_enc, +}; + +/* + * Bridge callbacks + */ + +static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) +{ + struct mtk_hdmi *hdmi =3D hdmi_ctx_from_bridge(bridge); + int ret; + + if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) { + DRM_ERROR("The flag DRM_BRIDGE_ATTACH_NO_CONNECTOR must be supplied\n"); + return -EINVAL; + } + if (hdmi->next_bridge) { + ret =3D drm_bridge_attach(bridge->encoder, hdmi->next_bridge, bridge, fl= ags); + if (ret) + return ret; + } + + pm_runtime_enable(hdmi->dev); + mtk_hdmi_enable_disable(hdmi, true); + + return 0; +} + +static void mtk_hdmi_bridge_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) +{ + struct mtk_hdmi *hdmi =3D hdmi_ctx_from_bridge(bridge); + + if (!hdmi->enabled) + return; + + mtk_hdmi_hw_send_av_mute(hdmi); + usleep_range(50000, 50050); + mtk_hdmi_hw_vid_black(hdmi, true); + mtk_hdmi_disable_hdcp_encrypt(hdmi); + usleep_range(50000, 50050); + + hdmi->enabled =3D false; +} + +static void mtk_hdmi_bridge_post_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_state) +{ + struct mtk_hdmi *hdmi =3D hdmi_ctx_from_bridge(bridge); + + if (!hdmi->powered) + return; + + phy_power_off(hdmi->phy); + + hdmi->powered =3D false; + + mtk_hdmi_reset_colorspace_setting(hdmi); +} + +static void mtk_hdmi_bridge_pre_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_state) +{ + struct mtk_hdmi *hdmi =3D hdmi_ctx_from_bridge(bridge); + union phy_configure_opts opts =3D { + .dp =3D { .link_rate =3D hdmi->mode.clock * 1000 } + }; + + mtk_hdmi_convert_colorspace_depth(hdmi); + mtk_hdmi_output_set_display_mode(hdmi, &hdmi->mode); + /* configuring phy clock link with appropriate rate */ + phy_configure(hdmi->phy, &opts); + phy_power_on(hdmi->phy); + hdmi->powered =3D true; +} + +static void mtk_hdmi_bridge_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_state) +{ + struct mtk_hdmi *hdmi =3D hdmi_ctx_from_bridge(bridge); + u8 buffer_spd[HDMI_INFOFRAME_SIZE(SPD)]; + u8 buffer_avi[HDMI_INFOFRAME_SIZE(AVI)]; + + phy_power_on(hdmi->phy); + mtk_hdmi_send_infoframe(hdmi, buffer_spd, sizeof(buffer_spd), + buffer_avi, sizeof(buffer_avi), &hdmi->mode); + mtk_hdmi_hw_spd_infoframe(hdmi, buffer_spd, sizeof(buffer_spd)); + mtk_hdmi_hw_avi_infoframe(hdmi, buffer_avi, sizeof(buffer_avi)); + + mtk_hdmi_hw_vid_black(hdmi, false); + + hdmi->enabled =3D true; +} + +static enum drm_connector_status mtk_hdmi_bridge_detect(struct drm_bridge = *bridge) +{ + struct mtk_hdmi *hdmi =3D hdmi_ctx_from_bridge(bridge); + + if (hdmi->hpd !=3D HDMI_PLUG_IN_AND_SINK_POWER_ON && + hdmi->hpd !=3D HDMI_PLUG_IN_ONLY) { + hdmi->support_csp_depth =3D RGB444_8bit; + hdmi->set_csp_depth =3D RGB444_8bit; + hdmi->csp =3D HDMI_COLORSPACE_RGB; + hdmi->color_depth =3D HDMI_8_BIT; + hdmi->colorimtery =3D HDMI_COLORIMETRY_NONE; + hdmi->extended_colorimetry =3D HDMI_EXTENDED_COLORIMETRY_RESERVED; + hdmi->quantization_range =3D HDMI_QUANTIZATION_RANGE_DEFAULT; + hdmi->ycc_quantization_range =3D + HDMI_YCC_QUANTIZATION_RANGE_LIMITED; + } + + return (hdmi->hpd !=3D HDMI_PLUG_OUT) ? connector_status_connected : + connector_status_disconnected; +} + +const struct drm_bridge_funcs mtk_mt8195_hdmi_bridge_funcs =3D { + .attach =3D mtk_hdmi_bridge_attach, + .atomic_duplicate_state =3D drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state =3D drm_atomic_helper_bridge_destroy_state, + .atomic_reset =3D drm_atomic_helper_bridge_reset, + .mode_fixup =3D mtk_hdmi_bridge_mode_fixup, + .atomic_disable =3D mtk_hdmi_bridge_disable, + .atomic_post_disable =3D mtk_hdmi_bridge_post_disable, + .mode_set =3D mtk_hdmi_bridge_mode_set, + .atomic_pre_enable =3D mtk_hdmi_bridge_pre_enable, + .atomic_enable =3D mtk_hdmi_bridge_enable, + .get_edid =3D mtk_hdmi_bridge_get_edid, + .detect =3D mtk_hdmi_bridge_detect, +}; diff --git a/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h b/drivers/gpu/drm/m= ediatek/mtk_mt8195_hdmi.h new file mode 100644 index 000000000000..f59aea51dc74 --- /dev/null +++ b/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2022 MediaTek Inc. + * Copyright (c) 2022 BayLibre, SAS + */ + +#ifndef _MTK_HDMI_MT8195_CTRL_H +#define _MTK_HDMI_MT8195_CTRL_H + +#include +#include + +struct mtk_hdmi; + +extern struct platform_driver mtk_hdmi_mt8195_ddc_driver; +extern const struct drm_bridge_funcs mtk_mt8195_hdmi_bridge_funcs; +void mtk_hdmi_output_init_mt8195(struct mtk_hdmi *hdmi); +int mtk_hdmi_clk_enable_mt8195(struct mtk_hdmi *hdmi); +void mtk_hdmi_clk_disable_mt8195(struct mtk_hdmi *hdmi); + +enum mtk_hdmi_clk_id_mt8195 { + MTK_MT8195_HDIM_HDCP_SEL, + MTK_MT8195_HDMI_HDCP_24M_SEL, + MTK_MT8195_HDMI_VPP_SPLIT_HDMI, + MTK_MT8195_HDMI_CLK_COUNT, +}; + +extern const char *const mtk_hdmi_clk_names_mt8195[MTK_MT8195_HDMI_CLK_COU= NT]; +#endif /* _MTK_HDMI_MT8195_CTRL_H */ diff --git a/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.c b/drivers/gpu/d= rm/mediatek/mtk_mt8195_hdmi_ddc.c new file mode 100644 index 000000000000..a6b734b215a9 --- /dev/null +++ b/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.c @@ -0,0 +1,539 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + * Copyright (c) 2021 BayLibre, SAS + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mtk_mt8195_hdmi_regs.h" +#include "mtk_mt8195_hdmi.h" + +#define EDID_ID 0x50 +#define DDC2_CLOK 572 /* BIM=3D208M/(v*4) =3D 90Khz */ +#define DDC2_CLOK_EDID 832 /* BIM=3D208M/(v*4) =3D 62.5Khz */ + +struct mtk_hdmi_ddc { + /* Serialize read/write operations */ + struct mutex mtx; + struct i2c_adapter adap; + struct clk *clk; + void __iomem *regs; +}; + +enum sif_bit_t_hdmi { + SIF_8_BIT_HDMI, /* /< [8 bits data address.] */ + SIF_16_BIT_HDMI, /* /< [16 bits data address.] */ +}; + +static inline unsigned int mtk_ddc_read(struct mtk_hdmi_ddc *ddc, + unsigned short reg, u32 *val) +{ + return regmap_read(ddc->regs, reg, val); +} + +static inline void mtk_ddc_write(struct mtk_hdmi_ddc *ddc, unsigned short = reg, + unsigned int val) +{ + regmap_write(ddc->regs, reg, val); +} + +static inline void mtk_ddc_mask(struct mtk_hdmi_ddc *ddc, unsigned int reg, + unsigned int val, unsigned int mask) +{ + regmap_update_bits(ddc->regs, reg, mask, val); +} + +static void hdmi_ddc_request(struct mtk_hdmi_ddc *ddc) +{ + mtk_ddc_mask(ddc, HDCP2X_POL_CTRL, HDCP2X_DIS_POLL_EN, + HDCP2X_DIS_POLL_EN); +} + +static void DDC_WR_ONE(struct mtk_hdmi_ddc *ddc, unsigned int addr_id, + unsigned int offset_id, unsigned char wr_data) +{ + u32 val; + + mtk_ddc_read(ddc, HDCP2X_DDCM_STATUS, &val); + + if (val & DDC_I2C_BUS_LOW) { + mtk_ddc_mask(ddc, DDC_CTRL, (CLOCK_SCL << DDC_CMD_SHIFT), + DDC_CMD); + usleep_range(250, 300); + } + mtk_ddc_mask(ddc, HPD_DDC_CTRL, DDC2_CLOK << DDC_DELAY_CNT_SHIFT, + DDC_DELAY_CNT); + mtk_ddc_write(ddc, SI2C_CTRL, SI2C_ADDR_READ << SI2C_ADDR_SHIFT); + mtk_ddc_mask(ddc, SI2C_CTRL, wr_data << SI2C_WDATA_SHIFT, SI2C_WDATA); + mtk_ddc_mask(ddc, SI2C_CTRL, SI2C_WR, SI2C_WR); + + mtk_ddc_write(ddc, DDC_CTRL, + (SEQ_WRITE_REQ_ACK << DDC_CMD_SHIFT) + + (1 << DDC_DIN_CNT_SHIFT) + + (offset_id << DDC_OFFSET_SHIFT) + (addr_id << 1)); + + usleep_range(1000, 1250); + mtk_ddc_read(ddc, HDCP2X_DDCM_STATUS, &val); + + if ((val & DDC_I2C_NO_ACK) | DDC_I2C_BUS_LOW) { + mtk_ddc_read(ddc, HDCP2X_DDCM_STATUS, &val); + if (val & DDC_I2C_BUS_LOW) { + mtk_ddc_mask(ddc, DDC_CTRL, + (CLOCK_SCL << DDC_CMD_SHIFT), DDC_CMD); + usleep_range(250, 300); + } + } +} + +static unsigned char +ddcm_read_hdmi(struct mtk_hdmi_ddc *ddc, + unsigned int u4_clk_div, unsigned char uc_dev, unsigned int u4_add= r, + enum sif_bit_t_hdmi uc_addr_type, unsigned char *puc_value, + unsigned int u4_count) +{ + unsigned int i, temp_length, loop_counter, temp_ksvlist, device_n; + unsigned int uc_read_count, uc_idx; + unsigned long ddc_start_time, ddc_end_time, ddc_timeout; + u32 val; + + if (!puc_value || !u4_count || !u4_clk_div) + return 0; + + uc_idx =3D 0; + mtk_ddc_read(ddc, HDCP2X_DDCM_STATUS, &val); + if (val & DDC_I2C_BUS_LOW) { + mtk_ddc_mask(ddc, DDC_CTRL, (CLOCK_SCL << DDC_CMD_SHIFT), + DDC_CMD); + usleep_range(250, 300); + } + + mtk_ddc_mask(ddc, DDC_CTRL, (CLEAR_FIFO << DDC_CMD_SHIFT), DDC_CMD); + + if (u4_addr =3D=3D 0x43) { + mtk_ddc_write(ddc, DDC_CTRL, + (SEQ_READ_NO_ACK << DDC_CMD_SHIFT) + + (u4_count << DDC_DIN_CNT_SHIFT) + + (u4_addr << DDC_OFFSET_SHIFT) + + (uc_dev << 1)); + usleep_range(700, 1000); + + if (u4_count > 10) + temp_ksvlist =3D 10; + else + temp_ksvlist =3D u4_count; + + for (uc_idx =3D 0; uc_idx < temp_ksvlist; uc_idx++) { + mtk_ddc_write(ddc, SI2C_CTRL, + (SI2C_ADDR_READ << SI2C_ADDR_SHIFT) + + SI2C_RD); + mtk_ddc_write(ddc, SI2C_CTRL, + (SI2C_ADDR_READ << SI2C_ADDR_SHIFT) + + SI2C_CONFIRM_READ); + + mtk_ddc_read(ddc, HPD_DDC_STATUS, &val); + puc_value[uc_idx] =3D (val & DDC_DATA_OUT) >> DDC_DATA_OUT_SHIFT; + usleep_range(100, 150); + } + + if (u4_count =3D=3D temp_ksvlist) + return (uc_idx + 1); + + usleep_range(500, 600); + + if (u4_count / 5 =3D=3D 3) + device_n =3D 5; + else + device_n =3D 10; + + for (uc_idx =3D 10; uc_idx < (10 + device_n); uc_idx++) { + mtk_ddc_write(ddc, SI2C_CTRL, + (SI2C_ADDR_READ << SI2C_ADDR_SHIFT) + + SI2C_RD); + mtk_ddc_write(ddc, SI2C_CTRL, + (SI2C_ADDR_READ << SI2C_ADDR_SHIFT) + + SI2C_CONFIRM_READ); + mtk_ddc_read(ddc, HPD_DDC_STATUS, &val); + puc_value[uc_idx] =3D (val & DDC_DATA_OUT) >> DDC_DATA_OUT_SHIFT; + usleep_range(100, 150); + } + + if (u4_count =3D=3D (10 + device_n)) + return (uc_idx + 1); + + usleep_range(500, 700); + + if (u4_count / 5 =3D=3D 5) + device_n =3D 5; + else + device_n =3D 10; + + for (uc_idx =3D 20; uc_idx < (20 + device_n); uc_idx++) { + mtk_ddc_write(ddc, SI2C_CTRL, + (SI2C_ADDR_READ << SI2C_ADDR_SHIFT) + + SI2C_RD); + mtk_ddc_write(ddc, SI2C_CTRL, + (SI2C_ADDR_READ << SI2C_ADDR_SHIFT) + + SI2C_CONFIRM_READ); + mtk_ddc_read(ddc, HPD_DDC_STATUS, &val); + puc_value[uc_idx] =3D (val & DDC_DATA_OUT) >> DDC_DATA_OUT_SHIFT; + usleep_range(100, 150); + } + + if (u4_count =3D=3D (20 + device_n)) + return (uc_idx + 1); + + usleep_range(500, 700); + + if (u4_count / 5 =3D=3D 7) + device_n =3D 5; + else + device_n =3D 10; + + for (uc_idx =3D 30; uc_idx < (30 + device_n); uc_idx++) { + mtk_ddc_write(ddc, SI2C_CTRL, + (SI2C_ADDR_READ << SI2C_ADDR_SHIFT) + + SI2C_RD); + mtk_ddc_write(ddc, SI2C_CTRL, + (SI2C_ADDR_READ << SI2C_ADDR_SHIFT) + + SI2C_CONFIRM_READ); + mtk_ddc_read(ddc, HPD_DDC_STATUS, &val); + puc_value[uc_idx] =3D (val & DDC_DATA_OUT) >> DDC_DATA_OUT_SHIFT; + usleep_range(100, 150); + } + + if (u4_count =3D=3D (30 + device_n)) + return (uc_idx + 1); + + usleep_range(500, 700); + + for (uc_idx =3D 40; uc_idx < (40 + 5); uc_idx++) { + mtk_ddc_write(ddc, SI2C_CTRL, + (SI2C_ADDR_READ << SI2C_ADDR_SHIFT) + + SI2C_RD); + mtk_ddc_write(ddc, SI2C_CTRL, + (SI2C_ADDR_READ << SI2C_ADDR_SHIFT) + + SI2C_CONFIRM_READ); + + mtk_ddc_read(ddc, HPD_DDC_STATUS, &val); + puc_value[uc_idx] =3D (val & DDC_DATA_OUT) >> DDC_DATA_OUT_SHIFT; + usleep_range(100, 150); + } + + if (u4_count =3D=3D 45) + return (uc_idx + 1); + } else { + if (u4_count >=3D 16) { + temp_length =3D 16; + loop_counter =3D + u4_count / 16 + ((u4_count % 16 =3D=3D 0) ? 0 : 1); + } else { + temp_length =3D u4_count; + loop_counter =3D 1; + } + if (uc_dev >=3D EDID_ID) { + if (u4_clk_div < DDC2_CLOK_EDID) + u4_clk_div =3D DDC2_CLOK_EDID; + } + mtk_ddc_mask(ddc, HPD_DDC_CTRL, u4_clk_div << DDC_DELAY_CNT_SHIFT, + DDC_DELAY_CNT); + for (i =3D 0; i < loop_counter; i++) { + if (i =3D=3D (loop_counter - 1) && i !=3D 0 && + u4_count % 16) + temp_length =3D u4_count % 16; + + if (uc_dev > EDID_ID) { + mtk_ddc_mask(ddc, SCDC_CTRL, + (uc_dev - EDID_ID) << DDC_SEGMENT_SHIFT, DDC_SEGMENT); + mtk_ddc_write(ddc, DDC_CTRL, (ENH_READ_NO_ACK << DDC_CMD_SHIFT) + + (temp_length << DDC_DIN_CNT_SHIFT) + + ((u4_addr + i * temp_length) << DDC_OFFSET_SHIFT) + + (EDID_ID << 1)); + } else { + mtk_ddc_write(ddc, DDC_CTRL, (SEQ_READ_NO_ACK << DDC_CMD_SHIFT) + + (temp_length << DDC_DIN_CNT_SHIFT) + + ((u4_addr + ((u4_addr =3D=3D 0x43) ? 0 : (i * 16))) + << DDC_OFFSET_SHIFT) + + (uc_dev << 1)); + } + usleep_range(5000, 5500); + ddc_start_time =3D jiffies; + ddc_timeout =3D temp_length + 5; + ddc_end_time =3D ddc_start_time + ddc_timeout * HZ / 1000; + while (1) { + mtk_ddc_read(ddc, HPD_DDC_STATUS, &val); + if ((val & DDC_I2C_IN_PROG) =3D=3D 0) + break; + + if (time_after(jiffies, ddc_end_time)) { + pr_info("[HDMI][DDC] error: time out\n"); + return 0; + } + usleep_range(1000, 1500); + } + mtk_ddc_read(ddc, HDCP2X_DDCM_STATUS, &val); + if ((val & (DDC_I2C_NO_ACK | DDC_I2C_BUS_LOW))) { + mtk_ddc_read(ddc, HDCP2X_DDCM_STATUS, &val); + if (val & DDC_I2C_BUS_LOW) { + mtk_ddc_mask(ddc, DDC_CTRL, + (CLOCK_SCL + << DDC_CMD_SHIFT), + DDC_CMD); + usleep_range(250, 300); + } + return 0; + } + for (uc_idx =3D 0; uc_idx < temp_length; uc_idx++) { + mtk_ddc_write(ddc, SI2C_CTRL, + (SI2C_ADDR_READ + << SI2C_ADDR_SHIFT) + + SI2C_RD); + mtk_ddc_write(ddc, SI2C_CTRL, + (SI2C_ADDR_READ + << SI2C_ADDR_SHIFT) + + SI2C_CONFIRM_READ); + + mtk_ddc_read(ddc, HPD_DDC_STATUS, &val); + puc_value[i * 16 + uc_idx] =3D (val & DDC_DATA_OUT) + >> DDC_DATA_OUT_SHIFT; + /* + * when reading edid, if hdmi module been reset, + * ddc will fail and it's + *speed will be set to 400. + */ + mtk_ddc_read(ddc, HPD_DDC_CTRL, &val); + if (((val >> 16) & 0xFFFF) < DDC2_CLOK) + return 0; + + uc_read_count =3D i * 16 + uc_idx + 1; + } + } + return uc_read_count; + } + return 0; +} + +static unsigned char vddc_read(struct mtk_hdmi_ddc *ddc, unsigned int u4_c= lk_div, + unsigned char uc_dev, unsigned int u4_addr, + enum sif_bit_t_hdmi uc_addr_type, + unsigned char *puc_value, unsigned int u4_count) +{ + unsigned int u4_read_count =3D 0; + unsigned char uc_return_value =3D 0; + + if (!puc_value || !u4_count || !u4_clk_div || + uc_addr_type > SIF_16_BIT_HDMI || + (uc_addr_type =3D=3D SIF_8_BIT_HDMI && u4_addr > 255) || + (uc_addr_type =3D=3D SIF_16_BIT_HDMI && u4_addr > 65535)) { + return 0; + } + + if (uc_addr_type =3D=3D SIF_8_BIT_HDMI) + u4_read_count =3D 255 - u4_addr + 1; + else if (uc_addr_type =3D=3D SIF_16_BIT_HDMI) + u4_read_count =3D 65535 - u4_addr + 1; + + u4_read_count =3D (u4_read_count > u4_count) ? u4_count : u4_read_count; + uc_return_value =3D ddcm_read_hdmi(ddc, u4_clk_div, uc_dev, u4_addr, + uc_addr_type, puc_value, u4_read_count); + return uc_return_value; +} + +static unsigned char fg_ddc_data_read(struct mtk_hdmi_ddc *ddc, + unsigned char b_dev, + unsigned char b_data_addr, + unsigned char b_data_count, + unsigned char *pr_data) +{ + bool flag; + + mutex_lock(&ddc->mtx); + + hdmi_ddc_request(ddc); + if (vddc_read(ddc, DDC2_CLOK, (unsigned char)b_dev, + (unsigned int)b_data_addr, SIF_8_BIT_HDMI, + (unsigned char *)pr_data, + (unsigned int)b_data_count) =3D=3D b_data_count) { + flag =3D true; + } else { + flag =3D false; + } + + mutex_unlock(&ddc->mtx); + return flag; +} + +static unsigned char fg_ddc_data_write(struct mtk_hdmi_ddc *ddc, + unsigned char b_dev, + unsigned char b_data_addr, + unsigned char b_data_count, + unsigned char *pr_data) +{ + unsigned int i; + + mutex_lock(&ddc->mtx); + + hdmi_ddc_request(ddc); + for (i =3D 0; i < b_data_count; i++) + DDC_WR_ONE(ddc, b_dev, b_data_addr + i, *(pr_data + i)); + + mutex_unlock(&ddc->mtx); + return 1; +} + +static int mtk_hdmi_ddc_xfer(struct i2c_adapter *adapter, struct i2c_msg *= msgs, + int num) +{ + struct mtk_hdmi_ddc *ddc =3D adapter->algo_data; + struct device *dev =3D adapter->dev.parent; + int ret; + int i; + unsigned char offset; + + if (!ddc) + return -EINVAL; + + for (i =3D 0; i < num; i++) { + struct i2c_msg *msg =3D &msgs[i]; + + if (msg->flags & I2C_M_RD) { + /* The underlying DDC hardware always issue a write request + * that assigns the read offset as part of the read operation. + * Therefore we need to use the offset value assigned + * in the previous write request from the drm_edid.c + */ + ret =3D fg_ddc_data_read(ddc, msg->addr, + offset, /* determined by previous write requests */ + (msg->len), &msg->buf[0]); + } else { + ret =3D fg_ddc_data_write(ddc, msg->addr, msg->buf[0], + (msg->len - 1), &msg->buf[1]); + + /* we store the offset value requested by drm_edid framework + * to use in subsequent read requests. + */ + if (DDC_ADDR =3D=3D msg->addr && 1 =3D=3D msg->len) + offset =3D msg->buf[0]; + } + + if (ret <=3D 0) + goto xfer_end; + } + + return i; + +xfer_end: + dev_err(dev, "ddc failed! : %d\n", ret); + return ret; +} + +static u32 mtk_hdmi_ddc_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm mtk_hdmi_ddc_algorithm =3D { + .master_xfer =3D mtk_hdmi_ddc_xfer, + .functionality =3D mtk_hdmi_ddc_func, +}; + +static int mtk_hdmi_ddc_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct mtk_hdmi_ddc *ddc; + int ret; + + ddc =3D devm_kzalloc(dev, sizeof(struct mtk_hdmi_ddc), GFP_KERNEL); + if (!ddc) + return -ENOMEM; + + ddc->regs =3D syscon_regmap_lookup_by_compatible("mediatek,mt8195-hdmi"); + if (IS_ERR(ddc->regs)) + return dev_err_probe(dev, PTR_ERR(ddc->regs), "Unable to get mt8195-hdmi= syscon"); + + ddc->clk =3D devm_clk_get(dev, "ddc-i2c"); + if (IS_ERR(ddc->clk)) { + dev_err(dev, "get ddc_clk failed: %p ,\n", ddc->clk); + return PTR_ERR(ddc->clk); + } + ret =3D clk_prepare_enable(ddc->clk); + if (ret) { + dev_err(dev, "enable ddc clk failed!\n"); + return ret; + } + + mutex_init(&ddc->mtx); + + strscpy(ddc->adap.name, "mediatek-hdmi-ddc", sizeof(ddc->adap.name)); + ddc->adap.owner =3D THIS_MODULE; + ddc->adap.class =3D I2C_CLASS_DDC; + ddc->adap.algo =3D &mtk_hdmi_ddc_algorithm; + ddc->adap.retries =3D 3; + ddc->adap.dev.of_node =3D dev->of_node; + ddc->adap.algo_data =3D ddc; + ddc->adap.dev.parent =3D &pdev->dev; + + ret =3D i2c_add_adapter(&ddc->adap); + if (ret < 0) { + dev_err(dev, "failed to add bus to i2c core\n"); + goto err_clk_disable; + } + + platform_set_drvdata(pdev, ddc); + return 0; + +err_clk_disable: + clk_disable_unprepare(ddc->clk); + return ret; +} + +static int mtk_hdmi_ddc_remove(struct platform_device *pdev) +{ + struct mtk_hdmi_ddc *ddc =3D platform_get_drvdata(pdev); + + mutex_destroy(&ddc->mtx); + i2c_del_adapter(&ddc->adap); + clk_disable_unprepare(ddc->clk); + + return 0; +} + +static const struct of_device_id mtk_hdmi_ddc_match[] =3D { + { + .compatible =3D "mediatek,mt8195-hdmi-ddc", + }, + {}, +}; + +struct platform_driver mtk_hdmi_mt8195_ddc_driver =3D { + .probe =3D mtk_hdmi_ddc_probe, + .remove =3D mtk_hdmi_ddc_remove, + .driver =3D { + .name =3D "mediatek-hdmi-mt8195-ddc", + .of_match_table =3D mtk_hdmi_ddc_match, + }, +}; + +MODULE_AUTHOR("Can Zeng "); +MODULE_DESCRIPTION("MediaTek HDMI DDC Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_regs.h b/drivers/gpu/= drm/mediatek/mtk_mt8195_hdmi_regs.h new file mode 100644 index 000000000000..66fc388bc7a9 --- /dev/null +++ b/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_regs.h @@ -0,0 +1,329 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 MediaTek Inc. + * Copyright (c) 2021 BayLibre, SAS + */ + +#ifndef _MTK_HDMI_REGS_H +#define _MTK_HDMI_REGS_H + +#define AIF_HEADER GENMASK(19, 0) +#define AIF_PKT00 GENMASK(31, 0) +#define AIF_PKT01 (23, 0) +#define AIF_PKT02 (31, 0) +#define AIF_PKT03 (23, 0) + +#define AIP_CTRL BIT(10) +#define AIP_CTS_SVAL 0x408 +#define AIP_DOWNSAMPLE_CTRL 0x41C +#define AIP_I2S_CHST0 0x414 +#define AIP_I2S_CHST1 0x418 +#define AIP_I2S_CTRL 0x410 +#define AIP_N_VAL 0x404 +#define AIP_SPDIF_CTRL 0x40C +#define AIP_TPI_CTRL 0x428 +#define AIP_TXCTRL 0x424 + +#define AUD_DIS (0x0) +#define AUD_DIS_WR (0x0) +#define AUD_EN BIT(2) +#define AUD_EN_WR BIT(18) +#define AUD_ERR_THRESH GENMASK(29, 24) +#define AUD_ERR_THRESH_SHIFT 24 +#define AUD_IN_EN BIT(8) +#define AUD_IN_EN_SHIFT 8 +#define AUD_MUTE_DIS (0x0) +#define AUD_MUTE_FIFO_EN BIT(5) +#define AUD_PACKET_DROP BIT(6) +#define AUD_RPT_DIS (0x0) +#define AUD_RPT_EN BIT(2) +#define AUD_SEL_OWRT BIT(9) + +#define AVI_DIS (0) +#define AVI_DIS_WR (0) +#define AVI_EN (0x1) +#define AVI_EN_WR BIT(16) +#define AVI_HEADER GENMASK(23, 0) +#define AVI_PKT00 GENMASK(31, 0) +#define AVI_PKT01 GENMASK(23, 0) +#define AVI_PKT02 GENMASK(31, 0) +#define AVI_PKT03 GENMASK(23, 0) +#define AVI_PKT04 GENMASK(31, 0) +#define AVI_PKT05 GENMASK(23, 0) +#define AVI_RPT_DIS (0x0) +#define AVI_RPT_EN (0x1) + +#define C422_C420_CONFIG_BYPASS BIT(5) +#define C422_C420_CONFIG_ENABLE BIT(4) +#define C422_C420_CONFIG_OUT_CB_OR_CR BIT(6) +#define C444_C422_CONFIG_ENABLE (0x1) + +#define CBIT_ORDER_SAME BIT(13) + +#define CEA_AUD_EN BIT(9) +#define CEA_AVI_EN BIT(11) +#define CEA_CP_EN BIT(6) +#define CEA_SPD_EN BIT(10) + +#define CLEAR_FIFO 0x9 + +#define CLOCK_SCL 0xA + +#define CP_CLR_MUTE_EN BIT(1) +#define CP_EN BIT(5) +#define CP_EN_WR BIT(21) +#define CP_RPT_EN BIT(5) +#define CP_SET_MUTE_DIS (0) +#define CP_SET_MUTE_EN (1) + +#define CTS_CAL_N4 BIT(23) +#define CTS_REQ_EN BIT(1) +#define CTS_SW_SEL (1) + +#define C_SD0 (0x0) +#define C_SD1 BIT(4) +#define C_SD2 BIT(9) +#define C_SD3 GENMASK(14, 12) +#define C_SD4 BIT(19) +#define C_SD5 (0x5 << 20) +#define C_SD6 GENMASK(26, 25) +#define C_SD7 GENMASK(30, 28) + +#define DATA_DIR_LSB BIT(9) +#define DATA_DIR_MSB (0) + +#define DDC_CMD GENMASK(31, 28) +#define DDC_CMD_SHIFT (28) +#define DDC_CTRL 0xC10 +#define DDC_DATA_OUT GENMASK(23, 16) +#define DDC_DATA_OUT_CNT GENMASK(12, 8) +#define DDC_DATA_OUT_SHIFT (16) +#define DDC_DELAY_CNT GENMASK(31, 16) +#define DDC_DELAY_CNT_SHIFT (16) +#define DDC_DIN_CNT (25, 16) +#define DDC_DIN_CNT_SHIFT (16) +#define DDC_I2C_BUS_LOW BIT(11) +#define DDC_I2C_IN_PROG BIT(13) +#define DDC_I2C_IN_PROG_INT_CLR BIT(29) +#define DDC_I2C_IN_PROG_INT_MASK (0) +#define DDC_I2C_IN_PROG_INT_STA BIT(1) +#define DDC_I2C_IN_PROG_INT_UNCLR (0) +#define DDC_I2C_IN_PROG_INT_UNMASK BIT(29) +#define DDC_I2C_NO_ACK BIT(10) +#define DDC_OFFSET GENMASK(15, 8) +#define DDC_OFFSET_SHIFT (8) +#define DDC_SEGMENT GENMASK(15, 8) +#define DDC_SEGMENT_SHIFT (8) + +#define DEEPCOLOR_MODE_10BIT BIT(8) +#define DEEPCOLOR_MODE_12BIT GENMASK(9, 8) +#define DEEPCOLOR_MODE_16BIT GENMASK(10, 8) +#define DEEPCOLOR_MODE_8BIT (0) +#define DEEPCOLOR_MODE_MASKBIT GENMASK(10, 8) +#define DEEPCOLOR_PAT_EN BIT(12) +#define DEEP_COLOR_ADD BIT(4) + +#define DOWNSAMPLE 0x2 + +#define DSD_EN BIT(15) +#define DSD_MUTE_DATA BIT(7) + +#define ENH_READ_NO_ACK 0x4 + +#define FIFO0_MAP GENMASK(1, 0) +#define FIFO1_MAP GENMASK(3, 2) +#define FIFO2_MAP GENMASK(5, 4) +#define FIFO3_MAP GENMASK(7, 6) + +#define FS_OVERRIDE_WRITE BIT(1) +#define FS_UNOVERRIDE (0) + +#define HBRA_ON BIT(14) + +#define HBR_FROM_SPDIF BIT(20) + +#define HDCP1X_CTRL 0xCD0 +#define HDCP1X_ENC_EN BIT(6) +#define HDCP1X_ENC_EN_SHIFT (6) +#define HDCP2X_CTRL_0 0xC20 +#define HDCP2X_DDCM_STATUS 0xC68 +#define HDCP2X_DIS_POLL_EN BIT(16) +#define HDCP2X_EN (0x1) +#define HDCP2X_ENCRYPTING_ON BIT(10) +#define HDCP2X_ENCRYPT_EN BIT(7) +#define HDCP2X_ENCRYPT_EN_SHIFT (7) +#define HDCP2X_HPD_OVR BIT(10) +#define HDCP2X_HPD_SW BIT(11) +#define HDCP2X_POL_CTRL 0xC54 +#define HDCP2X_RX_REAUTH_REQ_DDCM_INT_MASK (0) +#define HDCP2X_RX_REAUTH_REQ_DDCM_INT_UNMASK BIT(25) +#define HDCP_ENABLE (0) +#define HDCP_ENCRYPTING_ON BIT(26) +#define HDCP_TOP_CTRL 0xC00 + +#define HDMI2_OFF (0) +#define HDMI2_ON BIT(2) + +#define HDMITX_CONFIG 0x900 +#define HDMITX_SW_HPD BIT(29) +#define HDMITX_SW_HPD_SHIFT (29) +#define HDMITX_SW_RSTB BIT(31) +#define HDMITX_SW_RSTB_SHIFT (31) + +#define HDMI_MODE_DVI (0) +#define HDMI_MODE_HDMI BIT(3) + +#define HDMI_YUV420_MODE BIT(10) +#define HDMI_YUV420_MODE_SHIFT (10) + +#define HPD_DDC_CTRL 0xC08 +#define HPD_DDC_STATUS 0xC60 + +#define HPD_PIN_STA BIT(4) +#define HPD_STATE (0x3) +#define HPD_STATE_CONNECTED (2) +#define HPD_STATE_DISCONNECTED (0) +#define HPD_STATE_SHIFT (0) + +#define HTPLG_F_INT_STA BIT(1) +#define HTPLG_R_INT_STA BIT(0) + +#define I2S2DSD_EN BIT(30) +#define I2S_1ST_BIT_NOSHIFT BIT(8) +#define I2S_EN GENMASK(19, 16) +#define I2S_EN_SHIFT 16 + +#define JUSTIFY_RIGHT BIT(10) + +#define LAYOUT BIT(18) +#define LAYOUT0 0 +#define LAYOUT1 BIT(4) + +#define LFE_CC_SWAP BIT(1) + +#define MAP_SD0 0x0 +#define MAP_SD1 0x1 +#define MAP_SD2 0x2 +#define MAP_SD3 0x3 + +#define MAX_1UI_WRITE GENMASK(15, 8) +#define MAX_1UI_WRITE_SHIFT 8 +#define MAX_2UI_WRITE GENMASK(23, 16) +#define MAX_2UI_WRITE_SHIFT 16 + +#define MCLK_1152FS 0x6 +#define MCLK_128FS 0x0 +#define MCLK_192FS 0x7 +#define MCLK_256FS 0x1 +#define MCLK_384FS 0x2 +#define MCLK_512FS 0x3 +#define MCLK_768FS 0x4 +#define MCLK_CTSGEN_SEL 0 +#define MCLK_EN BIT(2) +#define NO_MCLK_CTSGEN_SEL BIT(3) + +#define NULL_PKT_EN BIT(2) +#define NULL_PKT_VSYNC_HIGH_EN BIT(3) + +#define OUTPUT_FORMAT_DEMUX_420_ENABLE BIT(10) + +#define PORD_F_INT_STA BIT(3) +#define PORD_PIN_STA BIT(5) +#define PORD_R_INT_STA BIT(2) + +#define REG_VMUTE_EN BIT(16) +#define RST4AUDIO BIT(0) +#define RST4AUDIO_ACR BIT(2) +#define RST4AUDIO_FIFO BIT(1) + +#define SCDC_CTRL 0xC18 + +#define SCK_EDGE_RISE BIT(14) + +#define SCR_OFF 0 +#define SCR_ON BIT(4) + +#define SEQ_READ_NO_ACK 0x2 +#define SEQ_WRITE_REQ_ACK 0x7 + +#define SI2C_ADDR GENMASK(23, 16) +#define SI2C_ADDR_READ (0xF4) +#define SI2C_ADDR_SHIFT (16) +#define SI2C_CONFIRM_READ BIT(2) +#define SI2C_CTRL 0xCAC +#define SI2C_RD BIT(1) +#define SI2C_WDATA GENMASK(15, 8) +#define SI2C_WDATA_SHIFT (8) +#define SI2C_WR BIT(0) + +#define SPDIF_EN BIT(13) +#define SPDIF_EN_SHIFT 13 +#define SPDIF_HEADER GENMASK(23, 0) +#define SPDIF_INTERNAL_MODULE BIT(24) +#define SPDIF_PKT00 GENMASK(31, 0) +#define SPDIF_PKT01 GENMASK(23, 0) +#define SPDIF_PKT02 GENMASK(31, 0) +#define SPDIF_PKT03 GENMASK(23, 0) +#define SPDIF_PKT04 GENMASK(31, 0) +#define SPDIF_PKT05 GENMASK(23, 0) +#define SPDIF_PKT06 GENMASK(31, 0) +#define SPDIF_PKT07 GENMASK(23, 0) + +#define SPD_DIS 0 +#define SPD_DIS_WR 0 +#define SPD_EN BIT(1) +#define SPD_EN_WR BIT(17) +#define SPD_RPT_DIS 0 +#define SPD_RPT_EN BIT(1) + +#define TOP_AIF_HEADER 0x040 +#define TOP_AIF_PKT00 0x044 +#define TOP_AIF_PKT01 0x048 +#define TOP_AIF_PKT02 0x04C +#define TOP_AIF_PKT03 0x050 +#define TOP_AUD_MAP 0x00C +#define TOP_AVI_HEADER 0x024 +#define TOP_AVI_PKT00 0x028 +#define TOP_AVI_PKT01 0x02C +#define TOP_AVI_PKT02 0x030 +#define TOP_AVI_PKT03 0x034 +#define TOP_AVI_PKT04 0x038 +#define TOP_AVI_PKT05 0x03C +#define TOP_CFG00 0x000 +#define TOP_CFG01 0x004 +#define TOP_INFO_EN 0x01C +#define TOP_INFO_EN_EXPAND 0x368 +#define TOP_INFO_RPT 0x020 +#define TOP_INT_CLR00 0x1B8 +#define TOP_INT_CLR01 0x1BC +#define TOP_INT_MASK00 0x1B0 +#define TOP_INT_MASK01 0x1B4 +#define TOP_INT_STA00 0x1A8 +#define TOP_MISC_CTLR 0x1A4 +#define TOP_SPDIF_HEADER 0x054 +#define TOP_SPDIF_PKT00 0x058 +#define TOP_SPDIF_PKT01 0x05C +#define TOP_SPDIF_PKT02 0x060 +#define TOP_SPDIF_PKT03 0x064 +#define TOP_SPDIF_PKT04 0x068 +#define TOP_SPDIF_PKT05 0x06C +#define TOP_SPDIF_PKT06 0x070 +#define TOP_SPDIF_PKT07 0x074 +#define TOP_VMUTE_CFG1 0x1C8 + +#define TPI_AUDIO_LOOKUP_DIS 0 +#define TPI_AUDIO_LOOKUP_EN BIT(2) + +#define VBIT_COM BIT(12) +#define VBIT_PCM 0 + +#define VID_DOWNSAMPLE_CONFIG 0x8F0 +#define VID_OUT_FORMAT 0x8FC + +#define WR_1UI_LOCK BIT(0) +#define WR_1UI_UNLOCK 0 +#define WR_2UI_LOCK BIT(2) +#define WR_2UI_UNLOCK 0 +#define WS_HIGH BIT(11) + +#endif /* _MTK_HDMI_REGS_H */ --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71436ECAAD3 for ; Mon, 19 Sep 2022 17:01:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230428AbiISRBf (ORCPT ); Mon, 19 Sep 2022 13:01:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45436 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230489AbiISRAs (ORCPT ); Mon, 19 Sep 2022 13:00:48 -0400 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3DCE83E77C for ; Mon, 19 Sep 2022 10:00:17 -0700 (PDT) Received: by mail-ed1-x52b.google.com with SMTP id z13so75343edb.13 for ; Mon, 19 Sep 2022 10:00:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=Kre50nfb+6BEGbTGtWkvwNMQoegOcYtOYC9/SwSm6f8=; b=0Th6xkomiw7RRU4eV8xKvzeVuqv9igT4YUIiF+fz9FtJl6AQJr6cUylRl97Sa49hBh 6l17/VtOS1JfGRYEA9ktohgZP64v55BdSEHVABve9fHkykAZU7T0QxxsGnZKMhdp/+rP v2BIL/btnIss2j44wG1sjgY2Y969e8rwzpXg3FjadU0AS/8z1pp0AijmMhnAP2C5G2t6 MJFHd1fTbnKVlWzfY10KM8HgfGVkki+TxxSPD1qv+sBLCJqtGEHiXOqMNJpYs47emDAN tKYx3XuJh1oUxEr1ULu0S+pcqTNSNu73nq54FfIv8re10yOtZGZDHaHUiGHmxSIMa9em DHBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=Kre50nfb+6BEGbTGtWkvwNMQoegOcYtOYC9/SwSm6f8=; b=KAIP6xXUPYuxdHq2lbQ6qOqGGwwCJJxWKbrwBPGoGgu6e0jNnh/aTxr3ot/JGhails oWZaqMbzmXxnuj6LRlHw2QN0CSac9wOCZXvpHUj3JaeaRaustx2Afk7/fSwFbCWUpetQ EpKHBzSfYl9uqzIfEdhBwmejlluNBiW7fEq+mUaIAhPkQ2oMtujconFX59f4Lad8cayT pHkKdRHM5g2h1NxSfEw/FuBnDeqljVF7wJO58HiQDO3AFpUaSgfz2jxQfu58Ht5Y6xWh ix7JrBg6d/bXOwFWTQS7xYZKD6wtU809D7rqOOkTKPQQDtrFDjYoJETtyxMGL8LRQfli S44w== X-Gm-Message-State: ACrzQf2vVEaEyqdDe7WErwcCL23S8aAAw3pJJgQGocunURZSEVzTV8Rt SVy83C34uV4k/QES8zIRh/ni+g== X-Google-Smtp-Source: AMsMyM7TDj1djPWF1WAySIx2Qr5YHYlG3ALhTric6pPD6CiuqCk+rwvCWWl/Ki8GCY4roCAi+n60uQ== X-Received: by 2002:a05:6402:40d1:b0:44f:e974:f981 with SMTP id z17-20020a05640240d100b0044fe974f981mr16903554edb.222.1663606812334; Mon, 19 Sep 2022 10:00:12 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.10.00.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 10:00:11 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:10 +0200 Subject: [PATCH v1 12/17] drm/mediatek: hdmi: mt8195: add audio support MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-12-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add HDMI audio support for mt8195 Signed-off-by: Guillaume Ranquet diff --git a/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c b/drivers/gpu/drm/m= ediatek/mtk_mt8195_hdmi.c index 39e07a6dd490..bb7593ea4c86 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c @@ -215,6 +215,26 @@ static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdm= i, bool black) mtk_hdmi_mask(hdmi, TOP_VMUTE_CFG1, 0, REG_VMUTE_EN); } =20 +static void mtk_hdmi_hw_aud_mute(struct mtk_hdmi *hdmi) +{ + u32 val; + + val =3D mtk_hdmi_read(hdmi, AIP_CTRL, &val); + + if (val & DSD_EN) + mtk_hdmi_mask(hdmi, AIP_TXCTRL, + DSD_MUTE_DATA | AUD_MUTE_FIFO_EN, + DSD_MUTE_DATA | AUD_MUTE_FIFO_EN); + else + mtk_hdmi_mask(hdmi, AIP_TXCTRL, AUD_MUTE_FIFO_EN, + AUD_MUTE_FIFO_EN); +} + +static void mtk_hdmi_hw_aud_unmute(struct mtk_hdmi *hdmi) +{ + mtk_hdmi_mask(hdmi, AIP_TXCTRL, AUD_MUTE_DIS, AUD_MUTE_FIFO_EN); +} + static void mtk_hdmi_hw_reset(struct mtk_hdmi *hdmi) { mtk_hdmi_mask(hdmi, HDMITX_CONFIG, 0x0 << HDMITX_SW_RSTB_SHIFT, @@ -899,6 +919,7 @@ static void mtk_hdmi_audio_reset(struct mtk_hdmi *hdmi,= bool rst) static void mtk_hdmi_aud_output_config(struct mtk_hdmi *hdmi, struct drm_display_mode *display_mode) { + mtk_hdmi_hw_aud_mute(hdmi); mtk_hdmi_aud_enable_packet(hdmi, false); mtk_hdmi_audio_reset(hdmi, true); mtk_hdmi_aip_ctrl_init(hdmi); @@ -911,6 +932,7 @@ static void mtk_hdmi_aud_output_config(struct mtk_hdmi = *hdmi, usleep_range(25, 50); mtk_hdmi_aud_on_off_hw_ncts(hdmi, true); mtk_hdmi_aud_enable_packet(hdmi, true); + mtk_hdmi_hw_aud_unmute(hdmi); } =20 void mtk_hdmi_output_init_mt8195(struct mtk_hdmi *hdmi) @@ -945,6 +967,28 @@ static void mtk_hdmi_reset_colorspace_setting(struct m= tk_hdmi *hdmi) hdmi->ycc_quantization_range =3D HDMI_YCC_QUANTIZATION_RANGE_LIMITED; } =20 +static void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi) +{ + mtk_hdmi_aud_enable_packet(hdmi, true); + hdmi->audio_enable =3D true; +} + +static void mtk_hdmi_audio_disable(struct mtk_hdmi *hdmi) +{ + mtk_hdmi_aud_enable_packet(hdmi, false); + hdmi->audio_enable =3D false; +} + +static void mtk_hdmi_audio_set_param(struct mtk_hdmi *hdmi, + struct hdmi_audio_param *param) +{ + if (!hdmi->audio_enable) + return; + + memcpy(&hdmi->aud_param, param, sizeof(*param)); + mtk_hdmi_aud_output_config(hdmi, &hdmi->mode); +} + static void mtk_hdmi_change_video_resolution(struct mtk_hdmi *hdmi) { bool is_over_340M =3D false; @@ -965,6 +1009,7 @@ static void mtk_hdmi_change_video_resolution(struct mt= k_hdmi *hdmi) =20 usleep_range(5, 10); mtk_hdmi_hw_vid_black(hdmi, true); + mtk_hdmi_hw_aud_mute(hdmi); mtk_hdmi_hw_send_av_unmute(hdmi); =20 mtk_hdmi_mask(hdmi, TOP_CFG01, NULL_PKT_VSYNC_HIGH_EN, @@ -1295,12 +1340,21 @@ static void mtk_hdmi_bridge_disable(struct drm_brid= ge *bridge, mtk_hdmi_hw_send_av_mute(hdmi); usleep_range(50000, 50050); mtk_hdmi_hw_vid_black(hdmi, true); + mtk_hdmi_hw_aud_mute(hdmi); mtk_hdmi_disable_hdcp_encrypt(hdmi); usleep_range(50000, 50050); =20 hdmi->enabled =3D false; } =20 +static void mtk_hdmi_handle_plugged_change(struct mtk_hdmi *hdmi, bool plu= gged) +{ + mutex_lock(&hdmi->update_plugged_status_lock); + if (hdmi->plugged_cb && hdmi->codec_dev) + hdmi->plugged_cb(hdmi->codec_dev, plugged); + mutex_unlock(&hdmi->update_plugged_status_lock); +} + static void mtk_hdmi_bridge_post_disable(struct drm_bridge *bridge, struct drm_bridge_state *old_state) { @@ -1314,6 +1368,9 @@ static void mtk_hdmi_bridge_post_disable(struct drm_b= ridge *bridge, hdmi->powered =3D false; =20 mtk_hdmi_reset_colorspace_setting(hdmi); + + /* signal the disconnect event to audio codec */ + mtk_hdmi_handle_plugged_change(hdmi, false); } =20 static void mtk_hdmi_bridge_pre_enable(struct drm_bridge *bridge, @@ -1346,6 +1403,10 @@ static void mtk_hdmi_bridge_enable(struct drm_bridge= *bridge, mtk_hdmi_hw_avi_infoframe(hdmi, buffer_avi, sizeof(buffer_avi)); =20 mtk_hdmi_hw_vid_black(hdmi, false); + mtk_hdmi_hw_aud_unmute(hdmi); + + /* signal the connect event to audio codec */ + mtk_hdmi_handle_plugged_change(hdmi, true); =20 hdmi->enabled =3D true; } @@ -1385,3 +1446,155 @@ const struct drm_bridge_funcs mtk_mt8195_hdmi_bridg= e_funcs =3D { .get_edid =3D mtk_hdmi_bridge_get_edid, .detect =3D mtk_hdmi_bridge_detect, }; + +static void mtk_hdmi_set_plugged_cb(struct mtk_hdmi *hdmi, + hdmi_codec_plugged_cb fn, + struct device *codec_dev) +{ + bool plugged; + + mutex_lock(&hdmi->update_plugged_status_lock); + hdmi->plugged_cb =3D fn; + hdmi->codec_dev =3D codec_dev; + plugged =3D (hdmi->hpd =3D=3D HDMI_PLUG_IN_AND_SINK_POWER_ON) ? true : fa= lse; + mutex_unlock(&hdmi->update_plugged_status_lock); + + mtk_hdmi_handle_plugged_change(hdmi, plugged); +} + +/* + * HDMI audio codec callbacks + */ +static int mtk_hdmi_audio_hook_plugged_cb(struct device *dev, void *data, + hdmi_codec_plugged_cb fn, + struct device *codec_dev) +{ + struct mtk_hdmi *hdmi =3D dev_get_drvdata(dev); + + if (!hdmi) + return -ENODEV; + + mtk_hdmi_set_plugged_cb(hdmi, fn, codec_dev); + return 0; +} + +static int mtk_hdmi_audio_hw_params(struct device *dev, void *data, + struct hdmi_codec_daifmt *daifmt, + struct hdmi_codec_params *params) +{ + struct mtk_hdmi *hdmi =3D dev_get_drvdata(dev); + struct hdmi_audio_param hdmi_params; + unsigned int chan =3D params->cea.channels; + + if (!hdmi->bridge.encoder) + return -ENODEV; + + switch (chan) { + case 2: + hdmi_params.aud_input_chan_type =3D HDMI_AUD_CHAN_TYPE_2_0; + break; + case 4: + hdmi_params.aud_input_chan_type =3D HDMI_AUD_CHAN_TYPE_4_0; + break; + case 6: + hdmi_params.aud_input_chan_type =3D HDMI_AUD_CHAN_TYPE_5_1; + break; + case 8: + hdmi_params.aud_input_chan_type =3D HDMI_AUD_CHAN_TYPE_7_1; + break; + default: + return -EINVAL; + } + + switch (params->sample_rate) { + case 32000: + case 44100: + case 48000: + case 88200: + case 96000: + case 176400: + case 192000: + break; + default: + return -EINVAL; + } + + switch (daifmt->fmt) { + case HDMI_I2S: + hdmi_params.aud_codec =3D HDMI_AUDIO_CODING_TYPE_PCM; + hdmi_params.aud_sampe_size =3D HDMI_AUDIO_SAMPLE_SIZE_16; + hdmi_params.aud_input_type =3D HDMI_AUD_INPUT_I2S; + hdmi_params.aud_i2s_fmt =3D HDMI_I2S_MODE_I2S_24BIT; + hdmi_params.aud_mclk =3D HDMI_AUD_MCLK_128FS; + break; + default: + return -EINVAL; + } + + memcpy(&hdmi_params.codec_params, params, + sizeof(hdmi_params.codec_params)); + + mtk_hdmi_audio_set_param(hdmi, &hdmi_params); + + return 0; +} + +static int mtk_hdmi_audio_startup(struct device *dev, void *data) +{ + struct mtk_hdmi *hdmi =3D dev_get_drvdata(dev); + + mtk_hdmi_audio_enable(hdmi); + + return 0; +} + +static void mtk_hdmi_audio_shutdown(struct device *dev, void *data) +{ + struct mtk_hdmi *hdmi =3D dev_get_drvdata(dev); + + mtk_hdmi_audio_disable(hdmi); +} + +static int mtk_hdmi_audio_mute(struct device *dev, void *data, bool enable, + int direction) +{ + struct mtk_hdmi *hdmi =3D dev_get_drvdata(dev); + + if (direction !=3D SNDRV_PCM_STREAM_PLAYBACK) + return 0; + + if (enable) + mtk_hdmi_hw_aud_mute(hdmi); + else + mtk_hdmi_hw_aud_unmute(hdmi); + + return 0; +} + +static int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t = *buf, + size_t len) +{ + struct mtk_hdmi *hdmi =3D dev_get_drvdata(dev); + + if (hdmi->enabled) + memcpy(buf, hdmi->conn.eld, min(sizeof(hdmi->conn.eld), len)); + else + memset(buf, 0, len); + return 0; +} + +static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops =3D { + .hw_params =3D mtk_hdmi_audio_hw_params, + .audio_startup =3D mtk_hdmi_audio_startup, + .audio_shutdown =3D mtk_hdmi_audio_shutdown, + .mute_stream =3D mtk_hdmi_audio_mute, + .get_eld =3D mtk_hdmi_audio_get_eld, + .hook_plugged_cb =3D mtk_hdmi_audio_hook_plugged_cb, +}; + +void set_hdmi_codec_pdata_mt8195(struct hdmi_codec_pdata *codec_data) +{ + codec_data->ops =3D &mtk_hdmi_audio_codec_ops; + codec_data->max_i2s_channels =3D 2; + codec_data->i2s =3D 1; +} diff --git a/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h b/drivers/gpu/drm/m= ediatek/mtk_mt8195_hdmi.h index f59aea51dc74..22af64916219 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h +++ b/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h @@ -9,6 +9,7 @@ =20 #include #include +#include =20 struct mtk_hdmi; =20 @@ -17,6 +18,7 @@ extern const struct drm_bridge_funcs mtk_mt8195_hdmi_brid= ge_funcs; void mtk_hdmi_output_init_mt8195(struct mtk_hdmi *hdmi); int mtk_hdmi_clk_enable_mt8195(struct mtk_hdmi *hdmi); void mtk_hdmi_clk_disable_mt8195(struct mtk_hdmi *hdmi); +void set_hdmi_codec_pdata_mt8195(struct hdmi_codec_pdata *codec_data); =20 enum mtk_hdmi_clk_id_mt8195 { MTK_MT8195_HDIM_HDCP_SEL, --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6EF1EECAAA1 for ; Mon, 19 Sep 2022 17:01:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230303AbiISRBG (ORCPT ); Mon, 19 Sep 2022 13:01:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230471AbiISRAo (ORCPT ); Mon, 19 Sep 2022 13:00:44 -0400 Received: from mail-ej1-x62b.google.com (mail-ej1-x62b.google.com [IPv6:2a00:1450:4864:20::62b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB81C3ECC4 for ; Mon, 19 Sep 2022 10:00:17 -0700 (PDT) Received: by mail-ej1-x62b.google.com with SMTP id y3so183964ejc.1 for ; Mon, 19 Sep 2022 10:00:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=23EqGi3gFXXOB6EHxNrULl8XJT9OcS+TsgqB/BHqbHw=; b=cn9iS0q0xgkjHJD+ds6dZQH5Wy9i/TPkeNeu1+g/E8IpAhA+7/wzTwuy7sZV3qHvfQ GC/lUWWZJ92voqvSw2+0phX12M4JLdIbDHkhE+jM7LKwpctaymK9eaAv17XKtP6uRqnn 4kqirP8cJnH0CPHjDEkXydaKMjHfFtUdgLMpTup6zuKcOicQQ6jeMHFPeHK/Gl4qLwah yrKgsk45GGW17HRqO1FIk3NnwzwIkgCbTq8T7p/Hje+0dxGUVe6op7iQ0gRQsLeYldiI 1q+9QKpoYBPCHArfwScqBaDWwBgERHtGHIRSLAdz/VQBZyeHVoC4Yqz5qDa4kvYw6HMe LwbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=23EqGi3gFXXOB6EHxNrULl8XJT9OcS+TsgqB/BHqbHw=; b=RHgNfBIF57LRHiQMfxn7OREn2SxjpbosPGdq9thtd98qOE3AYY9KNKO0b4T+3G3XmL RsVzRzstnE1pkpVNPgzabpzCPBnnOusug69Ms9u37GyOuwLWDLof4KBSXdYiPEloc8G+ sjYVJTbVSo9SpokDaSAjd0RjY6h/6Lx5UQTV8PgC5AjNWP7lVDH6qrRwIjJlJuFGqTYQ wTVaoeOr9XdONufcv4Quaz7CLLea0kdlB686QjJL0U/U6zzqRAb8dcNFp7F++MX1wE1l TBdfD3zAHY3thT584AKcti1tmPOSFsL7Zyz5fdvx9l4YFEy4NF1iBvLx6sdF/YNm1gjB Xdzw== X-Gm-Message-State: ACrzQf2uJUdpA5b1CXY3gvJlOqeV/w2cxnRe8eaJFN/R5XdxUC1jPMgK ChSVixNNQ0oYCVahn2/Xo/s98A== X-Google-Smtp-Source: AMsMyM4ibbztqMuL5CwwVz+5760qZJ0rcMYySRyQ9feIjgEn12tXb0Qh8bg5Wo1IiM/vXpoPAiZsRg== X-Received: by 2002:a17:907:728d:b0:77e:1942:f772 with SMTP id dt13-20020a170907728d00b0077e1942f772mr13919231ejc.222.1663606815174; Mon, 19 Sep 2022 10:00:15 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.10.00.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 10:00:14 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:11 +0200 Subject: [PATCH v1 13/17] phy: phy-mtk-hdmi: Add generic phy configure callback MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-13-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some phys, such as mt8195, needs to have a configure callback defined. Signed-off-by: Guillaume Ranquet diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy= -mtk-hdmi.c index d4bd419abc3c..af46472237e0 100644 Reviewed-by: AngeloGioacchino Del Regno --- a/drivers/phy/mediatek/phy-mtk-hdmi.c +++ b/drivers/phy/mediatek/phy-mtk-hdmi.c @@ -8,10 +8,12 @@ =20 static int mtk_hdmi_phy_power_on(struct phy *phy); static int mtk_hdmi_phy_power_off(struct phy *phy); +static int mtk_hdmi_phy_configure(struct phy *phy, union phy_configure_opt= s *opts); =20 static const struct phy_ops mtk_hdmi_phy_dev_ops =3D { .power_on =3D mtk_hdmi_phy_power_on, .power_off =3D mtk_hdmi_phy_power_off, + .configure =3D mtk_hdmi_phy_configure, .owner =3D THIS_MODULE, }; =20 @@ -76,6 +78,16 @@ static int mtk_hdmi_phy_power_off(struct phy *phy) return 0; } =20 +static int mtk_hdmi_phy_configure(struct phy *phy, union phy_configure_opt= s *opts) +{ + struct mtk_hdmi_phy *hdmi_phy =3D phy_get_drvdata(phy); + + if (hdmi_phy->conf->hdmi_phy_configure) + return hdmi_phy->conf->hdmi_phy_configure(phy, opts); + + return 0; +} + static const struct phy_ops * mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy) { diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.h b/drivers/phy/mediatek/phy= -mtk-hdmi.h index dcf9bb13699b..05de93f63a61 100644 --- a/drivers/phy/mediatek/phy-mtk-hdmi.h +++ b/drivers/phy/mediatek/phy-mtk-hdmi.h @@ -25,6 +25,7 @@ struct mtk_hdmi_phy_conf { const struct clk_ops *hdmi_phy_clk_ops; void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy); void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy); + int (*hdmi_phy_configure)(struct phy *phy, union phy_configure_opts *opts= ); }; =20 struct mtk_hdmi_phy { --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 42A75C6FA91 for ; Mon, 19 Sep 2022 17:01:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230258AbiISRBl (ORCPT ); Mon, 19 Sep 2022 13:01:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45578 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230396AbiISRAx (ORCPT ); Mon, 19 Sep 2022 13:00:53 -0400 Received: from mail-ej1-x633.google.com (mail-ej1-x633.google.com [IPv6:2a00:1450:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9192F3ECCD for ; Mon, 19 Sep 2022 10:00:18 -0700 (PDT) Received: by mail-ej1-x633.google.com with SMTP id go34so170374ejc.2 for ; Mon, 19 Sep 2022 10:00:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=6Ns2Pm2rUGq3jiG60VjqsDK4HnnQNmbR98T2rl8ehdM=; b=xHa+hjfRysbfvpRLDelq0D+eTiaWSE9FJjQKdNuHEG1YGMfAaC+mxlcASeXZvRQlqO LE+oaHfPwI1XokIpOn2Ohn71LJSM83opsNOo9QxHYCVz7UZ6GNoR6ESLYo0Yh9Tn2o+1 TGHq5sGYxFpFgU+rCdSBlu6wsLw1C62zfkMf6wLwDlhqxLVIoDQtPl2cgqgaVNKIgLKS X8Iopk5ZsvoXsmUOFKMUnz7sgrrqfYNX3H46OXkMDGmffPBCoiXt4MP3tjr0tfXCTAc6 o29uQvfI+eNmw9iSuqcvhKc9Nek0m/CNEVoIorIVBQgIJPWXF7gOJaEIlWsrw5+fmQGl nUZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=6Ns2Pm2rUGq3jiG60VjqsDK4HnnQNmbR98T2rl8ehdM=; b=L93L+mIy4XzatA1I4C5pySIx2bUxegVzyF44fUetSyDWK1wzE0QUMBSC21ZM1PZENd SBaf+Q0toanFdxL8mRZw8Evt2patpOUX71wDtxZwWJnI8ZcZdn2rZg1H7lEmwFsvfqyO 63hFhmYx+4nQoSf5pBCWBr3fauATthkLiV9coxhul03hrUjNzIqFvDxfJjHIMJF2LWul 83AzV+Mnvsby4wermbST+yrgP1qMVmzwRbqoHGZV5VaOrTxB+8iQPSNCHbpSkzcl8Wpx H2HRkZUlMbCQweSBGSOXSRnX0VKoBi+IiDj89pIzWB4yGtShQG1dU3LEDl6GnvNgdJ5Q fJ3A== X-Gm-Message-State: ACrzQf3gcVTYjyQADaBPrEHu4JVwcOidclam1vaexdjBn16yPYdRDdZS 9nuTxYxREaFVX48+z+VmCzmetA== X-Google-Smtp-Source: AMsMyM4ViGIL+wahkET1UxkP8Q5HLa7yxo8yLdVZVd91v61eSJzWLKupJCkRKRPb2RCBBckCjZvq5A== X-Received: by 2002:a17:907:2c77:b0:77c:59aa:c011 with SMTP id ib23-20020a1709072c7700b0077c59aac011mr13940102ejc.724.1663606817806; Mon, 19 Sep 2022 10:00:17 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.10.00.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 10:00:16 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:12 +0200 Subject: [PATCH v1 14/17] phy: mediatek: add support for phy-mtk-hdmi-mt8195 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-14-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add basic support for the mediatek hdmi phy on MT8195 SoC Signed-off-by: Guillaume Ranquet diff --git a/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c b/drivers/gpu/drm/m= ediatek/mtk_mt8195_hdmi.c index bb7593ea4c86..0157acdce56c 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c @@ -1344,6 +1344,8 @@ static void mtk_hdmi_bridge_disable(struct drm_bridge= *bridge, mtk_hdmi_disable_hdcp_encrypt(hdmi); usleep_range(50000, 50050); =20 + phy_power_off(hdmi->phy); + hdmi->enabled =3D false; } =20 diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile index fb1f8edaffa7..c9a50395533e 100644 --- a/drivers/phy/mediatek/Makefile +++ b/drivers/phy/mediatek/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_PHY_MTK_XSPHY) +=3D phy-mtk-xsphy.o phy-mtk-hdmi-drv-y :=3D phy-mtk-hdmi.o phy-mtk-hdmi-drv-y +=3D phy-mtk-hdmi-mt2701.o phy-mtk-hdmi-drv-y +=3D phy-mtk-hdmi-mt8173.o +phy-mtk-hdmi-drv-y +=3D phy-mtk-hdmi-mt8195.o obj-$(CONFIG_PHY_MTK_HDMI) +=3D phy-mtk-hdmi-drv.o =20 phy-mtk-mipi-dsi-drv-y :=3D phy-mtk-mipi-dsi.o diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c b/drivers/phy/media= tek/phy-mtk-hdmi-mt8195.c new file mode 100644 index 000000000000..149015b64c02 --- /dev/null +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c @@ -0,0 +1,673 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + * Copyright (c) 2021 BayLibre, SAS + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "phy-mtk-hdmi.h" +#include "phy-mtk-hdmi-mt8195.h" + +static void mtk_hdmi_ana_fifo_en(struct mtk_hdmi_phy *hdmi_phy) +{ + /* make data fifo writable for hdmi2.0 */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_ANA_CTL, REG_ANA_HDMI20_FIFO_EN, + REG_ANA_HDMI20_FIFO_EN); +} + +static void +mtk_mt8195_phy_tmds_high_bit_clk_ratio(struct mtk_hdmi_phy *hdmi_phy, + bool enable) +{ + mtk_hdmi_ana_fifo_en(hdmi_phy); + + /* HDMI 2.0 specification, 3.4Gbps <=3D TMDS Bit Rate <=3D 6G, + * clock bit ratio 1:40, under 3.4Gbps, clock bit ratio 1:10 + */ + if (enable) + mtk_hdmi_phy_mask(hdmi_phy, HDMI20_CLK_CFG, + 0x2 << REG_TXC_DIV_SHIFT, REG_TXC_DIV); + else + mtk_hdmi_phy_mask(hdmi_phy, HDMI20_CLK_CFG, 0, REG_TXC_DIV); +} + +static void mtk_hdmi_pll_select_source(struct clk_hw *hw) +{ + struct mtk_hdmi_phy *hdmi_phy =3D to_mtk_hdmi_phy(hw); + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CTL_3, 0x0, REG_HDMITX_REF_XTAL_SEL); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CTL_3, 0x0, REG_HDMITX_REF_RESPLL_SEL); + + /* DA_HDMITX21_REF_CK for TXPLL input source */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_10, 0x0, + RG_HDMITXPLL_REF_CK_SEL); +} + +static int mtk_hdmi_pll_performance_setting(struct clk_hw *hw) +{ + struct mtk_hdmi_phy *hdmi_phy =3D to_mtk_hdmi_phy(hw); + + /* BP2 */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_0, + 0x1 << RG_HDMITXPLL_BP2_SHIFT, RG_HDMITXPLL_BP2); + + /* BC */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_2, + 0x3 << RG_HDMITXPLL_BC_SHIFT, RG_HDMITXPLL_BC); + + /* IC */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_2, + 0x1 << RG_HDMITXPLL_IC_SHIFT, RG_HDMITXPLL_IC); + + /* BR */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_2, + 0x2 << RG_HDMITXPLL_BR_SHIFT, RG_HDMITXPLL_BR); + + /* IR */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_2, + 0x2 << RG_HDMITXPLL_IR_SHIFT, RG_HDMITXPLL_IR); + + /* BP */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_2, + 0xf << RG_HDMITXPLL_BP_SHIFT, RG_HDMITXPLL_BP); + + /* IBAND_FIX_EN, RESERVE[14] */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_0, + 0x0 << RG_HDMITXPLL_IBAND_FIX_EN_SHIFT, + RG_HDMITXPLL_IBAND_FIX_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_1, + 0x0 << RG_HDMITXPLL_RESERVE_BIT14_SHIFT, + RG_HDMITXPLL_RESERVE_BIT14); + + /* HIKVCO */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_2, + 0x0 << RG_HDMITXPLL_HIKVCO_SHIFT, + RG_HDMITXPLL_HIKVCO); + + /* HREN */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_0, + 0x1 << RG_HDMITXPLL_HREN_SHIFT, RG_HDMITXPLL_HREN); + + /* LVR_SEL */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_0, + 0x1 << RG_HDMITXPLL_LVR_SEL_SHIFT, + RG_HDMITXPLL_LVR_SEL); + + /* RG_HDMITXPLL_RESERVE[12:11] */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_1, + 0x3 << RG_HDMITXPLL_RESERVE_BIT12_11_SHIFT, + RG_HDMITXPLL_RESERVE_BIT12_11); + + /* TCL_EN */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_0, + 0x1 << RG_HDMITXPLL_TCL_EN_SHIFT, + RG_HDMITXPLL_TCL_EN); + + return 0; +} + +static int mtk_hdmi_pll_set_hw(struct clk_hw *hw, unsigned char prediv, + unsigned char fbkdiv_high, + unsigned long fbkdiv_low, + unsigned char fbkdiv_hs3, unsigned char posdiv1, + unsigned char posdiv2, unsigned char txprediv, + unsigned char txposdiv, + unsigned char digital_div) +{ + unsigned char txposdiv_value =3D 0; + unsigned char div3_ctrl_value =3D 0; + unsigned char posdiv_vallue =3D 0; + unsigned char div_ctrl_value =3D 0; + unsigned char reserve_3_2_value =3D 0; + unsigned char prediv_value =3D 0; + unsigned char reserve13_value =3D 0; + struct mtk_hdmi_phy *hdmi_phy =3D to_mtk_hdmi_phy(hw); + + mtk_hdmi_pll_select_source(hw); + + mtk_hdmi_pll_performance_setting(hw); + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_10, + 0x2 << RG_HDMITX21_BIAS_PE_BG_VREF_SEL_SHIFT, + RG_HDMITX21_BIAS_PE_BG_VREF_SEL); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_10, + 0x0 << RG_HDMITX21_VREF_SEL_SHIFT, + RG_HDMITX21_VREF_SEL); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_9, + 0x2 << RG_HDMITX21_SLDO_VREF_SEL_SHIFT, + RG_HDMITX21_SLDO_VREF_SEL); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_10, + 0x0 << RG_HDMITX21_BIAS_PE_VREF_SELB_SHIFT, + RG_HDMITX21_BIAS_PE_VREF_SELB); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_3, + 0x1 << RG_HDMITX21_SLDOLPF_EN_SHIFT, + RG_HDMITX21_SLDOLPF_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + 0x11 << RG_HDMITX21_INTR_CAL_SHIFT, + RG_HDMITX21_INTR_CAL); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_2, + 0x1 << RG_HDMITXPLL_PWD_SHIFT, RG_HDMITXPLL_PWD); + + /* TXPOSDIV */ + if (txposdiv =3D=3D 1) + txposdiv_value =3D 0x0; + else if (txposdiv =3D=3D 2) + txposdiv_value =3D 0x1; + else if (txposdiv =3D=3D 4) + txposdiv_value =3D 0x2; + else if (txposdiv =3D=3D 8) + txposdiv_value =3D 0x3; + else + return -EINVAL; + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + txposdiv_value << RG_HDMITX21_TX_POSDIV_SHIFT, + RG_HDMITX21_TX_POSDIV); + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + 0x1 << RG_HDMITX21_TX_POSDIV_EN_SHIFT, + RG_HDMITX21_TX_POSDIV_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + 0x0 << RG_HDMITX21_FRL_EN_SHIFT, RG_HDMITX21_FRL_EN); + + /* TXPREDIV */ + if (txprediv =3D=3D 2) { + div3_ctrl_value =3D 0x0; + posdiv_vallue =3D 0x0; + } else if (txprediv =3D=3D 4) { + div3_ctrl_value =3D 0x0; + posdiv_vallue =3D 0x1; + } else if (txprediv =3D=3D 6) { + div3_ctrl_value =3D 0x1; + posdiv_vallue =3D 0x0; + } else if (txprediv =3D=3D 12) { + div3_ctrl_value =3D 0x1; + posdiv_vallue =3D 0x1; + } else { + return -EINVAL; + } + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_4, + div3_ctrl_value + << RG_HDMITXPLL_POSDIV_DIV3_CTRL_SHIFT, + RG_HDMITXPLL_POSDIV_DIV3_CTRL); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_4, + posdiv_vallue << RG_HDMITXPLL_POSDIV_SHIFT, + RG_HDMITXPLL_POSDIV); + + /* POSDIV1 */ + if (posdiv1 =3D=3D 5) + div_ctrl_value =3D 0x0; + else if (posdiv1 =3D=3D 10) + div_ctrl_value =3D 0x1; + else if (posdiv1 =3D=3D (125 / 10)) + div_ctrl_value =3D 0x2; + else if (posdiv1 =3D=3D 15) + div_ctrl_value =3D 0x3; + else + return -EINVAL; + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_4, + div_ctrl_value << RG_HDMITXPLL_DIV_CTRL_SHIFT, + RG_HDMITXPLL_DIV_CTRL); + + /* DE add new setting */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_1, + 0x0 << RG_HDMITXPLL_RESERVE_BIT14_SHIFT, + RG_HDMITXPLL_RESERVE_BIT14); + + /* POSDIV2 */ + if (posdiv2 =3D=3D 1) + reserve_3_2_value =3D 0x0; + else if (posdiv2 =3D=3D 2) + reserve_3_2_value =3D 0x1; + else if (posdiv2 =3D=3D 4) + reserve_3_2_value =3D 0x2; + else if (posdiv2 =3D=3D 6) + reserve_3_2_value =3D 0x3; + else + return -EINVAL; + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_1, + reserve_3_2_value + << RG_HDMITXPLL_RESERVE_BIT3_2_SHIFT, + RG_HDMITXPLL_RESERVE_BIT3_2); + + /* DE add new setting */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_1, + 0x2 << RG_HDMITXPLL_RESERVE_BIT1_0_SHIFT, + RG_HDMITXPLL_RESERVE_BIT1_0); + + /* PREDIV */ + if (prediv =3D=3D 1) + prediv_value =3D 0x0; + else if (prediv =3D=3D 2) + prediv_value =3D 0x1; + else if (prediv =3D=3D 4) + prediv_value =3D 0x2; + else + return -EINVAL; + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_4, + prediv_value << RG_HDMITXPLL_PREDIV_SHIFT, + RG_HDMITXPLL_PREDIV); + + /* FBKDIV_HS3 */ + if (fbkdiv_hs3 =3D=3D 1) + reserve13_value =3D 0x0; + else if (fbkdiv_hs3 =3D=3D 2) + reserve13_value =3D 0x1; + else + return -EINVAL; + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_1, + reserve13_value << RG_HDMITXPLL_RESERVE_BIT13_SHIFT, + RG_HDMITXPLL_RESERVE_BIT13); + + /* FBDIV */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_4, + fbkdiv_high << RG_HDMITXPLL_FBKDIV_high_SHIFT, + RG_HDMITXPLL_FBKDIV_HIGH); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_3, + fbkdiv_low << RG_HDMITXPLL_FBKDIV_low_SHIFT, + RG_HDMITXPLL_FBKDIV_low); + + /* Digital DIVIDER */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CTL_3, + 0x0 << REG_PIXEL_CLOCK_SEL_SHIFT, + REG_PIXEL_CLOCK_SEL); + + if (digital_div =3D=3D 1) { + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CTL_3, + 0x0 << REG_HDMITX_PIXEL_CLOCK_SHIFT, + REG_HDMITX_PIXEL_CLOCK); + } else { + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CTL_3, + 0x1 << REG_HDMITX_PIXEL_CLOCK_SHIFT, + REG_HDMITX_PIXEL_CLOCK); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CTL_3, + (digital_div - 1) << REG_HDMITXPLL_DIV_SHIFT, + REG_HDMITXPLL_DIV); + } + + return 0; +} + +#define PCW_DECIMAL_WIDTH 24 + +static int mtk_hdmi_pll_calculate_params(struct clk_hw *hw, unsigned long = rate, + unsigned long parent_rate) +{ + int ret; + unsigned long long tmds_clk =3D 0; + unsigned long long pixel_clk =3D 0; + //pll input source frequency + unsigned long long da_hdmitx21_ref_ck =3D 0; + unsigned long long ns_hdmipll_ck =3D 0; //ICO output clk + //source clk for Display digital + unsigned long long ad_hdmipll_pixel_ck =3D 0; + unsigned char digital_div =3D 0; + unsigned long long pcw =3D 0; //FBDIV + unsigned char txprediv =3D 0; + unsigned char txposdiv =3D 0; + unsigned char fbkdiv_high =3D 0; + unsigned long fbkdiv_low =3D 0; + unsigned char posdiv1 =3D 0; + unsigned char posdiv2 =3D 0; + unsigned char prediv =3D 1; //prediv is always 1 + unsigned char fbkdiv_hs3 =3D 1; //fbkdiv_hs3 is always 1 + int i =3D 0; + unsigned char txpredivs[4] =3D { 2, 4, 6, 12 }; + + pixel_clk =3D rate; + tmds_clk =3D pixel_clk; + + if (tmds_clk < 25000000 || tmds_clk > 594000000) + return -EINVAL; + + da_hdmitx21_ref_ck =3D 26000000UL; //in HZ + + /* TXPOSDIV stage treatment: + * 0M < TMDS clk < 54M /8 + * 54M <=3D TMDS clk < 148.35M /4 + * 148.35M <=3DTMDS clk < 296.7M /2 + * 296.7 <=3DTMDS clk <=3D 594M /1 + */ + if (tmds_clk < 54000000UL) + txposdiv =3D 8; + else if (tmds_clk >=3D 54000000UL && tmds_clk < 148350000UL) + txposdiv =3D 4; + else if (tmds_clk >=3D 148350000UL && tmds_clk < 296700000UL) + txposdiv =3D 2; + else if (tmds_clk >=3D 296700000UL && tmds_clk <=3D 594000000UL) + txposdiv =3D 1; + else + return -EINVAL; + + /* calculate txprediv: can be 2, 4, 6, 12 + * ICO clk =3D 5*TMDS_CLK*TXPOSDIV*TXPREDIV + * ICO clk constraint: 5G =3D< ICO clk <=3D 12G + */ + for (i =3D 0; i < ARRAY_SIZE(txpredivs); i++) { + ns_hdmipll_ck =3D 5 * tmds_clk * txposdiv * txpredivs[i]; + if (ns_hdmipll_ck >=3D 5000000000UL && + ns_hdmipll_ck <=3D 12000000000UL) + break; + } + if (i =3D=3D (ARRAY_SIZE(txpredivs) - 1) && + (ns_hdmipll_ck < 5000000000UL || ns_hdmipll_ck > 12000000000UL)) { + return -EINVAL; + } + if (i =3D=3D ARRAY_SIZE(txpredivs)) + return -EINVAL; + + txprediv =3D txpredivs[i]; + + /* PCW calculation: FBKDIV + * formula: pcw=3D(frequency_out*2^pcw_bit) / frequency_in / FBKDIV_HS3; + * RG_HDMITXPLL_FBKDIV[32:0]: + * [32,24] 9bit integer, [23,0]:24bit fraction + */ + pcw =3D ns_hdmipll_ck; + pcw =3D pcw << PCW_DECIMAL_WIDTH; + pcw =3D pcw / da_hdmitx21_ref_ck; + pcw =3D pcw / fbkdiv_hs3; + + if ((pcw / BIT(32)) > 1) { + return -EINVAL; + } else if ((pcw / BIT(32)) =3D=3D 1) { + fbkdiv_high =3D 1; + fbkdiv_low =3D pcw % BIT(32); + } else { + fbkdiv_high =3D 0; + fbkdiv_low =3D pcw; + } + + /* posdiv1: + * posdiv1 stage treatment according to color_depth: + * 24bit -> posdiv1 /10, 30bit -> posdiv1 /12.5, + * 36bit -> posdiv1 /15, 48bit -> posdiv1 /10 + */ + posdiv1 =3D 10; // div 10 + posdiv2 =3D 1; + ad_hdmipll_pixel_ck =3D (ns_hdmipll_ck / 10) / 1; + + /* Digital clk divider, max /32 */ + digital_div =3D ad_hdmipll_pixel_ck / pixel_clk; + if (!(digital_div <=3D 32 && digital_div >=3D 1)) + return -EINVAL; + + ret =3D mtk_hdmi_pll_set_hw(hw, prediv, fbkdiv_high, fbkdiv_low, + fbkdiv_hs3, posdiv1, posdiv2, txprediv, + txposdiv, digital_div); + if (ret) + return -EINVAL; + + return 0; +} + +static int mtk_hdmi_pll_drv_setting(struct clk_hw *hw) +{ + unsigned char data_channel_bias, clk_channel_bias; + unsigned char impedance, impedance_en; + struct mtk_hdmi_phy *hdmi_phy =3D to_mtk_hdmi_phy(hw); + unsigned long tmds_clk; + unsigned long pixel_clk =3D hdmi_phy->pll_rate; + + tmds_clk =3D pixel_clk; + + /* bias & impedance setting: + * 3G < data rate <=3D 6G: enable impedance 100ohm, + * data channel bias 24mA, clock channel bias 20mA + * pixel clk >=3D HD, 74.175MHZ <=3D pixel clk <=3D 300MHZ: + * enalbe impedance 100ohm + * data channel 20mA, clock channel 16mA + * 27M =3D< pixel clk < 74.175: disable impedance + * data channel & clock channel bias 10mA + */ + + /* 3G < data rate <=3D 6G, 300M < tmds rate <=3D 594M */ + if (tmds_clk > 300000000UL && tmds_clk <=3D 594000000UL) { + data_channel_bias =3D 0x3c; //24mA + clk_channel_bias =3D 0x34; //20mA + impedance_en =3D 0xf; + impedance =3D 0x36; //100ohm + } else if (pixel_clk >=3D 74175000UL && pixel_clk <=3D 300000000UL) { + data_channel_bias =3D 0x34; //20mA + clk_channel_bias =3D 0x2c; //16mA + impedance_en =3D 0xf; + impedance =3D 0x36; //100ohm + } else if (pixel_clk >=3D 27000000UL && pixel_clk < 74175000UL) { + data_channel_bias =3D 0x14; //10mA + clk_channel_bias =3D 0x14; //10mA + impedance_en =3D 0x0; + impedance =3D 0x0; + } else { + return -EINVAL; + } + + /* bias */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_1, + data_channel_bias << RG_HDMITX21_DRV_IBIAS_D0_SHIFT, + RG_HDMITX21_DRV_IBIAS_D0); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_1, + data_channel_bias << RG_HDMITX21_DRV_IBIAS_D1_SHIFT, + RG_HDMITX21_DRV_IBIAS_D1); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_1, + data_channel_bias << RG_HDMITX21_DRV_IBIAS_D2_SHIFT, + RG_HDMITX21_DRV_IBIAS_D2); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_0, + clk_channel_bias << RG_HDMITX21_DRV_IBIAS_CLK_SHIFT, + RG_HDMITX21_DRV_IBIAS_CLK); + + /* impedance */ + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_0, + impedance_en << RG_HDMITX21_DRV_IMP_EN_SHIFT, + RG_HDMITX21_DRV_IMP_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_2, + impedance << RG_HDMITX21_DRV_IMP_D0_EN1_SHIFT, + RG_HDMITX21_DRV_IMP_D0_EN1); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_2, + impedance << RG_HDMITX21_DRV_IMP_D1_EN1_SHIFT, + RG_HDMITX21_DRV_IMP_D1_EN1); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_2, + impedance << RG_HDMITX21_DRV_IMP_D2_EN1_SHIFT, + RG_HDMITX21_DRV_IMP_D2_EN1); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_2, + impedance << RG_HDMITX21_DRV_IMP_CLK_EN1_SHIFT, + RG_HDMITX21_DRV_IMP_CLK_EN1); + + return 0; +} + +static int mtk_hdmi_pll_prepare(struct clk_hw *hw) +{ + struct mtk_hdmi_phy *hdmi_phy =3D to_mtk_hdmi_phy(hw); + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + 0x1 << RG_HDMITX21_TX_POSDIV_EN_SHIFT, + RG_HDMITX21_TX_POSDIV_EN); + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_0, + 0xf << RG_HDMITX21_SER_EN_SHIFT, RG_HDMITX21_SER_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + 0x1 << RG_HDMITX21_D0_DRV_OP_EN_SHIFT, + RG_HDMITX21_D0_DRV_OP_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + 0x1 << RG_HDMITX21_D1_DRV_OP_EN_SHIFT, + RG_HDMITX21_D1_DRV_OP_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + 0x1 << RG_HDMITX21_D2_DRV_OP_EN_SHIFT, + RG_HDMITX21_D2_DRV_OP_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + 0x1 << RG_HDMITX21_CK_DRV_OP_EN_SHIFT, + RG_HDMITX21_CK_DRV_OP_EN); + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + 0x0 << RG_HDMITX21_FRL_D0_EN_SHIFT, + RG_HDMITX21_FRL_D0_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + 0x0 << RG_HDMITX21_FRL_D1_EN_SHIFT, + RG_HDMITX21_FRL_D1_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + 0x0 << RG_HDMITX21_FRL_D2_EN_SHIFT, + RG_HDMITX21_FRL_D2_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + 0x0 << RG_HDMITX21_FRL_CK_EN_SHIFT, + RG_HDMITX21_FRL_CK_EN); + + mtk_hdmi_pll_drv_setting(hw); + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_10, + 0x0 << RG_HDMITX21_BG_PWD_SHIFT, RG_HDMITX21_BG_PWD); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + 0x1 << RG_HDMITX21_BIAS_EN_SHIFT, + RG_HDMITX21_BIAS_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_3, + 0x1 << RG_HDMITX21_CKLDO_EN_SHIFT, + RG_HDMITX21_CKLDO_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_3, + 0xf << RG_HDMITX21_SLDO_EN_SHIFT, + RG_HDMITX21_SLDO_EN); + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_4, + 0x1 << DA_HDMITXPLL_PWR_ON_SHIFT, + DA_HDMITXPLL_PWR_ON); + usleep_range(5, 10); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_4, + 0x0 << DA_HDMITXPLL_ISO_EN_SHIFT, + DA_HDMITXPLL_ISO_EN); + usleep_range(5, 10); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_2, + 0x0 << RG_HDMITXPLL_PWD_SHIFT, RG_HDMITXPLL_PWD); + usleep_range(30, 50); + return 0; +} + +static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) +{ + struct mtk_hdmi_phy *hdmi_phy =3D to_mtk_hdmi_phy(hw); + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_10, + 0x1 << RG_HDMITX21_BG_PWD_SHIFT, RG_HDMITX21_BG_PWD); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_6, + 0x0 << RG_HDMITX21_BIAS_EN_SHIFT, + RG_HDMITX21_BIAS_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_3, + 0x0 << RG_HDMITX21_CKLDO_EN_SHIFT, + RG_HDMITX21_CKLDO_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_3, + 0x0 << RG_HDMITX21_SLDO_EN_SHIFT, + RG_HDMITX21_SLDO_EN); + + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_2, + 0x1 << RG_HDMITXPLL_PWD_SHIFT, RG_HDMITXPLL_PWD); + usleep_range(10, 20); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_4, + 0x1 << DA_HDMITXPLL_ISO_EN_SHIFT, + DA_HDMITXPLL_ISO_EN); + usleep_range(10, 20); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_PLL_CFG_4, + 0x0 << DA_HDMITXPLL_PWR_ON_SHIFT, + DA_HDMITXPLL_PWR_ON); +} + +static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct mtk_hdmi_phy *hdmi_phy =3D to_mtk_hdmi_phy(hw); + int ret; + + dev_dbg(hdmi_phy->dev, "%s: %lu Hz, parent: %lu Hz\n", __func__, rate, + parent_rate); + + ret =3D mtk_hdmi_pll_calculate_params(hw, rate, parent_rate); + if (ret !=3D 0) + return -EINVAL; + + return 0; +} + +static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct mtk_hdmi_phy *hdmi_phy =3D to_mtk_hdmi_phy(hw); + + hdmi_phy->pll_rate =3D rate; + return rate; +} + +static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct mtk_hdmi_phy *hdmi_phy =3D to_mtk_hdmi_phy(hw); + + return hdmi_phy->pll_rate; +} + +static const struct clk_ops mtk_hdmi_pll_ops =3D { + .prepare =3D mtk_hdmi_pll_prepare, + .unprepare =3D mtk_hdmi_pll_unprepare, + .set_rate =3D mtk_hdmi_pll_set_rate, + .round_rate =3D mtk_hdmi_pll_round_rate, + .recalc_rate =3D mtk_hdmi_pll_recalc_rate, +}; + +static void vtx_signal_en(struct mtk_hdmi_phy *hdmi_phy, bool on) +{ + if (on) + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_0, RG_HDMITX21_DRV_EN, + RG_HDMITX21_DRV_EN); + else + mtk_hdmi_phy_mask(hdmi_phy, HDMI_1_CFG_0, + 0x0 << RG_HDMITX21_DRV_EN_SHIFT, + RG_HDMITX21_DRV_EN); +} + +static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy) +{ + vtx_signal_en(hdmi_phy, true); + usleep_range(100, 150); +} + +static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) +{ + vtx_signal_en(hdmi_phy, false); +} + +static int mtk_hdmi_phy_configure(struct phy *phy, union phy_configure_opt= s *opts) +{ + struct phy_configure_opts_dp *dp_opts =3D &opts->dp; + struct mtk_hdmi_phy *hdmi_phy =3D phy_get_drvdata(phy); + int ret =3D 0; + bool enable =3D 0; + + ret =3D clk_set_rate(hdmi_phy->pll, dp_opts->link_rate); + + if (ret) + goto out; + + mtk_mt8195_phy_tmds_high_bit_clk_ratio(hdmi_phy, enable); + +out: + return ret; +} + +struct mtk_hdmi_phy_conf mtk_hdmi_phy_8195_conf =3D { + .flags =3D CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, + .hdmi_phy_clk_ops =3D &mtk_hdmi_pll_ops, + .hdmi_phy_enable_tmds =3D mtk_hdmi_phy_enable_tmds, + .hdmi_phy_disable_tmds =3D mtk_hdmi_phy_disable_tmds, + .hdmi_phy_configure =3D mtk_hdmi_phy_configure, +}; + +MODULE_AUTHOR("Can Zeng "); +MODULE_DESCRIPTION("MediaTek MT8195 HDMI PHY Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h b/drivers/phy/media= tek/phy-mtk-hdmi-mt8195.h new file mode 100644 index 000000000000..3cc51d8a18a4 --- /dev/null +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h @@ -0,0 +1,204 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 MediaTek Inc. + * Copyright (c) 2021 BayLibre, SAS + */ + +#ifndef _MTK_HDMI_PHY_8195_H +#define _MTK_HDMI_PHY_8195_H + +#include +#include +#include + +#define DA_HDMITXPLL_ISO_EN BIT(1) +#define DA_HDMITXPLL_ISO_EN_SHIFT (1) +#define DA_HDMITXPLL_PWR_ON BIT(2) +#define DA_HDMITXPLL_PWR_ON_SHIFT (2) + +#define HDMI20_CLK_CFG 0x70 + +#define HDMI_1_CFG_0 0x00 +#define HDMI_1_CFG_1 0x04 +#define HDMI_1_CFG_10 0x40 +#define HDMI_1_CFG_2 0x08 +#define HDMI_1_CFG_21 0x84 +#define HDMI_1_CFG_22 0x88 +#define HDMI_1_CFG_3 0x0c +#define HDMI_1_CFG_6 0x18 +#define HDMI_1_CFG_9 0x24 +#define HDMI_1_PLL_CFG_0 0x44 +#define HDMI_1_PLL_CFG_1 0x48 +#define HDMI_1_PLL_CFG_2 0x4c +#define HDMI_1_PLL_CFG_3 0x50 +#define HDMI_1_PLL_CFG_4 0x54 + +#define HDMI_ANA_CTL 0x7c + +#define HDMI_CTL_1 0xc4 +#define HDMI_CTL_3 0xcc + +#define REG_ANA_HDMI20_FIFO_EN BIT(16) + +#define REG_HDMITXPLL_DIV GENMASK(4, 0) +#define REG_HDMITXPLL_DIV_SHIFT (0) +#define REG_HDMITX_PIXEL_CLOCK BIT(23) +#define REG_HDMITX_PIXEL_CLOCK_SHIFT (23) +#define REG_HDMITX_REF_RESPLL_SEL BIT(9) +#define REG_HDMITX_REF_RESPLL_SEL_SHIFT (9) +#define REG_HDMITX_REF_XTAL_SEL BIT(7) +#define REG_HDMITX_REF_XTAL_SEL_SHIFT (7) + +#define REG_PIXEL_CLOCK_SEL BIT(10) +#define REG_PIXEL_CLOCK_SEL_SHIFT (10) + +#define REG_TXC_DIV GENMASK(31, 30) +#define REG_TXC_DIV_SHIFT (30) + +#define RG_HDMITX21_BG_PWD BIT(20) +#define RG_HDMITX21_BG_PWD_SHIFT (20) + +#define RG_HDMITX21_BIAS_EN BIT(29) +#define RG_HDMITX21_BIAS_EN_SHIFT (29) +#define RG_HDMITX21_BIAS_PE_BG_VREF_SEL GENMASK(16, 15) +#define RG_HDMITX21_BIAS_PE_BG_VREF_SEL_SHIFT (15) +#define RG_HDMITX21_BIAS_PE_VREF_SELB GENMASK(10, 10) +#define RG_HDMITX21_BIAS_PE_VREF_SELB_SHIFT (10) + +#define RG_HDMITX21_CKLDO_EN BIT(3) +#define RG_HDMITX21_CKLDO_EN_SHIFT (3) + +#define RG_HDMITX21_CK_DRV_OP_EN BIT(11) +#define RG_HDMITX21_CK_DRV_OP_EN_SHIFT (11) + +#define RG_HDMITX21_D0_DRV_OP_EN BIT(10) +#define RG_HDMITX21_D0_DRV_OP_EN_SHIFT (10) + +#define RG_HDMITX21_D1_DRV_OP_EN BIT(9) +#define RG_HDMITX21_D1_DRV_OP_EN_SHIFT (9) + +#define RG_HDMITX21_D2_DRV_OP_EN BIT(8) +#define RG_HDMITX21_D2_DRV_OP_EN_SHIFT (8) + +#define RG_HDMITX21_DRV_EN GENMASK(27, 24) +#define RG_HDMITX21_DRV_EN_SHIFT (24) +#define RG_HDMITX21_DRV_IBIAS_CLK GENMASK(10, 5) +#define RG_HDMITX21_DRV_IBIAS_CLK_SHIFT (5) +#define RG_HDMITX21_DRV_IBIAS_D0 GENMASK(19, 14) +#define RG_HDMITX21_DRV_IBIAS_D0_FFE1 GENMASK(21, 17) +#define RG_HDMITX21_DRV_IBIAS_D0_FFE1_SHIFT (17) +#define RG_HDMITX21_DRV_IBIAS_D0_FFE2 GENMASK(23, 20) +#define RG_HDMITX21_DRV_IBIAS_D0_FFE2_SHIFT (20) +#define RG_HDMITX21_DRV_IBIAS_D0_SHIFT (14) +#define RG_HDMITX21_DRV_IBIAS_D1 GENMASK(25, 20) +#define RG_HDMITX21_DRV_IBIAS_D1_FFE1 GENMASK(26, 22) +#define RG_HDMITX21_DRV_IBIAS_D1_FFE1_SHIFT (22) +#define RG_HDMITX21_DRV_IBIAS_D1_FFE2 GENMASK(27, 24) +#define RG_HDMITX21_DRV_IBIAS_D1_FFE2_SHIFT (24) +#define RG_HDMITX21_DRV_IBIAS_D1_SHIFT (20) +#define RG_HDMITX21_DRV_IBIAS_D2 GENMASK(31, 26) +#define RG_HDMITX21_DRV_IBIAS_D2_FFE1 GENMASK(31, 27) +#define RG_HDMITX21_DRV_IBIAS_D2_FFE1_SHIFT (27) +#define RG_HDMITX21_DRV_IBIAS_D2_FFE2 GENMASK(31, 28) +#define RG_HDMITX21_DRV_IBIAS_D2_FFE2_SHIFT (28) +#define RG_HDMITX21_DRV_IBIAS_D2_SHIFT (26) +#define RG_HDMITX21_DRV_IMP_CLK_EN1 GENMASK(31, 26) +#define RG_HDMITX21_DRV_IMP_CLK_EN1_SHIFT (26) +#define RG_HDMITX21_DRV_IMP_D0_EN1 GENMASK(13, 8) +#define RG_HDMITX21_DRV_IMP_D0_EN1_SHIFT (8) +#define RG_HDMITX21_DRV_IMP_D1_EN1 GENMASK(19, 14) +#define RG_HDMITX21_DRV_IMP_D1_EN1_SHIFT (14) +#define RG_HDMITX21_DRV_IMP_D2_EN1 GENMASK(25, 20) +#define RG_HDMITX21_DRV_IMP_D2_EN1_SHIFT (20) +#define RG_HDMITX21_DRV_IMP_EN GENMASK(23, 20) +#define RG_HDMITX21_DRV_IMP_EN_SHIFT (20) + +#define RG_HDMITX21_FRL_CK_EN BIT(13) +#define RG_HDMITX21_FRL_CK_EN_SHIFT (13) +#define RG_HDMITX21_FRL_D0_EN BIT(14) +#define RG_HDMITX21_FRL_D0_EN_SHIFT (14) +#define RG_HDMITX21_FRL_D1_EN BIT(15) +#define RG_HDMITX21_FRL_D1_EN_SHIFT (15) +#define RG_HDMITX21_FRL_D2_EN BIT(16) +#define RG_HDMITX21_FRL_D2_EN_SHIFT (16) +#define RG_HDMITX21_FRL_EN BIT(12) +#define RG_HDMITX21_FRL_EN_SHIFT (12) + +#define RG_HDMITX21_INTR_CAL GENMASK(22, 18) +#define RG_HDMITX21_INTR_CAL_READOUT GENMASK(22, 18) +#define RG_HDMITX21_INTR_CAL_READOUT_SHIFT (18) +#define RG_HDMITX21_INTR_CAL_SHIFT (18) + +#define RG_HDMITX21_SER_EN GENMASK(31, 28) +#define RG_HDMITX21_SER_EN_SHIFT (28) + +#define RG_HDMITX21_SLDOLPF_EN BIT(7) +#define RG_HDMITX21_SLDOLPF_EN_SHIFT (7) +#define RG_HDMITX21_SLDO_EN GENMASK(11, 8) +#define RG_HDMITX21_SLDO_EN_SHIFT (8) +#define RG_HDMITX21_SLDO_VREF_SEL GENMASK(5, 4) +#define RG_HDMITX21_SLDO_VREF_SEL_SHIFT (4) + +#define RG_HDMITX21_TX_POSDIV GENMASK(27, 26) +#define RG_HDMITX21_TX_POSDIV_EN GENMASK(28, 28) +#define RG_HDMITX21_TX_POSDIV_EN_SHIFT (28) +#define RG_HDMITX21_TX_POSDIV_SHIFT (26) + +#define RG_HDMITX21_VREF_SEL BIT(4) +#define RG_HDMITX21_VREF_SEL_SHIFT (4) + +#define RG_HDMITXPLL_BC GENMASK(28, 27) +#define RG_HDMITXPLL_BC_SHIFT (27) +#define RG_HDMITXPLL_BP GENMASK(13, 10) +#define RG_HDMITXPLL_BP2 BIT(30) +#define RG_HDMITXPLL_BP2_SHIFT (30) +#define RG_HDMITXPLL_BP_SHIFT (10) +#define RG_HDMITXPLL_BR GENMASK(21, 19) +#define RG_HDMITXPLL_BR_SHIFT (19) +#define RG_HDMITXPLL_DIV_CTRL GENMASK(25, 24) +#define RG_HDMITXPLL_DIV_CTRL_SHIFT (24) +#define RG_HDMITXPLL_FBKDIV_HIGH BIT(31) +#define RG_HDMITXPLL_FBKDIV_high_SHIFT (31) +#define RG_HDMITXPLL_FBKDIV_low (0xffffffff) +#define RG_HDMITXPLL_FBKDIV_low_SHIFT (0) +#define RG_HDMITXPLL_HIKVCO GENMASK(29, 29) +#define RG_HDMITXPLL_HIKVCO_SHIFT (29) +#define RG_HDMITXPLL_HREN GENMASK(13, 12) +#define RG_HDMITXPLL_HREN_SHIFT (12) +#define RG_HDMITXPLL_IBAND_FIX_EN GENMASK(24, 24) +#define RG_HDMITXPLL_IBAND_FIX_EN_SHIFT (24) +#define RG_HDMITXPLL_IC GENMASK(26, 22) +#define RG_HDMITXPLL_IC_SHIFT (22) +#define RG_HDMITXPLL_IR GENMASK(18, 14) +#define RG_HDMITXPLL_IR_SHIFT (14) +#define RG_HDMITXPLL_LVR_SEL GENMASK(27, 26) +#define RG_HDMITXPLL_LVR_SEL_SHIFT (26) +#define RG_HDMITXPLL_POSDIV GENMASK(23, 22) +#define RG_HDMITXPLL_POSDIV_DIV3_CTRL BIT(21) +#define RG_HDMITXPLL_POSDIV_DIV3_CTRL_SHIFT (21) +#define RG_HDMITXPLL_POSDIV_SHIFT (22) +#define RG_HDMITXPLL_PREDIV GENMASK(29, 28) +#define RG_HDMITXPLL_PREDIV_SHIFT (28) +#define RG_HDMITXPLL_PWD BIT(31) +#define RG_HDMITXPLL_PWD_SHIFT (31) +#define RG_HDMITXPLL_REF_CK_SEL GENMASK(2, 1) +#define RG_HDMITXPLL_REF_CK_SEL_SHIFT (1) +#define RG_HDMITXPLL_RESERVE GENMASK(15, 0) +#define RG_HDMITXPLL_RESERVE_BIT12_11 GENMASK(12, 11) +#define RG_HDMITXPLL_RESERVE_BIT12_11_SHIFT (11) +#define RG_HDMITXPLL_RESERVE_BIT13 BIT(13) +#define RG_HDMITXPLL_RESERVE_BIT13_SHIFT (13) +#define RG_HDMITXPLL_RESERVE_BIT14 BIT(14) +#define RG_HDMITXPLL_RESERVE_BIT14_SHIFT (14) +#define RG_HDMITXPLL_RESERVE_BIT1_0 GENMASK(1, 0) +#define RG_HDMITXPLL_RESERVE_BIT1_0_SHIFT (0) +#define RG_HDMITXPLL_RESERVE_BIT3_2 GENMASK(3, 2) +#define RG_HDMITXPLL_RESERVE_BIT3_2_SHIFT (2) +#define RG_HDMITXPLL_RESERVE_SHIFT (0) +#define RG_HDMITXPLL_TCL_EN BIT(31) +#define RG_HDMITXPLL_TCL_EN_SHIFT (31) + +#define RG_INTR_IMP_RG_MODE GENMASK(7, 3) +#define RG_INTR_IMP_RG_MODE_SHIFT (3) + +#endif /* MTK_HDMI_PHY_8195_H */ diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy= -mtk-hdmi.c index af46472237e0..3fb60ab53668 100644 --- a/drivers/phy/mediatek/phy-mtk-hdmi.c +++ b/drivers/phy/mediatek/phy-mtk-hdmi.c @@ -194,6 +194,9 @@ static const struct of_device_id mtk_hdmi_phy_match[] = =3D { { .compatible =3D "mediatek,mt8173-hdmi-phy", .data =3D &mtk_hdmi_phy_8173_conf, }, + { .compatible =3D "mediatek,mt8195-hdmi-phy", + .data =3D &mtk_hdmi_phy_8195_conf, + }, {}, }; MODULE_DEVICE_TABLE(of, mtk_hdmi_phy_match); diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.h b/drivers/phy/mediatek/phy= -mtk-hdmi.h index 05de93f63a61..9d6399be71e9 100644 --- a/drivers/phy/mediatek/phy-mtk-hdmi.h +++ b/drivers/phy/mediatek/phy-mtk-hdmi.h @@ -51,6 +51,7 @@ void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32= offset, u32 val, u32 mask); struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw); =20 +extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8195_conf; extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf; extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf; =20 --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 686C1C6FA90 for ; Mon, 19 Sep 2022 17:02:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231176AbiISRCB (ORCPT ); Mon, 19 Sep 2022 13:02:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46322 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230514AbiISRBC (ORCPT ); Mon, 19 Sep 2022 13:01:02 -0400 Received: from mail-ed1-x536.google.com (mail-ed1-x536.google.com [IPv6:2a00:1450:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AE6373F1E8 for ; Mon, 19 Sep 2022 10:00:28 -0700 (PDT) Received: by mail-ed1-x536.google.com with SMTP id e17so138863edc.5 for ; Mon, 19 Sep 2022 10:00:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=2Meo31PuvkGIwIM5AdXoX0Hd0Yqmep6vNoeB5sp1WIo=; b=h4xvs+f5cmaWKYK71+hYnOmPVkiLtaB2mRla9tuoCEJPd+4ppfNzN0FBFiwIs70U65 tbJ9aJA3dpNgt1Ckv+Bx6Hc8Syb3OFhB4z+FJI0fxOKxNgoDOjZd8j6Uskwq0OWUm816 O7xPp4SJYuri2o1ZZKVZOB4LzhA9nFL2qpDxRJhsPPzW8j/vsldo+OZmErddviwJRjTi p4lfIW565oRIN/c+Vrhth50HEka7xMLu+MKAjKA+FPbmPD21phAwhccqtGiVTtSD60Zd EGLplHMN2dasKn0QgJPqQZBi+CeACR4L5U4Dlj9odh9YO7SKHNRH5sQETerhK+QEqrcG P3/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=2Meo31PuvkGIwIM5AdXoX0Hd0Yqmep6vNoeB5sp1WIo=; b=4UjhTE9gIhVhvh/1Fkn//xBZWae5uoIBWDy3rVi6Map7xBe12DPiNXOIxxz1Fd3UGv rarmlpYnHTEe0l+L7Orfuv9SVGQ4l4/sIRmWY+EKwMye+bHcAhL9W14v3IZ6p8jPAyH4 /D/yZb5Gk6P5UKv5FOys5CDdKFlX7FRcrqO/ruZm2i0nrZGUrJDSKjWe361XTgg4AA+O voc4W8f/RIdSdWRmnLMqwf0D0zyEOG7UrUtMzWawSSb9ilGdduwzTpCiiYeBS4fmJq+Q 68mfcU/yJ7j3PeyyTmMXxkaZGmNxU/1odf1qwLAM7fl1JEiEegPSPu9uMd991dt5J3yh Dq3w== X-Gm-Message-State: ACrzQf2SvtRV0gyqqGmk4y652v3zT7+fBBeiIbMb6MAO05UtLShXiUOn /NqJtRrUmJ27mXRpNvTyfpjZmw== X-Google-Smtp-Source: AMsMyM4nXsx/EGy8bNgRHqGUolsSurVZgmUHv5N2kQ+oMKWiHF7U6zG3vs9wXOsAsDPUMkE0zR3f8A== X-Received: by 2002:a05:6402:847:b0:453:943b:bf4 with SMTP id b7-20020a056402084700b00453943b0bf4mr11555407edz.301.1663606819619; Mon, 19 Sep 2022 10:00:19 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.10.00.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 10:00:19 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:13 +0200 Subject: [PATCH v1 15/17] dt-bindings: display: mediatek: dpi: Add compatible for MediaTek MT8195 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-15-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add dt-binding documentation of dpi for MediaTek MT8195 SoC. Signed-off-by: Guillaume Ranquet diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp= i.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.ya= ml index 5bb23e97cf33..2c7ecef54986 100644 Acked-by: Krzysztof Kozlowski --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml @@ -24,6 +24,7 @@ properties: - mediatek,mt8183-dpi - mediatek,mt8186-dpi - mediatek,mt8192-dpi + - mediatek,mt8195-dpi - mediatek,mt8195-dp-intf =20 reg: --=20 b4 0.10.0-dev From nobody Sat Sep 21 14:20:03 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 35B40ECAAA1 for ; Mon, 19 Sep 2022 17:02:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230370AbiISRCE (ORCPT ); Mon, 19 Sep 2022 13:02:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44566 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230517AbiISRBC (ORCPT ); Mon, 19 Sep 2022 13:01:02 -0400 Received: from mail-ed1-x536.google.com (mail-ed1-x536.google.com [IPv6:2a00:1450:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CCDE43ECDC for ; Mon, 19 Sep 2022 10:00:30 -0700 (PDT) Received: by mail-ed1-x536.google.com with SMTP id m3so82893eda.12 for ; Mon, 19 Sep 2022 10:00:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date; bh=cYnF9EMqvJwBXtKjwPxOYE0j1VtRuRBIfSm4h3GFMsc=; b=iZVbPY0gqBmoseFBcJkhJVbnPFAd49GmKzFxcRN5at5rxS298sNWWPHdlzwC9/At6C LlV7ZcQvHh7D7XKdzRzap7wgB2dNYOOd+Qz9TpRZcs6iQk4W6zJ9nxdwLwsBnlNs0DgM pxDTp9y49XawsYSC+t8cgCEoEvLPPlnps4MHxKYFZaBGzzpSdSsw3zT3gDGNY7h4FicX uSwtJL55l5PwXnYdUR60+DLQZ/p5ro7hxKmZSTZp7h7SDAtFTs80k54ibWZIVgnaqSf0 XcdM2GeXVrM4I/6IQjW/KmmZeF4v9jQgwD3eY3ESEHfGWw+H3OhZfn5AyFci85myIYBV pu+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date; bh=cYnF9EMqvJwBXtKjwPxOYE0j1VtRuRBIfSm4h3GFMsc=; b=qCJ28Xi/c7m7gl9bfKUGCL7dIoW5lapstM58/gVTpRS8RKvwR75ZrQYdyJOlx+AdYA 0w+sd103oe0GKEX7K7JDXclHVn/ojVXL3Jmf8dGACUIN7950sb3qcMQbAEMF5a4JnUnR fmoo5bUX6FT+TIK2UqvkdfJelVTv4zT3nY5fDytOOZiBDyC+no5w3ujvjcSQK2v2jBts J+zMI9zh5sPE7ks3uEP5AspVLNZ7hDOQ7dh8PvGhIh/lbNd18mC0GU1CRRg9QCCSdrsN NvAsfVhq5LAoaLFBc4wlsjV2WcCEuf3xdpEl4yukbVnhK3gZHsqPXYkCOyk1gTBnYC+U brnw== X-Gm-Message-State: ACrzQf2x/jojVfPSA2tyy8ginRtFr+552Jp+FKcE8N6HysqdhRHwffti iOtNG+z/kyB/cozoLfMIWwdAZg== X-Google-Smtp-Source: AMsMyM5y+2yvqezi2pwFyAIQOiGMfwwTVtHA+6PsM+rfZFMVmMKrf8594wP/QtB9y2Qn19/mpgA5kQ== X-Received: by 2002:a05:6402:2894:b0:453:b17b:d540 with SMTP id eg20-20020a056402289400b00453b17bd540mr9603339edb.178.1663606821705; Mon, 19 Sep 2022 10:00:21 -0700 (PDT) Received: from [127.0.0.1] (2a02-8440-6340-f287-3074-96af-9642-0003.rev.sfr.net. [2a02:8440:6340:f287:3074:96af:9642:3]) by smtp.gmail.com with ESMTPSA id cf16-20020a0564020b9000b0044fc3c0930csm20424246edb.16.2022.09.19.10.00.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 10:00:21 -0700 (PDT) From: Guillaume Ranquet Date: Mon, 19 Sep 2022 18:56:14 +0200 Subject: [PATCH v1 16/17] drm/mediatek: dpi: Add mt8195 hdmi to DPI driver MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20220919-v1-16-4844816c9808@baylibre.com> References: <20220919-v1-0-4844816c9808@baylibre.com> In-Reply-To: <20220919-v1-0-4844816c9808@baylibre.com> To: Vinod Koul , Stephen Boyd , David Airlie , Rob Herring , Philipp Zabel , Krzysztof Kozlowski , Daniel Vetter , Chunfeng Yun , CK Hu , Jitao shi , Chun-Kuang Hu , Michael Turquette , Kishon Vijay Abraham I , Matthias Brugger Cc: linux-mediatek@lists.infradead.org, dri-devel@lists.freedesktop.org, Pablo Sun , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Mattijs Korpershoek , linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, Guillaume Ranquet , devicetree@vger.kernel.org X-Mailer: b4 0.10.0-dev Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add the DPI1 hdmi path support in mtk dpi driver Signed-off-by: Guillaume Ranquet diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/= mtk_dpi.c index 630a4e301ef6..91212b7610e8 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -15,7 +15,10 @@ #include #include #include +#include #include +#include +#include =20 #include