Received: by 2002:a05:6a10:7420:0:0:0:0 with SMTP id hk32csp1617708pxb; Fri, 18 Feb 2022 11:32:20 -0800 (PST) X-Google-Smtp-Source: ABdhPJyY4t0FBlXyv4i+iy9SSg36vfHWzmIsn27jXcDOX0Y6PZ9jrm3oWbYVLRPZMIEHpJIMA4sO X-Received: by 2002:a65:464b:0:b0:36c:58da:5892 with SMTP id k11-20020a65464b000000b0036c58da5892mr7459223pgr.439.1645212740292; Fri, 18 Feb 2022 11:32:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1645212740; cv=none; d=google.com; s=arc-20160816; b=PzkGYOiUrx2ipsj2d4nb9H3d1FNQmdWY9oQgwGSBXrc8AHoc5pHrjDhgtW7wcN2CNv eAmVzVQrohjGIQvU7kpna/T/yfxRjZRA9GbOEJOar3LwPQwlIIaV4uPi7y2alRAgGS59 HhO8TowGpAKZ5pHt6XPM+hvEUBQKCzyWCv1v4sNjOy3H2WW7JGti4HL9UFXlIRm//ELz J0PrroL5DLiQRsEOsHIaKcaXE7yLY2f1ltVW6o7NSq51UPXgpocNp0/XXSnspIFPP42W 6r8AQj9J9SvCQByrhdZLexAHC7EC7b0+xD0FSrxex9iM+2M6mtXYOAW5dIr/euaT+c// W0Eg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=FmTzBPHzHBlgNyXdS8msKww/2/pZyasEe5TaA+1G0xw=; b=JAUf6zlnENNp3gFgwdLGTtiDW+mgMgGjWRas2eiELNU1J/50zcUEZA0TL9DJcB1ohR 9boBmAK/6wusqXRH7e8+qKkWoi8jJUG+NgqxUekQGHGmTu1K+oVLbN1rJnaz0FDCJGv7 XWI4p8eXQbmkjCVMvyQE5tDCbHA0855igezS4T2ylOWniYtDTPhISRNY7vfuA4aysX/O 1T2eTn2hLlEKUwkDEngNlewJ9dX1W7h/wmIJi+0RMmCZyfhwWmpytzYtEu5RUlr3PCn9 xwitWRR1nRp8v4fCfP76SzLMPvDSHgsquH/biCQV6QfbzQoq2xtJF59Zbj6DJMdhDMkA txZg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@baylibre-com.20210112.gappssmtp.com header.s=20210112 header.b=PnTxoKuI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id q205si11009845pgq.11.2022.02.18.11.32.03; Fri, 18 Feb 2022 11:32:20 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@baylibre-com.20210112.gappssmtp.com header.s=20210112 header.b=PnTxoKuI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236399AbiBRO5p (ORCPT + 99 others); Fri, 18 Feb 2022 09:57:45 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:50540 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236443AbiBRO5W (ORCPT ); Fri, 18 Feb 2022 09:57:22 -0500 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7FC51BB08A for ; Fri, 18 Feb 2022 06:56:29 -0800 (PST) Received: by mail-wr1-x42d.google.com with SMTP id u1so15006905wrg.11 for ; Fri, 18 Feb 2022 06:56:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=FmTzBPHzHBlgNyXdS8msKww/2/pZyasEe5TaA+1G0xw=; b=PnTxoKuI3eci8egRQuS1UR1drnRH/uBNjmj1fxFFlOAmavevFRb4fFy3N/rGuOKi6K w5gSnBwtrzQTws7XHFFViORyCNxbZJtDEklirkkVuTGLxsQNNLlOTDv2zRzMUbLPFvt5 eN0l3VBz7jrw4zMKBb7ppifwURPIgLn1nIfWH3m7K4JCt/sejNBLEhQv8kw6EDZ8YcSH 6uov6GbzpbMci9BRfWnSnuLguV5RIJpBn3KNYGyz3hhrV1CITWUHBe/RUbi9gU3EH3om pPDgWlbN8lnLNAyLg7xpnPDxbUy4KziP08/zxb+MkepGNKTA4Z6mCRKy2xpAl0v1uvdo 0kiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FmTzBPHzHBlgNyXdS8msKww/2/pZyasEe5TaA+1G0xw=; b=hBrF/eFHjV3Y1F6o0FmeX6bIUDQocYupcg4Sw8DhQtvK4t2AoQUyYRocIBUidDqV62 ruzinda48JG3KA+C3LS5LcSYu8PR3MkK4RZu2+jkXBYxODG44mToIa4kmF3zamjzysnt lBUCY66vkPwL/Ypqy2f3vm58+yasszHJ763nJXdMHZmeGQYNuzPaeAd5Rw9z48nbczxG FNColKQPfS+Ap6pFBfI4GP7itN0srkOBKFO5iNjiUKZEUjVq1yVovu2iOJjFPykHr3TJ W26pVbGwbEmJ8L/3WIREv4BDUmprHB94BChRfkrw84+5U/4ZZycIpdw87agKHU4YXe+p qj6g== X-Gm-Message-State: AOAM531cu3PJ00bo8UgqVRIiUDUTtZaGnxJq4z7lZTUtp9wZDzd+VqOA xtcToHIgSRmqsbB9N+BZqiiUdw== X-Received: by 2002:a5d:6292:0:b0:1e7:8afb:73ea with SMTP id k18-20020a5d6292000000b001e78afb73eamr6206482wru.149.1645196187876; Fri, 18 Feb 2022 06:56:27 -0800 (PST) Received: from localhost.localdomain (2a02-8440-6241-3b28-3074-96af-9642-0002.rev.sfr.net. [2a02:8440:6241:3b28:3074:96af:9642:2]) by smtp.gmail.com with ESMTPSA id b10sm47431454wrd.8.2022.02.18.06.56.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Feb 2022 06:56:27 -0800 (PST) From: Guillaume Ranquet To: chunkuang.hu@kernel.org, p.zabel@pengutronix.de, airlied@linux.ie, daniel@ffwll.ch, robh+dt@kernel.org, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, matthias.bgg@gmail.com, chunfeng.yun@mediatek.com, kishon@ti.com, vkoul@kernel.org, deller@gmx.de, ck.hu@mediatek.com, jitao.shi@mediatek.com, angelogioacchino.delregno@collabora.com Cc: dri-devel@lists.freedesktop.org, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, linux-fbdev@vger.kernel.org, Markus Schneider-Pargmann Subject: [PATCH v8 14/19] phy: phy-mtk-dp: Add driver for DP phy Date: Fri, 18 Feb 2022 15:54:32 +0100 Message-Id: <20220218145437.18563-15-granquet@baylibre.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220218145437.18563-1-granquet@baylibre.com> References: <20220218145437.18563-1-granquet@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Markus Schneider-Pargmann This is a new driver that supports the integrated DisplayPort phy for mediatek SoCs, especially the mt8195. The phy is integrated into the DisplayPort controller and will be created by the mtk-dp driver. This driver expects a struct regmap to be able to work on the same registers as the DisplayPort controller. It sets the device data to be the struct phy so that the DisplayPort controller can easily work with it. The driver does not have any devicetree bindings because the datasheet does not list the controller and the phy as distinct units. The interaction with the controller can be covered by the configure callback of the phy framework and its displayport parameters. Signed-off-by: Markus Schneider-Pargmann Signed-off-by: Guillaume Ranquet --- MAINTAINERS | 1 + drivers/phy/mediatek/Kconfig | 8 ++ drivers/phy/mediatek/Makefile | 1 + drivers/phy/mediatek/phy-mtk-dp.c | 199 ++++++++++++++++++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c diff --git a/MAINTAINERS b/MAINTAINERS index fca970a46e77a..33a05d396dd03 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6467,6 +6467,7 @@ L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) S: Supported F: Documentation/devicetree/bindings/display/mediatek/ F: drivers/gpu/drm/mediatek/ +F: drivers/phy/mediatek/phy-mtk-dp.c F: drivers/phy/mediatek/phy-mtk-hdmi* F: drivers/phy/mediatek/phy-mtk-mipi* diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig index 55f8e6c048ab3..f7ec860590492 100644 --- a/drivers/phy/mediatek/Kconfig +++ b/drivers/phy/mediatek/Kconfig @@ -55,3 +55,11 @@ config PHY_MTK_MIPI_DSI select GENERIC_PHY help Support MIPI DSI for Mediatek SoCs. + +config PHY_MTK_DP + tristate "MediaTek DP-PHY Driver" + depends on ARCH_MEDIATEK || COMPILE_TEST + depends on OF + select GENERIC_PHY + help + Support DisplayPort PHY for Mediatek SoCs. diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile index ace660fbed3a1..4ba1e06504346 100644 --- a/drivers/phy/mediatek/Makefile +++ b/drivers/phy/mediatek/Makefile @@ -3,6 +3,7 @@ # Makefile for the phy drivers. # +obj-$(CONFIG_PHY_MTK_DP) += phy-mtk-dp.o obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o obj-$(CONFIG_PHY_MTK_UFS) += phy-mtk-ufs.o obj-$(CONFIG_PHY_MTK_XSPHY) += phy-mtk-xsphy.o diff --git a/drivers/phy/mediatek/phy-mtk-dp.c b/drivers/phy/mediatek/phy-mtk-dp.c new file mode 100644 index 0000000000000..2841dd3f22543 --- /dev/null +++ b/drivers/phy/mediatek/phy-mtk-dp.c @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 BayLibre + * Author: Markus Schneider-Pargmann + */ + +#include +#include +#include +#include +#include +#include + +#define PHY_OFFSET 0x1000 + +#define MTK_DP_PHY_DIG_PLL_CTL_1 (PHY_OFFSET + 0x014) +#define TPLL_SSC_EN BIT(3) + +#define MTK_DP_PHY_DIG_BIT_RATE (PHY_OFFSET + 0x03C) +#define BIT_RATE_RBR 0 +#define BIT_RATE_HBR 1 +#define BIT_RATE_HBR2 2 +#define BIT_RATE_HBR3 3 + +#define MTK_DP_PHY_DIG_SW_RST (PHY_OFFSET + 0x038) +#define DP_GLB_SW_RST_PHYD BIT(0) + +#define MTK_DP_LANE0_DRIVING_PARAM_3 (PHY_OFFSET + 0x138) +#define MTK_DP_LANE1_DRIVING_PARAM_3 (PHY_OFFSET + 0x238) +#define MTK_DP_LANE2_DRIVING_PARAM_3 (PHY_OFFSET + 0x338) +#define MTK_DP_LANE3_DRIVING_PARAM_3 (PHY_OFFSET + 0x438) +#define XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT 0x10 +#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT (0x14 << 8) +#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT (0x18 << 16) +#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT (0x20 << 24) +#define DRIVING_PARAM_3_DEFAULT (XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT | \ + XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT | \ + XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT | \ + XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT) + +#define XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT 0x18 +#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT (0x1e << 8) +#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT (0x24 << 16) +#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT (0x20 << 24) +#define DRIVING_PARAM_4_DEFAULT (XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \ + XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \ + XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \ + XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT) + +#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT 0x28 +#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT (0x30 << 8) +#define DRIVING_PARAM_5_DEFAULT (XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \ + XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT) + +#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT 0x00 +#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT (0x04 << 8) +#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT (0x08 << 16) +#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT (0x10 << 24) +#define DRIVING_PARAM_6_DEFAULT (XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \ + XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \ + XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \ + XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT) + +#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT 0x00 +#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT (0x06 << 8) +#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT (0x0c << 16) +#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT (0x00 << 24) +#define DRIVING_PARAM_7_DEFAULT (XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \ + XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \ + XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \ + XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT) + +#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT 0x08 +#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT (0x00 << 8) +#define DRIVING_PARAM_8_DEFAULT (XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \ + XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT) + +struct mtk_dp_phy { + struct regmap *regs; +}; + +static int mtk_dp_phy_init(struct phy *phy) +{ + struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy); + u32 driving_params[] = { + DRIVING_PARAM_3_DEFAULT, + DRIVING_PARAM_4_DEFAULT, + DRIVING_PARAM_5_DEFAULT, + DRIVING_PARAM_6_DEFAULT, + DRIVING_PARAM_7_DEFAULT, + DRIVING_PARAM_8_DEFAULT + }; + + regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3, + driving_params, ARRAY_SIZE(driving_params)); + regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3, + driving_params, ARRAY_SIZE(driving_params)); + regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3, + driving_params, ARRAY_SIZE(driving_params)); + regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3, + driving_params, ARRAY_SIZE(driving_params)); + + return 0; +} + +static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts) +{ + struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy); + u32 val; + + if (opts->dp.set_rate) { + switch (opts->dp.link_rate) { + default: + dev_err(&phy->dev, + "Implementation error, unknown linkrate %x\n", + opts->dp.link_rate); + return -EINVAL; + case 1620: + val = BIT_RATE_RBR; + break; + case 2700: + val = BIT_RATE_HBR; + break; + case 5400: + val = BIT_RATE_HBR2; + break; + case 8100: + val = BIT_RATE_HBR3; + break; + } + regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val); + } + + regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1, + TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0); + + return 0; +} + +static int mtk_dp_phy_reset(struct phy *phy) +{ + struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy); + + regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST, + DP_GLB_SW_RST_PHYD, 0); + usleep_range(50, 200); + regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST, + DP_GLB_SW_RST_PHYD, 1); + + return 0; +} + +static const struct phy_ops mtk_dp_phy_dev_ops = { + .init = mtk_dp_phy_init, + .configure = mtk_dp_phy_configure, + .reset = mtk_dp_phy_reset, + .owner = THIS_MODULE, +}; + +static int mtk_dp_phy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mtk_dp_phy *dp_phy; + struct phy *phy; + + dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL); + if (!dp_phy) + return -ENOMEM; + + dp_phy->regs = *(struct regmap **)dev->platform_data; + if (!dp_phy->regs) { + dev_err(dev, "No data passed, requires struct regmap**\n"); + return -EINVAL; + } + + phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops); + if (IS_ERR(phy)) { + dev_err(dev, "Failed to create DP PHY: %ld\n", PTR_ERR(phy)); + return PTR_ERR(phy); + } + phy_set_drvdata(phy, dp_phy); + + if (!dev->of_node) + phy_create_lookup(phy, "dp", dev_name(dev)); + + return 0; +} + +struct platform_driver mtk_dp_phy_driver = { + .probe = mtk_dp_phy_probe, + .driver = { + .name = "mediatek-dp-phy", + }, +}; +module_platform_driver(mtk_dp_phy_driver); + +MODULE_AUTHOR("Markus Schneider-Pargmann "); +MODULE_DESCRIPTION("MediaTek DP PHY Driver"); +MODULE_LICENSE("GPL v2"); -- 2.34.1