From patchwork Thu Mar 20 13:00:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 14023942 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 91F60C28B30 for ; Thu, 20 Mar 2025 13:08:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=OmOPfpJVfcWXguVQwh5H1a4Kr+dNUzPiMh4L/wol70I=; b=ryJQLP+N2y3Vz3 MOjJjJbIrwxzcuyNDLtPDvdHbrEUI2UdApKifvUXTpSehncVSb+N8aRWaGoV7Zao4RcKyv3HWj5LR l47dIz1Ksd11sS7wWgxeuXqXelgtgD7QsEc9eTUxToYPsRr98p8G02JLFrhVAXB2oTIfFf1OLKRQ2 obxdkMUHZt9OJsQyg0uYhpK/3KD8dczK0TCdIBjXFmuAELWO84lFQZxtxpVeaZ85TBqG2DRnQp309 eUI/opN/fWkLeD4pTm6JK6+psq7qfgK/JbL7Ya9Xu1EHK4HoD4ypqPk+rP3MXOfZlC2/LQtJPFDuL ZO7e+a7spGyRArHvxkKw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tvFd2-0000000CBlV-1VBF; Thu, 20 Mar 2025 13:08:08 +0000 Received: from mail-wm1-x335.google.com ([2a00:1450:4864:20::335]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tvFWb-0000000CAYy-153G; Thu, 20 Mar 2025 13:01:30 +0000 Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-43cf58eea0fso4020245e9.0; Thu, 20 Mar 2025 06:01:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1742475688; x=1743080488; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=zXGZSQaYq8bc/tr8X+R6iDGpv0XCfiL/MLUXqqcdlyQ=; b=IZyCN9aoHB7RUzMwEJyH9P3OxodiKT9xu68k969og/fgLx6PZtHVZ0o3UVt5JbTMqW TcT7jASAJn5z3G7QiXvZUzHKksW1c3LxMdJnc6jUZG/BIZnw+tjadabkqeMWJZZc8ApH KyPKJDZmOcUgwsHxrDFF7gYL3J8fspXVCEByUcuAM1CBQPNxvlZa1ajopcpKJx1wdTiG 9RlKhyHDr7LQRGMR4Ix561/YJPh0VaH0eJnmYVAgyH11ZFkVR1+TMyvJauuIWxkZ/0uB d4N3DNCtalTBMnbDKNCtH5EGQrI5LjxAVTvZZOvqotqaSJi3t8NrwUObJ/0GHdZ5RAN5 mOIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742475688; x=1743080488; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zXGZSQaYq8bc/tr8X+R6iDGpv0XCfiL/MLUXqqcdlyQ=; b=YrhPQLsblQURpZqPPgWdm5VR6agLA3WXzuC/301mu0fC1hgSIDYhakif7E5mLdIKKa RYFextABprqEKn0oPrY993qPpFnE54PUZa34L5njavri09w66UOXUGndl2AsavOy7wmI fJPhqabVM79XG7lO9zZM49TYl60VT4JWVcQQ5q/LcR8nKDBJaqAa09Gv9CL9nqgt5qfI zEB1zYLmPPF2gVJCq+39zmS3vGbwAI9iF6iyTFmtcZAjy43anoYAGgTrf91KY/1GLXNf z7at5AmTSa9yDGHv63wxzNgLiH/D/KBgQkS4yGETSfh/tuIdTWcVjEallXfnZ+ipn7po BBag== X-Forwarded-Encrypted: i=1; AJvYcCU8CpIoUUrIahxLkDM+d88wcd8aSjehuDPhsGFTvWIlgXPXwRSboM8+9gRTPa9p1MQaHVIZvEUYBEyL2nbDtvac@lists.infradead.org, AJvYcCWZmoIurXt8NPsowbgruHWQ9Yim4rO4CDzkjI3YvgjqYoclotXj8/z3AdPSn6wuDF4Atcu5CD0w2YZn@lists.infradead.org, AJvYcCXzOj+NQR/Ybmcm28EGYMfT8nwoNRYwOowBlzTGfPkniruJ/gn9NTKnoV5raj3Fti9ad3HNxmVXqqk3HELArIc=@lists.infradead.org X-Gm-Message-State: AOJu0Yxf+YeKPG4iSxiihFXBFQAQ3Hm3VtO80Dwkwj/rlwOTmhXkenuk JaZPDYFznUfZN3vv9FtMo2te66gpzwzs4LwNc0lwy7+04nl1yNLb X-Gm-Gg: ASbGnctzm6uD/Dbix+noq6DsaSOCkPVMP1FcPOU1LvvB7MTLFZ7DuYSaDUTTjx0KDTo w2rD3z87amy0UbRyzasDb9A+S1Wes8BEYOemonH1gOnYGSnF4ACrPO/inw/9BP4uM1zbaVizj+z ZfzSUeBYK09RHud+syyJlQ0m00rJTtq5ZmouLSCVIwpBFoIQPzwa9BXabMf9tfficArzuD9Fj4W U7gbHQK2er/p7gZXPJQb9gOiT2XIavB+YxbBioLrvvifyEeOKFCAVIGdG1Put44zIGvg96RhpVm I7m49cgNVe0yceldD7iDvLN6W62EbujsU5z3LpXO+4aW8jiDCLMjss2+OxBF0J4x5k7KBPSifGM JqeaLpV59AQnCx+/F8PGhyFLG X-Google-Smtp-Source: AGHT+IEuObpmg3yOapMwPpVVWSs/wQpdUsdFeU9kVqS7nHNyOr/jMa+9GDR775od73FEkiQXApr31g== X-Received: by 2002:a05:600c:a00e:b0:43b:c0fa:f9dd with SMTP id 5b1f17b1804b1-43d4381618dmr55265165e9.25.1742475687246; Thu, 20 Mar 2025 06:01:27 -0700 (PDT) Received: from localhost.localdomain (93-34-90-129.ip49.fastwebnet.it. [93.34.90.129]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-397f2837e61sm18492328f8f.97.2025.03.20.06.01.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Mar 2025 06:01:26 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Kishon Vijay Abraham I , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Greg Kroah-Hartman , Daniel Danzberger , Arnd Bergmann , Alexander Sverdlin , Nikita Shubin , Linus Walleij , Yangyu Chen , Ben Hutchings , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-usb@vger.kernel.org, upstream@airoha.com Subject: [PATCH v2 01/11] clk: en7523: convert driver to regmap API Date: Thu, 20 Mar 2025 14:00:24 +0100 Message-ID: <20250320130054.4804-2-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250320130054.4804-1-ansuelsmth@gmail.com> References: <20250320130054.4804-1-ansuelsmth@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250320_060129_313278_49281724 X-CRM114-Status: GOOD ( 22.15 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Convert driver to regmap API, in preparation for support of Airoha AN7583 as the SCU will be an MFD and the regmap will be provided in the parent node. Also Airoha EN7581 benefits from this in preparation of USB support that required checking and configuring SCU SSR bits. While at it also cleanup some register mask and use bitfield macro. Signed-off-by: Christian Marangi --- drivers/clk/clk-en7523.c | 137 ++++++++++++++++++++++----------------- 1 file changed, 76 insertions(+), 61 deletions(-) diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c index 15bbdeb60b8e..314e7450313f 100644 --- a/drivers/clk/clk-en7523.c +++ b/drivers/clk/clk-en7523.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only +#include #include #include #include @@ -34,6 +35,7 @@ #define REG_RESET_CONTROL_PCIE2 BIT(26) /* EN7581 */ #define REG_NP_SCU_PCIC 0x88 +#define REG_PCIE_CTRL GENMASK(7, 0) #define REG_NP_SCU_SSTR 0x9c #define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13) #define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11) @@ -63,14 +65,14 @@ struct en_clk_desc { }; struct en_clk_gate { - void __iomem *base; + struct regmap *map; struct clk_hw hw; }; struct en_rst_data { const u16 *bank_ofs; const u16 *idx_map; - void __iomem *base; + struct regmap *map; struct reset_controller_dev rcdev; }; @@ -388,44 +390,44 @@ static u32 en7523_get_div(const struct en_clk_desc *desc, u32 val) static int en7523_pci_is_enabled(struct clk_hw *hw) { struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); + u32 val; - return !!(readl(cg->base + REG_PCI_CONTROL) & REG_PCI_CONTROL_REFCLK_EN1); + regmap_read(cg->map, REG_PCI_CONTROL, &val); + return !!(val & REG_PCI_CONTROL_REFCLK_EN1); } static int en7523_pci_prepare(struct clk_hw *hw) { struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); - void __iomem *np_base = cg->base; - u32 val, mask; + struct regmap *map = cg->map; + u32 mask; /* Need to pull device low before reset */ - val = readl(np_base + REG_PCI_CONTROL); - val &= ~(REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT); - writel(val, np_base + REG_PCI_CONTROL); + regmap_clear_bits(map, REG_PCI_CONTROL, + REG_PCI_CONTROL_PERSTOUT1 | + REG_PCI_CONTROL_PERSTOUT); usleep_range(1000, 2000); /* Enable PCIe port 1 */ - val |= REG_PCI_CONTROL_REFCLK_EN1; - writel(val, np_base + REG_PCI_CONTROL); + regmap_set_bits(map, REG_PCI_CONTROL, + REG_PCI_CONTROL_REFCLK_EN1); usleep_range(1000, 2000); /* Reset to default */ - val = readl(np_base + REG_RESET_CONTROL1); mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 | REG_RESET_CONTROL_PCIEHB; - writel(val & ~mask, np_base + REG_RESET_CONTROL1); + regmap_clear_bits(map, REG_RESET_CONTROL1, mask); usleep_range(1000, 2000); - writel(val | mask, np_base + REG_RESET_CONTROL1); + regmap_set_bits(map, REG_RESET_CONTROL1, mask); msleep(100); - writel(val & ~mask, np_base + REG_RESET_CONTROL1); + regmap_clear_bits(map, REG_RESET_CONTROL1, mask); usleep_range(5000, 10000); /* Release device */ mask = REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT; - val = readl(np_base + REG_PCI_CONTROL); - writel(val & ~mask, np_base + REG_PCI_CONTROL); + regmap_clear_bits(map, REG_PCI_CONTROL, mask); usleep_range(1000, 2000); - writel(val | mask, np_base + REG_PCI_CONTROL); + regmap_set_bits(map, REG_PCI_CONTROL, mask); msleep(250); return 0; @@ -434,16 +436,13 @@ static int en7523_pci_prepare(struct clk_hw *hw) static void en7523_pci_unprepare(struct clk_hw *hw) { struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); - void __iomem *np_base = cg->base; - u32 val; + struct regmap *map = cg->map; - val = readl(np_base + REG_PCI_CONTROL); - val &= ~REG_PCI_CONTROL_REFCLK_EN1; - writel(val, np_base + REG_PCI_CONTROL); + regmap_clear_bits(map, REG_PCI_CONTROL, REG_PCI_CONTROL_REFCLK_EN1); } static struct clk_hw *en7523_register_pcie_clk(struct device *dev, - void __iomem *np_base) + struct regmap *clk_map) { const struct en_clk_soc_data *soc_data = device_get_match_data(dev); struct clk_init_data init = { @@ -456,7 +455,7 @@ static struct clk_hw *en7523_register_pcie_clk(struct device *dev, if (!cg) return NULL; - cg->base = np_base; + cg->map = clk_map; cg->hw.init = &init; if (init.ops->unprepare) @@ -474,21 +473,20 @@ static int en7581_pci_is_enabled(struct clk_hw *hw) u32 val, mask; mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1; - val = readl(cg->base + REG_PCI_CONTROL); + regmap_read(cg->map, REG_PCI_CONTROL, &val); return (val & mask) == mask; } static int en7581_pci_enable(struct clk_hw *hw) { struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); - void __iomem *np_base = cg->base; - u32 val, mask; + struct regmap *map = cg->map; + u32 mask; mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 | REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 | REG_PCI_CONTROL_PERSTOUT; - val = readl(np_base + REG_PCI_CONTROL); - writel(val | mask, np_base + REG_PCI_CONTROL); + regmap_set_bits(map, REG_PCI_CONTROL, mask); return 0; } @@ -496,19 +494,18 @@ static int en7581_pci_enable(struct clk_hw *hw) static void en7581_pci_disable(struct clk_hw *hw) { struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); - void __iomem *np_base = cg->base; - u32 val, mask; + struct regmap *map = cg->map; + u32 mask; mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 | REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 | REG_PCI_CONTROL_PERSTOUT; - val = readl(np_base + REG_PCI_CONTROL); - writel(val & ~mask, np_base + REG_PCI_CONTROL); + regmap_clear_bits(map, REG_PCI_CONTROL, mask); usleep_range(1000, 2000); } static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, - void __iomem *base, void __iomem *np_base) + struct regmap *map, struct regmap *clk_map) { struct clk_hw *hw; u32 rate; @@ -517,10 +514,12 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) { const struct en_clk_desc *desc = &en7523_base_clks[i]; u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg; - u32 val = readl(base + desc->base_reg); + u32 val; + + regmap_read(map, desc->base_reg, &val); rate = en7523_get_base_rate(desc, val); - val = readl(base + reg); + regmap_read(map, reg, &val); rate /= en7523_get_div(desc, val); hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); @@ -533,30 +532,47 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat clk_data->hws[desc->id] = hw; } - hw = en7523_register_pcie_clk(dev, np_base); + hw = en7523_register_pcie_clk(dev, clk_map); clk_data->hws[EN7523_CLK_PCIE] = hw; } +static const struct regmap_config en7523_clk_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + static int en7523_clk_hw_init(struct platform_device *pdev, struct clk_hw_onecell_data *clk_data) { void __iomem *base, *np_base; + struct regmap *map, *clk_map; base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); + map = devm_regmap_init_mmio(&pdev->dev, base, + &en7523_clk_regmap_config); + if (IS_ERR(map)) + return PTR_ERR(map); + np_base = devm_platform_ioremap_resource(pdev, 1); if (IS_ERR(np_base)) return PTR_ERR(np_base); - en7523_register_clocks(&pdev->dev, clk_data, base, np_base); + clk_map = devm_regmap_init_mmio(&pdev->dev, np_base, + &en7523_clk_regmap_config); + if (IS_ERR(clk_map)) + return PTR_ERR(clk_map); + + en7523_register_clocks(&pdev->dev, clk_data, map, clk_map); return 0; } static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, - struct regmap *map, void __iomem *base) + struct regmap *map, struct regmap *clk_map) { struct clk_hw *hw; u32 rate; @@ -593,7 +609,7 @@ static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_dat clk_data->hws[desc->id] = hw; } - hw = en7523_register_pcie_clk(dev, base); + hw = en7523_register_pcie_clk(dev, clk_map); clk_data->hws[EN7523_CLK_PCIE] = hw; } @@ -601,15 +617,10 @@ static int en7523_reset_update(struct reset_controller_dev *rcdev, unsigned long id, bool assert) { struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev); - void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK]; - u32 val; + u32 addr = rst_data->bank_ofs[id / RST_NR_PER_BANK]; - val = readl(addr); - if (assert) - val |= BIT(id % RST_NR_PER_BANK); - else - val &= ~BIT(id % RST_NR_PER_BANK); - writel(val, addr); + regmap_update_bits(rst_data->map, addr, BIT(id % RST_NR_PER_BANK), + assert ? BIT(id % RST_NR_PER_BANK) : 0); return 0; } @@ -630,9 +641,11 @@ static int en7523_reset_status(struct reset_controller_dev *rcdev, unsigned long id) { struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev); - void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK]; + u32 addr = rst_data->bank_ofs[id / RST_NR_PER_BANK]; + u32 val; - return !!(readl(addr) & BIT(id % RST_NR_PER_BANK)); + regmap_read(rst_data->map, addr, &val); + return !!(val & BIT(id % RST_NR_PER_BANK)); } static int en7523_reset_xlate(struct reset_controller_dev *rcdev, @@ -652,7 +665,7 @@ static const struct reset_control_ops en7581_reset_ops = { .status = en7523_reset_status, }; -static int en7581_reset_register(struct device *dev, void __iomem *base) +static int en7581_reset_register(struct device *dev, struct regmap *map) { struct en_rst_data *rst_data; @@ -662,7 +675,7 @@ static int en7581_reset_register(struct device *dev, void __iomem *base) rst_data->bank_ofs = en7581_rst_ofs; rst_data->idx_map = en7581_rst_map; - rst_data->base = base; + rst_data->map = map; rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map); rst_data->rcdev.of_xlate = en7523_reset_xlate; @@ -678,9 +691,8 @@ static int en7581_reset_register(struct device *dev, void __iomem *base) static int en7581_clk_hw_init(struct platform_device *pdev, struct clk_hw_onecell_data *clk_data) { - struct regmap *map; + struct regmap *map, *clk_map; void __iomem *base; - u32 val; map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); if (IS_ERR(map)) @@ -690,15 +702,18 @@ static int en7581_clk_hw_init(struct platform_device *pdev, if (IS_ERR(base)) return PTR_ERR(base); - en7581_register_clocks(&pdev->dev, clk_data, map, base); + clk_map = devm_regmap_init_mmio(&pdev->dev, base, &en7523_clk_regmap_config); + if (IS_ERR(clk_map)) + return PTR_ERR(clk_map); + + en7581_register_clocks(&pdev->dev, clk_data, map, clk_map); - val = readl(base + REG_NP_SCU_SSTR); - val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); - writel(val, base + REG_NP_SCU_SSTR); - val = readl(base + REG_NP_SCU_PCIC); - writel(val | 3, base + REG_NP_SCU_PCIC); + regmap_clear_bits(clk_map, REG_NP_SCU_SSTR, + REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); + regmap_update_bits(clk_map, REG_NP_SCU_PCIC, REG_PCIE_CTRL, + FIELD_PREP(REG_PCIE_CTRL, 3)); - return en7581_reset_register(&pdev->dev, base); + return en7581_reset_register(&pdev->dev, clk_map); } static int en7523_clk_probe(struct platform_device *pdev) From patchwork Thu Mar 20 13:00:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 14023943 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 20EAEC28B30 for ; Thu, 20 Mar 2025 13:09:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=r38IIF22k42RkcZbaVdDqb+xmm5aOvAJKA+1OYVnaac=; b=ANrYcAhHES1mMJ xcN1Hp9aL95cTRUWZtf2/TAq0IpPh0U3cUxhCF2uyZtgkBEeP2Qkwlc7LgEFwqF3aV1Bj0/nFdqOV JHbEFCY5cwlVRetFDIYtPofgVkboIktsg4siTgCuzFwygwQdEXWzPmKAXxdcZOj6PF/EoxLInFk0T re9Yva5xyjzY1Ai+IEHhBbr95zbOVyxYChqsR29yordv6gtOxYpqCwMBS4TH96kMphqkeolx9QMBb PYWkiwafYW7dGr7RMa863oj0MGoWHqUVvvnyigqN92VvMArt0KdYkjdSvJ46pebKUz12ZlP5MSE8i BpfSSC5ARvtYzFrGkDjg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tvFei-0000000CBxY-3YfW; Thu, 20 Mar 2025 13:09:52 +0000 Received: from mail-wm1-x32b.google.com ([2a00:1450:4864:20::32b]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tvFWd-0000000CAaR-2WSq; Thu, 20 Mar 2025 13:01:32 +0000 Received: by mail-wm1-x32b.google.com with SMTP id 5b1f17b1804b1-43cf06eabdaso7365895e9.2; Thu, 20 Mar 2025 06:01:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1742475690; x=1743080490; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=qYnsaKwLQcaTkvM+4ffTJRr6nfs/V7lVq/qqbRtol90=; b=Ar45eeJ2Wg/UjtF8yIfENX5qbOje1kpny8uRlM5CQG6f32DsUY8MhyorUpyfjukIAO Fukk7uAv2dvYlhkiqTrRZwfeWzlvW9Vy3om65yO0EK7abGerWR9sGpqhMMUBRqrjOSJJ 9DdUfE7SF3XBBbn0gmq+bvxDBGqeugbIVaxvUV1H4whK08Aijqz7GffE17kbEwk6db5s ZyYdBuso3Fld7BxoYgIwqq8u8K/87WxLouWfUwc9v2x5t1eYPe2TyeNrsCA7hEP3LeT2 fI8Jflt5FteEYusF7jydvSWcWuylkh9lyDdlhwKngXmKxl1QdQf6rNJSYefrz9pQXGdc Pf6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742475690; x=1743080490; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qYnsaKwLQcaTkvM+4ffTJRr6nfs/V7lVq/qqbRtol90=; b=gtsf2t8gZUgLJ74cGHjwKEDF/Uy9e4eA67tuk8zaVcEQAOykA/4UzibnVHxSTRNMTN S/gyivv8Nsgr9jEx/+wBO2qle3rpVyjQWMRod1LpAP5WFjXloOvjW64dZR6YsxipCbow FTNfaYJjAaTHLLQZKm5l8PPqH1rT5tHdqy7bCjiBf7ttw2FivpokjR1yIDXj4Uwyupns BaKynrcQqPQP4xe8QWl3T/VwLEYuNKOl9kkhApIpNO/LuLzzzJBUDzoAql5wEBBHfUkD Y/8vFxG+E0W+zlk12QaUobUIo8lYoBx4gxQ982dtyz/Eyx4RbLgCzUpKr283uWGHnfSY t7ig== X-Forwarded-Encrypted: i=1; AJvYcCW0/CKynbkksN35FO36SUaC0F/8ipqSJRQvypN2VPyqoDt2E+A31Y/Ey+8YVuT/C5aJJtSdTxkH0FUQ@lists.infradead.org, AJvYcCWZtHHBBdGD3UD/V3/thHZ2eZtz/xrCgiTTc3g8Q77+aXW2NSK1ZhdLlZTc35CNn9dlWydb8lwyCaFQaodeh0E=@lists.infradead.org, AJvYcCWaSa7MonInz7cCiTmSCM6Hj9LSyaswzNUxqk3FzaV/YUuQYUfmeZd/dO6mI5nWdtREWP2nFPjWQ6YcqVfm5p5a@lists.infradead.org X-Gm-Message-State: AOJu0YwABO4oCe1Z4jMiqIJjc1DiwiyNHA1NZ4zfmRJ71kl7p9gY+jCo eggDsGkJrBM8Jst49r88iDQqafunwHupOVBV2khzdQQI7W0B1KeN X-Gm-Gg: ASbGncu5OTkhU+B6wewF6CXWAKFTgR6PuJmRSMjkVqa6R/QVCubG6JMIhadHZ98q2WT NV1FjTwgJPzXDg9SxlqUxhI+F3yqlYHISj0S6h5Jw/oNuxRLjkbZ5Bjw9nWZYXwRN/gIBarMWav kOBFjUpqJdvoFqWO0scu2srQredYy/9axNitaDxGbI+wzvj8u1E1SM6uuFAg2cC1H344l/OaHx+ h5/t/5jO3zUM/se0dguZOgsRGOQaoX8HplM733EtRxP0RxRgpwhTVdAP8lPCaBBYNibS0M3OIbY CcQdMNMRndTH/MWQy58ssCjlY3NgRfkED8/GA6uf8Uwp0ljRw9OedX97jXWZTXpfD+swqNfbMej PFKCVL886fgdh8g== X-Google-Smtp-Source: AGHT+IHitBKtOOy1SucPgUEGQLzzWHiEWJEFOJ0pyvyjc03NX9aNdjwUqdZDmvLHpRN43tzfEYYlSg== X-Received: by 2002:a05:6000:21c7:b0:390:e1e0:1300 with SMTP id ffacd0b85a97d-399739d437amr4854037f8f.33.1742475689504; Thu, 20 Mar 2025 06:01:29 -0700 (PDT) Received: from localhost.localdomain (93-34-90-129.ip49.fastwebnet.it. [93.34.90.129]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-397f2837e61sm18492328f8f.97.2025.03.20.06.01.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Mar 2025 06:01:28 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Kishon Vijay Abraham I , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Greg Kroah-Hartman , Daniel Danzberger , Arnd Bergmann , Alexander Sverdlin , Nikita Shubin , Linus Walleij , Yangyu Chen , Ben Hutchings , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-usb@vger.kernel.org, upstream@airoha.com Subject: [PATCH v2 02/11] clk: en7523: generalize register clocks function Date: Thu, 20 Mar 2025 14:00:25 +0100 Message-ID: <20250320130054.4804-3-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250320130054.4804-1-ansuelsmth@gmail.com> References: <20250320130054.4804-1-ansuelsmth@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250320_060131_641993_36A54FC4 X-CRM114-Status: GOOD ( 20.76 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Generalize register clocks function for Airoha EN7523 and EN7581 clocks driver. The same logic is applied for both clock hence code can be reduced and simplified by putting the base_clocks struct in the soc_data and passing that to a generic register clocks function. There is always the pattern where the last clock is always the PCIe one. Signed-off-by: Christian Marangi --- drivers/clk/clk-en7523.c | 130 ++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 77 deletions(-) diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c index 314e7450313f..2a74bc8fed24 100644 --- a/drivers/clk/clk-en7523.c +++ b/drivers/clk/clk-en7523.c @@ -78,8 +78,10 @@ struct en_rst_data { struct en_clk_soc_data { u32 num_clocks; + const struct en_clk_desc *base_clks; const struct clk_ops pcie_ops; int (*hw_init)(struct platform_device *pdev, + const struct en_clk_soc_data *soc_data, struct clk_hw_onecell_data *clk_data); }; @@ -467,6 +469,50 @@ static struct clk_hw *en7523_register_pcie_clk(struct device *dev, return &cg->hw; } +static void en75xx_register_clocks(struct device *dev, + const struct en_clk_soc_data *soc_data, + struct clk_hw_onecell_data *clk_data, + struct regmap *map, struct regmap *clk_map) +{ + struct clk_hw *hw; + u32 rate; + int i; + + for (i = 0; i < soc_data->num_clocks - 1; i++) { + const struct en_clk_desc *desc = &soc_data->base_clks[i]; + u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg; + int err; + + err = regmap_read(map, desc->base_reg, &val); + if (err) { + pr_err("Failed reading fixed clk rate %s: %d\n", + desc->name, err); + continue; + } + rate = en7523_get_base_rate(desc, val); + + err = regmap_read(map, reg, &val); + if (err) { + pr_err("Failed reading fixed clk div %s: %d\n", + desc->name, err); + continue; + } + rate /= en7523_get_div(desc, val); + + hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); + if (IS_ERR(hw)) { + pr_err("Failed to register clk %s: %ld\n", + desc->name, PTR_ERR(hw)); + continue; + } + + clk_data->hws[desc->id] = hw; + } + + hw = en7523_register_pcie_clk(dev, clk_map); + clk_data->hws[soc_data->num_clocks] = hw; +} + static int en7581_pci_is_enabled(struct clk_hw *hw) { struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); @@ -504,38 +550,6 @@ static void en7581_pci_disable(struct clk_hw *hw) usleep_range(1000, 2000); } -static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, - struct regmap *map, struct regmap *clk_map) -{ - struct clk_hw *hw; - u32 rate; - int i; - - for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) { - const struct en_clk_desc *desc = &en7523_base_clks[i]; - u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg; - u32 val; - - regmap_read(map, desc->base_reg, &val); - - rate = en7523_get_base_rate(desc, val); - regmap_read(map, reg, &val); - rate /= en7523_get_div(desc, val); - - hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); - if (IS_ERR(hw)) { - pr_err("Failed to register clk %s: %ld\n", - desc->name, PTR_ERR(hw)); - continue; - } - - clk_data->hws[desc->id] = hw; - } - - hw = en7523_register_pcie_clk(dev, clk_map); - clk_data->hws[EN7523_CLK_PCIE] = hw; -} - static const struct regmap_config en7523_clk_regmap_config = { .reg_bits = 32, .val_bits = 32, @@ -543,6 +557,7 @@ static const struct regmap_config en7523_clk_regmap_config = { }; static int en7523_clk_hw_init(struct platform_device *pdev, + const struct en_clk_soc_data *soc_data, struct clk_hw_onecell_data *clk_data) { void __iomem *base, *np_base; @@ -566,53 +581,11 @@ static int en7523_clk_hw_init(struct platform_device *pdev, if (IS_ERR(clk_map)) return PTR_ERR(clk_map); - en7523_register_clocks(&pdev->dev, clk_data, map, clk_map); + en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map); return 0; } -static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, - struct regmap *map, struct regmap *clk_map) -{ - struct clk_hw *hw; - u32 rate; - int i; - - for (i = 0; i < ARRAY_SIZE(en7581_base_clks); i++) { - const struct en_clk_desc *desc = &en7581_base_clks[i]; - u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg; - int err; - - err = regmap_read(map, desc->base_reg, &val); - if (err) { - pr_err("Failed reading fixed clk rate %s: %d\n", - desc->name, err); - continue; - } - rate = en7523_get_base_rate(desc, val); - - err = regmap_read(map, reg, &val); - if (err) { - pr_err("Failed reading fixed clk div %s: %d\n", - desc->name, err); - continue; - } - rate /= en7523_get_div(desc, val); - - hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); - if (IS_ERR(hw)) { - pr_err("Failed to register clk %s: %ld\n", - desc->name, PTR_ERR(hw)); - continue; - } - - clk_data->hws[desc->id] = hw; - } - - hw = en7523_register_pcie_clk(dev, clk_map); - clk_data->hws[EN7523_CLK_PCIE] = hw; -} - static int en7523_reset_update(struct reset_controller_dev *rcdev, unsigned long id, bool assert) { @@ -689,6 +662,7 @@ static int en7581_reset_register(struct device *dev, struct regmap *map) } static int en7581_clk_hw_init(struct platform_device *pdev, + const struct en_clk_soc_data *soc_data, struct clk_hw_onecell_data *clk_data) { struct regmap *map, *clk_map; @@ -706,7 +680,7 @@ static int en7581_clk_hw_init(struct platform_device *pdev, if (IS_ERR(clk_map)) return PTR_ERR(clk_map); - en7581_register_clocks(&pdev->dev, clk_data, map, clk_map); + en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map); regmap_clear_bits(clk_map, REG_NP_SCU_SSTR, REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); @@ -732,7 +706,7 @@ static int en7523_clk_probe(struct platform_device *pdev) return -ENOMEM; clk_data->num = soc_data->num_clocks; - r = soc_data->hw_init(pdev, clk_data); + r = soc_data->hw_init(pdev, soc_data, clk_data); if (r) return r; @@ -740,6 +714,7 @@ static int en7523_clk_probe(struct platform_device *pdev) } static const struct en_clk_soc_data en7523_data = { + .base_clks = en7523_base_clks, .num_clocks = ARRAY_SIZE(en7523_base_clks) + 1, .pcie_ops = { .is_enabled = en7523_pci_is_enabled, @@ -750,6 +725,7 @@ static const struct en_clk_soc_data en7523_data = { }; static const struct en_clk_soc_data en7581_data = { + .base_clks = en7581_base_clks, /* We increment num_clocks by 1 to account for additional PCIe clock */ .num_clocks = ARRAY_SIZE(en7581_base_clks) + 1, .pcie_ops = { From patchwork Thu Mar 20 13:00:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 14023944 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id ED726C28B30 for ; Thu, 20 Mar 2025 13:10:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=ewT15ASIXVkhrtDt1zQ0z1XossdZwzI7jEDs7l6oAJw=; b=TSC/gS97Sg3KmC WOzIFo0brjMduoE+70Mm3Z/ZXX8kH4HV2C3HQh3GNlyzJWiCjX1tcaHI35uU69mOdUeI4tMG5uPW5 ZdwKd4/ddSs11h1ehTwsvQONKrpFlar/WIitzGBfQFdMC54KgVM5qK3C0TB+LIX4VlqEluWLbrCM3 QZ9jpkWb0yFr86zFzn8wd6YoOz/U6pSxeLo/+Xa3i69giF/HzVeXDMJo7xkJ5vxskIaD61rcCqJPy UCNo1llBF7smPOc3qIz/22RNUbFhDrKFAbW1WE/fv18pWLINWU3fCHr93RXsllMrnDNHpmsmK6ptr Zaemadi7tdR8WI7npKsA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tvFet-0000000CC0u-2z7S; Thu, 20 Mar 2025 13:10:03 +0000 Received: from mail-wm1-x333.google.com ([2a00:1450:4864:20::333]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tvFWf-0000000CAb6-3zUo; Thu, 20 Mar 2025 13:01:35 +0000 Received: by mail-wm1-x333.google.com with SMTP id 5b1f17b1804b1-43cf0d787eeso7903095e9.3; Thu, 20 Mar 2025 06:01:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1742475692; x=1743080492; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=a9NDCwlC9t4pV6apOxhp/Woh5xsA/boRS4RgotHWwmw=; b=ALP7cn2Uga2qYBE+IZabvMWqs/iYkW/60KOTwWyG3R8UpabZsS7tdHxFJsMuKFI5Zz 39qejDRYFwcZfl/+PwgDQF8+H7X8a/kjvWLXwBHnO0vswhY+gIBOCmUT8kiZE4QVHoTc BDOt161rLi4TaLr7NZdOGcKlJzdCPjFasqW9nPkO/I4boRQ/eeCcJ5pKj+VjM0hRFXFu qb+iE++uIXYZsuxkL+4TtvEGWnJG6xQfXgfRw9/U7EDnXanuLqgPSb9FMhsfR2Ip2ThA hrDXDFVXS0KjhrEf4GH7sRqBP/epmS2BlHf4MGC/71fAF68ur5FBvysyfvZUMCr65fW7 rUtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742475692; x=1743080492; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=a9NDCwlC9t4pV6apOxhp/Woh5xsA/boRS4RgotHWwmw=; b=hbgOd+4hqU7tdb8EOn/A8rDxykrlK7vSTluvNG7U2A/piSWCNxDI8/gZD1Do+K5LxN i1AXUm3Sex8w7A5b/S6UAmIw/kUSvE5FmgjeNIlt7jmaGCgHgRjDhYocyp4ZbfZ0WqyM f2bkviMVR2IZCHQo+MsJNwNDBw7i+liflNclpxQxHPUc8GVu5BNw0Tk/mH+2Z63OQI4u MXdQ7JYRQGsvjfFt09rzRPeckJDuPWTacdlMsXZVow8cB+YCxPk1TmqyKpxbWSL29++0 aIdSBDFLcsAWHi2BAY7s6o5RBzbzOHoUy2Baw/S/xngE8zL0JlOghneKickyveYHKote /50A== X-Forwarded-Encrypted: i=1; AJvYcCUICXZoKlr/Kl0WIR7ag0r9GRXFAqjTlmRXJU+YtIlCJVYFaBsM0Z+J1xEZYc23kzB9ra3dFv+E384XO/oTzuNa@lists.infradead.org, AJvYcCV8txN6fL8a6lM3970caGRJLz2Wyj/qJeYBHTtJh5eH4ZWvxxpIKRBG698qCEwHcyrUhZhIzdSJEFA4@lists.infradead.org, AJvYcCXMgaeO8UXPcpoXD4z3SJtFSCG4lML4Rb0CEC3eLGmpnP1YScnjAQM5BiQ8nLizvV1yiaI5pz5V+uzvgewjuOs=@lists.infradead.org X-Gm-Message-State: AOJu0YxxakJ+B9RHJVoPh6/ijohMjtCfisilL9VHexheIi5JRibr/44Q om56RYAmnRC/8Eo70S81STPSgpruW12SVl0AfnUayrVuvjwY1ZAX X-Gm-Gg: ASbGnctQlKnLQsLp6TjXFZ/kI3hd+52Sq8XDbFcsqxKy6yGoKLcGnJdttJHfK155oFj DFxQZcXp474cZxHIh8wPmdSomBBV7rk8RQ2sgKhVtjME8JJL0RYwoT9ou51QncWNuqZTqEnZkvN OnpgThFTUTV+Yq0IIW6EVvj3BkSIdPVG30TejP8ASA41q4sz9HqUMJXhxRxV8hvBBxG97nKmnxB rfirVOA+NwQuebnWg+Gv3zePDzn9TwqBJqAF77XxjhBWbvTCT6u6K/Wy4te0EDqmwy1kbVDivce XhfIaFYp+dYNirWUPE3qVMZ8jkMHNpXMEY9iCkyWI7yrMzZqqtHzb3NJcvCslx5NsPLGkOUTlv8 GFlP+oa4s5UTr6g== X-Google-Smtp-Source: AGHT+IHeiWUjZYzxtkXpntYYlsW6atQC3N/FUEVhxccbCxLV+C3rtXXpoHMzxMjkwdKTi2hGl7WWew== X-Received: by 2002:a05:6000:21c4:b0:399:795e:d899 with SMTP id ffacd0b85a97d-399795ed8b6mr2509291f8f.14.1742475691925; Thu, 20 Mar 2025 06:01:31 -0700 (PDT) Received: from localhost.localdomain (93-34-90-129.ip49.fastwebnet.it. [93.34.90.129]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-397f2837e61sm18492328f8f.97.2025.03.20.06.01.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Mar 2025 06:01:31 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Kishon Vijay Abraham I , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Greg Kroah-Hartman , Daniel Danzberger , Arnd Bergmann , Alexander Sverdlin , Nikita Shubin , Linus Walleij , Yangyu Chen , Ben Hutchings , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-usb@vger.kernel.org, upstream@airoha.com Subject: [PATCH v2 03/11] dt-bindings: clock: en7523: add Documentation for Airoha AN7581 SCU SSR Date: Thu, 20 Mar 2025 14:00:26 +0100 Message-ID: <20250320130054.4804-4-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250320130054.4804-1-ansuelsmth@gmail.com> References: <20250320130054.4804-1-ansuelsmth@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250320_060133_993566_0BC55492 X-CRM114-Status: GOOD ( 21.94 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org The Airoha AN7581 SoC have in the SCU register space particular address that control how some peripheral are configured. These are toggeled in the System Status Register and are used to toggle Serdes port for USB 3.0 mode or HSGMII, USB 3.0 mode or PCIe2 or setup port for PCIe mode or Ethrnet mode (HSGMII/USXGMII). Modes are mutually exclusive and selecting one mode cause the other feature to not work (example a mode in USB 3.0 cause PCIe port 2 to not work) This depends also on what is physically connected to the Hardware and needs to correctly reflect the System Status Register bits. Special care is needed for PCIe port 0 in 2 line mode that requires both WiFi1 and WiFi2 Serdes port set to PCIe0 2 Line mode. Expose these configuration as an enum of strings in the SCU node and also add dt-bindings header to reference each serdes port in DT. Signed-off-by: Christian Marangi --- .../bindings/clock/airoha,en7523-scu.yaml | 101 ++++++++++++++++-- MAINTAINERS | 7 ++ include/dt-bindings/soc/airoha,scu-ssr.h | 11 ++ 3 files changed, 110 insertions(+), 9 deletions(-) create mode 100644 include/dt-bindings/soc/airoha,scu-ssr.h diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml index fe2c5c1baf43..637ce0e06619 100644 --- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml @@ -9,6 +9,7 @@ title: EN7523 Clock maintainers: - Felix Fietkau - John Crispin + - Christian Marangi description: | This node defines the System Control Unit of the EN7523 SoC, @@ -26,6 +27,23 @@ description: | The clocks are provided inside a system controller node. + The System Control Unit may also set different mode for the Serdes ports + present on the SoC. + + These are toggeled in the System Status Register and are used to + toggle Serdes port for USB 3.0 mode or HSGMII, USB 3.0 mode or PCIe2 + or setup port for PCIe mode or Ethernet mode (HSGMII/USXGMII). + + Modes are mutually exclusive and selecting one mode cause the + other feature to not work (example a mode in USB 3.0 cause PCIe + port 2 to not work) This depends also on what is physically + connected to the Hardware and needs to correctly reflect the + System Status Register bits. + + Special care is needed for PCIe port 0 in 2 line mode that + requires both WiFi1 and WiFi2 Serdes port set to PCIe0 2 Line + mode. + properties: compatible: items: @@ -49,6 +67,40 @@ properties: description: ID of the controller reset line const: 1 + airoha,serdes-wifi1: + description: Configure the WiFi1 Serdes port + $ref: /schemas/types.yaml#/definitions/string + enum: + - pcie0_x2 + - pcie0_x1 + - ethernet + default: pcie0_x1 + + airoha,serdes-wifi2: + description: Configure the WiFi2 Serdes port + $ref: /schemas/types.yaml#/definitions/string + enum: + - pcie0_x2 + - pcie1_x1 + - ethernet + default: pcie1_x1 + + airoha,serdes-usb1: + description: Configure the USB1 Serdes port + $ref: /schemas/types.yaml#/definitions/string + enum: + - usb3 + - ethernet + default: usb3 + + airoha,serdes-usb2: + description: Configure the USB2 Serdes port + $ref: /schemas/types.yaml#/definitions/string + enum: + - usb3 + - pcie2_x1 + default: usb3 + required: - compatible - reg @@ -64,6 +116,12 @@ allOf: reg: minItems: 2 + airoha,serdes-wifi1: false + airoha,serdes-wifi2: false + + airoha,serdes-usb1: false + airoha,serdes-usb2: false + '#reset-cells': false - if: @@ -75,6 +133,24 @@ allOf: reg: maxItems: 1 + - if: + properties: + airoha,serdes-wifi1: + const: pcie0_x2 + then: + properties: + airoha,serdes-wifi2: + const: pcie0_x2 + + - if: + properties: + airoha,serdes-wifi2: + const: pcie0_x2 + then: + properties: + airoha,serdes-wifi1: + const: pcie0_x2 + additionalProperties: false examples: @@ -87,15 +163,22 @@ examples: #clock-cells = <1>; }; + # Example SCU node with Serdes set to PCIe0 to x2 mode + # and USB2 set to PCIe2 to x1 mode - | soc { - #address-cells = <2>; - #size-cells = <2>; - - scuclk: clock-controller@1fb00000 { - compatible = "airoha,en7581-scu"; - reg = <0x0 0x1fb00000 0x0 0x970>; - #clock-cells = <1>; - #reset-cells = <1>; - }; + #address-cells = <2>; + #size-cells = <2>; + + scuclk: clock-controller@1fb00000 { + compatible = "airoha,en7581-scu"; + reg = <0x0 0x1fb00000 0x0 0x970>; + + airoha,serdes-wifi1 = "pcie0_x2"; + airoha,serdes-wifi2 = "pcie0_x2"; + airoha,serdes-usb2 = "pcie2_x1"; + + #clock-cells = <1>; + #reset-cells = <1>; + }; }; diff --git a/MAINTAINERS b/MAINTAINERS index 3eee238c2ea2..9944845ae9f5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -736,6 +736,13 @@ F: Documentation/devicetree/bindings/phy/airoha,en7581-pcie-phy.yaml F: drivers/phy/phy-airoha-pcie-regs.h F: drivers/phy/phy-airoha-pcie.c +AIROHA SCU SSR DRIVER +M: Christian Marangi +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: Documentation/devicetree/bindings/soc/airoha/airoha,an7581-scu-ssr.yaml +F: include/dt-bindings/soc/airoha,scu-ssr.h + AIROHA SPI SNFI DRIVER M: Lorenzo Bianconi M: Ray Liu diff --git a/include/dt-bindings/soc/airoha,scu-ssr.h b/include/dt-bindings/soc/airoha,scu-ssr.h new file mode 100644 index 000000000000..915f3cde7c1a --- /dev/null +++ b/include/dt-bindings/soc/airoha,scu-ssr.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef __DT_BINDINGS_AIROHA_SCU_SSR_H +#define __DT_BINDINGS_AIROHA_SCU_SSR_H + +#define AIROHA_SCU_SERDES_WIFI1 0 +#define AIROHA_SCU_SERDES_WIFI2 1 +#define AIROHA_SCU_SERDES_USB1 2 +#define AIROHA_SCU_SERDES_USB2 3 + +#endif /* __DT_BINDINGS_AIROHA_SCU_SSR_H */ From patchwork Thu Mar 20 13:00:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 14023945 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 884E5C28B30 for ; Thu, 20 Mar 2025 13:10:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=bQ2wdVMX25G6yPnTPPSR8+3ieRsqcm26ZiZZ4sIYHog=; b=wematLDg8/IpyH hCbJJKkR/U/gfuM6ni2TWBCijpeUrsslC4F3lz+CRwnsXOF9DMyMxvMFu/VFCY5hWop9Q2/PnuTFl adSnpIWWzkgGJH7pllXkbMlP2F4yCJCaOJiYqUKuO88z8EAizPVRt6MOV5rJnF1R706FqsC1qrTKs 1N1kTCXoiBhza1gC4BDiiMxiGCL1iTd0Iq6zABt9iiTx/X0erV38gpQl+gW9ukzFRjGvmFr/TQkuT hXxxl5J0p5U38Fjoy8ISuS6Y9Q8rTl7FqN3Xq0pWCO1ss8KHsoB2ELKXT6Niln07/SBHHLGBqRlRU t3OAr3NszEkaMVGI4+gw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tvFf4-0000000CC4f-1H0L; Thu, 20 Mar 2025 13:10:14 +0000 Received: from mail-wm1-x334.google.com ([2a00:1450:4864:20::334]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tvFWi-0000000CAcU-4Bek; Thu, 20 Mar 2025 13:01:38 +0000 Received: by mail-wm1-x334.google.com with SMTP id 5b1f17b1804b1-43cfe63c592so7709945e9.2; Thu, 20 Mar 2025 06:01:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1742475695; x=1743080495; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=wn2/hmuc3pnGhw1oNI9gcjxThAXzwvaMI5eUiGxYDOA=; b=CH0FATJDjMnJviwsQacV3QAuDYJXpNhSPV+3AF1Y6zpUDsI2118XZSEUHQzv93EZ5f LeKEb6juk/NlobP6MN4zAePz0UNQWyE2aEY/PS1GXYpr7zuNdPDoUgQiohrPSPcooNEx DrORqZYO6N3B6z5ugRtjFDBwk2p5rt5Fu70L4pa3QOqh3YI3JLRtuUATAKXS2Eyc3jyf T6l0KZ6ycIqnKCd9GvEq648yKRJFPkaRfiyAC2SxhM4Km5JvBXTjh8yA/nmcFOYnVy5K s4jL2yLh9lQPiB27crkW27P62w4hf8LF+htkz1MHYuHF8R4VTMWy5u5MEHlenkrg+/5k vtvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742475695; x=1743080495; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wn2/hmuc3pnGhw1oNI9gcjxThAXzwvaMI5eUiGxYDOA=; b=v+JZzSKsHXgN6VVl85unFcbqe8fBY4uc8IrkrPGk03Gxe5jJuZNv1X/1J0qJG5Elof dCK5C8dkg4EhO3yxsUAuFueMOSZL5+S/gMStRL8W6q+aohrv+DKGyCT1OpSSTmK8Zq/o EQbpMzX3sl7OkEy+uLsC4IBUk+khHgHnSQiaEK0nipJLsvPAzLawSw3ObJPx1StQ6K8l BApXp3Pu8hdXsMmHtu9GBZhwBjdrUjWu5aRtthvDwATzZTERt8W9OMER8pVu3evaBF7Q pTbqkwvqqA3ZMEs/ALb8hPA73h5tqOv5KenAGJ0+H0Mp4UzCjQPQF61d42tpHF0EhqOq Qykw== X-Forwarded-Encrypted: i=1; AJvYcCVXgQYbf6ALcOFIBaHWkgGamFdzCJUjFY1rmfOj1LppXqb+BQYZ6Dns5NPikBSjJTitNcnJqE4dzsvUxtePyGM=@lists.infradead.org, AJvYcCXRPcyNYdn1Bv/iFqk0ouMo6sS3bhfdwRW+4+8fPkMK4bXcCOvBM9+pa9Nz5INGQPR1mbwaA5m+O0BUMaZw7XqR@lists.infradead.org, AJvYcCXTzKt3I1/gaC8IE9RftP+MnLtgoSJbRGlpOyvt0tY8QJQfKuidyMLgHSRpH+auz753rNIUAInBAiMo@lists.infradead.org X-Gm-Message-State: AOJu0YwSRTzrB2Ny35Mr66dZR0Csc6qMzeCKKW0TJAWY/rzlSRJ+kPYo cfxFopgaPcbNOQY9ggJcJ9gYAGP339kbjHgBJf6owLdAp6ImUlvv X-Gm-Gg: ASbGncup0h9Yw+yVSVIpK4H0O09D50PQ6bX60UZ1NJpXKgVAWbiJJLCstlewNO9XVwI bmMduLF3s+SMhKBcqNAlXXf8E2zMH8UiujY5vhD6qrKZdm185gadqmCxqnJAwaT8ma2T6mctetF cVGYUVg0PYlCKr/7IUhuTyGtHjLouX5jUco5GkbZtHmDhwBOZ2GfRtrPK9AEoXdtKOQAq4fxwmb b8RE15FYR1Xk9DZAUugyh7Zxce19bt6Pihx6zbT3ak93gf6A+LtN0qapCV/HsF652zstjxMkaB/ sJctdeZUo6peFn2xs0iH3toHBzWYjK665NaCii2oSEEe+DsaOJLYLTek3mmioA3D/HFdctljJ/a 5vBxv97JqDdU6YCKruOzdR0xF X-Google-Smtp-Source: AGHT+IGi5vCdtEa2LCRHJP2raJyvd24trrbEgKD5KtNz8cQAFgw+tCXFVtwNUxD1X7czDtnEosU6xQ== X-Received: by 2002:a5d:5f4b:0:b0:391:12a5:3cb3 with SMTP id ffacd0b85a97d-399795a4fc2mr2851317f8f.3.1742475694722; Thu, 20 Mar 2025 06:01:34 -0700 (PDT) Received: from localhost.localdomain (93-34-90-129.ip49.fastwebnet.it. [93.34.90.129]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-397f2837e61sm18492328f8f.97.2025.03.20.06.01.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Mar 2025 06:01:33 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Kishon Vijay Abraham I , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Greg Kroah-Hartman , Daniel Danzberger , Arnd Bergmann , Alexander Sverdlin , Nikita Shubin , Linus Walleij , Yangyu Chen , Ben Hutchings , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-usb@vger.kernel.org, upstream@airoha.com Subject: [PATCH v2 04/11] soc: airoha: add support for configuring SCU SSR Serdes port Date: Thu, 20 Mar 2025 14:00:27 +0100 Message-ID: <20250320130054.4804-5-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250320130054.4804-1-ansuelsmth@gmail.com> References: <20250320130054.4804-1-ansuelsmth@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250320_060137_049095_9D51B693 X-CRM114-Status: GOOD ( 33.24 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Add support for configuring SCU SSR Serdes port. Airoha AN7581 SoC can configure the different Serdes port by toggling bits in the SCU register space. Port Serdes mode are mutually exclusive, force example the USB2 Serdes port can either used for USB 3.0 or PCIe 2 port. Enabling USB 3.0 makes the PCIe 2 to not work. The current supported Serdes port are: - WiFi 1 and defaults to PCIe0 1 line mode - Wifi 2 and defaults to PCIe1 1 line mode - USB 1 and defaults to USB 3.0 mode - USB 2 and defaults to USB 3.0 mode WiFi 1, WiFi 2 and USB 1 also support a particular Ethernet mode that can toggle between USXGMII or HSGMII mode (USB 1 only to HSGMII) Such mode doesn't configure bits as specific Ethernet PCS driver will take care of configuring the Serdes mode based on what is required. This driver is to correctly setup these bits. Single driver can't independently set the Serdes port mode as that would cause a conflict if someone declare, for example, in DT (and enable) PCIe 2 port and USB2 3.0 port. Signed-off-by: Christian Marangi --- MAINTAINERS | 2 + drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/airoha/Kconfig | 18 ++ drivers/soc/airoha/Makefile | 3 + drivers/soc/airoha/airoha-scu-ssr.c | 221 ++++++++++++++++++++++ include/linux/soc/airoha/airoha-scu-ssr.h | 23 +++ 7 files changed, 269 insertions(+) create mode 100644 drivers/soc/airoha/Kconfig create mode 100644 drivers/soc/airoha/Makefile create mode 100644 drivers/soc/airoha/airoha-scu-ssr.c create mode 100644 include/linux/soc/airoha/airoha-scu-ssr.h diff --git a/MAINTAINERS b/MAINTAINERS index 9944845ae9f5..7cd54c70aeed 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -741,7 +741,9 @@ M: Christian Marangi L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/soc/airoha/airoha,an7581-scu-ssr.yaml +F: drivers/soc/airoha/airoha-scu-ssr.c F: include/dt-bindings/soc/airoha,scu-ssr.h +F: include/linux/soc/airoha/airoha-scu-ssr.h AIROHA SPI SNFI DRIVER M: Lorenzo Bianconi diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index 6a8daeb8c4b9..21bacefd2e06 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only menu "SOC (System On Chip) specific Drivers" +source "drivers/soc/airoha/Kconfig" source "drivers/soc/amlogic/Kconfig" source "drivers/soc/apple/Kconfig" source "drivers/soc/aspeed/Kconfig" diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 2037a8695cb2..2b4027837d60 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -3,6 +3,7 @@ # Makefile for the Linux Kernel SOC specific device drivers. # +obj-y += airoha/ obj-y += apple/ obj-y += aspeed/ obj-$(CONFIG_ARCH_AT91) += atmel/ diff --git a/drivers/soc/airoha/Kconfig b/drivers/soc/airoha/Kconfig new file mode 100644 index 000000000000..56c677f8238d --- /dev/null +++ b/drivers/soc/airoha/Kconfig @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config AIROHA_SCU_SSR + tristate "Airoha SCU SSR Driver" + depends on ARCH_AIROHA || COMPILE_TEST + depends on OF + help + Say 'Y' here to add support for Airoha SCU SSR driver. + + Airoha SoC pheriperal (like USB/PCIe/Ethernet port) are + selected by toggling specific bit. Serdes Port line + are mutually exclusive such as selecting PCIe port 2 + disable support for USB port 2 3.0 mode. + + This driver is used to configure such bit and expose + an API to read the current status from a user of such + Serdes lines. + diff --git a/drivers/soc/airoha/Makefile b/drivers/soc/airoha/Makefile new file mode 100644 index 000000000000..530825251ae9 --- /dev/null +++ b/drivers/soc/airoha/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_AIROHA_SCU_SSR) += airoha-scu-ssr.o diff --git a/drivers/soc/airoha/airoha-scu-ssr.c b/drivers/soc/airoha/airoha-scu-ssr.c new file mode 100644 index 000000000000..29e17577e9a4 --- /dev/null +++ b/drivers/soc/airoha/airoha-scu-ssr.c @@ -0,0 +1,221 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Author: Christian Marangi + */ + +#include +#include +#include +#include +#include +#include +#include + +#define AIROHA_SCU_PCIC 0x88 +#define AIROHA_SCU_PCIE_2LANE_MODE BIT(14) + +#define AIROHA_SCU_SSR3 0x94 +#define AIROHA_SCU_SSUSB_HSGMII_SEL BIT(29) + +#define AIROHA_SCU_SSTR 0x9c +#define AIROHA_SCU_PCIE_XSI0_SEL GENMASK(14, 13) +#define AIROHA_SCU_PCIE_XSI0_SEL_PCIE FIELD_PREP_CONST(AIROHA_SCU_PCIE_XSI0_SEL, 0x0) +#define AIROHA_SCU_PCIE_XSI1_SEL GENMASK(12, 11) +#define AIROHA_SCU_PCIE_XSI1_SEL_PCIE FIELD_PREP_CONST(AIROHA_SCU_PCIE_XSI0_SEL, 0x0) +#define AIROHA_SCU_USB_PCIE_SEL BIT(3) + +#define AIROHA_SCU_MAX_SERDES_PORT 4 + +struct airoha_scu_ssr_priv { + struct device *dev; + struct regmap *regmap; + + unsigned int serdes_port[AIROHA_SCU_MAX_SERDES_PORT]; +}; + +static const char * const airoha_scu_serdes_mode_to_str[] = { + [AIROHA_SCU_SERDES_MODE_PCIE0_X1] = "pcie0_x1", + [AIROHA_SCU_SERDES_MODE_PCIE0_X2] = "pcie0_x2", + [AIROHA_SCU_SERDES_MODE_PCIE1_X1] = "pcie1_x1", + [AIROHA_SCU_SERDES_MODE_PCIE2_X1] = "pcie2_x1", + [AIROHA_SCU_SERDES_MODE_USB3] = "usb3", + [AIROHA_SCU_SERDES_MODE_ETHERNET] = "ethernet", +}; + +static int airoha_scu_serdes_str_to_mode(const char *serdes_str) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(airoha_scu_serdes_mode_to_str); i++) + if (!strncmp(serdes_str, airoha_scu_serdes_mode_to_str[i], + strlen(airoha_scu_serdes_mode_to_str[i]))) + return i; + + return -EINVAL; +} + +static int airoha_scu_ssr_apply_modes(struct airoha_scu_ssr_priv *priv) +{ + int ret; + + /* + * This is a very bad scenario and needs to be correctly warned + * as it cause PCIe malfunction. + */ + if ((priv->serdes_port[AIROHA_SCU_SERDES_WIFI1] == AIROHA_SCU_SERDES_MODE_PCIE0_X2 && + priv->serdes_port[AIROHA_SCU_SERDES_WIFI2] != AIROHA_SCU_SERDES_MODE_PCIE0_X2) || + (priv->serdes_port[AIROHA_SCU_SERDES_WIFI1] != AIROHA_SCU_SERDES_MODE_PCIE0_X2 && + priv->serdes_port[AIROHA_SCU_SERDES_WIFI2] == AIROHA_SCU_SERDES_MODE_PCIE0_X2)) { + WARN(true, "Wrong Serdes configuration for PCIe0 2 Line mode. Please check DT.\n"); + return -EINVAL; + } + + /* PCS driver takes care of setting the SCU bit for HSGMII or USXGMII */ + if (priv->serdes_port[AIROHA_SCU_SERDES_WIFI1] == AIROHA_SCU_SERDES_MODE_PCIE0_X1 || + priv->serdes_port[AIROHA_SCU_SERDES_WIFI1] == AIROHA_SCU_SERDES_MODE_PCIE0_X2) { + ret = regmap_update_bits(priv->regmap, AIROHA_SCU_SSTR, + AIROHA_SCU_PCIE_XSI0_SEL, + AIROHA_SCU_PCIE_XSI0_SEL_PCIE); + if (ret) + return ret; + } + + /* PCS driver takes care of setting the SCU bit for HSGMII or USXGMII */ + if (priv->serdes_port[AIROHA_SCU_SERDES_WIFI2] == AIROHA_SCU_SERDES_MODE_PCIE1_X1 || + priv->serdes_port[AIROHA_SCU_SERDES_WIFI2] == AIROHA_SCU_SERDES_MODE_PCIE0_X2) { + ret = regmap_update_bits(priv->regmap, AIROHA_SCU_SSTR, + AIROHA_SCU_PCIE_XSI1_SEL, + AIROHA_SCU_PCIE_XSI1_SEL_PCIE); + if (ret) + return ret; + } + + /* Toggle PCIe0 2 Line mode if enabled or not */ + if (priv->serdes_port[AIROHA_SCU_SERDES_WIFI1] == AIROHA_SCU_SERDES_MODE_PCIE0_X2) + ret = regmap_set_bits(priv->regmap, AIROHA_SCU_PCIC, + AIROHA_SCU_PCIE_2LANE_MODE); + else + ret = regmap_clear_bits(priv->regmap, AIROHA_SCU_PCIC, + AIROHA_SCU_PCIE_2LANE_MODE); + if (ret) + return ret; + + if (priv->serdes_port[AIROHA_SCU_SERDES_USB1] == AIROHA_SCU_SERDES_MODE_ETHERNET) + ret = regmap_clear_bits(priv->regmap, AIROHA_SCU_SSR3, + AIROHA_SCU_SSUSB_HSGMII_SEL); + else + ret = regmap_set_bits(priv->regmap, AIROHA_SCU_SSR3, + AIROHA_SCU_SSUSB_HSGMII_SEL); + if (ret) + return ret; + + if (priv->serdes_port[AIROHA_SCU_SERDES_USB2] == AIROHA_SCU_SERDES_MODE_PCIE2_X1) + ret = regmap_clear_bits(priv->regmap, AIROHA_SCU_SSTR, + AIROHA_SCU_USB_PCIE_SEL); + else + ret = regmap_set_bits(priv->regmap, AIROHA_SCU_SSTR, + AIROHA_SCU_USB_PCIE_SEL); + if (ret) + return ret; + + return 0; +} + +static int airoha_scu_ssr_parse_mode(struct device *dev, + struct airoha_scu_ssr_priv *priv, + const char *property_name, unsigned int port, + unsigned int default_mode) +{ + const struct airoha_scu_ssr_serdes_info *port_info; + const struct airoha_scu_ssr_data *pdata; + const char *serdes_mode; + int mode, i; + + pdata = dev->platform_data; + + if (of_property_read_string(dev->of_node, property_name, + &serdes_mode)) { + priv->serdes_port[port] = default_mode; + return 0; + } + + mode = airoha_scu_serdes_str_to_mode(serdes_mode); + if (mode) { + dev_err(dev, "invalid mode %s for %s\n", serdes_mode, property_name); + return mode; + } + + port_info = &pdata->ports_info[port]; + for (i = 0; i < port_info->num_modes; i++) { + if (port_info->possible_modes[i] == mode) { + priv->serdes_port[port] = mode; + return 0; + } + } + + dev_err(dev, "mode %s not supported for %s", serdes_mode, property_name); + return -EINVAL; +} + +static int airoha_scu_ssr_probe(struct platform_device *pdev) +{ + struct airoha_scu_ssr_priv *priv; + struct device *dev = &pdev->dev; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + + /* Get regmap from MFD */ + priv->regmap = dev_get_regmap(dev->parent, NULL); + if (!priv->regmap) + return -EINVAL; + + ret = airoha_scu_ssr_parse_mode(dev, priv, "airoha,serdes-wifi1", + AIROHA_SCU_SERDES_WIFI1, + AIROHA_SCU_SERDES_MODE_PCIE0_X1); + if (ret) + return ret; + + ret = airoha_scu_ssr_parse_mode(dev, priv, "airoha,serdes-wifi2", + AIROHA_SCU_SERDES_WIFI2, + AIROHA_SCU_SERDES_MODE_PCIE1_X1); + if (ret) + return ret; + + ret = airoha_scu_ssr_parse_mode(dev, priv, "airoha,serdes-usb1", + AIROHA_SCU_SERDES_USB1, + AIROHA_SCU_SERDES_MODE_USB3); + if (ret) + return ret; + + ret = airoha_scu_ssr_parse_mode(dev, priv, "airoha,serdes-usb2", + AIROHA_SCU_SERDES_USB2, + AIROHA_SCU_SERDES_MODE_USB3); + if (ret) + return ret; + + ret = airoha_scu_ssr_apply_modes(priv); + if (ret) + return ret; + + platform_set_drvdata(pdev, priv); + + return 0; +} + +static struct platform_driver airoha_scu_ssr_driver = { + .probe = airoha_scu_ssr_probe, + .driver = { + .name = "airoha-scu-ssr", + }, +}; + +module_platform_driver(airoha_scu_ssr_driver); + +MODULE_AUTHOR("Christian Marangi "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Airoha SCU SSR/STR driver"); diff --git a/include/linux/soc/airoha/airoha-scu-ssr.h b/include/linux/soc/airoha/airoha-scu-ssr.h new file mode 100644 index 000000000000..0224c0340b6d --- /dev/null +++ b/include/linux/soc/airoha/airoha-scu-ssr.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __AIROHA_SCU_SSR__ +#define __AIROHA_SCU_SSR__ + +enum airoha_scu_serdes_modes { + AIROHA_SCU_SERDES_MODE_PCIE0_X1, + AIROHA_SCU_SERDES_MODE_PCIE0_X2, + AIROHA_SCU_SERDES_MODE_PCIE1_X1, + AIROHA_SCU_SERDES_MODE_PCIE2_X1, + AIROHA_SCU_SERDES_MODE_USB3, + AIROHA_SCU_SERDES_MODE_ETHERNET, +}; + +struct airoha_scu_ssr_serdes_info { + unsigned int *possible_modes; + unsigned int num_modes; +}; + +struct airoha_scu_ssr_data { + const struct airoha_scu_ssr_serdes_info *ports_info; +}; + +#endif From patchwork Thu Mar 20 13:00:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 14023946 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AEE32C28B30 for ; Thu, 20 Mar 2025 13:10:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=GEclULX/MFgzXJBhNCAbXgibAC8ZktzjGsDAf6tzvn4=; b=VSmPzjejMa1RVc /9tY172bR+ouIzvqKDEmGN9Pk1XsJsTyjgcduGU17JdFRpEcb01pVSgTSB3g5u2X3F3WGvv3cR71b 3XcHOUOmeIRvyd+8dId+jx9lKlJaN8VHrVjpT3m/shSoYZUUghIG0lTNi+H1nLTBpgN6O4v7GWMUK ntoWcbjrOSkBITBuJM1KtHyAhmnHOjPdB3PWREuFty7HdNK47IQKhLKwEkZg+mbPpa0E8yUwofXx4 u+fXL8qY2sDcrX09dh6NjY8HO7GT/CyadUvX3HY1/TT5KEmxTNojsmTwlKaYs4eLEv5mEPepOoACD he1Ednw2Q2WH8LQxymFQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tvFfF-0000000CC7O-1v0s; Thu, 20 Mar 2025 13:10:25 +0000 Received: from mail-wm1-x32e.google.com ([2a00:1450:4864:20::32e]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tvFWn-0000000CAdg-19ar; Thu, 20 Mar 2025 13:01:42 +0000 Received: by mail-wm1-x32e.google.com with SMTP id 5b1f17b1804b1-4393dc02b78so4531255e9.3; Thu, 20 Mar 2025 06:01:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1742475699; x=1743080499; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=GjXZXNCMR7AMS8CMSFsXOaQrfC4KYnxI7xnrEz3bVbs=; b=DApH5j6GCF3U4HyXypErJkJ84L5zaurbPinbOWMm6ItHQB2bvvhq6EedjZDUbKGEVN AD/db2csFkpkM940ot8k0C43lNQAaQJe8fxX4ygN6KZoUEsxM8n+di7+0aTY3nfANArx nuiwDR4isWRU1Vp2gNZMwtKbqqsQjU1BhPRAZadOem5ZeJw6cX93fs+hHhRaJUJYQex9 NEZvspZfCrXd5JL6g9GIaCQr5ml9qK/UaA5XFIV5o0BGizkxmCJDBpsI2Uh4hv3L6Smf +bcHg3HFOWEws55H31PQ/mPTkTZybbTceloX2i0zRXH5clM+49SiW8YSBplRFBqJWyef 5RQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742475699; x=1743080499; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GjXZXNCMR7AMS8CMSFsXOaQrfC4KYnxI7xnrEz3bVbs=; b=oXaHct9KG7pvhGYp7USgcgtEwDAQBYBtQeARzfeZs2d0u5jyhWDpCfNq82deFhhcHM CDZrUlPU7y56I7M/QcnjKBsmR8bdmySyBMGfwHNQ0kxxQH1CZFTQR3QOjT9BBAZ+APUj oMgG0Qhyk8j1mc1cL3mlMnRiitSwfRGZ8mDhRu8i6xEmJtkQ5fWhr286PDuuSjhSh81p EXedz0NPnsMS+9InUdEbLJd/S6LuB1Ugmi7lcg9Py7zHTLhMXGzNKNXDUQZMmfh13cSk x5W5ZKkDsZmQyIuyL/8iSHEk84S2Ygb7dt6kvU+k4YyRhXu9WOwlY2XRwWXH8RYG8ZSb m1cQ== X-Forwarded-Encrypted: i=1; AJvYcCWqITBAyOsYzzAocbRB/El5uwlf2TjLxufpbQt4YqdVuy7zh2EIgaBs2aQC37pq6ldpIXo/dMh2iSZMOV/U/b0=@lists.infradead.org, AJvYcCXZFTCKtMhB+Fh1TEvbt/ybr7lqZWbREfUwgBG3480nanj8Fv/BasYdz2RBXCTXdkM6EM2IcAqcqm02TxbbDjiL@lists.infradead.org, AJvYcCXmkAfHrwHt7sEIy7HFBMm+l4pLRzFrHDC5n17kXpy2j9pxdbz22STGjDRHIg4Ra7iV28e5T4GuQGp9@lists.infradead.org X-Gm-Message-State: AOJu0YwNZRht9GH4Ot5RYskY5vuKHtA9Af1IHFNKPmcFin6NgVhSdI/Z 2C2oXF7niML6B45ISBdDKmojUQLrKuIAableKC8S4v7WeDk6R6j5 X-Gm-Gg: ASbGnct1VWKiee31vRhxQVL5w7J3VU2MZjnOAEsbmfTL69Hl4KPw632FKwZo5rs8cR1 FVVmZ4OdZZbY04KQ7fmX5WO0IlAyXKk2G731DbCDGu/6JVDIcJ/jseXBl49BEttw/JHPppGB6+1 jlbtaNSgOYRFq4WYNOW+i90uURCBs4agqn4gRo/buC6w3JSQyo6gHblNFr5gSX7rgYJEBXuMH6w Eht7RBKPtpFHUZWmwaPVs8I0ZI/9x2eK7jDYBx5l4WUZmmloSMVaY+y1QIuV1iGiomywXCCBEbC GHP6+Han//+gmmxMBFIp71cPXAfMm7o8U1q1HKne+8CNA2Od0SAr9tCemkPeYBvbPWqFEBgvCDr 2XhXiaj2nBjVVs9HLE63aYwat X-Google-Smtp-Source: AGHT+IGmkDnnkoASLNKc7beCB36KTynfhE5+lNlk/tMYqhdW/dQRvuIWvPUsIp9fafc4LTtsm02Xxg== X-Received: by 2002:a05:6000:186b:b0:391:2a9f:2fcb with SMTP id ffacd0b85a97d-39973b028a9mr4710707f8f.36.1742475697214; Thu, 20 Mar 2025 06:01:37 -0700 (PDT) Received: from localhost.localdomain (93-34-90-129.ip49.fastwebnet.it. [93.34.90.129]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-397f2837e61sm18492328f8f.97.2025.03.20.06.01.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Mar 2025 06:01:36 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Kishon Vijay Abraham I , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Greg Kroah-Hartman , Daniel Danzberger , Arnd Bergmann , Alexander Sverdlin , Nikita Shubin , Linus Walleij , Yangyu Chen , Ben Hutchings , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-usb@vger.kernel.org, upstream@airoha.com Subject: [PATCH v2 05/11] clk: en7523: define and register SoC SCU SSR driver for EN7581 Date: Thu, 20 Mar 2025 14:00:28 +0100 Message-ID: <20250320130054.4804-6-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250320130054.4804-1-ansuelsmth@gmail.com> References: <20250320130054.4804-1-ansuelsmth@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250320_060141_314604_DFB63E83 X-CRM114-Status: GOOD ( 24.37 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Define all the possible interface modes and register the SoC SCU SSR platform driver for EN7581. Failing to register the SCU SSR driver is not a critical error (example the SoC driver is not enable) but will prevent PCIe or USB port to function correctly. Reference to the SSR pdev are stored in the new en7523 priv struct. Signed-off-by: Christian Marangi --- drivers/clk/clk-en7523.c | 99 ++++++++++++++++++++++++++++++++-- include/linux/clk/clk-en7523.h | 10 ++++ 2 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 include/linux/clk/clk-en7523.h diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c index 2a74bc8fed24..1f11fa769090 100644 --- a/drivers/clk/clk-en7523.c +++ b/drivers/clk/clk-en7523.c @@ -3,14 +3,17 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #define RST_NR_PER_BANK 32 @@ -81,6 +84,7 @@ struct en_clk_soc_data { const struct en_clk_desc *base_clks; const struct clk_ops pcie_ops; int (*hw_init)(struct platform_device *pdev, + struct en_clk_priv *priv, const struct en_clk_soc_data *soc_data, struct clk_hw_onecell_data *clk_data); }; @@ -361,6 +365,51 @@ static const u16 en7581_rst_map[] = { [EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31, }; +static unsigned int an7581_serdes_wifi1_possible_modes[] = { + AIROHA_SCU_SERDES_MODE_PCIE0_X1, + AIROHA_SCU_SERDES_MODE_PCIE0_X2, + AIROHA_SCU_SERDES_MODE_ETHERNET, +}; + +static unsigned int an7581_serdes_wifi2_possible_modes[] = { + AIROHA_SCU_SERDES_MODE_PCIE1_X1, + AIROHA_SCU_SERDES_MODE_PCIE0_X2, + AIROHA_SCU_SERDES_MODE_ETHERNET, +}; + +static unsigned int an7581_serdes_usb1_possible_modes[] = { + AIROHA_SCU_SERDES_MODE_USB3, + AIROHA_SCU_SERDES_MODE_ETHERNET, +}; + +static unsigned int an7581_serdes_usb2_possible_modes[] = { + AIROHA_SCU_SERDES_MODE_PCIE2_X1, + AIROHA_SCU_SERDES_MODE_ETHERNET, +}; + +static const struct airoha_scu_ssr_serdes_info an7581_ports_info[] = { + [AIROHA_SCU_SERDES_WIFI1] = { + .possible_modes = an7581_serdes_wifi1_possible_modes, + .num_modes = ARRAY_SIZE(an7581_serdes_wifi1_possible_modes), + }, + [AIROHA_SCU_SERDES_WIFI2] = { + .possible_modes = an7581_serdes_wifi2_possible_modes, + .num_modes = ARRAY_SIZE(an7581_serdes_wifi2_possible_modes), + }, + [AIROHA_SCU_SERDES_USB1] = { + .possible_modes = an7581_serdes_usb1_possible_modes, + .num_modes = ARRAY_SIZE(an7581_serdes_usb1_possible_modes), + }, + [AIROHA_SCU_SERDES_USB2] = { + .possible_modes = an7581_serdes_usb2_possible_modes, + .num_modes = ARRAY_SIZE(an7581_serdes_usb2_possible_modes), + }, +}; + +static const struct airoha_scu_ssr_data an7581_scu_ssr_data = { + .ports_info = an7581_ports_info, +}; + static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val) { if (!desc->base_bits) @@ -557,6 +606,7 @@ static const struct regmap_config en7523_clk_regmap_config = { }; static int en7523_clk_hw_init(struct platform_device *pdev, + struct en_clk_priv *priv, const struct en_clk_soc_data *soc_data, struct clk_hw_onecell_data *clk_data) { @@ -661,12 +711,38 @@ static int en7581_reset_register(struct device *dev, struct regmap *map) return devm_reset_controller_register(dev, &rst_data->rcdev); } +static void en7581_clk_register_ssr(struct platform_device *pdev, + struct en_clk_priv *priv) +{ + struct platform_device_info pinfo = { }; + struct platform_device *ssr_pdev; + + pinfo.name = "airoha-scu-ssr"; + pinfo.parent = &pdev->dev; + pinfo.id = PLATFORM_DEVID_AUTO; + pinfo.fwnode = of_fwnode_handle(pdev->dev.of_node); + pinfo.of_node_reused = true; + pinfo.data = &an7581_scu_ssr_data; + pinfo.size_data = sizeof(an7581_scu_ssr_data); + + ssr_pdev = platform_device_register_data(&pdev->dev, "airoha-scu-ssr", + PLATFORM_DEVID_AUTO, + &an7581_scu_ssr_data, + sizeof(an7581_scu_ssr_data)); + if (IS_ERR(ssr_pdev)) + dev_warn_probe(&pdev->dev, PTR_ERR(ssr_pdev), "failed to register SCU SSR driver.\n"); + + priv->ssr_pdev = ssr_pdev; +} + static int en7581_clk_hw_init(struct platform_device *pdev, + struct en_clk_priv *priv, const struct en_clk_soc_data *soc_data, struct clk_hw_onecell_data *clk_data) { struct regmap *map, *clk_map; void __iomem *base; + int ret; map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); if (IS_ERR(map)) @@ -687,7 +763,13 @@ static int en7581_clk_hw_init(struct platform_device *pdev, regmap_update_bits(clk_map, REG_NP_SCU_PCIC, REG_PCIE_CTRL, FIELD_PREP(REG_PCIE_CTRL, 3)); - return en7581_reset_register(&pdev->dev, clk_map); + ret = en7581_reset_register(&pdev->dev, clk_map); + if (ret) + return ret; + + en7581_clk_register_ssr(pdev, priv); + + return 0; } static int en7523_clk_probe(struct platform_device *pdev) @@ -695,10 +777,15 @@ static int en7523_clk_probe(struct platform_device *pdev) struct device_node *node = pdev->dev.of_node; const struct en_clk_soc_data *soc_data; struct clk_hw_onecell_data *clk_data; + struct en_clk_priv *priv; int r; soc_data = device_get_match_data(&pdev->dev); + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hws, soc_data->num_clocks), GFP_KERNEL); @@ -706,11 +793,17 @@ static int en7523_clk_probe(struct platform_device *pdev) return -ENOMEM; clk_data->num = soc_data->num_clocks; - r = soc_data->hw_init(pdev, soc_data, clk_data); + r = soc_data->hw_init(pdev, priv, soc_data, clk_data); if (r) return r; - return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + if (r) + return r; + + platform_set_drvdata(pdev, priv); + + return 0; } static const struct en_clk_soc_data en7523_data = { diff --git a/include/linux/clk/clk-en7523.h b/include/linux/clk/clk-en7523.h new file mode 100644 index 000000000000..fc3b320dc7e9 --- /dev/null +++ b/include/linux/clk/clk-en7523.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __LINUX_CLK_EN7523_H_ +#define __LINUX_CLK_EN7523_H_ + +struct en_clk_priv { + struct platform_device *ssr_pdev; +}; + +#endif From patchwork Thu Mar 20 13:00:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 14023956 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 04B8DC28B30 for ; Thu, 20 Mar 2025 13:12:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=mHCjVzRU42MilGvXosd8iK0DBaIPV/1QqgjkLqB3IHw=; b=q8KrNIlvVXt32h kxjyEGaEbDbBlfo/MA6CO/eLbAaxfylL5kTwDNCcsU4xvAvx09jAgIvwIAFECJseTW5DLZAmQsFNK jhCXMhSIX1rSoXsYFFW9Qb/KJJlMa4WUhbN/L1CI3Ddy/OoBHtK8/kCUrCJhhUb2giI5JKc4jpS5C nLByK9xnLWIa6q81ZEGwerLI/AWAu4x3A+LRh4ksbhBWua3lmB/aRrNDEG42z+msdPfQ1FRpb1oXs YQGEqL+u0bFuekjDkAnbEnbodsGTeT30P8Tfsvg3oEv2QhYq2+q76QxHUhXoqFMOO9I2l8PW0sR3f di0Vo9kZ2KhuoF6DLBkA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tvFh6-0000000CCFP-3EYW; Thu, 20 Mar 2025 13:12:20 +0000 Received: from mail-wr1-x434.google.com ([2a00:1450:4864:20::434]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tvFWo-0000000CAeE-3DgK; Thu, 20 Mar 2025 13:01:44 +0000 Received: by mail-wr1-x434.google.com with SMTP id ffacd0b85a97d-3912baafc58so630460f8f.1; Thu, 20 Mar 2025 06:01:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1742475701; x=1743080501; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=1i3DRbTdyzbpnAKiDfDQZ1mLdcscqRmuPns+JX+LUjs=; b=nYWHyQm94Jxl2s2XH8oBtnsOxBKBFrzARo2U1u68sZver3yQjk88Nb6Zcb/tvbD9My YhahQcPS71Ux7XmatlJzydWVu63hp2oaBpuvex2+yjxKEpmzuBchMThsdED5/4OtdU0z +4FD5wlaaRXsKHhLo15fLbpbB//9bS8uep1IAAIENzNVuTJfy56ZRJ9qT0Snubna17UO dybnxgzJF2L9KsYRpy5urABv/Xktdy/diDs5pQ5xUCGiDpeIQm+Py9kEvgiFxhbb5d06 /oL1Vwt3kNruXHUqodjmRsZtAtZWLDaJVH2v0fiRj78qNnIdsZpIcIeyvdWSQ8qhHOE3 6aRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742475701; x=1743080501; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1i3DRbTdyzbpnAKiDfDQZ1mLdcscqRmuPns+JX+LUjs=; b=NtAzYExjpdOzfZFXf2uQS961bFZ9m2g+i6EKYnojV61iHZ41FCJQQvjUwDbIFV8N0+ Te7SC36xM5giQpS//UaivZUuBrVhPqfPMPzTMk0XcXQHWVaN9UhFFyG8mGD/cJwtaR/k rGt2isN4wd80blFANhElxR2/iQELojYA2r90Hil1URmQQ2in0izOEmd/u665+tquKqYL u3ChFnxhiQi6O3T7xEv3t0uYIvfm46sgLSjMdl+a0WvQcOP1otI023Bgc1/MC4UETbuI QBoGERBmd2WOnSONxHF8MjKM+1WMUpTAUM6jnbbDXSk8EYy/4sxL+E3Ur52WrBS4EDqI Ldug== X-Forwarded-Encrypted: i=1; AJvYcCVO7+36KXZPoktN3NQ4pucDXAHIouGYrssMC8lbL23a/2iIQvNPfcYxH49pFq0LHUc2QT/v7keexixq@lists.infradead.org, AJvYcCVeVJTTCgcRf/8rFlD2NHtse0xnYO0a49B6aOKstKeK42BVSY2aGgJmo0kOH/hygCpgOiB+NGtiiNly1aQPL/U=@lists.infradead.org, AJvYcCWg44lvqKWVMhSXcCnMTZ7mX+/6oUePBimwzPivBJ0h2EuKLmlVkenh+MnxKlX27hoHtV7MIsyn95YMfzTQj/DQ@lists.infradead.org X-Gm-Message-State: AOJu0YyO318Smoi9cByh3wpb9g4SIHFBNLNE9MNbzpdGKypRqFEi0OLi 4oGMaNQR01OaYYFe2xpIciQuPknpCsJTYivBZpFP6R5BMOQmbsHt X-Gm-Gg: ASbGncuXzFioPXdTc4bmuVTWTdQVhphUHRQ5ysvTYIvsiXZpqNBDbj+daPkrB1iwMpT JiTFq+A7JB/cDdD20dKrD6WJF81A2BXeXcJ9yVbU77V0VcE1NJ2M17VfFnrE7XQiX8e1XE2q8ih vqcpNbHT98uOxZTLonoseoaa9uTMa5t2V3KwbrloN61IvpEIDc9mwNTnywLJfk3zpejCHZorEjo /uBJ5dihXa6n10f+UufH0iSnbBIu7fjPasKU2liy7KGD8nCNU3POtIpn0K3DUNyAktSNHArBAlE zK9abZBJf43DMqXmlGFNZ5bu6Q64wGA8xNGj5+bdSI+QauBdEb3dc/FEa4g2uK0XEZKuN9qfin1 sgsfqS3JC8g2qGQ== X-Google-Smtp-Source: AGHT+IEQRynyz9JGzu+Wy/hCcpiQtdW/bJaEM9RuaZOW49I93OxOlyiURvahKTtdmPXSEWXajsfaYQ== X-Received: by 2002:a5d:6c6a:0:b0:391:4559:876a with SMTP id ffacd0b85a97d-399795e77d5mr3094168f8f.46.1742475699266; Thu, 20 Mar 2025 06:01:39 -0700 (PDT) Received: from localhost.localdomain (93-34-90-129.ip49.fastwebnet.it. [93.34.90.129]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-397f2837e61sm18492328f8f.97.2025.03.20.06.01.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Mar 2025 06:01:38 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Kishon Vijay Abraham I , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Greg Kroah-Hartman , Daniel Danzberger , Arnd Bergmann , Alexander Sverdlin , Nikita Shubin , Linus Walleij , Yangyu Chen , Ben Hutchings , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-usb@vger.kernel.org, upstream@airoha.com Subject: [PATCH v2 06/11] soc: airoha: scu-ssr: expose API to read current Serdes Port mode Date: Thu, 20 Mar 2025 14:00:29 +0100 Message-ID: <20250320130054.4804-7-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250320130054.4804-1-ansuelsmth@gmail.com> References: <20250320130054.4804-1-ansuelsmth@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250320_060142_822573_A8B9CCEE X-CRM114-Status: GOOD ( 19.00 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Expose an API to read the current Serdes Port mode. This is needed for pheriperal attached to the Serdes mode to validate the Serdes port is in the correct mode. Each driver will have to define in DT the phandle airoha,scu pointing to the SCU node to make use of this API. Function airoha_scu_ssr_get_serdes_mode() will then parse the phandle, and extract tha Serdes Port state from the SCU SSR driver priv. Driver will use the new API airoha_scu_ssr_get_serdes_mode() by passing the dev and the serdes mode reference from dt-bindings header. Signed-off-by: Christian Marangi --- drivers/soc/airoha/airoha-scu-ssr.c | 50 +++++++++++++++++++++++ include/linux/soc/airoha/airoha-scu-ssr.h | 11 +++++ 2 files changed, 61 insertions(+) diff --git a/drivers/soc/airoha/airoha-scu-ssr.c b/drivers/soc/airoha/airoha-scu-ssr.c index 29e17577e9a4..3fbc36f793d0 100644 --- a/drivers/soc/airoha/airoha-scu-ssr.c +++ b/drivers/soc/airoha/airoha-scu-ssr.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -54,6 +55,55 @@ static int airoha_scu_serdes_str_to_mode(const char *serdes_str) return -EINVAL; } +/** + * airoha_scu_ssr_get_serdes_mode - Get current Mode for Serdes Port + * @dev: Device pointer of the Serdes Port peripheral + * @port: Reference number of the Serdes Port + * + * Parse the phandle pointed by the Device Node property + * "airoha,scu" present in Devide Node of dev and get + * the current Mode of the Serdes Port reference by port + * + * Return the mode or a negative error code. If the pdev + * or the driver data for the SCU can't be found, + * -EPROBE_DEFER is returned. + */ +int airoha_scu_ssr_get_serdes_mode(struct device *dev, + unsigned int port) +{ + struct airoha_scu_ssr_priv *priv; + struct en_clk_priv *clk_priv; + struct platform_device *pdev; + struct device_node *np; + + np = of_parse_phandle(dev->of_node, "airoha,scu", 0); + if (!np) + return -ENODEV; + + if (!of_device_is_available(np)) { + of_node_put(np); + return -ENODEV; + } + + pdev = of_find_device_by_node(np); + of_node_put(np); + if (!pdev || !platform_get_drvdata(pdev)) { + if (pdev) + put_device(&pdev->dev); + return -EPROBE_DEFER; + } + + /* + * Get pdev from clk priv. Clock driver register + * SSR driver hence it can be assumed present. + */ + clk_priv = platform_get_drvdata(pdev); + priv = platform_get_drvdata(clk_priv->ssr_pdev); + + return priv->serdes_port[port]; +} +EXPORT_SYMBOL_GPL(airoha_scu_ssr_get_serdes_mode); + static int airoha_scu_ssr_apply_modes(struct airoha_scu_ssr_priv *priv) { int ret; diff --git a/include/linux/soc/airoha/airoha-scu-ssr.h b/include/linux/soc/airoha/airoha-scu-ssr.h index 0224c0340b6d..81f2c1b57889 100644 --- a/include/linux/soc/airoha/airoha-scu-ssr.h +++ b/include/linux/soc/airoha/airoha-scu-ssr.h @@ -20,4 +20,15 @@ struct airoha_scu_ssr_data { const struct airoha_scu_ssr_serdes_info *ports_info; }; +#if IS_ENABLED(CONFIG_AIROHA_SCU_SSR) +int airoha_scu_ssr_get_serdes_mode(struct device *dev, + unsigned int port); +#else +static inline int airoha_scu_ssr_get_serdes_mode(struct device *dev, + unsigned int port); +{ + return -EOPNOTSUPP; +} +#endif + #endif From patchwork Thu Mar 20 13:00:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 14023957 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 53198C28B30 for ; Thu, 20 Mar 2025 13:14:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Enaz/aq6wpT66f+7wIxhAzrzY9r1JVC+VJ986e6oZj0=; b=GgVcF1XcPbAunk GparHoPAPKnQwC+DPrr87z3kVoM0D4dVApowZCH3Up8/haXf7SK93GeE7eSpKlK3dlrthNmKrsgfx nXhs78nd1pSkO/fHFZyoGQmUsbCQEAwqdmmUiqGwCiQMZ/2BzrkaCxIOuWSD1B7wOg90kTbhx+ixr Pr9Xr1Chu2ounSvXumYnADiiQSOiLf7vTynLQXuB3I0uhfzV1BcDjNmwmQB3rxOYCRKT7WCUqLlOE ZVMzJlSWf8A/SlDEG9h37lZf0YtgdJM6pNkpXE7s4B4N3bF/npfXj9JNo1q5IKGC/u2fEodp53SJI LL+azCfzW4WTWO1qMiuQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tvFim-0000000CCQU-0NdR; Thu, 20 Mar 2025 13:14:04 +0000 Received: from mail-wm1-x331.google.com ([2a00:1450:4864:20::331]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tvFWr-0000000CAfJ-20dZ; Thu, 20 Mar 2025 13:01:47 +0000 Received: by mail-wm1-x331.google.com with SMTP id 5b1f17b1804b1-43cec5cd73bso4556795e9.3; Thu, 20 Mar 2025 06:01:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1742475704; x=1743080504; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Vc3dKjde0rLVyDC0QPLc/14aVKYKizi/3+LepGRxWFU=; b=Csi2zum1XPkTORecvpN2iWPExWO3KCJQAB/jYG2lBf1hx8lXg4trDDQJMynDIZVlGp +bu8vw6YYuUhfswBdYLFImN1H+TM8N6lQ22uU3vI6MoJZS1jejXQe6PRj+1b2p437qWu Rocu2a5yi6cfADIqKQ6iPnR1xhz0aa4G+0F7kCmS7txbWqZHkY/j8AGOexs1SbkkYJ+M LyaThJfeMGiQ42EbpglM0Hvo2m6M3TXR6NLuoeF6VNPSwH9XguDJGIxy/7Y+5t3NFUSz HVuP19krtD6ykeIKnCzmXA2Um05gMrRJKhamGBam995Sa0bKZVW2GqdAyqMREaWXSoWb /vCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742475704; x=1743080504; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Vc3dKjde0rLVyDC0QPLc/14aVKYKizi/3+LepGRxWFU=; b=V5+kginZTSkMuwMcIlQ0j5qIaKA1W+v3gwOh/Gvz6WPIpvwISFMzM2oVH8gcNGlZL/ NVB0zyAgtTSQtUqrQXVkvj7WWee4dxXMlBqzaL/ZXiysirPFWNf0v3Mi8GS2NYQnR5Wp 3S2dbrImMMnBUx1EAkzhnkCJFyeW4afMYV9g81sSxfXwlQc+ilrlVITh+PHlE+cUfTqq CYUHiH0jkmH/tLsXOCpXqY1GpednIvOg9yKtp8Mf7AW9RtnEEGjOedowBmi22vTy2LVd Zdieo6/ytnVgcTQ7/GU7YJRaIlamjV/wmD10yDxd4E6TgBndyJrcK0R74RSPKFqSBazE 7NNQ== X-Forwarded-Encrypted: i=1; AJvYcCU2UHNAQZSoZGc3YxfSjAhH0CtchsK31wLVPDnzr3Z/8EwmLSjUCpMgKxgbzj9uuo36ti7iUcq6jafX5LSQ3tA/@lists.infradead.org, AJvYcCW6cTp+NSMJh+4wvn17AS7kjo9FqhbYIHHnDBWhcSmR+Bc9buGx2dYXq1ejr7co2JkFOxsBaumdz/216ShJuHw=@lists.infradead.org, AJvYcCW9a2hMmkEE2w43CrrgUsecJHgyJFF+mSpfRYF6gW3zjyeYMLPgEc7zYrrf6EwHE4ob5Ih8R5MuGqxC@lists.infradead.org X-Gm-Message-State: AOJu0YymjcIMFNRylgYPRicKHeDkb8C+Xj+BzmnYpDlsfQrzXrWcSaUo rudn/fRTn9OIFGHlR2eSDDUWWPG0Z/ziVMB3/vUU3XCkuLO2+3o7 X-Gm-Gg: ASbGncsUmN4XXbCxf1cwReuR4hmSKA/otiUCcoLV1nwsaXlUhbdb/xjzHOkraFwtzXy HS91QLu2x5tiOMinrJi29DRf4YrJ3ERQ7Bq+r3eipB6pD4pwf8QCVTUdLb/yTnOGjHH8tzC13AX QOBz7h6PBxpeylAEPPTxdji3hZ2YUKiuxUl2VyEIoCqK20rGufoQ+6y7X48Vu/seQSo9KEra8C2 A2H14SL03kKPwcxSS3K5+nfcScwTfz9nmDHczHhI48+0hFzOnefwgCr3SBNa41z630DvRlcEOUa j1p5AigGaegNZ7mSvlsyU9+28+c9HzLN3XiwCVAfnSvuZreLalTirni9Ar5y6XQPcbTbnou8HFt sTelyx6JqWbedug== X-Google-Smtp-Source: AGHT+IF/l6XMrjHci+BW3RGcUAaz5jM7jX2EkvkrL4ZuF2YFu9cX6Xupx/UFNRAGRB5FWZYiIkaFbw== X-Received: by 2002:a5d:6d07:0:b0:38d:d9bd:18a6 with SMTP id ffacd0b85a97d-39973b32cf5mr5739209f8f.42.1742475701698; Thu, 20 Mar 2025 06:01:41 -0700 (PDT) Received: from localhost.localdomain (93-34-90-129.ip49.fastwebnet.it. [93.34.90.129]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-397f2837e61sm18492328f8f.97.2025.03.20.06.01.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Mar 2025 06:01:41 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Kishon Vijay Abraham I , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Greg Kroah-Hartman , Daniel Danzberger , Arnd Bergmann , Alexander Sverdlin , Nikita Shubin , Linus Walleij , Yangyu Chen , Ben Hutchings , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-usb@vger.kernel.org, upstream@airoha.com Subject: [PATCH v2 07/11] dt-bindings: phy: Add documentation for Airoha AN7581 USB PHY Date: Thu, 20 Mar 2025 14:00:30 +0100 Message-ID: <20250320130054.4804-8-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250320130054.4804-1-ansuelsmth@gmail.com> References: <20250320130054.4804-1-ansuelsmth@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250320_060145_521585_04D2A319 X-CRM114-Status: GOOD ( 19.80 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Add documentation for Airoha AN7581 USB PHY that describe the USB PHY for the USB controller. Airoha AN7581 SoC support a maximum of 2 USB port. The USB 2.0 mode is always supported. The USB 3.0 mode is optional and depends on the Serdes mode currently configured on the system for the USB port. If the airoha,serdes-port property is not declared, it's assumed USB 3.0 mode is not supported, as the Serdes mode can't be validated. Signed-off-by: Christian Marangi --- .../bindings/phy/airoha,an7581-usb-phy.yaml | 83 +++++++++++++++++++ MAINTAINERS | 7 ++ .../dt-bindings/phy/airoha,an7581-usb-phy.h | 11 +++ 3 files changed, 101 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml create mode 100644 include/dt-bindings/phy/airoha,an7581-usb-phy.h diff --git a/Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml b/Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml new file mode 100644 index 000000000000..39ceaded5d0e --- /dev/null +++ b/Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml @@ -0,0 +1,83 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/airoha,an7581-usb-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Airoha AN7581 SoC USB PHY + +maintainers: + - Christian Marangi + +description: > + The Airoha AN7581 SoC USB PHY describes the USB PHY for the USB controller. + + Airoha AN7581 SoC support a maximum of 2 USB port. The USB 2.0 mode is + always supported. The USB 3.0 mode is optional and depends on the Serdes + mode currently configured on the system for the USB port. + + If the airoha,serdes-port property is not declared, it's assumed USB 3.0 + mode is not supported, as the Serdes mode can't be validated. + +properties: + compatible: + const: airoha,an7581-usb-phy + + reg: + maxItems: 1 + + + airoha,usb2-monitor-clk-sel: + description: Describe what oscillator across the available 4 + should be selected for USB 2.0 Slew Rate calibration. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3] + + airoha,serdes-port: + description: Describe what Serdes Port is attached to the USB 3.0 port. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3] + + airoha,scu: + description: Phandle to the SCU node for USB 3.0 Serdes mode validation. + $ref: /schemas/types.yaml#/definitions/phandle + + '#phy-cells': + const: 1 + +required: + - compatible + - reg + - airoha,usb2-monitor-clk-sel + - '#phy-cells' + +dependentRequired: + airoha,serdes-port: [ 'airoha,scu' ] + +additionalProperties: false + +examples: + - | + #include + #include + + phy@1fac0000 { + compatible = "airoha,an7581-usb-phy"; + reg = <0x1fac0000 0x10000>; + + airoha,usb2-monitor-clk-sel = ; + airoha,scu = <&scu>; + airoha,serdes-port = ; + + #phy-cells = <1>; + }; + + phy@1fae0000 { + compatible = "airoha,an7581-usb-phy"; + reg = <0x1fae0000 0x10000>; + + airoha,usb2-monitor-clk-sel = ; + + #phy-cells = <1>; + }; + diff --git a/MAINTAINERS b/MAINTAINERS index 7cd54c70aeed..c4a374da2b12 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -754,6 +754,13 @@ S: Maintained F: Documentation/devicetree/bindings/spi/airoha,en7581-snand.yaml F: drivers/spi/spi-airoha-snfi.c +AIROHA USB PHY DRIVER +M: Christian Marangi +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml +F: include/dt-bindings/phy/airoha,an7581-usb-phy.h + AIRSPY MEDIA DRIVER L: linux-media@vger.kernel.org S: Orphan diff --git a/include/dt-bindings/phy/airoha,an7581-usb-phy.h b/include/dt-bindings/phy/airoha,an7581-usb-phy.h new file mode 100644 index 000000000000..efbb0ae75e3a --- /dev/null +++ b/include/dt-bindings/phy/airoha,an7581-usb-phy.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ + +#ifndef _DT_BINDINGS_AIROHA_AN7581_USB_PHY_H_ +#define _DT_BINDINGS_AIROHA_AN7581_USB_PHY_H_ + +#define AIROHA_USB2_MONCLK_SEL0 0 +#define AIROHA_USB2_MONCLK_SEL1 1 +#define AIROHA_USB2_MONCLK_SEL2 2 +#define AIROHA_USB2_MONCLK_SEL3 3 + +#endif From patchwork Thu Mar 20 13:00:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 14023958 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 291DDC28B30 for ; Thu, 20 Mar 2025 13:15:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=KBK5BZQaVMN7vEPgRqaHSEzey18aNz4HJ69g8c6BUIU=; b=P6FpFx7kogMFvH Azw550Tqce4BW4PeQz65+Rd3FjoabByGUidO762V2PNGlQ7zKn4tZoXV3CRxLWW5pvKA+UpB2mEyQ Fb9ky4g4FmrPa3R2tGYq24U9M2C+WP5RV2JGtC09O+2MfqTw1MkygiPKTxm9MYpysAGURwlC71fKN VTeb6kN22RiTJrTbcDatO8B8Jeq2hIH/zoECZod5o108cd/hxgpsKZQ09oFCfm0gCwX25tNFcs8JP yvS+FyxaKbJUQKIAvIG3FvVArCSjTIffc48SEmL+Dr4LOIeFv411u1RzAq14z5tQtRSyXkx+RzO+t UiwvY6Hej+LfjTepIXhw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tvFkR-0000000CCaw-3o0O; Thu, 20 Mar 2025 13:15:47 +0000 Received: from mail-wm1-x334.google.com ([2a00:1450:4864:20::334]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tvFWs-0000000CAgI-1eEs; Thu, 20 Mar 2025 13:01:48 +0000 Received: by mail-wm1-x334.google.com with SMTP id 5b1f17b1804b1-43690d4605dso4851715e9.0; Thu, 20 Mar 2025 06:01:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1742475705; x=1743080505; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=k+zeHfM2s5nyXBkANIJRscsnuLHTK8RBHZgXCdIfUm8=; b=cA9ihlRWS0ZVeVU1bm5asgJqaSUbfOrUfS/94dai+YHdvl7hcwygKqEqOW3reHMm9x NwoQJ3EkiqqjBNR/FvrqsVw7ReYsEl1lOn+eSwXcUOV2uSh+dLUA9QCjzilkNstwjywL hrGQSQSAvBGY+yWTM/0j0hQbl/WqwmLr8xP9RAuOcDxQM36VFNnkzSDLYpchf0t6sAYC qX1k6OqJ8LoTlzN/Y8u0aHfkEYbt2ly7g2MtZ8m8O5+CVv7Uc5UBaq6pfR1eNaEyNY1X GwOq5/dxttz5sVpx3TPX63VXmDreXfdiLgtuhtobYWefN1YQbx07XRBGcU+3KwUc6j6/ z4ww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742475705; x=1743080505; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=k+zeHfM2s5nyXBkANIJRscsnuLHTK8RBHZgXCdIfUm8=; b=kF5CzWiZkEyMBammE+gMjggqftiB9k2aK+7sNqdraeeb/drtHbz8Af9cahE/wfz5qU 9ve6hMG3vW0D9AC+UzgrzyUqiC6hZM0QgJb9OMT8odAUvrTfI+4ubZpHwNtPweTkDTsX aXf4HQ0DkCBRrGUdSk4Px2/XdWbuXl3G5RlB592/cU0GjZdDvDd9dOHBBM/oSW6zPKnz VooPO26ow4WehifIfwjotW6QQkPFV8gJleqstRlqxL2i44YiCKRdZbExBICLCLxmma9d TdtBb0R28br3GC65oNccdzyBDg3O6RduWNW3k0Yd7eBwNhbPxc0OO2LqcwwWjm6vkWdU pjuA== X-Forwarded-Encrypted: i=1; AJvYcCUuxvLf9eoBxDlOkKTw5/6oHDpJ2axtLCeBwFTeO2Qr6h7WKePCwW4n9Ha4LZrczkq3NXbXSLu8SH5n3bMUR34Q@lists.infradead.org, AJvYcCVtG+7WrKKsRtCVjikaeonyvNgdVzaqXP60IhRXsxZocSV4A8prLMY3BZNs+vu5fhVWoLLeUXOW0Fpy@lists.infradead.org, AJvYcCWML+BCKz6O8h74lNgYKuRMzZP/aIZXgfTmt8xZdwsqfJDSarr7tlnQDLGr7m8YVjSlTjT6/oAQWNLIns2elfY=@lists.infradead.org X-Gm-Message-State: AOJu0YzYvHsOd/u6Woua7zLygzkXeNPa7OFebnf20x6i6EHtl8oQm0Kn iEsvZ6c8luC8vhsjFIYVV2EJ3Ok7EsS3yqV60fTGN7Lqc/+VhAHk X-Gm-Gg: ASbGncvd1H4QcV7kj74+w0gVsobn7xSI1+Q1++/Tq0LrseRKepw1aIXSVgIBNuS8kHM m3YmKXSbLIk8hsPXmxxOZcfyMRUUZl9fjaaIWrPCmqIo3FQFQatW3DeNWgSmfp4UNH0Xx+mZGV7 9uPSdBW77bxV/78qJFYuvkUQA7/FNtALODyTBtong4jn5mwgqjtnzVyl971ZJr8MhiuTxglZ+Ei FoxACjC+a0nJQ3MNDeK7ZENWVCc7e4V6i5V/Nq96FSt/f0skkf8wfT3FOWu+8jTyUIP+3BuugYy T8jZnCyzMoos+IXd8GbaO2vhQbOyLv6pdpj0C6RIs0Ta/qYG/MiMyvEZXERjeRfXGwBBjTHqONw hupdZ/37qOzasVw== X-Google-Smtp-Source: AGHT+IFySmYEuIQkHV3hcdE8d9b1dxUxSOmTU/YQwWAlYd4l6DoE/UxiHP7IMAhJSjVJtbdlQGk19Q== X-Received: by 2002:a05:6000:2cd:b0:391:2fe3:24ec with SMTP id ffacd0b85a97d-399739bc8c0mr7028513f8f.14.1742475703674; Thu, 20 Mar 2025 06:01:43 -0700 (PDT) Received: from localhost.localdomain (93-34-90-129.ip49.fastwebnet.it. [93.34.90.129]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-397f2837e61sm18492328f8f.97.2025.03.20.06.01.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Mar 2025 06:01:43 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Kishon Vijay Abraham I , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Greg Kroah-Hartman , Daniel Danzberger , Arnd Bergmann , Alexander Sverdlin , Nikita Shubin , Linus Walleij , Yangyu Chen , Ben Hutchings , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-usb@vger.kernel.org, upstream@airoha.com Subject: [PATCH v2 08/11] phy: move Airoha PCIe PHY driver to dedicated directory Date: Thu, 20 Mar 2025 14:00:31 +0100 Message-ID: <20250320130054.4804-9-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250320130054.4804-1-ansuelsmth@gmail.com> References: <20250320130054.4804-1-ansuelsmth@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250320_060146_919173_8F234C4F X-CRM114-Status: GOOD ( 21.12 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org To keep the generic PHY directory tidy, move the PCIe PHY driver to a dedicated directory. This is also in preparation for support of the Airoha USB PHY driver. Signed-off-by: Christian Marangi --- MAINTAINERS | 4 +- drivers/phy/Kconfig | 11 +- drivers/phy/Makefile | 5 +- drivers/phy/airoha/Kconfig | 13 + drivers/phy/airoha/Makefile | 3 + drivers/phy/airoha/phy-airoha-pcie-regs.h | 494 ++++++++ drivers/phy/airoha/phy-airoha-pcie.c | 1290 +++++++++++++++++++++ 7 files changed, 1806 insertions(+), 14 deletions(-) create mode 100644 drivers/phy/airoha/Kconfig create mode 100644 drivers/phy/airoha/Makefile create mode 100644 drivers/phy/airoha/phy-airoha-pcie-regs.h create mode 100644 drivers/phy/airoha/phy-airoha-pcie.c diff --git a/MAINTAINERS b/MAINTAINERS index c4a374da2b12..4e11db5d203a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -733,8 +733,8 @@ M: Lorenzo Bianconi L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/phy/airoha,en7581-pcie-phy.yaml -F: drivers/phy/phy-airoha-pcie-regs.h -F: drivers/phy/phy-airoha-pcie.c +F: drivers/phy/airoha/phy-airoha-pcie-regs.h +F: drivers/phy/airoha/phy-airoha-pcie.c AIROHA SCU SSR DRIVER M: Christian Marangi diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 8d58efe998ec..7f9f5b786643 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -72,16 +72,6 @@ config PHY_CAN_TRANSCEIVER functional modes using gpios and sets the attribute max link rate, for CAN drivers. -config PHY_AIROHA_PCIE - tristate "Airoha PCIe-PHY Driver" - depends on ARCH_AIROHA || COMPILE_TEST - depends on OF - select GENERIC_PHY - help - Say Y here to add support for Airoha PCIe PHY driver. - This driver create the basic PHY instance and provides initialize - callback for PCIe GEN3 port. - config PHY_NXP_PTN3222 tristate "NXP PTN3222 1-port eUSB2 to USB2 redriver" depends on I2C @@ -93,6 +83,7 @@ config PHY_NXP_PTN3222 schemes. It supports all three USB 2.0 data rates: Low Speed, Full Speed and High Speed. +source "drivers/phy/airoha/Kconfig" source "drivers/phy/allwinner/Kconfig" source "drivers/phy/amlogic/Kconfig" source "drivers/phy/broadcom/Kconfig" diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index e281442acc75..9ab557db59e6 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -10,9 +10,10 @@ obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o obj-$(CONFIG_PHY_XGENE) += phy-xgene.o obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o -obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o + obj-$(CONFIG_PHY_NXP_PTN3222) += phy-nxp-ptn3222.o -obj-y += allwinner/ \ +obj-y += airoha/ \ + allwinner/ \ amlogic/ \ broadcom/ \ cadence/ \ diff --git a/drivers/phy/airoha/Kconfig b/drivers/phy/airoha/Kconfig new file mode 100644 index 000000000000..70b7eac4a2bf --- /dev/null +++ b/drivers/phy/airoha/Kconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Phy drivers for Airoha devices +# +config PHY_AIROHA_PCIE + tristate "Airoha PCIe-PHY Driver" + depends on ARCH_AIROHA || COMPILE_TEST + depends on OF + select GENERIC_PHY + help + Say Y here to add support for Airoha PCIe PHY driver. + This driver create the basic PHY instance and provides initialize + callback for PCIe GEN3 port. diff --git a/drivers/phy/airoha/Makefile b/drivers/phy/airoha/Makefile new file mode 100644 index 000000000000..3222f749546b --- /dev/null +++ b/drivers/phy/airoha/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o diff --git a/drivers/phy/airoha/phy-airoha-pcie-regs.h b/drivers/phy/airoha/phy-airoha-pcie-regs.h new file mode 100644 index 000000000000..b938a7b468fe --- /dev/null +++ b/drivers/phy/airoha/phy-airoha-pcie-regs.h @@ -0,0 +1,494 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 AIROHA Inc + * Author: Lorenzo Bianconi + */ + +#ifndef _PHY_AIROHA_PCIE_H +#define _PHY_AIROHA_PCIE_H + +/* CSR_2L */ +#define REG_CSR_2L_CMN 0x0000 +#define CSR_2L_PXP_CMN_LANE_EN BIT(0) +#define CSR_2L_PXP_CMN_TRIM_MASK GENMASK(28, 24) + +#define REG_CSR_2L_JCPLL_IB_EXT 0x0004 +#define REG_CSR_2L_JCPLL_LPF_SHCK_EN BIT(8) +#define CSR_2L_PXP_JCPLL_CHP_IBIAS GENMASK(21, 16) +#define CSR_2L_PXP_JCPLL_CHP_IOFST GENMASK(29, 24) + +#define REG_CSR_2L_JCPLL_LPF_BR 0x0008 +#define CSR_2L_PXP_JCPLL_LPF_BR GENMASK(4, 0) +#define CSR_2L_PXP_JCPLL_LPF_BC GENMASK(12, 8) +#define CSR_2L_PXP_JCPLL_LPF_BP GENMASK(20, 16) +#define CSR_2L_PXP_JCPLL_LPF_BWR GENMASK(28, 24) + +#define REG_CSR_2L_JCPLL_LPF_BWC 0x000c +#define CSR_2L_PXP_JCPLL_LPF_BWC GENMASK(4, 0) +#define CSR_2L_PXP_JCPLL_KBAND_CODE GENMASK(23, 16) +#define CSR_2L_PXP_JCPLL_KBAND_DIV GENMASK(26, 24) + +#define REG_CSR_2L_JCPLL_KBAND_KFC 0x0010 +#define CSR_2L_PXP_JCPLL_KBAND_KFC GENMASK(1, 0) +#define CSR_2L_PXP_JCPLL_KBAND_KF GENMASK(9, 8) +#define CSR_2L_PXP_JCPLL_KBAND_KS GENMASK(17, 16) +#define CSR_2L_PXP_JCPLL_POSTDIV_EN BIT(24) + +#define REG_CSR_2L_JCPLL_MMD_PREDIV_MODE 0x0014 +#define CSR_2L_PXP_JCPLL_MMD_PREDIV_MODE GENMASK(1, 0) +#define CSR_2L_PXP_JCPLL_POSTDIV_D2 BIT(16) +#define CSR_2L_PXP_JCPLL_POSTDIV_D5 BIT(24) + +#define CSR_2L_PXP_JCPLL_MONCK 0x0018 +#define CSR_2L_PXP_JCPLL_REFIN_DIV GENMASK(25, 24) + +#define REG_CSR_2L_JCPLL_RST_DLY 0x001c +#define CSR_2L_PXP_JCPLL_RST_DLY GENMASK(2, 0) +#define CSR_2L_PXP_JCPLL_RST BIT(8) +#define CSR_2L_PXP_JCPLL_SDM_DI_EN BIT(16) +#define CSR_2L_PXP_JCPLL_SDM_DI_LS GENMASK(25, 24) + +#define REG_CSR_2L_JCPLL_SDM_IFM 0x0020 +#define CSR_2L_PXP_JCPLL_SDM_IFM BIT(0) + +#define REG_CSR_2L_JCPLL_SDM_HREN 0x0024 +#define CSR_2L_PXP_JCPLL_SDM_HREN BIT(0) +#define CSR_2L_PXP_JCPLL_TCL_AMP_EN BIT(8) +#define CSR_2L_PXP_JCPLL_TCL_AMP_GAIN GENMASK(18, 16) +#define CSR_2L_PXP_JCPLL_TCL_AMP_VREF GENMASK(28, 24) + +#define REG_CSR_2L_JCPLL_TCL_CMP 0x0028 +#define CSR_2L_PXP_JCPLL_TCL_LPF_EN BIT(16) +#define CSR_2L_PXP_JCPLL_TCL_LPF_BW GENMASK(26, 24) + +#define REG_CSR_2L_JCPLL_VCODIV 0x002c +#define CSR_2L_PXP_JCPLL_VCO_CFIX GENMASK(9, 8) +#define CSR_2L_PXP_JCPLL_VCO_HALFLSB_EN BIT(16) +#define CSR_2L_PXP_JCPLL_VCO_SCAPWR GENMASK(26, 24) + +#define REG_CSR_2L_JCPLL_VCO_TCLVAR 0x0030 +#define CSR_2L_PXP_JCPLL_VCO_TCLVAR GENMASK(2, 0) + +#define REG_CSR_2L_JCPLL_SSC 0x0038 +#define CSR_2L_PXP_JCPLL_SSC_EN BIT(0) +#define CSR_2L_PXP_JCPLL_SSC_PHASE_INI BIT(8) +#define CSR_2L_PXP_JCPLL_SSC_TRI_EN BIT(16) + +#define REG_CSR_2L_JCPLL_SSC_DELTA1 0x003c +#define CSR_2L_PXP_JCPLL_SSC_DELTA1 GENMASK(15, 0) +#define CSR_2L_PXP_JCPLL_SSC_DELTA GENMASK(31, 16) + +#define REG_CSR_2L_JCPLL_SSC_PERIOD 0x0040 +#define CSR_2L_PXP_JCPLL_SSC_PERIOD GENMASK(15, 0) + +#define REG_CSR_2L_JCPLL_TCL_VTP_EN 0x004c +#define CSR_2L_PXP_JCPLL_SPARE_LOW GENMASK(31, 24) + +#define REG_CSR_2L_JCPLL_TCL_KBAND_VREF 0x0050 +#define CSR_2L_PXP_JCPLL_TCL_KBAND_VREF GENMASK(4, 0) +#define CSR_2L_PXP_JCPLL_VCO_KBAND_MEAS_EN BIT(24) + +#define REG_CSR_2L_750M_SYS_CK 0x0054 +#define CSR_2L_PXP_TXPLL_LPF_SHCK_EN BIT(16) +#define CSR_2L_PXP_TXPLL_CHP_IBIAS GENMASK(29, 24) + +#define REG_CSR_2L_TXPLL_CHP_IOFST 0x0058 +#define CSR_2L_PXP_TXPLL_CHP_IOFST GENMASK(5, 0) +#define CSR_2L_PXP_TXPLL_LPF_BR GENMASK(12, 8) +#define CSR_2L_PXP_TXPLL_LPF_BC GENMASK(20, 16) +#define CSR_2L_PXP_TXPLL_LPF_BP GENMASK(28, 24) + +#define REG_CSR_2L_TXPLL_LPF_BWR 0x005c +#define CSR_2L_PXP_TXPLL_LPF_BWR GENMASK(4, 0) +#define CSR_2L_PXP_TXPLL_LPF_BWC GENMASK(12, 8) +#define CSR_2L_PXP_TXPLL_KBAND_CODE GENMASK(31, 24) + +#define REG_CSR_2L_TXPLL_KBAND_DIV 0x0060 +#define CSR_2L_PXP_TXPLL_KBAND_DIV GENMASK(2, 0) +#define CSR_2L_PXP_TXPLL_KBAND_KFC GENMASK(9, 8) +#define CSR_2L_PXP_TXPLL_KBAND_KF GENMASK(17, 16) +#define CSR_2L_PXP_txpll_KBAND_KS GENMASK(25, 24) + +#define REG_CSR_2L_TXPLL_POSTDIV 0x0064 +#define CSR_2L_PXP_TXPLL_POSTDIV_EN BIT(0) +#define CSR_2L_PXP_TXPLL_MMD_PREDIV_MODE GENMASK(9, 8) +#define CSR_2L_PXP_TXPLL_PHY_CK1_EN BIT(24) + +#define REG_CSR_2L_TXPLL_PHY_CK2 0x0068 +#define CSR_2L_PXP_TXPLL_REFIN_INTERNAL BIT(24) + +#define REG_CSR_2L_TXPLL_REFIN_DIV 0x006c +#define CSR_2L_PXP_TXPLL_REFIN_DIV GENMASK(1, 0) +#define CSR_2L_PXP_TXPLL_RST_DLY GENMASK(10, 8) +#define CSR_2L_PXP_TXPLL_PLL_RSTB BIT(16) + +#define REG_CSR_2L_TXPLL_SDM_DI_LS 0x0070 +#define CSR_2L_PXP_TXPLL_SDM_DI_LS GENMASK(1, 0) +#define CSR_2L_PXP_TXPLL_SDM_IFM BIT(8) +#define CSR_2L_PXP_TXPLL_SDM_ORD GENMASK(25, 24) + +#define REG_CSR_2L_TXPLL_SDM_OUT 0x0074 +#define CSR_2L_PXP_TXPLL_TCL_AMP_EN BIT(16) +#define CSR_2L_PXP_TXPLL_TCL_AMP_GAIN GENMASK(26, 24) + +#define REG_CSR_2L_TXPLL_TCL_AMP_VREF 0x0078 +#define CSR_2L_PXP_TXPLL_TCL_AMP_VREF GENMASK(4, 0) +#define CSR_2L_PXP_TXPLL_TCL_LPF_EN BIT(24) + +#define REG_CSR_2L_TXPLL_TCL_LPF_BW 0x007c +#define CSR_2L_PXP_TXPLL_TCL_LPF_BW GENMASK(2, 0) +#define CSR_2L_PXP_TXPLL_VCO_CFIX GENMASK(17, 16) +#define CSR_2L_PXP_TXPLL_VCO_HALFLSB_EN BIT(24) + +#define REG_CSR_2L_TXPLL_VCO_SCAPWR 0x0080 +#define CSR_2L_PXP_TXPLL_VCO_SCAPWR GENMASK(2, 0) + +#define REG_CSR_2L_TXPLL_SSC 0x0084 +#define CSR_2L_PXP_TXPLL_SSC_EN BIT(0) +#define CSR_2L_PXP_TXPLL_SSC_PHASE_INI BIT(8) + +#define REG_CSR_2L_TXPLL_SSC_DELTA1 0x0088 +#define CSR_2L_PXP_TXPLL_SSC_DELTA1 GENMASK(15, 0) +#define CSR_2L_PXP_TXPLL_SSC_DELTA GENMASK(31, 16) + +#define REG_CSR_2L_TXPLL_SSC_PERIOD 0x008c +#define CSR_2L_PXP_txpll_SSC_PERIOD GENMASK(15, 0) + +#define REG_CSR_2L_TXPLL_VTP 0x0090 +#define CSR_2L_PXP_TXPLL_VTP_EN BIT(0) + +#define REG_CSR_2L_TXPLL_TCL_VTP 0x0098 +#define CSR_2L_PXP_TXPLL_SPARE_L GENMASK(31, 24) + +#define REG_CSR_2L_TXPLL_TCL_KBAND_VREF 0x009c +#define CSR_2L_PXP_TXPLL_TCL_KBAND_VREF GENMASK(4, 0) +#define CSR_2L_PXP_TXPLL_VCO_KBAND_MEAS_EN BIT(24) + +#define REG_CSR_2L_TXPLL_POSTDIV_D256 0x00a0 +#define CSR_2L_PXP_CLKTX0_AMP GENMASK(10, 8) +#define CSR_2L_PXP_CLKTX0_OFFSET GENMASK(17, 16) +#define CSR_2L_PXP_CLKTX0_SR GENMASK(25, 24) + +#define REG_CSR_2L_CLKTX0_FORCE_OUT1 0x00a4 +#define CSR_2L_PXP_CLKTX0_HZ BIT(8) +#define CSR_2L_PXP_CLKTX0_IMP_SEL GENMASK(20, 16) +#define CSR_2L_PXP_CLKTX1_AMP GENMASK(26, 24) + +#define REG_CSR_2L_CLKTX1_OFFSET 0x00a8 +#define CSR_2L_PXP_CLKTX1_OFFSET GENMASK(1, 0) +#define CSR_2L_PXP_CLKTX1_SR GENMASK(9, 8) +#define CSR_2L_PXP_CLKTX1_HZ BIT(24) + +#define REG_CSR_2L_CLKTX1_IMP_SEL 0x00ac +#define CSR_2L_PXP_CLKTX1_IMP_SEL GENMASK(4, 0) + +#define REG_CSR_2L_PLL_CMN_RESERVE0 0x00b0 +#define CSR_2L_PXP_PLL_RESERVE_MASK GENMASK(15, 0) + +#define REG_CSR_2L_TX0_CKLDO 0x00cc +#define CSR_2L_PXP_TX0_CKLDO_EN BIT(0) +#define CSR_2L_PXP_TX0_DMEDGEGEN_EN BIT(24) + +#define REG_CSR_2L_TX1_CKLDO 0x00e8 +#define CSR_2L_PXP_TX1_CKLDO_EN BIT(0) +#define CSR_2L_PXP_TX1_DMEDGEGEN_EN BIT(24) + +#define REG_CSR_2L_TX1_MULTLANE 0x00ec +#define CSR_2L_PXP_TX1_MULTLANE_EN BIT(0) + +#define REG_CSR_2L_RX0_REV0 0x00fc +#define CSR_2L_PXP_VOS_PNINV GENMASK(19, 18) +#define CSR_2L_PXP_FE_GAIN_NORMAL_MODE GENMASK(22, 20) +#define CSR_2L_PXP_FE_GAIN_TRAIN_MODE GENMASK(26, 24) + +#define REG_CSR_2L_RX0_PHYCK_DIV 0x0100 +#define CSR_2L_PXP_RX0_PHYCK_SEL GENMASK(9, 8) +#define CSR_2L_PXP_RX0_PHYCK_RSTB BIT(16) +#define CSR_2L_PXP_RX0_TDC_CK_SEL BIT(24) + +#define REG_CSR_2L_CDR0_PD_PICAL_CKD8_INV 0x0104 +#define CSR_2L_PXP_CDR0_PD_EDGE_DISABLE BIT(8) + +#define REG_CSR_2L_CDR0_LPF_RATIO 0x0110 +#define CSR_2L_PXP_CDR0_LPF_TOP_LIM GENMASK(26, 8) + +#define REG_CSR_2L_CDR0_PR_INJ_MODE 0x011c +#define CSR_2L_PXP_CDR0_INJ_FORCE_OFF BIT(24) + +#define REG_CSR_2L_CDR0_PR_BETA_DAC 0x0120 +#define CSR_2L_PXP_CDR0_PR_BETA_SEL GENMASK(19, 16) +#define CSR_2L_PXP_CDR0_PR_KBAND_DIV GENMASK(26, 24) + +#define REG_CSR_2L_CDR0_PR_VREG_IBAND 0x0124 +#define CSR_2L_PXP_CDR0_PR_VREG_IBAND GENMASK(2, 0) +#define CSR_2L_PXP_CDR0_PR_VREG_CKBUF GENMASK(10, 8) + +#define REG_CSR_2L_CDR0_PR_CKREF_DIV 0x0128 +#define CSR_2L_PXP_CDR0_PR_CKREF_DIV GENMASK(1, 0) + +#define REG_CSR_2L_CDR0_PR_MONCK 0x012c +#define CSR_2L_PXP_CDR0_PR_MONCK_ENABLE BIT(0) +#define CSR_2L_PXP_CDR0_PR_RESERVE0 GENMASK(19, 16) + +#define REG_CSR_2L_CDR0_PR_COR_HBW 0x0130 +#define CSR_2L_PXP_CDR0_PR_LDO_FORCE_ON BIT(8) +#define CSR_2L_PXP_CDR0_PR_CKREF_DIV1 GENMASK(17, 16) + +#define REG_CSR_2L_CDR0_PR_MONPI 0x0134 +#define CSR_2L_PXP_CDR0_PR_XFICK_EN BIT(8) + +#define REG_CSR_2L_RX0_SIGDET_DCTEST 0x0140 +#define CSR_2L_PXP_RX0_SIGDET_LPF_CTRL GENMASK(9, 8) +#define CSR_2L_PXP_RX0_SIGDET_PEAK GENMASK(25, 24) + +#define REG_CSR_2L_RX0_SIGDET_VTH_SEL 0x0144 +#define CSR_2L_PXP_RX0_SIGDET_VTH_SEL GENMASK(4, 0) +#define CSR_2L_PXP_RX0_FE_VB_EQ1_EN BIT(24) + +#define REG_CSR_2L_PXP_RX0_FE_VB_EQ2 0x0148 +#define CSR_2L_PXP_RX0_FE_VB_EQ2_EN BIT(0) +#define CSR_2L_PXP_RX0_FE_VB_EQ3_EN BIT(8) +#define CSR_2L_PXP_RX0_FE_VCM_GEN_PWDB BIT(16) + +#define REG_CSR_2L_PXP_RX0_OSCAL_CTLE1IOS 0x0158 +#define CSR_2L_PXP_RX0_PR_OSCAL_VGA1IOS GENMASK(29, 24) + +#define REG_CSR_2L_PXP_RX0_OSCA_VGA1VOS 0x015c +#define CSR_2L_PXP_RX0_PR_OSCAL_VGA1VOS GENMASK(5, 0) +#define CSR_2L_PXP_RX0_PR_OSCAL_VGA2IOS GENMASK(13, 8) + +#define REG_CSR_2L_RX1_REV0 0x01b4 + +#define REG_CSR_2L_RX1_PHYCK_DIV 0x01b8 +#define CSR_2L_PXP_RX1_PHYCK_SEL GENMASK(9, 8) +#define CSR_2L_PXP_RX1_PHYCK_RSTB BIT(16) +#define CSR_2L_PXP_RX1_TDC_CK_SEL BIT(24) + +#define REG_CSR_2L_CDR1_PD_PICAL_CKD8_INV 0x01bc +#define CSR_2L_PXP_CDR1_PD_EDGE_DISABLE BIT(8) + +#define REG_CSR_2L_CDR1_PR_BETA_DAC 0x01d8 +#define CSR_2L_PXP_CDR1_PR_BETA_SEL GENMASK(19, 16) +#define CSR_2L_PXP_CDR1_PR_KBAND_DIV GENMASK(26, 24) + +#define REG_CSR_2L_CDR1_PR_MONCK 0x01e4 +#define CSR_2L_PXP_CDR1_PR_MONCK_ENABLE BIT(0) +#define CSR_2L_PXP_CDR1_PR_RESERVE0 GENMASK(19, 16) + +#define REG_CSR_2L_CDR1_LPF_RATIO 0x01c8 +#define CSR_2L_PXP_CDR1_LPF_TOP_LIM GENMASK(26, 8) + +#define REG_CSR_2L_CDR1_PR_INJ_MODE 0x01d4 +#define CSR_2L_PXP_CDR1_INJ_FORCE_OFF BIT(24) + +#define REG_CSR_2L_CDR1_PR_VREG_IBAND_VAL 0x01dc +#define CSR_2L_PXP_CDR1_PR_VREG_IBAND GENMASK(2, 0) +#define CSR_2L_PXP_CDR1_PR_VREG_CKBUF GENMASK(10, 8) + +#define REG_CSR_2L_CDR1_PR_CKREF_DIV 0x01e0 +#define CSR_2L_PXP_CDR1_PR_CKREF_DIV GENMASK(1, 0) + +#define REG_CSR_2L_CDR1_PR_COR_HBW 0x01e8 +#define CSR_2L_PXP_CDR1_PR_LDO_FORCE_ON BIT(8) +#define CSR_2L_PXP_CDR1_PR_CKREF_DIV1 GENMASK(17, 16) + +#define REG_CSR_2L_CDR1_PR_MONPI 0x01ec +#define CSR_2L_PXP_CDR1_PR_XFICK_EN BIT(8) + +#define REG_CSR_2L_RX1_DAC_RANGE_EYE 0x01f4 +#define CSR_2L_PXP_RX1_SIGDET_LPF_CTRL GENMASK(25, 24) + +#define REG_CSR_2L_RX1_SIGDET_NOVTH 0x01f8 +#define CSR_2L_PXP_RX1_SIGDET_PEAK GENMASK(9, 8) +#define CSR_2L_PXP_RX1_SIGDET_VTH_SEL GENMASK(20, 16) + +#define REG_CSR_2L_RX1_FE_VB_EQ1 0x0200 +#define CSR_2L_PXP_RX1_FE_VB_EQ1_EN BIT(0) +#define CSR_2L_PXP_RX1_FE_VB_EQ2_EN BIT(8) +#define CSR_2L_PXP_RX1_FE_VB_EQ3_EN BIT(16) +#define CSR_2L_PXP_RX1_FE_VCM_GEN_PWDB BIT(24) + +#define REG_CSR_2L_RX1_OSCAL_VGA1IOS 0x0214 +#define CSR_2L_PXP_RX1_PR_OSCAL_VGA1IOS GENMASK(5, 0) +#define CSR_2L_PXP_RX1_PR_OSCAL_VGA1VOS GENMASK(13, 8) +#define CSR_2L_PXP_RX1_PR_OSCAL_VGA2IOS GENMASK(21, 16) + +/* PMA */ +#define REG_PCIE_PMA_SS_LCPLL_PWCTL_SETTING_1 0x0004 +#define PCIE_LCPLL_MAN_PWDB BIT(0) + +#define REG_PCIE_PMA_SEQUENCE_DISB_CTRL1 0x010c +#define PCIE_DISB_RX_SDCAL_EN BIT(0) + +#define REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1 0x0114 +#define PCIE_FORCE_RX_SDCAL_EN BIT(0) + +#define REG_PCIE_PMA_SS_RX_FREQ_DET1 0x014c +#define PCIE_PLL_FT_LOCK_CYCLECNT GENMASK(15, 0) +#define PCIE_PLL_FT_UNLOCK_CYCLECNT GENMASK(31, 16) + +#define REG_PCIE_PMA_SS_RX_FREQ_DET2 0x0150 +#define PCIE_LOCK_TARGET_BEG GENMASK(15, 0) +#define PCIE_LOCK_TARGET_END GENMASK(31, 16) + +#define REG_PCIE_PMA_SS_RX_FREQ_DET3 0x0154 +#define PCIE_UNLOCK_TARGET_BEG GENMASK(15, 0) +#define PCIE_UNLOCK_TARGET_END GENMASK(31, 16) + +#define REG_PCIE_PMA_SS_RX_FREQ_DET4 0x0158 +#define PCIE_FREQLOCK_DET_EN GENMASK(2, 0) +#define PCIE_LOCK_LOCKTH GENMASK(11, 8) +#define PCIE_UNLOCK_LOCKTH GENMASK(15, 12) + +#define REG_PCIE_PMA_SS_RX_CAL1 0x0160 +#define REG_PCIE_PMA_SS_RX_CAL2 0x0164 +#define PCIE_CAL_OUT_OS GENMASK(11, 8) + +#define REG_PCIE_PMA_SS_RX_SIGDET0 0x0168 +#define PCIE_SIGDET_WIN_NONVLD_TIMES GENMASK(28, 24) + +#define REG_PCIE_PMA_TX_RESET 0x0260 +#define PCIE_TX_TOP_RST BIT(0) +#define PCIE_TX_CAL_RST BIT(8) + +#define REG_PCIE_PMA_RX_FORCE_MODE0 0x0294 +#define PCIE_FORCE_DA_XPON_RX_FE_GAIN_CTRL GENMASK(1, 0) + +#define REG_PCIE_PMA_SS_DA_XPON_PWDB0 0x034c +#define PCIE_DA_XPON_CDR_PR_PWDB BIT(8) + +#define REG_PCIE_PMA_SW_RESET 0x0460 +#define PCIE_SW_RX_FIFO_RST BIT(0) +#define PCIE_SW_RX_RST BIT(1) +#define PCIE_SW_TX_RST BIT(2) +#define PCIE_SW_PMA_RST BIT(3) +#define PCIE_SW_ALLPCS_RST BIT(4) +#define PCIE_SW_REF_RST BIT(5) +#define PCIE_SW_TX_FIFO_RST BIT(6) +#define PCIE_SW_XFI_TXPCS_RST BIT(7) +#define PCIE_SW_XFI_RXPCS_RST BIT(8) +#define PCIE_SW_XFI_RXPCS_BIST_RST BIT(9) +#define PCIE_SW_HSG_TXPCS_RST BIT(10) +#define PCIE_SW_HSG_RXPCS_RST BIT(11) +#define PCIE_PMA_SW_RST (PCIE_SW_RX_FIFO_RST | \ + PCIE_SW_RX_RST | \ + PCIE_SW_TX_RST | \ + PCIE_SW_PMA_RST | \ + PCIE_SW_ALLPCS_RST | \ + PCIE_SW_REF_RST | \ + PCIE_SW_TX_FIFO_RST | \ + PCIE_SW_XFI_TXPCS_RST | \ + PCIE_SW_XFI_RXPCS_RST | \ + PCIE_SW_XFI_RXPCS_BIST_RST | \ + PCIE_SW_HSG_TXPCS_RST | \ + PCIE_SW_HSG_RXPCS_RST) + +#define REG_PCIE_PMA_RO_RX_FREQDET 0x0530 +#define PCIE_RO_FBCK_LOCK BIT(0) +#define PCIE_RO_FL_OUT GENMASK(31, 16) + +#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC 0x0794 +#define PCIE_FORCE_DA_PXP_CDR_PR_IDAC GENMASK(10, 0) +#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC BIT(16) +#define PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW BIT(24) + +#define REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_SDM_PCW 0x0798 +#define PCIE_FORCE_DA_PXP_TXPLL_SDM_PCW GENMASK(30, 0) + +#define REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_VOS 0x079c +#define PCIE_FORCE_SEL_DA_PXP_JCPLL_SDM_PCW BIT(16) + +#define REG_PCIE_PMA_FORCE_DA_PXP_JCPLL_SDM_PCW 0x0800 +#define PCIE_FORCE_DA_PXP_JCPLL_SDM_PCW GENMASK(30, 0) + +#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PD_PWDB 0x081c +#define PCIE_FORCE_DA_PXP_CDR_PD_PWDB BIT(0) +#define PCIE_FORCE_SEL_DA_PXP_CDR_PD_PWDB BIT(8) + +#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C 0x0820 +#define PCIE_FORCE_DA_PXP_CDR_PR_LPF_C_EN BIT(0) +#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN BIT(8) +#define PCIE_FORCE_DA_PXP_CDR_PR_LPF_R_EN BIT(16) +#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN BIT(24) + +#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB 0x0824 +#define PCIE_FORCE_DA_PXP_CDR_PR_PWDB BIT(16) +#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB BIT(24) + +#define REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT 0x0828 +#define PCIE_FORCE_DA_PXP_JCPLL_CKOUT_EN BIT(0) +#define PCIE_FORCE_SEL_DA_PXP_JCPLL_CKOUT_EN BIT(8) +#define PCIE_FORCE_DA_PXP_JCPLL_EN BIT(16) +#define PCIE_FORCE_SEL_DA_PXP_JCPLL_EN BIT(24) + +#define REG_PCIE_PMA_FORCE_DA_PXP_RX_SCAN_RST 0x0084c +#define PCIE_FORCE_DA_PXP_RX_SIGDET_PWDB BIT(16) +#define PCIE_FORCE_SEL_DA_PXP_RX_SIGDET_PWDB BIT(24) + +#define REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT 0x0854 +#define PCIE_FORCE_DA_PXP_TXPLL_CKOUT_EN BIT(0) +#define PCIE_FORCE_SEL_DA_PXP_TXPLL_CKOUT_EN BIT(8) +#define PCIE_FORCE_DA_PXP_TXPLL_EN BIT(16) +#define PCIE_FORCE_SEL_DA_PXP_TXPLL_EN BIT(24) + +#define REG_PCIE_PMA_SCAN_MODE 0x0884 +#define PCIE_FORCE_DA_PXP_JCPLL_KBAND_LOAD_EN BIT(0) +#define PCIE_FORCE_SEL_DA_PXP_JCPLL_KBAND_LOAD_EN BIT(8) + +#define REG_PCIE_PMA_DIG_RESERVE_13 0x08bc +#define PCIE_FLL_IDAC_PCIEG1 GENMASK(10, 0) +#define PCIE_FLL_IDAC_PCIEG2 GENMASK(26, 16) + +#define REG_PCIE_PMA_DIG_RESERVE_14 0x08c0 +#define PCIE_FLL_IDAC_PCIEG3 GENMASK(10, 0) +#define PCIE_FLL_LOAD_EN BIT(16) + +#define REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL 0x088c +#define PCIE_FORCE_DA_PXP_RX_FE_GAIN_CTRL GENMASK(1, 0) +#define PCIE_FORCE_SEL_DA_PXP_RX_FE_GAIN_CTRL BIT(8) + +#define REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_PWDB 0x0894 +#define PCIE_FORCE_DA_PXP_RX_FE_PWDB BIT(0) +#define PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB BIT(8) + +#define REG_PCIE_PMA_DIG_RESERVE_12 0x08b8 +#define PCIE_FORCE_PMA_RX_SPEED GENMASK(7, 4) +#define PCIE_FORCE_SEL_PMA_RX_SPEED BIT(7) + +#define REG_PCIE_PMA_DIG_RESERVE_17 0x08e0 + +#define REG_PCIE_PMA_DIG_RESERVE_18 0x08e4 +#define PCIE_PXP_RX_VTH_SEL_PCIE_G1 GENMASK(4, 0) +#define PCIE_PXP_RX_VTH_SEL_PCIE_G2 GENMASK(12, 8) +#define PCIE_PXP_RX_VTH_SEL_PCIE_G3 GENMASK(20, 16) + +#define REG_PCIE_PMA_DIG_RESERVE_19 0x08e8 +#define PCIE_PCP_RX_REV0_PCIE_GEN1 GENMASK(31, 16) + +#define REG_PCIE_PMA_DIG_RESERVE_20 0x08ec +#define PCIE_PCP_RX_REV0_PCIE_GEN2 GENMASK(15, 0) +#define PCIE_PCP_RX_REV0_PCIE_GEN3 GENMASK(31, 16) + +#define REG_PCIE_PMA_DIG_RESERVE_21 0x08f0 +#define REG_PCIE_PMA_DIG_RESERVE_22 0x08f4 +#define REG_PCIE_PMA_DIG_RESERVE_27 0x0908 +#define REG_PCIE_PMA_DIG_RESERVE_30 0x0914 + +/* DTIME */ +#define REG_PCIE_PEXTP_DIG_GLB44 0x00 +#define PCIE_XTP_RXDET_VCM_OFF_STB_T_SEL GENMASK(7, 0) +#define PCIE_XTP_RXDET_EN_STB_T_SEL GENMASK(15, 8) +#define PCIE_XTP_RXDET_FINISH_STB_T_SEL GENMASK(23, 16) +#define PCIE_XTP_TXPD_TX_DATA_EN_DLY GENMASK(27, 24) +#define PCIE_XTP_TXPD_RXDET_DONE_CDT BIT(28) +#define PCIE_XTP_RXDET_LATCH_STB_T_SEL GENMASK(31, 29) + +/* RX AEQ */ +#define REG_PCIE_PEXTP_DIG_LN_RX30_P0 0x0000 +#define PCIE_XTP_LN_RX_PDOWN_L1P2_EXIT_WAIT GENMASK(7, 0) +#define PCIE_XTP_LN_RX_PDOWN_T2RLB_DIG_EN BIT(8) +#define PCIE_XTP_LN_RX_PDOWN_E0_AEQEN_WAIT GENMASK(31, 16) + +#define REG_PCIE_PEXTP_DIG_LN_RX30_P1 0x0100 + +#endif /* _PHY_AIROHA_PCIE_H */ diff --git a/drivers/phy/airoha/phy-airoha-pcie.c b/drivers/phy/airoha/phy-airoha-pcie.c new file mode 100644 index 000000000000..56e9ade8a9fd --- /dev/null +++ b/drivers/phy/airoha/phy-airoha-pcie.c @@ -0,0 +1,1290 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 AIROHA Inc + * Author: Lorenzo Bianconi + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "phy-airoha-pcie-regs.h" + +#define LEQ_LEN_CTRL_MAX_VAL 7 +#define FREQ_LOCK_MAX_ATTEMPT 10 + +/* PCIe-PHY initialization time in ms needed by the hw to complete */ +#define PHY_HW_INIT_TIME_MS 30 + +enum airoha_pcie_port_gen { + PCIE_PORT_GEN1 = 1, + PCIE_PORT_GEN2, + PCIE_PORT_GEN3, +}; + +/** + * struct airoha_pcie_phy - PCIe phy driver main structure + * @dev: pointer to device + * @phy: pointer to generic phy + * @csr_2l: Analogic lane IO mapped register base address + * @pma0: IO mapped register base address of PMA0-PCIe + * @pma1: IO mapped register base address of PMA1-PCIe + * @p0_xr_dtime: IO mapped register base address of port0 Tx-Rx detection time + * @p1_xr_dtime: IO mapped register base address of port1 Tx-Rx detection time + * @rx_aeq: IO mapped register base address of Rx AEQ training + */ +struct airoha_pcie_phy { + struct device *dev; + struct phy *phy; + void __iomem *csr_2l; + void __iomem *pma0; + void __iomem *pma1; + void __iomem *p0_xr_dtime; + void __iomem *p1_xr_dtime; + void __iomem *rx_aeq; +}; + +static void airoha_phy_clear_bits(void __iomem *reg, u32 mask) +{ + u32 val = readl(reg) & ~mask; + + writel(val, reg); +} + +static void airoha_phy_set_bits(void __iomem *reg, u32 mask) +{ + u32 val = readl(reg) | mask; + + writel(val, reg); +} + +static void airoha_phy_update_bits(void __iomem *reg, u32 mask, u32 val) +{ + u32 tmp = readl(reg); + + tmp &= ~mask; + tmp |= val & mask; + writel(tmp, reg); +} + +#define airoha_phy_update_field(reg, mask, val) \ + do { \ + BUILD_BUG_ON_MSG(!__builtin_constant_p((mask)), \ + "mask is not constant"); \ + airoha_phy_update_bits((reg), (mask), \ + FIELD_PREP((mask), (val))); \ + } while (0) + +#define airoha_phy_csr_2l_clear_bits(pcie_phy, reg, mask) \ + airoha_phy_clear_bits((pcie_phy)->csr_2l + (reg), (mask)) +#define airoha_phy_csr_2l_set_bits(pcie_phy, reg, mask) \ + airoha_phy_set_bits((pcie_phy)->csr_2l + (reg), (mask)) +#define airoha_phy_csr_2l_update_field(pcie_phy, reg, mask, val) \ + airoha_phy_update_field((pcie_phy)->csr_2l + (reg), (mask), (val)) +#define airoha_phy_pma0_clear_bits(pcie_phy, reg, mask) \ + airoha_phy_clear_bits((pcie_phy)->pma0 + (reg), (mask)) +#define airoha_phy_pma1_clear_bits(pcie_phy, reg, mask) \ + airoha_phy_clear_bits((pcie_phy)->pma1 + (reg), (mask)) +#define airoha_phy_pma0_set_bits(pcie_phy, reg, mask) \ + airoha_phy_set_bits((pcie_phy)->pma0 + (reg), (mask)) +#define airoha_phy_pma1_set_bits(pcie_phy, reg, mask) \ + airoha_phy_set_bits((pcie_phy)->pma1 + (reg), (mask)) +#define airoha_phy_pma0_update_field(pcie_phy, reg, mask, val) \ + airoha_phy_update_field((pcie_phy)->pma0 + (reg), (mask), (val)) +#define airoha_phy_pma1_update_field(pcie_phy, reg, mask, val) \ + airoha_phy_update_field((pcie_phy)->pma1 + (reg), (mask), (val)) + +static void +airoha_phy_init_lane0_rx_fw_pre_calib(struct airoha_pcie_phy *pcie_phy, + enum airoha_pcie_port_gen gen) +{ + u32 fl_out_target = gen == PCIE_PORT_GEN3 ? 41600 : 41941; + u32 lock_cyclecnt = gen == PCIE_PORT_GEN3 ? 26000 : 32767; + u32 pr_idac, val, cdr_pr_idac_tmp = 0; + int i; + + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_SS_LCPLL_PWCTL_SETTING_1, + PCIE_LCPLL_MAN_PWDB); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2, + PCIE_LOCK_TARGET_BEG, + fl_out_target - 100); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2, + PCIE_LOCK_TARGET_END, + fl_out_target + 100); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1, + PCIE_PLL_FT_LOCK_CYCLECNT, lock_cyclecnt); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_LOCK_LOCKTH, 0x3); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3, + PCIE_UNLOCK_TARGET_BEG, + fl_out_target - 100); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3, + PCIE_UNLOCK_TARGET_END, + fl_out_target + 100); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1, + PCIE_PLL_FT_UNLOCK_CYCLECNT, + lock_cyclecnt); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_UNLOCK_LOCKTH, 0x3); + + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR0_PR_INJ_MODE, + CSR_2L_PXP_CDR0_INJ_FORCE_OFF); + + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, + PCIE_FORCE_DA_PXP_CDR_PR_LPF_R_EN); + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); + airoha_phy_pma0_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, + PCIE_FORCE_DA_PXP_CDR_PR_LPF_C_EN); + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); + + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); + airoha_phy_pma0_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, + PCIE_FORCE_DA_PXP_CDR_PR_PWDB); + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, + PCIE_FORCE_DA_PXP_CDR_PR_PWDB); + + for (i = 0; i < LEQ_LEN_CTRL_MAX_VAL; i++) { + airoha_phy_pma0_update_field(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, + PCIE_FORCE_DA_PXP_CDR_PR_IDAC, i << 8); + airoha_phy_pma0_clear_bits(pcie_phy, + REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_FREQLOCK_DET_EN); + airoha_phy_pma0_update_field(pcie_phy, + REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_FREQLOCK_DET_EN, 0x3); + + usleep_range(10000, 15000); + + val = FIELD_GET(PCIE_RO_FL_OUT, + readl(pcie_phy->pma0 + + REG_PCIE_PMA_RO_RX_FREQDET)); + if (val > fl_out_target) + cdr_pr_idac_tmp = i << 8; + } + + for (i = LEQ_LEN_CTRL_MAX_VAL; i >= 0; i--) { + pr_idac = cdr_pr_idac_tmp | (0x1 << i); + airoha_phy_pma0_update_field(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, + PCIE_FORCE_DA_PXP_CDR_PR_IDAC, pr_idac); + airoha_phy_pma0_clear_bits(pcie_phy, + REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_FREQLOCK_DET_EN); + airoha_phy_pma0_update_field(pcie_phy, + REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_FREQLOCK_DET_EN, 0x3); + + usleep_range(10000, 15000); + + val = FIELD_GET(PCIE_RO_FL_OUT, + readl(pcie_phy->pma0 + + REG_PCIE_PMA_RO_RX_FREQDET)); + if (val < fl_out_target) + pr_idac &= ~(0x1 << i); + + cdr_pr_idac_tmp = pr_idac; + } + + airoha_phy_pma0_update_field(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, + PCIE_FORCE_DA_PXP_CDR_PR_IDAC, + cdr_pr_idac_tmp); + + for (i = 0; i < FREQ_LOCK_MAX_ATTEMPT; i++) { + u32 val; + + airoha_phy_pma0_clear_bits(pcie_phy, + REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_FREQLOCK_DET_EN); + airoha_phy_pma0_update_field(pcie_phy, + REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_FREQLOCK_DET_EN, 0x3); + + usleep_range(10000, 15000); + + val = readl(pcie_phy->pma0 + REG_PCIE_PMA_RO_RX_FREQDET); + if (val & PCIE_RO_FBCK_LOCK) + break; + } + + /* turn off force mode and update band values */ + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_INJ_MODE, + CSR_2L_PXP_CDR0_INJ_FORCE_OFF); + + airoha_phy_pma0_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); + airoha_phy_pma0_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); + airoha_phy_pma0_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); + airoha_phy_pma0_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); + if (gen == PCIE_PORT_GEN3) { + airoha_phy_pma0_update_field(pcie_phy, + REG_PCIE_PMA_DIG_RESERVE_14, + PCIE_FLL_IDAC_PCIEG3, + cdr_pr_idac_tmp); + } else { + airoha_phy_pma0_update_field(pcie_phy, + REG_PCIE_PMA_DIG_RESERVE_13, + PCIE_FLL_IDAC_PCIEG1, + cdr_pr_idac_tmp); + airoha_phy_pma0_update_field(pcie_phy, + REG_PCIE_PMA_DIG_RESERVE_13, + PCIE_FLL_IDAC_PCIEG2, + cdr_pr_idac_tmp); + } +} + +static void +airoha_phy_init_lane1_rx_fw_pre_calib(struct airoha_pcie_phy *pcie_phy, + enum airoha_pcie_port_gen gen) +{ + u32 fl_out_target = gen == PCIE_PORT_GEN3 ? 41600 : 41941; + u32 lock_cyclecnt = gen == PCIE_PORT_GEN3 ? 26000 : 32767; + u32 pr_idac, val, cdr_pr_idac_tmp = 0; + int i; + + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_SS_LCPLL_PWCTL_SETTING_1, + PCIE_LCPLL_MAN_PWDB); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2, + PCIE_LOCK_TARGET_BEG, + fl_out_target - 100); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2, + PCIE_LOCK_TARGET_END, + fl_out_target + 100); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1, + PCIE_PLL_FT_LOCK_CYCLECNT, lock_cyclecnt); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_LOCK_LOCKTH, 0x3); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3, + PCIE_UNLOCK_TARGET_BEG, + fl_out_target - 100); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3, + PCIE_UNLOCK_TARGET_END, + fl_out_target + 100); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1, + PCIE_PLL_FT_UNLOCK_CYCLECNT, + lock_cyclecnt); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_UNLOCK_LOCKTH, 0x3); + + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR1_PR_INJ_MODE, + CSR_2L_PXP_CDR1_INJ_FORCE_OFF); + + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, + PCIE_FORCE_DA_PXP_CDR_PR_LPF_R_EN); + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); + airoha_phy_pma1_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, + PCIE_FORCE_DA_PXP_CDR_PR_LPF_C_EN); + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); + airoha_phy_pma1_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, + PCIE_FORCE_DA_PXP_CDR_PR_PWDB); + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, + PCIE_FORCE_DA_PXP_CDR_PR_PWDB); + + for (i = 0; i < LEQ_LEN_CTRL_MAX_VAL; i++) { + airoha_phy_pma1_update_field(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, + PCIE_FORCE_DA_PXP_CDR_PR_IDAC, i << 8); + airoha_phy_pma1_clear_bits(pcie_phy, + REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_FREQLOCK_DET_EN); + airoha_phy_pma1_update_field(pcie_phy, + REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_FREQLOCK_DET_EN, 0x3); + + usleep_range(10000, 15000); + + val = FIELD_GET(PCIE_RO_FL_OUT, + readl(pcie_phy->pma1 + + REG_PCIE_PMA_RO_RX_FREQDET)); + if (val > fl_out_target) + cdr_pr_idac_tmp = i << 8; + } + + for (i = LEQ_LEN_CTRL_MAX_VAL; i >= 0; i--) { + pr_idac = cdr_pr_idac_tmp | (0x1 << i); + airoha_phy_pma1_update_field(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, + PCIE_FORCE_DA_PXP_CDR_PR_IDAC, pr_idac); + airoha_phy_pma1_clear_bits(pcie_phy, + REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_FREQLOCK_DET_EN); + airoha_phy_pma1_update_field(pcie_phy, + REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_FREQLOCK_DET_EN, 0x3); + + usleep_range(10000, 15000); + + val = FIELD_GET(PCIE_RO_FL_OUT, + readl(pcie_phy->pma1 + + REG_PCIE_PMA_RO_RX_FREQDET)); + if (val < fl_out_target) + pr_idac &= ~(0x1 << i); + + cdr_pr_idac_tmp = pr_idac; + } + + airoha_phy_pma1_update_field(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, + PCIE_FORCE_DA_PXP_CDR_PR_IDAC, + cdr_pr_idac_tmp); + + for (i = 0; i < FREQ_LOCK_MAX_ATTEMPT; i++) { + u32 val; + + airoha_phy_pma1_clear_bits(pcie_phy, + REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_FREQLOCK_DET_EN); + airoha_phy_pma1_update_field(pcie_phy, + REG_PCIE_PMA_SS_RX_FREQ_DET4, + PCIE_FREQLOCK_DET_EN, 0x3); + + usleep_range(10000, 15000); + + val = readl(pcie_phy->pma1 + REG_PCIE_PMA_RO_RX_FREQDET); + if (val & PCIE_RO_FBCK_LOCK) + break; + } + + /* turn off force mode and update band values */ + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_INJ_MODE, + CSR_2L_PXP_CDR1_INJ_FORCE_OFF); + + airoha_phy_pma1_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); + airoha_phy_pma1_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); + airoha_phy_pma1_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); + airoha_phy_pma1_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, + PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); + if (gen == PCIE_PORT_GEN3) { + airoha_phy_pma1_update_field(pcie_phy, + REG_PCIE_PMA_DIG_RESERVE_14, + PCIE_FLL_IDAC_PCIEG3, + cdr_pr_idac_tmp); + } else { + airoha_phy_pma1_update_field(pcie_phy, + REG_PCIE_PMA_DIG_RESERVE_13, + PCIE_FLL_IDAC_PCIEG1, + cdr_pr_idac_tmp); + airoha_phy_pma1_update_field(pcie_phy, + REG_PCIE_PMA_DIG_RESERVE_13, + PCIE_FLL_IDAC_PCIEG2, + cdr_pr_idac_tmp); + } +} + +static void airoha_pcie_phy_init_default(struct airoha_pcie_phy *pcie_phy) +{ + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CMN, + CSR_2L_PXP_CMN_TRIM_MASK, 0x10); + writel(0xcccbcccb, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_21); + writel(0xcccb, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_22); + writel(0xcccbcccb, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_21); + writel(0xcccb, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_22); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CMN, + CSR_2L_PXP_CMN_LANE_EN); +} + +static void airoha_pcie_phy_init_clk_out(struct airoha_pcie_phy *pcie_phy) +{ + airoha_phy_csr_2l_update_field(pcie_phy, + REG_CSR_2L_TXPLL_POSTDIV_D256, + CSR_2L_PXP_CLKTX0_AMP, 0x5); + airoha_phy_csr_2l_update_field(pcie_phy, + REG_CSR_2L_CLKTX0_FORCE_OUT1, + CSR_2L_PXP_CLKTX1_AMP, 0x5); + airoha_phy_csr_2l_update_field(pcie_phy, + REG_CSR_2L_TXPLL_POSTDIV_D256, + CSR_2L_PXP_CLKTX0_OFFSET, 0x2); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CLKTX1_OFFSET, + CSR_2L_PXP_CLKTX1_OFFSET, 0x2); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CLKTX0_FORCE_OUT1, + CSR_2L_PXP_CLKTX0_HZ); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CLKTX1_OFFSET, + CSR_2L_PXP_CLKTX1_HZ); + airoha_phy_csr_2l_update_field(pcie_phy, + REG_CSR_2L_CLKTX0_FORCE_OUT1, + CSR_2L_PXP_CLKTX0_IMP_SEL, 0x12); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CLKTX1_IMP_SEL, + CSR_2L_PXP_CLKTX1_IMP_SEL, 0x12); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV_D256, + CSR_2L_PXP_CLKTX0_SR); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CLKTX1_OFFSET, + CSR_2L_PXP_CLKTX1_SR); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_PLL_CMN_RESERVE0, + CSR_2L_PXP_PLL_RESERVE_MASK, 0xd0d); +} + +static void airoha_pcie_phy_init_csr_2l(struct airoha_pcie_phy *pcie_phy) +{ + airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, + PCIE_SW_XFI_RXPCS_RST | PCIE_SW_REF_RST | + PCIE_SW_RX_RST); + airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, + PCIE_SW_XFI_RXPCS_RST | PCIE_SW_REF_RST | + PCIE_SW_RX_RST); + airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_TX_RESET, + PCIE_TX_TOP_RST | PCIE_TX_CAL_RST); + airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_TX_RESET, + PCIE_TX_TOP_RST | PCIE_TX_CAL_RST); +} + +static void airoha_pcie_phy_init_rx(struct airoha_pcie_phy *pcie_phy) +{ + writel(0x2a00090b, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_17); + writel(0x2a00090b, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_17); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR0_PR_MONPI, + CSR_2L_PXP_CDR0_PR_XFICK_EN); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR1_PR_MONPI, + CSR_2L_PXP_CDR1_PR_XFICK_EN); + airoha_phy_csr_2l_clear_bits(pcie_phy, + REG_CSR_2L_CDR0_PD_PICAL_CKD8_INV, + CSR_2L_PXP_CDR0_PD_EDGE_DISABLE); + airoha_phy_csr_2l_clear_bits(pcie_phy, + REG_CSR_2L_CDR1_PD_PICAL_CKD8_INV, + CSR_2L_PXP_CDR1_PD_EDGE_DISABLE); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_PHYCK_DIV, + CSR_2L_PXP_RX0_PHYCK_SEL, 0x1); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_PHYCK_DIV, + CSR_2L_PXP_RX1_PHYCK_SEL, 0x1); +} + +static void airoha_pcie_phy_init_jcpll(struct airoha_pcie_phy *pcie_phy) +{ + airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, + PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); + airoha_phy_pma0_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, + PCIE_FORCE_DA_PXP_JCPLL_EN); + airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, + PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); + airoha_phy_pma1_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, + PCIE_FORCE_DA_PXP_JCPLL_EN); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_TCL_VTP_EN, + CSR_2L_PXP_JCPLL_SPARE_LOW, 0x20); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, + CSR_2L_PXP_JCPLL_RST); + writel(0x0, pcie_phy->csr_2l + REG_CSR_2L_JCPLL_SSC_DELTA1); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC_PERIOD, + CSR_2L_PXP_JCPLL_SSC_PERIOD); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, + CSR_2L_PXP_JCPLL_SSC_PHASE_INI); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, + CSR_2L_PXP_JCPLL_SSC_TRI_EN); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, + CSR_2L_PXP_JCPLL_LPF_BR, 0xa); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, + CSR_2L_PXP_JCPLL_LPF_BP, 0xc); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, + CSR_2L_PXP_JCPLL_LPF_BC, 0x1f); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BWC, + CSR_2L_PXP_JCPLL_LPF_BWC, 0x1e); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, + CSR_2L_PXP_JCPLL_LPF_BWR, 0xa); + airoha_phy_csr_2l_update_field(pcie_phy, + REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, + CSR_2L_PXP_JCPLL_MMD_PREDIV_MODE, + 0x1); + airoha_phy_csr_2l_clear_bits(pcie_phy, CSR_2L_PXP_JCPLL_MONCK, + CSR_2L_PXP_JCPLL_REFIN_DIV); + + airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_VOS, + PCIE_FORCE_SEL_DA_PXP_JCPLL_SDM_PCW); + airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_VOS, + PCIE_FORCE_SEL_DA_PXP_JCPLL_SDM_PCW); + airoha_phy_pma0_update_field(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_JCPLL_SDM_PCW, + PCIE_FORCE_DA_PXP_JCPLL_SDM_PCW, + 0x50000000); + airoha_phy_pma1_update_field(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_JCPLL_SDM_PCW, + PCIE_FORCE_DA_PXP_JCPLL_SDM_PCW, + 0x50000000); + + airoha_phy_csr_2l_set_bits(pcie_phy, + REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, + CSR_2L_PXP_JCPLL_POSTDIV_D5); + airoha_phy_csr_2l_set_bits(pcie_phy, + REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, + CSR_2L_PXP_JCPLL_POSTDIV_D2); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, + CSR_2L_PXP_JCPLL_RST_DLY, 0x4); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, + CSR_2L_PXP_JCPLL_SDM_DI_LS); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_TCL_KBAND_VREF, + CSR_2L_PXP_JCPLL_VCO_KBAND_MEAS_EN); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_IB_EXT, + CSR_2L_PXP_JCPLL_CHP_IOFST); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_IB_EXT, + CSR_2L_PXP_JCPLL_CHP_IBIAS, 0xc); + airoha_phy_csr_2l_update_field(pcie_phy, + REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, + CSR_2L_PXP_JCPLL_MMD_PREDIV_MODE, + 0x1); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_VCODIV, + CSR_2L_PXP_JCPLL_VCO_HALFLSB_EN); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_VCODIV, + CSR_2L_PXP_JCPLL_VCO_CFIX, 0x1); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_VCODIV, + CSR_2L_PXP_JCPLL_VCO_SCAPWR, 0x4); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_IB_EXT, + REG_CSR_2L_JCPLL_LPF_SHCK_EN); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, + CSR_2L_PXP_JCPLL_POSTDIV_EN); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, + CSR_2L_PXP_JCPLL_KBAND_KFC); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, + CSR_2L_PXP_JCPLL_KBAND_KF, 0x3); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, + CSR_2L_PXP_JCPLL_KBAND_KS); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BWC, + CSR_2L_PXP_JCPLL_KBAND_DIV, 0x1); + + airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SCAN_MODE, + PCIE_FORCE_SEL_DA_PXP_JCPLL_KBAND_LOAD_EN); + airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SCAN_MODE, + PCIE_FORCE_DA_PXP_JCPLL_KBAND_LOAD_EN); + + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BWC, + CSR_2L_PXP_JCPLL_KBAND_CODE, 0xe4); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, + CSR_2L_PXP_JCPLL_TCL_AMP_EN); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_TCL_CMP, + CSR_2L_PXP_JCPLL_TCL_LPF_EN); + airoha_phy_csr_2l_update_field(pcie_phy, + REG_CSR_2L_JCPLL_TCL_KBAND_VREF, + CSR_2L_PXP_JCPLL_TCL_KBAND_VREF, 0xf); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, + CSR_2L_PXP_JCPLL_TCL_AMP_GAIN, 0x1); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, + CSR_2L_PXP_JCPLL_TCL_AMP_VREF, 0x5); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_TCL_CMP, + CSR_2L_PXP_JCPLL_TCL_LPF_BW, 0x1); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_VCO_TCLVAR, + CSR_2L_PXP_JCPLL_VCO_TCLVAR, 0x3); + + airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, + PCIE_FORCE_SEL_DA_PXP_JCPLL_CKOUT_EN); + airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, + PCIE_FORCE_DA_PXP_JCPLL_CKOUT_EN); + airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, + PCIE_FORCE_SEL_DA_PXP_JCPLL_CKOUT_EN); + airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, + PCIE_FORCE_DA_PXP_JCPLL_CKOUT_EN); + airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, + PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); + airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, + PCIE_FORCE_DA_PXP_JCPLL_EN); + airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, + PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); + airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, + PCIE_FORCE_DA_PXP_JCPLL_EN); +} + +static void airoha_pcie_phy_txpll(struct airoha_pcie_phy *pcie_phy) +{ + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, + PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); + airoha_phy_pma0_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, + PCIE_FORCE_DA_PXP_TXPLL_EN); + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, + PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); + airoha_phy_pma1_clear_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, + PCIE_FORCE_DA_PXP_TXPLL_EN); + + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, + CSR_2L_PXP_TXPLL_PLL_RSTB); + writel(0x0, pcie_phy->csr_2l + REG_CSR_2L_TXPLL_SSC_DELTA1); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC_PERIOD, + CSR_2L_PXP_txpll_SSC_PERIOD); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, + CSR_2L_PXP_TXPLL_CHP_IOFST, 0x1); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_750M_SYS_CK, + CSR_2L_PXP_TXPLL_CHP_IBIAS, 0x2d); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, + CSR_2L_PXP_TXPLL_REFIN_DIV); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, + CSR_2L_PXP_TXPLL_VCO_CFIX, 0x3); + + airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, + PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); + airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, + PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); + airoha_phy_pma0_update_field(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_SDM_PCW, + PCIE_FORCE_DA_PXP_TXPLL_SDM_PCW, + 0xc800000); + airoha_phy_pma1_update_field(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_SDM_PCW, + PCIE_FORCE_DA_PXP_TXPLL_SDM_PCW, + 0xc800000); + + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SDM_DI_LS, + CSR_2L_PXP_TXPLL_SDM_IFM); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC, + CSR_2L_PXP_TXPLL_SSC_PHASE_INI); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, + CSR_2L_PXP_TXPLL_RST_DLY, 0x4); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SDM_DI_LS, + CSR_2L_PXP_TXPLL_SDM_DI_LS); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_SDM_DI_LS, + CSR_2L_PXP_TXPLL_SDM_ORD, 0x3); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_KBAND_VREF, + CSR_2L_PXP_TXPLL_VCO_KBAND_MEAS_EN); + writel(0x0, pcie_phy->csr_2l + REG_CSR_2L_TXPLL_SSC_DELTA1); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, + CSR_2L_PXP_TXPLL_LPF_BP, 0x1); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, + CSR_2L_PXP_TXPLL_LPF_BC, 0x18); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, + CSR_2L_PXP_TXPLL_LPF_BR, 0x5); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, + CSR_2L_PXP_TXPLL_CHP_IOFST, 0x1); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_750M_SYS_CK, + CSR_2L_PXP_TXPLL_CHP_IBIAS, 0x2d); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_VTP, + CSR_2L_PXP_TXPLL_SPARE_L, 0x1); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_LPF_BWR, + CSR_2L_PXP_TXPLL_LPF_BWC); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV, + CSR_2L_PXP_TXPLL_MMD_PREDIV_MODE); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, + CSR_2L_PXP_TXPLL_REFIN_DIV); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, + CSR_2L_PXP_TXPLL_VCO_HALFLSB_EN); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_VCO_SCAPWR, + CSR_2L_PXP_TXPLL_VCO_SCAPWR, 0x7); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, + CSR_2L_PXP_TXPLL_VCO_CFIX, 0x3); + + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, + PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, + PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); + + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC, + CSR_2L_PXP_TXPLL_SSC_PHASE_INI); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_LPF_BWR, + CSR_2L_PXP_TXPLL_LPF_BWR); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_PHY_CK2, + CSR_2L_PXP_TXPLL_REFIN_INTERNAL); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_KBAND_VREF, + CSR_2L_PXP_TXPLL_VCO_KBAND_MEAS_EN); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_VTP, + CSR_2L_PXP_TXPLL_VTP_EN); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV, + CSR_2L_PXP_TXPLL_PHY_CK1_EN); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_PHY_CK2, + CSR_2L_PXP_TXPLL_REFIN_INTERNAL); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC, + CSR_2L_PXP_TXPLL_SSC_EN); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_750M_SYS_CK, + CSR_2L_PXP_TXPLL_LPF_SHCK_EN); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV, + CSR_2L_PXP_TXPLL_POSTDIV_EN); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, + CSR_2L_PXP_TXPLL_KBAND_KFC); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, + CSR_2L_PXP_TXPLL_KBAND_KF, 0x3); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, + CSR_2L_PXP_txpll_KBAND_KS, 0x1); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, + CSR_2L_PXP_TXPLL_KBAND_DIV, 0x4); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_LPF_BWR, + CSR_2L_PXP_TXPLL_KBAND_CODE, 0xe4); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_SDM_OUT, + CSR_2L_PXP_TXPLL_TCL_AMP_EN); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_AMP_VREF, + CSR_2L_PXP_TXPLL_TCL_LPF_EN); + airoha_phy_csr_2l_update_field(pcie_phy, + REG_CSR_2L_TXPLL_TCL_KBAND_VREF, + CSR_2L_PXP_TXPLL_TCL_KBAND_VREF, 0xf); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_SDM_OUT, + CSR_2L_PXP_TXPLL_TCL_AMP_GAIN, 0x3); + airoha_phy_csr_2l_update_field(pcie_phy, + REG_CSR_2L_TXPLL_TCL_AMP_VREF, + CSR_2L_PXP_TXPLL_TCL_AMP_VREF, 0xb); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, + CSR_2L_PXP_TXPLL_TCL_LPF_BW, 0x3); + + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, + PCIE_FORCE_SEL_DA_PXP_TXPLL_CKOUT_EN); + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, + PCIE_FORCE_DA_PXP_TXPLL_CKOUT_EN); + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, + PCIE_FORCE_SEL_DA_PXP_TXPLL_CKOUT_EN); + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, + PCIE_FORCE_DA_PXP_TXPLL_CKOUT_EN); + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, + PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, + PCIE_FORCE_DA_PXP_TXPLL_EN); + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, + PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, + PCIE_FORCE_DA_PXP_TXPLL_EN); +} + +static void airoha_pcie_phy_init_ssc_jcpll(struct airoha_pcie_phy *pcie_phy) +{ + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SSC_DELTA1, + CSR_2L_PXP_JCPLL_SSC_DELTA1, 0x106); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SSC_DELTA1, + CSR_2L_PXP_JCPLL_SSC_DELTA, 0x106); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SSC_PERIOD, + CSR_2L_PXP_JCPLL_SSC_PERIOD, 0x31b); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, + CSR_2L_PXP_JCPLL_SSC_PHASE_INI); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, + CSR_2L_PXP_JCPLL_SSC_EN); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_IFM, + CSR_2L_PXP_JCPLL_SDM_IFM); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, + CSR_2L_PXP_JCPLL_SDM_HREN); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, + CSR_2L_PXP_JCPLL_SDM_DI_EN); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, + CSR_2L_PXP_JCPLL_SSC_TRI_EN); +} + +static void +airoha_pcie_phy_set_rxlan0_signal_detect(struct airoha_pcie_phy *pcie_phy) +{ + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR0_PR_COR_HBW, + CSR_2L_PXP_CDR0_PR_LDO_FORCE_ON); + + usleep_range(100, 200); + + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_19, + PCIE_PCP_RX_REV0_PCIE_GEN1, 0x18b0); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, + PCIE_PCP_RX_REV0_PCIE_GEN2, 0x18b0); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, + PCIE_PCP_RX_REV0_PCIE_GEN3, 0x1030); + + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_SIGDET_DCTEST, + CSR_2L_PXP_RX0_SIGDET_PEAK, 0x2); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_SIGDET_VTH_SEL, + CSR_2L_PXP_RX0_SIGDET_VTH_SEL, 0x5); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_REV0, + CSR_2L_PXP_VOS_PNINV, 0x2); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_SIGDET_DCTEST, + CSR_2L_PXP_RX0_SIGDET_LPF_CTRL, 0x1); + + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_CAL2, + PCIE_CAL_OUT_OS, 0x0); + + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_PXP_RX0_FE_VB_EQ2, + CSR_2L_PXP_RX0_FE_VCM_GEN_PWDB); + + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, + PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); + airoha_phy_pma0_update_field(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, + PCIE_FORCE_DA_PXP_RX_FE_GAIN_CTRL, 0x3); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_RX_FORCE_MODE0, + PCIE_FORCE_DA_XPON_RX_FE_GAIN_CTRL, 0x1); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_SIGDET0, + PCIE_SIGDET_WIN_NONVLD_TIMES, 0x3); + airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SEQUENCE_DISB_CTRL1, + PCIE_DISB_RX_SDCAL_EN); + + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, + PCIE_FORCE_RX_SDCAL_EN); + usleep_range(150, 200); + airoha_phy_pma0_clear_bits(pcie_phy, + REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, + PCIE_FORCE_RX_SDCAL_EN); +} + +static void +airoha_pcie_phy_set_rxlan1_signal_detect(struct airoha_pcie_phy *pcie_phy) +{ + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR1_PR_COR_HBW, + CSR_2L_PXP_CDR1_PR_LDO_FORCE_ON); + + usleep_range(100, 200); + + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_19, + PCIE_PCP_RX_REV0_PCIE_GEN1, 0x18b0); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, + PCIE_PCP_RX_REV0_PCIE_GEN2, 0x18b0); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, + PCIE_PCP_RX_REV0_PCIE_GEN3, 0x1030); + + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_SIGDET_NOVTH, + CSR_2L_PXP_RX1_SIGDET_PEAK, 0x2); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_SIGDET_NOVTH, + CSR_2L_PXP_RX1_SIGDET_VTH_SEL, 0x5); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_REV0, + CSR_2L_PXP_VOS_PNINV, 0x2); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_DAC_RANGE_EYE, + CSR_2L_PXP_RX1_SIGDET_LPF_CTRL, 0x1); + + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_CAL2, + PCIE_CAL_OUT_OS, 0x0); + + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX1_FE_VB_EQ1, + CSR_2L_PXP_RX1_FE_VCM_GEN_PWDB); + + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, + PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); + airoha_phy_pma1_update_field(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, + PCIE_FORCE_DA_PXP_RX_FE_GAIN_CTRL, 0x3); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_RX_FORCE_MODE0, + PCIE_FORCE_DA_XPON_RX_FE_GAIN_CTRL, 0x1); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_SIGDET0, + PCIE_SIGDET_WIN_NONVLD_TIMES, 0x3); + airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_SEQUENCE_DISB_CTRL1, + PCIE_DISB_RX_SDCAL_EN); + + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, + PCIE_FORCE_RX_SDCAL_EN); + usleep_range(150, 200); + airoha_phy_pma1_clear_bits(pcie_phy, + REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, + PCIE_FORCE_RX_SDCAL_EN); +} + +static void airoha_pcie_phy_set_rxflow(struct airoha_pcie_phy *pcie_phy) +{ + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_RX_SCAN_RST, + PCIE_FORCE_DA_PXP_RX_SIGDET_PWDB | + PCIE_FORCE_SEL_DA_PXP_RX_SIGDET_PWDB); + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_RX_SCAN_RST, + PCIE_FORCE_DA_PXP_RX_SIGDET_PWDB | + PCIE_FORCE_SEL_DA_PXP_RX_SIGDET_PWDB); + + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PD_PWDB, + PCIE_FORCE_DA_PXP_CDR_PD_PWDB | + PCIE_FORCE_SEL_DA_PXP_CDR_PD_PWDB); + airoha_phy_pma0_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_PWDB, + PCIE_FORCE_DA_PXP_RX_FE_PWDB | + PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_CDR_PD_PWDB, + PCIE_FORCE_DA_PXP_CDR_PD_PWDB | + PCIE_FORCE_SEL_DA_PXP_CDR_PD_PWDB); + airoha_phy_pma1_set_bits(pcie_phy, + REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_PWDB, + PCIE_FORCE_DA_PXP_RX_FE_PWDB | + PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); + + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX0_PHYCK_DIV, + CSR_2L_PXP_RX0_PHYCK_RSTB | + CSR_2L_PXP_RX0_TDC_CK_SEL); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX1_PHYCK_DIV, + CSR_2L_PXP_RX1_PHYCK_RSTB | + CSR_2L_PXP_RX1_TDC_CK_SEL); + + airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, + PCIE_SW_RX_FIFO_RST | PCIE_SW_TX_RST | + PCIE_SW_PMA_RST | PCIE_SW_ALLPCS_RST | + PCIE_SW_TX_FIFO_RST); + airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, + PCIE_SW_RX_FIFO_RST | PCIE_SW_TX_RST | + PCIE_SW_PMA_RST | PCIE_SW_ALLPCS_RST | + PCIE_SW_TX_FIFO_RST); + + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_PXP_RX0_FE_VB_EQ2, + CSR_2L_PXP_RX0_FE_VB_EQ2_EN | + CSR_2L_PXP_RX0_FE_VB_EQ3_EN); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX0_SIGDET_VTH_SEL, + CSR_2L_PXP_RX0_FE_VB_EQ1_EN); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX1_FE_VB_EQ1, + CSR_2L_PXP_RX1_FE_VB_EQ1_EN | + CSR_2L_PXP_RX1_FE_VB_EQ2_EN | + CSR_2L_PXP_RX1_FE_VB_EQ3_EN); + + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_REV0, + CSR_2L_PXP_FE_GAIN_NORMAL_MODE, 0x4); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_REV0, + CSR_2L_PXP_FE_GAIN_TRAIN_MODE, 0x4); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_REV0, + CSR_2L_PXP_FE_GAIN_NORMAL_MODE, 0x4); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_REV0, + CSR_2L_PXP_FE_GAIN_TRAIN_MODE, 0x4); +} + +static void airoha_pcie_phy_set_pr(struct airoha_pcie_phy *pcie_phy) +{ + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_VREG_IBAND, + CSR_2L_PXP_CDR0_PR_VREG_IBAND, 0x5); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_VREG_IBAND, + CSR_2L_PXP_CDR0_PR_VREG_CKBUF, 0x5); + + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_CKREF_DIV, + CSR_2L_PXP_CDR0_PR_CKREF_DIV); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_COR_HBW, + CSR_2L_PXP_CDR0_PR_CKREF_DIV1); + + airoha_phy_csr_2l_update_field(pcie_phy, + REG_CSR_2L_CDR1_PR_VREG_IBAND_VAL, + CSR_2L_PXP_CDR1_PR_VREG_IBAND, 0x5); + airoha_phy_csr_2l_update_field(pcie_phy, + REG_CSR_2L_CDR1_PR_VREG_IBAND_VAL, + CSR_2L_PXP_CDR1_PR_VREG_CKBUF, 0x5); + + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_CKREF_DIV, + CSR_2L_PXP_CDR1_PR_CKREF_DIV); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_COR_HBW, + CSR_2L_PXP_CDR1_PR_CKREF_DIV1); + + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_LPF_RATIO, + CSR_2L_PXP_CDR0_LPF_TOP_LIM, 0x20000); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_LPF_RATIO, + CSR_2L_PXP_CDR1_LPF_TOP_LIM, 0x20000); + + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_BETA_DAC, + CSR_2L_PXP_CDR0_PR_BETA_SEL, 0x2); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_PR_BETA_DAC, + CSR_2L_PXP_CDR1_PR_BETA_SEL, 0x2); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_BETA_DAC, + CSR_2L_PXP_CDR0_PR_KBAND_DIV, 0x4); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_PR_BETA_DAC, + CSR_2L_PXP_CDR1_PR_KBAND_DIV, 0x4); +} + +static void airoha_pcie_phy_set_txflow(struct airoha_pcie_phy *pcie_phy) +{ + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX0_CKLDO, + CSR_2L_PXP_TX0_CKLDO_EN); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX1_CKLDO, + CSR_2L_PXP_TX1_CKLDO_EN); + + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX0_CKLDO, + CSR_2L_PXP_TX0_DMEDGEGEN_EN); + airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX1_CKLDO, + CSR_2L_PXP_TX1_DMEDGEGEN_EN); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TX1_MULTLANE, + CSR_2L_PXP_TX1_MULTLANE_EN); +} + +static void airoha_pcie_phy_set_rx_mode(struct airoha_pcie_phy *pcie_phy) +{ + writel(0x804000, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_27); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, + PCIE_PXP_RX_VTH_SEL_PCIE_G1, 0x5); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, + PCIE_PXP_RX_VTH_SEL_PCIE_G2, 0x5); + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, + PCIE_PXP_RX_VTH_SEL_PCIE_G3, 0x5); + airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_30, + 0x77700); + + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_MONCK, + CSR_2L_PXP_CDR0_PR_MONCK_ENABLE); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_MONCK, + CSR_2L_PXP_CDR0_PR_RESERVE0, 0x2); + airoha_phy_csr_2l_update_field(pcie_phy, + REG_CSR_2L_PXP_RX0_OSCAL_CTLE1IOS, + CSR_2L_PXP_RX0_PR_OSCAL_VGA1IOS, 0x19); + airoha_phy_csr_2l_update_field(pcie_phy, + REG_CSR_2L_PXP_RX0_OSCA_VGA1VOS, + CSR_2L_PXP_RX0_PR_OSCAL_VGA1VOS, 0x19); + airoha_phy_csr_2l_update_field(pcie_phy, + REG_CSR_2L_PXP_RX0_OSCA_VGA1VOS, + CSR_2L_PXP_RX0_PR_OSCAL_VGA2IOS, 0x14); + + writel(0x804000, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_27); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, + PCIE_PXP_RX_VTH_SEL_PCIE_G1, 0x5); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, + PCIE_PXP_RX_VTH_SEL_PCIE_G2, 0x5); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, + PCIE_PXP_RX_VTH_SEL_PCIE_G3, 0x5); + + airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_30, + 0x77700); + + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_MONCK, + CSR_2L_PXP_CDR1_PR_MONCK_ENABLE); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_PR_MONCK, + CSR_2L_PXP_CDR1_PR_RESERVE0, 0x2); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_OSCAL_VGA1IOS, + CSR_2L_PXP_RX1_PR_OSCAL_VGA1IOS, 0x19); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_OSCAL_VGA1IOS, + CSR_2L_PXP_RX1_PR_OSCAL_VGA1VOS, 0x19); + airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_OSCAL_VGA1IOS, + CSR_2L_PXP_RX1_PR_OSCAL_VGA2IOS, 0x14); +} + +static void airoha_pcie_phy_load_kflow(struct airoha_pcie_phy *pcie_phy) +{ + airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, + PCIE_FORCE_PMA_RX_SPEED, 0xa); + airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, + PCIE_FORCE_PMA_RX_SPEED, 0xa); + airoha_phy_init_lane0_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN3); + airoha_phy_init_lane1_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN3); + + airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, + PCIE_FORCE_PMA_RX_SPEED); + airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, + PCIE_FORCE_PMA_RX_SPEED); + usleep_range(100, 200); + + airoha_phy_init_lane0_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN2); + airoha_phy_init_lane1_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN2); +} + +/** + * airoha_pcie_phy_init() - Initialize the phy + * @phy: the phy to be initialized + * + * Initialize the phy registers. + * The hardware settings will be reset during suspend, it should be + * reinitialized when the consumer calls phy_init() again on resume. + */ +static int airoha_pcie_phy_init(struct phy *phy) +{ + struct airoha_pcie_phy *pcie_phy = phy_get_drvdata(phy); + u32 val; + + /* Setup Tx-Rx detection time */ + val = FIELD_PREP(PCIE_XTP_RXDET_VCM_OFF_STB_T_SEL, 0x33) | + FIELD_PREP(PCIE_XTP_RXDET_EN_STB_T_SEL, 0x1) | + FIELD_PREP(PCIE_XTP_RXDET_FINISH_STB_T_SEL, 0x2) | + FIELD_PREP(PCIE_XTP_TXPD_TX_DATA_EN_DLY, 0x3) | + FIELD_PREP(PCIE_XTP_RXDET_LATCH_STB_T_SEL, 0x1); + writel(val, pcie_phy->p0_xr_dtime + REG_PCIE_PEXTP_DIG_GLB44); + writel(val, pcie_phy->p1_xr_dtime + REG_PCIE_PEXTP_DIG_GLB44); + /* Setup Rx AEQ training time */ + val = FIELD_PREP(PCIE_XTP_LN_RX_PDOWN_L1P2_EXIT_WAIT, 0x32) | + FIELD_PREP(PCIE_XTP_LN_RX_PDOWN_E0_AEQEN_WAIT, 0x5050); + writel(val, pcie_phy->rx_aeq + REG_PCIE_PEXTP_DIG_LN_RX30_P0); + writel(val, pcie_phy->rx_aeq + REG_PCIE_PEXTP_DIG_LN_RX30_P1); + + /* enable load FLL-K flow */ + airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_14, + PCIE_FLL_LOAD_EN); + airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_14, + PCIE_FLL_LOAD_EN); + + airoha_pcie_phy_init_default(pcie_phy); + airoha_pcie_phy_init_clk_out(pcie_phy); + airoha_pcie_phy_init_csr_2l(pcie_phy); + + usleep_range(100, 200); + + airoha_pcie_phy_init_rx(pcie_phy); + /* phase 1, no ssc for K TXPLL */ + airoha_pcie_phy_init_jcpll(pcie_phy); + + usleep_range(500, 600); + + /* TX PLL settings */ + airoha_pcie_phy_txpll(pcie_phy); + + usleep_range(200, 300); + + /* SSC JCPLL setting */ + airoha_pcie_phy_init_ssc_jcpll(pcie_phy); + + usleep_range(100, 200); + + /* Rx lan0 signal detect */ + airoha_pcie_phy_set_rxlan0_signal_detect(pcie_phy); + /* Rx lan1 signal detect */ + airoha_pcie_phy_set_rxlan1_signal_detect(pcie_phy); + /* RX FLOW */ + airoha_pcie_phy_set_rxflow(pcie_phy); + + usleep_range(100, 200); + + airoha_pcie_phy_set_pr(pcie_phy); + /* TX FLOW */ + airoha_pcie_phy_set_txflow(pcie_phy); + + usleep_range(100, 200); + /* RX mode setting */ + airoha_pcie_phy_set_rx_mode(pcie_phy); + /* Load K-Flow */ + airoha_pcie_phy_load_kflow(pcie_phy); + airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, + PCIE_DA_XPON_CDR_PR_PWDB); + airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, + PCIE_DA_XPON_CDR_PR_PWDB); + + usleep_range(100, 200); + + airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, + PCIE_DA_XPON_CDR_PR_PWDB); + airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, + PCIE_DA_XPON_CDR_PR_PWDB); + + /* Wait for the PCIe PHY to complete initialization before returning */ + msleep(PHY_HW_INIT_TIME_MS); + + return 0; +} + +static int airoha_pcie_phy_exit(struct phy *phy) +{ + struct airoha_pcie_phy *pcie_phy = phy_get_drvdata(phy); + + airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, + PCIE_PMA_SW_RST); + airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, + PCIE_PMA_SW_RST); + airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, + CSR_2L_PXP_JCPLL_SSC_PHASE_INI | + CSR_2L_PXP_JCPLL_SSC_TRI_EN | + CSR_2L_PXP_JCPLL_SSC_EN); + + return 0; +} + +static const struct phy_ops airoha_pcie_phy_ops = { + .init = airoha_pcie_phy_init, + .exit = airoha_pcie_phy_exit, + .owner = THIS_MODULE, +}; + +static int airoha_pcie_phy_probe(struct platform_device *pdev) +{ + struct airoha_pcie_phy *pcie_phy; + struct device *dev = &pdev->dev; + struct phy_provider *provider; + + pcie_phy = devm_kzalloc(dev, sizeof(*pcie_phy), GFP_KERNEL); + if (!pcie_phy) + return -ENOMEM; + + pcie_phy->csr_2l = devm_platform_ioremap_resource_byname(pdev, "csr-2l"); + if (IS_ERR(pcie_phy->csr_2l)) + return dev_err_probe(dev, PTR_ERR(pcie_phy->csr_2l), + "Failed to map phy-csr-2l base\n"); + + pcie_phy->pma0 = devm_platform_ioremap_resource_byname(pdev, "pma0"); + if (IS_ERR(pcie_phy->pma0)) + return dev_err_probe(dev, PTR_ERR(pcie_phy->pma0), + "Failed to map phy-pma0 base\n"); + + pcie_phy->pma1 = devm_platform_ioremap_resource_byname(pdev, "pma1"); + if (IS_ERR(pcie_phy->pma1)) + return dev_err_probe(dev, PTR_ERR(pcie_phy->pma1), + "Failed to map phy-pma1 base\n"); + + pcie_phy->phy = devm_phy_create(dev, dev->of_node, &airoha_pcie_phy_ops); + if (IS_ERR(pcie_phy->phy)) + return dev_err_probe(dev, PTR_ERR(pcie_phy->phy), + "Failed to create PCIe phy\n"); + + pcie_phy->p0_xr_dtime = + devm_platform_ioremap_resource_byname(pdev, "p0-xr-dtime"); + if (IS_ERR(pcie_phy->p0_xr_dtime)) + return dev_err_probe(dev, PTR_ERR(pcie_phy->p0_xr_dtime), + "Failed to map P0 Tx-Rx dtime base\n"); + + pcie_phy->p1_xr_dtime = + devm_platform_ioremap_resource_byname(pdev, "p1-xr-dtime"); + if (IS_ERR(pcie_phy->p1_xr_dtime)) + return dev_err_probe(dev, PTR_ERR(pcie_phy->p1_xr_dtime), + "Failed to map P1 Tx-Rx dtime base\n"); + + pcie_phy->rx_aeq = devm_platform_ioremap_resource_byname(pdev, "rx-aeq"); + if (IS_ERR(pcie_phy->rx_aeq)) + return dev_err_probe(dev, PTR_ERR(pcie_phy->rx_aeq), + "Failed to map Rx AEQ base\n"); + + pcie_phy->dev = dev; + phy_set_drvdata(pcie_phy->phy, pcie_phy); + + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + if (IS_ERR(provider)) + return dev_err_probe(dev, PTR_ERR(provider), + "PCIe phy probe failed\n"); + + return 0; +} + +static const struct of_device_id airoha_pcie_phy_of_match[] = { + { .compatible = "airoha,en7581-pcie-phy" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, airoha_pcie_phy_of_match); + +static struct platform_driver airoha_pcie_phy_driver = { + .probe = airoha_pcie_phy_probe, + .driver = { + .name = "airoha-pcie-phy", + .of_match_table = airoha_pcie_phy_of_match, + }, +}; +module_platform_driver(airoha_pcie_phy_driver); + +MODULE_DESCRIPTION("Airoha PCIe PHY driver"); +MODULE_AUTHOR("Lorenzo Bianconi "); +MODULE_LICENSE("GPL"); From patchwork Thu Mar 20 13:00:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 14023965 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3CBD6C35FFF for ; Thu, 20 Mar 2025 13:17:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=UxDr9Y6TgwzFlsZMuiBqJe1iXWy0IOXLZR0myv7lnrk=; b=jCIDJYBPv9xosc Yj1Dyth5uyekOvMHfXcfEhIwhasAk8ZXYLcQt8bRhqjNNWfG2fgIgb6c3Nt4fG0ZXKS6euXWJ5FB0 e2jZitkso7hYiU94Hqk+DwYQJuIIGiEI0gxbSs4U/BXWGnPJ41zaNifQbUmlbsj9pzyfgZXHGMzDf zipmeow2DKJPL8J3pFUDGLGWXs6Hcagk6CdFFSvIh8zKwFuXXpUo3k6C9fD5i3+jnISE3WtCzy5nt k+uEM5Q/ZcxpdLmMVWy29ucBK2wDRdwSst2R13Q36g62lVdGAvuo9CkkjBW5HsmXhQq1+elR+Lzf5 s7s8QPS17N7+mQw1b6CA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tvFm6-0000000CCoi-3PwN; Thu, 20 Mar 2025 13:17:30 +0000 Received: from mail-wr1-x42e.google.com ([2a00:1450:4864:20::42e]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tvFWu-0000000CAgf-0ou2; Thu, 20 Mar 2025 13:01:49 +0000 Received: by mail-wr1-x42e.google.com with SMTP id ffacd0b85a97d-3913fdd0120so424943f8f.0; Thu, 20 Mar 2025 06:01:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1742475706; x=1743080506; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Mi1yesWKIqJhtiZkLMy50lRImXQrK1R3wBST4dI3DA0=; b=SzER51NDYvcOv44hq/4Vphp6WHNEHrgWMcVA6T0xaH33zi8mjhtrieWRZTna4LHb7e T5XIDYrh+WSKteUOeLsZUPRXFVm7N6EhXsjA4LBV1ezaHAR2d2t0LeV4qqbcO/W6p0WK NeCjHXCIuUJXyiXHmAlpIhbmV4EUpFo5aTE+DK4h5MYS4eT5ec5lZ9q6QpyxWYSB3CSL 5o2wcJO1QQ4Vj1Pm4kPOWxcXFwuD6K1FDgNKoUSVv4qnWi5XBUryJ9UxqC84XNLGHb0c l3MFcgjJsJbXUwHAG2XMJdSNmC9hA2fWmQmV2m3m7bZ0CSjB+/RaRJobkXrrCsuOB1s2 Rz3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742475706; x=1743080506; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Mi1yesWKIqJhtiZkLMy50lRImXQrK1R3wBST4dI3DA0=; b=AHSQ9s0cQYiza3/I2jtfbehf9Kx6LSxowOeHesFJZzNCJvbEAC8RRmFe5slBUNArEd tEjEYivYEm9gsxLBQeJ8LeZ/n2pcLGTvXsr+13z9eS+CiVZQpntShvJThri+qeEW35Q5 qNriWveHBEI8IMhOn7tbdAP03GtkkhY6zDCyUEizuH24ctGz1hl11I2yrfXHvabNmtI9 26q2lVlaxjzXRuENjFZCMMWhBnpKaRTgQk7/b6j2/qIHD7lzau+v95wkZuhu15Bsy4za FjOvBeFwnacXnAtKd5k1/ioJ9a5fdX2PHLw8M1Fq/RxTkzIC6bQwO5s2jKyu9BtaVUdd 0y+A== X-Forwarded-Encrypted: i=1; AJvYcCVPba4bpdhX2kkcbSQBzQCe1rwlqTs5vDzRvGbG25Kvx0B+Ley3m50mpMIyfXQCfwjwLeP8HV+86MtROxBPftg=@lists.infradead.org, AJvYcCWjvbzWLyvrCfVkY+ne7GrwmD9mANOJlyfhZSR0UT2XVLy/pe4JBYQtUM2Tp6TxMWTpejvyi3Cr4BAz@lists.infradead.org, AJvYcCX6YaIRVuSWMOPKoR4dVmtB/W6F1yGhYpsqzJBEDHYxc5ojH3Kfn2ytYQYl1GcbvTgdbBI+UJdY1efQRpQiESJY@lists.infradead.org X-Gm-Message-State: AOJu0Yw7N8QwHFwm77MmMxrlE3sI8IgZmoQIapnUcqWr84Om3RsR9gEL e/dU3YtbL9zYfUHRH8SPNZaL72MLPRNrWyceXIdkQyIsyQFDEQBE X-Gm-Gg: ASbGncugLcbGVJDKmxJ2izdfrEUkgKfAsQPt67MZpOuh4N09AAb4mp2V20fS90WX/eZ 5dE6kGjT3mvosHfPTAo2LxDRdlMSiad1keQfmJH3BDULCXLfwnd2OIzh2E+kKqv1oL0D6psfPEH cBl3E3o6I4Ssg0PMkAhyUfQIgZhz5wMNiO2HfzaF5UDcI7cXXTEVUVKtkTygIOi9UbPUZi5nEKB uDzMMJTXafj0t5XMjAto/1mcKpBSBnlQrY8Ym4d6J7JbsS1RwF6aWIZEt0XhnsIIQvXGgvG2tOm jUKTuiC6SsMSlrQ+lVvnmZaHwpO3FXDn8f/jb6ILmrNYfwTlsypmkFhXOQ8NFWPSlMB78VUgBU8 wyMYrblxqy/zsdw== X-Google-Smtp-Source: AGHT+IG+iVJ/ABK/y2dL05MNVOj3FOGYyJncq9qCsloYatB7jtGAcj9XxnyMz8605MZ6S/JAQTlx9A== X-Received: by 2002:a5d:5f81:0:b0:390:d6b0:b89 with SMTP id ffacd0b85a97d-399795e5142mr2332376f8f.50.1742475705702; Thu, 20 Mar 2025 06:01:45 -0700 (PDT) Received: from localhost.localdomain (93-34-90-129.ip49.fastwebnet.it. [93.34.90.129]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-397f2837e61sm18492328f8f.97.2025.03.20.06.01.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Mar 2025 06:01:45 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Kishon Vijay Abraham I , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Greg Kroah-Hartman , Daniel Danzberger , Arnd Bergmann , Alexander Sverdlin , Nikita Shubin , Linus Walleij , Yangyu Chen , Ben Hutchings , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-usb@vger.kernel.org, upstream@airoha.com Subject: [PATCH v2 09/11] phy: airoha: Add support for Airoha AN7581 USB PHY Date: Thu, 20 Mar 2025 14:00:32 +0100 Message-ID: <20250320130054.4804-10-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250320130054.4804-1-ansuelsmth@gmail.com> References: <20250320130054.4804-1-ansuelsmth@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250320_060148_244337_08DCE537 X-CRM114-Status: GOOD ( 24.69 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Add support for Airoha AN7581 USB PHY driver. AN7581 supports up to 2 USB port with USB 2.0 mode always supported and USB 3.0 mode available only if the Serdes port is correctly configured for USB 3.0. On xLate probe, the Serdes mode is validated and the driver return error if the Serdes mode doesn't reflect the expected mode. This is required as Serdes mode are controlled by the SCU SSR bits and can be either USB 3.0 mode or HSGMII or PCIe 2. In such case USB 3.0 won't work. If the USB 3.0 mode is not supported, the modes needs to be also disabled in the xHCI node or the driver will report unsable clock and fail probe. Also USB 3.0 PHY instance are provided only if the airoha,serdes-port property is defined in DT, if it's not then USB 3.0 PHY is assumed not supported. For USB 2.0 Slew Rate calibration, airoha,usb2-monitor-clk-sel is mandatory and is used to select the monitor clock for calibration. Normally it's 1 for USB port 1 and 2 for USB port 2. Signed-off-by: Christian Marangi --- MAINTAINERS | 1 + drivers/phy/airoha/Kconfig | 10 + drivers/phy/airoha/Makefile | 1 + drivers/phy/airoha/phy-airoha-usb.c | 571 ++++++++++++++++++++++++++++ 4 files changed, 583 insertions(+) create mode 100644 drivers/phy/airoha/phy-airoha-usb.c diff --git a/MAINTAINERS b/MAINTAINERS index 4e11db5d203a..f8208994d190 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -759,6 +759,7 @@ M: Christian Marangi L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml +F: drivers/phy/airoha/phy-airoha-usb.c F: include/dt-bindings/phy/airoha,an7581-usb-phy.h AIRSPY MEDIA DRIVER diff --git a/drivers/phy/airoha/Kconfig b/drivers/phy/airoha/Kconfig index 70b7eac4a2bf..0675d8f2f9d1 100644 --- a/drivers/phy/airoha/Kconfig +++ b/drivers/phy/airoha/Kconfig @@ -11,3 +11,13 @@ config PHY_AIROHA_PCIE Say Y here to add support for Airoha PCIe PHY driver. This driver create the basic PHY instance and provides initialize callback for PCIe GEN3 port. + +config PHY_AIROHA_USB + tristate "Airoha USB PHY Driver" + depends on ARCH_AIROHA || COMPILE_TEST + depends on OF + select GENERIC_PHY + help + Say 'Y' here to add support for Airoha USB PHY driver. + This driver create the basic PHY instance and provides initialize + callback for USB port. diff --git a/drivers/phy/airoha/Makefile b/drivers/phy/airoha/Makefile index 3222f749546b..fd188d08c412 100644 --- a/drivers/phy/airoha/Makefile +++ b/drivers/phy/airoha/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o +obj-$(CONFIG_PHY_AIROHA_USB) += phy-airoha-usb.o diff --git a/drivers/phy/airoha/phy-airoha-usb.c b/drivers/phy/airoha/phy-airoha-usb.c new file mode 100644 index 000000000000..72a3ee14b7a6 --- /dev/null +++ b/drivers/phy/airoha/phy-airoha-usb.c @@ -0,0 +1,571 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Author: Christian Marangi + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* U2PHY */ +#define AIROHA_USB_PHY_FMCR0 0x100 +#define AIROHA_USB_PHY_MONCLK_SEL GENMASK(27, 26) +#define AIROHA_USB_PHY_MONCLK_SEL0 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x0) +#define AIROHA_USB_PHY_MONCLK_SEL1 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x1) +#define AIROHA_USB_PHY_MONCLK_SEL2 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x2) +#define AIROHA_USB_PHY_MONCLK_SEL3 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x3) +#define AIROHA_USB_PHY_FREQDET_EN BIT(24) +#define AIROHA_USB_PHY_CYCLECNT GENMASK(23, 0) +#define AIROHA_USB_PHY_FMMONR0 0x10c +#define AIROHA_USB_PHY_USB_FM_OUT GENMASK(31, 0) +#define AIROHA_USB_PHY_FMMONR1 0x110 +#define AIROHA_USB_PHY_FRCK_EN BIT(8) + +#define AIROHA_USB_PHY_USBPHYACR4 0x310 +#define AIROHA_USB_PHY_USB20_FS_CR GENMASK(10, 8) +#define AIROHA_USB_PHY_USB20_FS_CR_MAX FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x0) +#define AIROHA_USB_PHY_USB20_FS_CR_NORMAL FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x2) +#define AIROHA_USB_PHY_USB20_FS_CR_SMALLER FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x4) +#define AIROHA_USB_PHY_USB20_FS_CR_MIN FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x6) +#define AIROHA_USB_PHY_USB20_FS_SR GENMASK(2, 0) +#define AIROHA_USB_PHY_USB20_FS_SR_MAX FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x0) +#define AIROHA_USB_PHY_USB20_FS_SR_NORMAL FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x2) +#define AIROHA_USB_PHY_USB20_FS_SR_SMALLER FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x4) +#define AIROHA_USB_PHY_USB20_FS_SR_MIN FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x6) +#define AIROHA_USB_PHY_USBPHYACR5 0x314 +#define AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN BIT(15) +#define AIROHA_USB_PHY_USB20_HSTX_SRCTRL GENMASK(14, 12) +#define AIROHA_USB_PHY_USBPHYACR6 0x318 +#define AIROHA_USB_PHY_USB20_BC11_SW_EN BIT(23) +#define AIROHA_USB_PHY_USB20_DISCTH GENMASK(7, 4) +#define AIROHA_USB_PHY_USB20_DISCTH_400 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x0) +#define AIROHA_USB_PHY_USB20_DISCTH_420 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x1) +#define AIROHA_USB_PHY_USB20_DISCTH_440 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x2) +#define AIROHA_USB_PHY_USB20_DISCTH_460 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x3) +#define AIROHA_USB_PHY_USB20_DISCTH_480 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x4) +#define AIROHA_USB_PHY_USB20_DISCTH_500 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x5) +#define AIROHA_USB_PHY_USB20_DISCTH_520 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x6) +#define AIROHA_USB_PHY_USB20_DISCTH_540 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x7) +#define AIROHA_USB_PHY_USB20_DISCTH_560 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x8) +#define AIROHA_USB_PHY_USB20_DISCTH_580 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x9) +#define AIROHA_USB_PHY_USB20_DISCTH_600 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xa) +#define AIROHA_USB_PHY_USB20_DISCTH_620 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xb) +#define AIROHA_USB_PHY_USB20_DISCTH_640 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xc) +#define AIROHA_USB_PHY_USB20_DISCTH_660 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xd) +#define AIROHA_USB_PHY_USB20_DISCTH_680 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xe) +#define AIROHA_USB_PHY_USB20_DISCTH_700 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xf) +#define AIROHA_USB_PHY_USB20_SQTH GENMASK(3, 0) +#define AIROHA_USB_PHY_USB20_SQTH_85 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x0) +#define AIROHA_USB_PHY_USB20_SQTH_90 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x1) +#define AIROHA_USB_PHY_USB20_SQTH_95 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x2) +#define AIROHA_USB_PHY_USB20_SQTH_100 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x3) +#define AIROHA_USB_PHY_USB20_SQTH_105 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x4) +#define AIROHA_USB_PHY_USB20_SQTH_110 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x5) +#define AIROHA_USB_PHY_USB20_SQTH_115 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x6) +#define AIROHA_USB_PHY_USB20_SQTH_120 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x7) +#define AIROHA_USB_PHY_USB20_SQTH_125 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x8) +#define AIROHA_USB_PHY_USB20_SQTH_130 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x9) +#define AIROHA_USB_PHY_USB20_SQTH_135 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xa) +#define AIROHA_USB_PHY_USB20_SQTH_140 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xb) +#define AIROHA_USB_PHY_USB20_SQTH_145 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xc) +#define AIROHA_USB_PHY_USB20_SQTH_150 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xd) +#define AIROHA_USB_PHY_USB20_SQTH_155 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xe) +#define AIROHA_USB_PHY_USB20_SQTH_160 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xf) + +#define AIROHA_USB_PHY_U2PHYDTM1 0x36c +#define AIROHA_USB_PHY_FORCE_IDDIG BIT(9) +#define AIROHA_USB_PHY_IDDIG BIT(1) + +#define AIROHA_USB_PHY_GPIO_CTLD 0x80c +#define AIROHA_USB_PHY_C60802_GPIO_CTLD GENMASK(31, 0) +#define AIROHA_USB_PHY_SSUSB_IP_SW_RST BIT(31) +#define AIROHA_USB_PHY_MCU_BUS_CK_GATE_EN BIT(30) +#define AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST BIT(29) +#define AIROHA_USB_PHY_SSUSB_SW_RST BIT(28) + +#define AIROHA_USB_PHY_U3_PHYA_REG0 0xb00 +#define AIROHA_USB_PHY_SSUSB_BG_DIV GENMASK(29, 28) +#define AIROHA_USB_PHY_SSUSB_BG_DIV_2 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x0) +#define AIROHA_USB_PHY_SSUSB_BG_DIV_4 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x1) +#define AIROHA_USB_PHY_SSUSB_BG_DIV_8 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x2) +#define AIROHA_USB_PHY_SSUSB_BG_DIV_16 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x3) +#define AIROHA_USB_PHY_U3_PHYA_REG1 0xb04 +#define AIROHA_USB_PHY_SSUSB_XTAL_TOP_RESERVE GENMASK(25, 10) +#define AIROHA_USB_PHY_U3_PHYA_REG6 0xb18 +#define AIROHA_USB_PHY_SSUSB_CDR_RESERVE GENMASK(31, 24) +#define AIROHA_USB_PHY_U3_PHYA_REG8 0xb20 +#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY GENMASK(7, 6) +#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_32 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x0) +#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_64 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x1) +#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_128 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x2) +#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_216 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x3) + +#define AIROHA_USB_PHY_U3_PHYA_DA_REG19 0xc38 +#define AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3 GENMASK(15, 0) + +#define AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT 1024 +#define AIROHA_USB_PHY_REF_CK 20 +#define AIROHA_USB_PHY_U2_SR_COEF 28 +#define AIROHA_USB_PHY_U2_SR_COEF_DIVISOR 1000 + +#define AIROHA_USB_PHY_DEFAULT_SR_CALIBRATION 0x5 +#define AIROHA_USB_PHY_FREQDET_SLEEP 1000 /* 1ms */ +#define AIROHA_USB_PHY_FREQDET_TIMEOUT (AIROHA_USB_PHY_FREQDET_SLEEP * 10) + +struct airoha_usb_phy_instance { + struct phy *phy; + u32 type; +}; + +enum airoha_usb_phy_instance_type { + AIROHA_PHY_USB2, + AIROHA_PHY_USB3, + + AIROHA_PHY_USB_MAX, +}; + +struct airoha_usb_phy_priv { + struct device *dev; + struct regmap *regmap; + + unsigned int monclk_sel; + unsigned int serdes_port; + + struct airoha_usb_phy_instance *phys[AIROHA_PHY_USB_MAX]; +}; + +static void airoha_usb_phy_u2_slew_rate_calibration(struct airoha_usb_phy_priv *priv) +{ + u32 fm_out; + u32 srctrl; + + /* Enable HS TX SR calibration */ + regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, + AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN); + + usleep_range(1000, 1500); + + /* Enable Free run clock */ + regmap_set_bits(priv->regmap, AIROHA_USB_PHY_FMMONR1, + AIROHA_USB_PHY_FRCK_EN); + + /* Select Monitor Clock */ + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, + AIROHA_USB_PHY_MONCLK_SEL, + FIELD_PREP(AIROHA_USB_PHY_MONCLK_SEL, + priv->monclk_sel)); + + /* Set cyclecnt */ + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, + AIROHA_USB_PHY_CYCLECNT, + FIELD_PREP(AIROHA_USB_PHY_CYCLECNT, + AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT)); + + /* Enable Frequency meter */ + regmap_set_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, + AIROHA_USB_PHY_FREQDET_EN); + + /* Timeout can happen and we will apply workaround at the end */ + regmap_read_poll_timeout(priv->regmap, AIROHA_USB_PHY_FMMONR0, fm_out, + fm_out, AIROHA_USB_PHY_FREQDET_SLEEP, + AIROHA_USB_PHY_FREQDET_TIMEOUT); + + /* Disable Frequency meter */ + regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, + AIROHA_USB_PHY_FREQDET_EN); + + /* Disable Free run clock */ + regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_FMMONR1, + AIROHA_USB_PHY_FRCK_EN); + + /* Disable HS TX SR calibration */ + regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, + AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN); + + usleep_range(1000, 1500); + + /* Frequency was not detected, use default SR calibration value */ + if (!fm_out) { + srctrl = AIROHA_USB_PHY_DEFAULT_SR_CALIBRATION; + dev_err(priv->dev, "Frequency not detected, using default SR calibration.\n"); + } else { + /* (1024 / FM_OUT) * REF_CK * U2_SR_COEF (round to the nearest digits) */ + srctrl = AIROHA_USB_PHY_REF_CK * AIROHA_USB_PHY_U2_SR_COEF; + srctrl = (srctrl * AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT) / fm_out; + srctrl = DIV_ROUND_CLOSEST(srctrl, AIROHA_USB_PHY_U2_SR_COEF_DIVISOR); + dev_dbg(priv->dev, "SR calibration applied: %x\n", srctrl); + } + + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, + AIROHA_USB_PHY_USB20_HSTX_SRCTRL, + FIELD_PREP(AIROHA_USB_PHY_USB20_HSTX_SRCTRL, srctrl)); +} + +static void airoha_usb_phy_u2_init(struct airoha_usb_phy_priv *priv) +{ + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR4, + AIROHA_USB_PHY_USB20_FS_CR, + AIROHA_USB_PHY_USB20_FS_CR_MIN); + + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR4, + AIROHA_USB_PHY_USB20_FS_SR, + AIROHA_USB_PHY_USB20_FS_SR_NORMAL); + + /* FIXME: evaluate if needed */ + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, + AIROHA_USB_PHY_USB20_SQTH, + AIROHA_USB_PHY_USB20_SQTH_130); + + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, + AIROHA_USB_PHY_USB20_DISCTH, + AIROHA_USB_PHY_USB20_DISCTH_600); + + /* Enable the USB port and then disable after calibration */ + regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, + AIROHA_USB_PHY_USB20_BC11_SW_EN); + + airoha_usb_phy_u2_slew_rate_calibration(priv); + + regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, + AIROHA_USB_PHY_USB20_BC11_SW_EN); + + usleep_range(1000, 1500); +} + +/* + * USB 3.0 mode can only work if USB serdes is correctly set. + * This is validated in xLate function. + */ +static void airoha_usb_phy_u3_init(struct airoha_usb_phy_priv *priv) +{ + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG8, + AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, + AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_32); + + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG6, + AIROHA_USB_PHY_SSUSB_CDR_RESERVE, + FIELD_PREP(AIROHA_USB_PHY_SSUSB_CDR_RESERVE, 0xe)); + + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG0, + AIROHA_USB_PHY_SSUSB_BG_DIV, + AIROHA_USB_PHY_SSUSB_BG_DIV_4); + + regmap_set_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG1, + FIELD_PREP(AIROHA_USB_PHY_SSUSB_XTAL_TOP_RESERVE, 0x600)); + + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_DA_REG19, + AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3, + FIELD_PREP(AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3, 0x43)); +} + +static int airoha_usb_phy_init(struct phy *phy) +{ + struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); + struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); + + switch (instance->type) { + case PHY_TYPE_USB2: + airoha_usb_phy_u2_init(priv); + break; + case PHY_TYPE_USB3: + airoha_usb_phy_u3_init(priv); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int airoha_usb_phy_u2_power_on(struct airoha_usb_phy_priv *priv) +{ + regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, + AIROHA_USB_PHY_USB20_BC11_SW_EN); + + usleep_range(1000, 1500); + + return 0; +} + +static int airoha_usb_phy_u3_power_on(struct airoha_usb_phy_priv *priv) +{ + regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_GPIO_CTLD, + AIROHA_USB_PHY_SSUSB_IP_SW_RST | + AIROHA_USB_PHY_MCU_BUS_CK_GATE_EN | + AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST | + AIROHA_USB_PHY_SSUSB_SW_RST); + + usleep_range(1000, 1500); + + return 0; +} + +static int airoha_usb_phy_power_on(struct phy *phy) +{ + struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); + struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); + + switch (instance->type) { + case PHY_TYPE_USB2: + airoha_usb_phy_u2_power_on(priv); + break; + case PHY_TYPE_USB3: + airoha_usb_phy_u3_power_on(priv); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int airoha_usb_phy_u2_power_off(struct airoha_usb_phy_priv *priv) +{ + regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, + AIROHA_USB_PHY_USB20_BC11_SW_EN); + + usleep_range(1000, 1500); + + return 0; +} + +static int airoha_usb_phy_u3_power_off(struct airoha_usb_phy_priv *priv) +{ + regmap_set_bits(priv->regmap, AIROHA_USB_PHY_GPIO_CTLD, + AIROHA_USB_PHY_SSUSB_IP_SW_RST | + AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST); + + usleep_range(1000, 1500); + + return 0; +} + +static int airoha_usb_phy_power_off(struct phy *phy) +{ + struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); + struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); + + switch (instance->type) { + case PHY_TYPE_USB2: + airoha_usb_phy_u2_power_off(priv); + break; + case PHY_TYPE_USB3: + airoha_usb_phy_u3_power_off(priv); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int airoha_usb_phy_u2_set_mode(struct airoha_usb_phy_priv *priv, + enum phy_mode mode) +{ + u32 val; + + /* + * For Device and Host mode, enable force IDDIG. + * For Device set IDDIG, for Host clear IDDIG. + * For OTG disable force and clear IDDIG bit while at it. + */ + switch (mode) { + case PHY_MODE_USB_DEVICE: + val = AIROHA_USB_PHY_IDDIG; + break; + case PHY_MODE_USB_HOST: + val = AIROHA_USB_PHY_FORCE_IDDIG | + AIROHA_USB_PHY_FORCE_IDDIG; + break; + case PHY_MODE_USB_OTG: + val = 0; + break; + default: + return 0; + } + + regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U2PHYDTM1, + AIROHA_USB_PHY_FORCE_IDDIG | + AIROHA_USB_PHY_IDDIG, val); + + return 0; +} + +static int airoha_usb_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) +{ + struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); + struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); + + if (instance->type == PHY_TYPE_USB2) + return airoha_usb_phy_u2_set_mode(priv, mode); + + return 0; +} + +static struct phy *airoha_usb_phy_xlate(struct device *dev, + const struct of_phandle_args *args) +{ + struct airoha_usb_phy_priv *priv = dev_get_drvdata(dev); + struct airoha_usb_phy_instance *instance = NULL; + int phy_type; + int index; + + if (args->args_count != 1) { + dev_err(dev, "invalid number of cells in 'phy' property\n"); + return ERR_PTR(-EINVAL); + } + + phy_type = args->args[0]; + if (!(phy_type == PHY_TYPE_USB2 || phy_type == PHY_TYPE_USB3)) { + dev_err(dev, "unsupported device type: %d\n", phy_type); + return ERR_PTR(-EINVAL); + } + + for (index = 0; index < AIROHA_PHY_USB_MAX; index++) + if (priv->phys[index] && + phy_type == priv->phys[index]->type) { + instance = priv->phys[index]; + break; + } + + if (!instance) { + dev_err(dev, "failed to find appropriate phy\n"); + return ERR_PTR(-EINVAL); + } + + /* Validate Serdes for USB 3.0 */ + if (instance->type == PHY_TYPE_USB3) { + int serdes_mode; + + serdes_mode = airoha_scu_ssr_get_serdes_mode(dev, priv->serdes_port); + if (serdes_mode < 0) { + dev_err(dev, "failed validating serdes mode: %d\n", + serdes_mode); + return ERR_PTR(serdes_mode); + } + + if (serdes_mode != AIROHA_SCU_SERDES_MODE_USB3) { + dev_err(dev, "wrong serdes mode for port\n"); + return ERR_PTR(-EINVAL); + } + } + + return instance->phy; +} + +static const struct phy_ops airoha_phy = { + .init = airoha_usb_phy_init, + .power_on = airoha_usb_phy_power_on, + .power_off = airoha_usb_phy_power_off, + .set_mode = airoha_usb_phy_set_mode, + .owner = THIS_MODULE, +}; + +static const struct regmap_config airoha_usb_phy_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + +static int airoha_usb_phy_probe(struct platform_device *pdev) +{ + struct phy_provider *phy_provider; + struct airoha_usb_phy_priv *priv; + struct device *dev = &pdev->dev; + void *base; + int index; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + + ret = of_property_read_u32(dev->of_node, "airoha,usb2-monitor-clk-sel", + &priv->monclk_sel); + if (ret) + return dev_err_probe(dev, ret, "Monitor clock selection is mandatory for USB PHY calibration.\n"); + + if (priv->monclk_sel > 3) + return dev_err_probe(dev, -EINVAL, "only 4 Monitor clock are selectable on the SoC.\n"); + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + priv->regmap = devm_regmap_init_mmio(dev, base, &airoha_usb_phy_regmap_config); + if (IS_ERR(priv->regmap)) + return PTR_ERR(priv->regmap); + + platform_set_drvdata(pdev, priv); + + for (index = 0; index < AIROHA_PHY_USB_MAX; index++) { + struct airoha_usb_phy_instance *instance; + unsigned int phy_type; + + switch (index) { + case AIROHA_PHY_USB2: + phy_type = PHY_TYPE_USB2; + break; + case AIROHA_PHY_USB3: + phy_type = PHY_TYPE_USB3; + break; + } + + /* Skip registering USB3 instance if not supported */ + if (phy_type == PHY_TYPE_USB3) { + ret = of_property_read_u32(dev->of_node, "airoha,serdes-port", + &priv->serdes_port); + if (ret) + continue; + + /* With Serdes Port property, SCU is required */ + if (!of_property_present(dev->of_node, "airoha,scu")) + return dev_err_probe(dev, ret, "missing required SCU definition.\n"); + } + + instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL); + if (!instance) + return -ENOMEM; + + instance->type = phy_type; + priv->phys[index] = instance; + + instance->phy = devm_phy_create(dev, NULL, &airoha_phy); + if (IS_ERR(instance->phy)) + return dev_err_probe(dev, PTR_ERR(instance->phy), "failed to create phy\n"); + + phy_set_drvdata(instance->phy, instance); + } + + phy_provider = devm_of_phy_provider_register(&pdev->dev, airoha_usb_phy_xlate); + + return PTR_ERR_OR_ZERO(phy_provider); +} + +static const struct of_device_id airoha_phy_id_table[] = { + { .compatible = "airoha,an7581-usb-phy" }, + { }, +}; +MODULE_DEVICE_TABLE(of, airoha_phy_id_table); + +static struct platform_driver airoha_usb_driver = { + .probe = airoha_usb_phy_probe, + .driver = { + .name = "airoha-usb-phy", + .of_match_table = airoha_phy_id_table, + }, +}; + +module_platform_driver(airoha_usb_driver); + +MODULE_AUTHOR("Christian Marangi "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Airoha USB PHY driver"); From patchwork Thu Mar 20 13:00:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 14023966 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 70FECC28B30 for ; Thu, 20 Mar 2025 13:19:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=g/DUT1oWEO9gBZ69EH+n3CStsDGewNiztg5rhNsodQM=; b=eXsdpr2OLKpI5b sZJwU0KJJbcL6fOOAZxHcE/5brcjqKo53zj+oY2uw11BMvknNuU2WO89JWhRWufINXAS+SX5XY4WQ SpUxI66f2EtQp9juUdpZA4EB0rgzoGm6jTekqPiYGYBPAyQTGYfI9Ik9B5tHMGChzuRQYLP0KckKe HvV8Fuwxx9+RtpCND6WATNa2fhjZhZTlvdZYmf0q5+nHMF/Z2JKeRhMfVB+75dWNG5gJOHFREuXyU dHKod6NXbO77EEzscjZt4sOdLmC3gFyMKtOUCVApwTn5+Oqy0yH/eZ/TWYnZndpwmSXJp4SMxo3Do xCf2aYz03xGpBoBXZK4Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tvFnm-0000000CD1r-0wLd; Thu, 20 Mar 2025 13:19:14 +0000 Received: from mail-wr1-x435.google.com ([2a00:1450:4864:20::435]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tvFWw-0000000CAhS-1N7o; Thu, 20 Mar 2025 13:01:51 +0000 Received: by mail-wr1-x435.google.com with SMTP id ffacd0b85a97d-399737f4fa4so415998f8f.0; Thu, 20 Mar 2025 06:01:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1742475709; x=1743080509; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=MZocKeaP4+m6t9O2v1jxFvpKpeZLmzryJkfebv96Xm0=; b=mLTwfYjmwVUJpsnaQ+Cb1ekV0tqtcqYAsOUXB8erg6oXTaoUmFGozXfgMcX9NzaCuq FSxx5PfxiD+zbefW0Rubye0T1EiLDM/iQ3kOy3LaTehqvqTvOO4uzx5z++KvDVlayCVP ZcgsAe6c9000PPt1ER7C6tMGXXi8qexrniLvn/xlYSPgCrdPHSLsUztoKdpzke/Q1oZV w1k+EQGSeSA70HQAxP8ag9cvInj9LaaRsbQ9oxxLZyXiGH2zmR+Jwe6EAhTWhNbDMwf2 mgf2Rn253yhvm+WoWX2Uk8lNOjiIoABERApebHYXRwblJ9BJPF713Dm/8m5cMe/XzPsJ XWUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742475709; x=1743080509; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MZocKeaP4+m6t9O2v1jxFvpKpeZLmzryJkfebv96Xm0=; b=STIZq0y2yndYo+YqCxj/Vd4apQDAEX4HMJu1pIG3e4X0N/HAqVWX7fv8lQnKeHaiTA 5uel5TPRTaAQKEBmBhdhzFRprya+f9LpIIzAGMHWugO3NMRdzwPpIU7SVgHQ9pt+Z64r fuXKiQdNnvE/ompQJDNJFzeOtW6Wm7sSlm1cEqQGhHpFIO2NmZisZFqgSTp03kYzpIUP MbXP8z7CHVNEV6IDlXLnHESb5K3Tc5XXmoAYMhyk5/SKan4olxxys9B6yic14U+C/bam zDZvFvh9fRwSan5FpQ60J2e3l/cWuzEn0D3PaRGK4WdPjS/Q5qi8KVB3+xaImLtnBV3L j/Iw== X-Forwarded-Encrypted: i=1; AJvYcCUXbR4ISItM33XHE2yDA946t/FrRyKYYIBOHGgZro0V0wtBKYfcxuRYQoBDkj/TCf6/dWkFqCU9XBtO@lists.infradead.org, AJvYcCW1ppYp444yQznNuAqaymoIa5dSixp5A9cL/gD9NM1u9nmft8TzZA2hVOZbuaJVC37idjYUF1BhEPgRKB+4l54=@lists.infradead.org, AJvYcCWhTqpiogYS6Os1ggwJKKclBjIELPOiK4y1KI+bME3CdqjebCKXB6sQ7fKm1PzdYsK4kXEqi4Oi+s/oPuLDtOsm@lists.infradead.org X-Gm-Message-State: AOJu0Yz51uTP3t5JCeXFviQK6fJkk1ptWzyDOb74fjbHFPTiTDnTUKhi i2lnSx2qpfKajdPo+AKamEjMFqHafYmIr7LVo/iwNijr3c0NM3Ax X-Gm-Gg: ASbGnctKyqkv48m4kINzCTc+wA5UUUg2AflC9y3I5rzbnEFt33z4ROZAVOjwg84I57j LHNkh7CmpD0xJ//QYXQJTammXxBqJjjEPxd2/8IfzmyCVEFsjlaBiQhBgL5FEL8JH1qbjanKvXP JkIYr/tGXDMnv71mMQsrP72cYY90BjS8q+qbHVnyQPlfoIXYSlB1qvcSc5qS2R9c0a13YIzEm2c Jg68WSOWdS+px76UE7zalUYNUA+rHp79H/fuf7WZXxrqy+KlPlt6YMdJHyi/HGi8W/J7bmWh/ml KKorDaiVKOv59SCk2jOtIayUQgyGCjkHIEPdmDB3OWK57xOTtE/6qPOODT8ELkJSHQrVYQPVfjR 5OjPG/9QEuwwmfw== X-Google-Smtp-Source: AGHT+IFwiZIO1zJG6xqsD6hkKvEBYIiPzPEpp2yNsbAclaZLwl3OGlaU/Gn9w+5dTLKNFCSQz4VNOA== X-Received: by 2002:a05:6000:402c:b0:391:4684:dbdb with SMTP id ffacd0b85a97d-399795ad76amr2805038f8f.17.1742475707909; Thu, 20 Mar 2025 06:01:47 -0700 (PDT) Received: from localhost.localdomain (93-34-90-129.ip49.fastwebnet.it. [93.34.90.129]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-397f2837e61sm18492328f8f.97.2025.03.20.06.01.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Mar 2025 06:01:47 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Kishon Vijay Abraham I , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Greg Kroah-Hartman , Daniel Danzberger , Arnd Bergmann , Alexander Sverdlin , Nikita Shubin , Linus Walleij , Yangyu Chen , Ben Hutchings , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-usb@vger.kernel.org, upstream@airoha.com Subject: [PATCH v2 10/11] usb: host: add ARCH_AIROHA in XHCI MTK dependency Date: Thu, 20 Mar 2025 14:00:33 +0100 Message-ID: <20250320130054.4804-11-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250320130054.4804-1-ansuelsmth@gmail.com> References: <20250320130054.4804-1-ansuelsmth@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250320_060150_364972_3C39CD9F X-CRM114-Status: GOOD ( 13.94 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Airoha SoC use the same register map a logic of the Mediatek xHCI driver, hence add it to the dependency list to permit compilation also on this ARCH. Signed-off-by: Christian Marangi --- drivers/usb/host/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index d011d6c753ed..9d8626f36ca6 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -71,7 +71,7 @@ config USB_XHCI_HISTB config USB_XHCI_MTK tristate "xHCI support for MediaTek SoCs" select MFD_SYSCON - depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || COMPILE_TEST + depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || ARCH_AIROHA || COMPILE_TEST help Say 'Y' to enable the support for the xHCI host controller found in MediaTek SoCs. From patchwork Thu Mar 20 13:00:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 14023967 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 423C6C28B30 for ; Thu, 20 Mar 2025 13:20:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=fOUBVYLGHBMQXDKHiUXsTpAiLBdcPtvf3nQSsKCrIXw=; b=U8EkbBvF/9kzXJ oYHUgiE7g5B+FwAkHoEsomYPtCaS7FsFXhvlKqaqv7/Kd5QVO5rYewA7PJC32sZKM7FRB3mX43NCj 68r8aGShLyaXBAHh3A0pNePgRef8esXtqLyg6K2WBQR/ZqI7+X9OsKruRdDxIpucv6TwsmElBdGy0 9cBXX/414GIr7/Cx6uWA0EaKv47VKTDjGgzlbkO0MiO2G4CJgWA2lSSmMoipgQJPeIuuXu45SYntH 5lWzx4EFXjgd139CY7NPtbzwtchrz99cyCf8RaGCe3tGLrGhBrVbTukvT2cfJ5ez8v0lFyhPxTHZc J7UiCCAw92AQlX1kTj5g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tvFpS-0000000CDKa-03c8; Thu, 20 Mar 2025 13:20:58 +0000 Received: from mail-wr1-x435.google.com ([2a00:1450:4864:20::435]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tvFWy-0000000CAiQ-2fEy; Thu, 20 Mar 2025 13:01:53 +0000 Received: by mail-wr1-x435.google.com with SMTP id ffacd0b85a97d-399744f74e9so458029f8f.1; Thu, 20 Mar 2025 06:01:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1742475711; x=1743080511; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=/2i/cLqH70rFIGQEh0as4tKq9BI5pDp8ooCRLadLuPs=; b=UNWPclpawWJ3w+F3KFoSRSOnOOJZSEMyl5eDTmcLUKZCil7X79wgDrv+BjL0WjPqa9 ykU5y811GsUY/ATdBWK0vnN6qcYlEc1EtSFag/fstwoBe4IN9ArLcCxrQEl7ziNTwVaG LMpjmQ8Yc7CXh5FWhgvJqDj33JH3BNo/ZdNGO1G9JPZnoTGZQj9pDede6wKUqwmkcB+k fYdT5H+qxXUE8aL74T5sURbEszmQTSbF+MnbD4VCECLODxINCVeKP5+Grs/ciAx2F3oX lo/2Z1GSfwpPUH4WCrbRYEdro4Gj8YJtgetzl7Wxl4NkVQdLlWtomQhBWuAjC+pg2Eru kEQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742475711; x=1743080511; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/2i/cLqH70rFIGQEh0as4tKq9BI5pDp8ooCRLadLuPs=; b=nfuI5WEU2ScUHuUBNCtGTcWkScxr4l87wBKFYUKpLtQUvpdOU2wU6B0A/YKReKDBqL FteE8uhpSBrr+26sVBXeAnLTAtTrcY8sQv5GRLnJ4NBQa9nffBOOmVDkdQ2XH0PJlnTg RXAOByA/3I+BbR0rmLq+xDZGyULlL3dzuTPY+Oe5Rh09LnHtYE6glPuGvSmsiy/WOhtn UCpoi16xPAUObw68HRLZn8K/h8OjZY4W1hGyf9TDCEMxviQNkAhvW4pv6YFpcjOervS+ 3hNbcAhKfufKimP4SldAXi3O0ZCgRh5gN0cg1mR1dEAEuq3U53UN1ou5dBPyNeMoed4L jrLA== X-Forwarded-Encrypted: i=1; AJvYcCUxcwdjIRGIb9TiQeg6VET3MQqnbMD89r2yyjVNVa2nI3DZ9UhEVl5Yx9rPETx5xPaw3eal3pLsvwa4I69s5Wh2@lists.infradead.org, AJvYcCWhEzRNpDPBZDpRkD8zqzJKU4tH3Qh5y3NfEIrj57CkjTiJjSIp69KmLK3vV5iTQxXjYBDyW7to/ev7@lists.infradead.org, AJvYcCXG9ndxBqfSXie13z2XWIwiry4kJjSfvGJy8sLy+QsQJ3eb9ujGpuxECTaWcnjaCJubmRGHh/5TdTpb/21iPGA=@lists.infradead.org X-Gm-Message-State: AOJu0YztAb9aMAl0Yx48Qg7oZQSNW+2iWY8Q25ZEw+IIEO76UXJ+cvK1 iuH6NwRBJORR15lEJKgSs6K+h+L6FcEuggNUFHPaYuZZNXS1AVOC X-Gm-Gg: ASbGnctTTgweoq+BmWAnQuhFrV+mwfpwu4HH7hKcFjfuRejz3b0yHQkA+/czbnwBw+P flokxZqNc632JmkbQnLXosfV8pKA7ETREWB8KxoZgjrxLAOPWy2Z42CJJZMf+Q5Pzyu4Pa/heqx /iUUwEJTqZlzYnmZsPwRaVwcVJe9wd5a7kHLzxF8UKy8O1BKX9j3cxKpLCW4ErlWGwk4J7aOJzG OLPdU8/gREygyQSODruZPQ6+gETGsvIwsls06UySiYFvoiSB7Tmf+WuxyCESa1NESnUcGI5QH2N aPAhWQa9ZRmopMZvslYOc5U2LgvtHoWn30iazjJPTrfJMkElGHBk1hdMsJLEn9c3ZHrxQQdJDBZ qlRsgtWqcVFiruA== X-Google-Smtp-Source: AGHT+IGPoVf9Gxeq+Z6YkgZOF9dLEtuHhARuJ5TNPwOSxmTqplkNjLTuQh6kUIXQk8Ui4saz4dpBhQ== X-Received: by 2002:a05:6000:1564:b0:391:4095:49b7 with SMTP id ffacd0b85a97d-399739c8f6dmr6626914f8f.25.1742475709979; Thu, 20 Mar 2025 06:01:49 -0700 (PDT) Received: from localhost.localdomain (93-34-90-129.ip49.fastwebnet.it. [93.34.90.129]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-397f2837e61sm18492328f8f.97.2025.03.20.06.01.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Mar 2025 06:01:49 -0700 (PDT) From: Christian Marangi To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Christian Marangi , Vinod Koul , Kishon Vijay Abraham I , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Greg Kroah-Hartman , Daniel Danzberger , Arnd Bergmann , Alexander Sverdlin , Nikita Shubin , Linus Walleij , Yangyu Chen , Ben Hutchings , Felix Fietkau , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-usb@vger.kernel.org, upstream@airoha.com Subject: [PATCH v2 11/11] arm64: dts: airoha: en7581: add USB nodes Date: Thu, 20 Mar 2025 14:00:34 +0100 Message-ID: <20250320130054.4804-12-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250320130054.4804-1-ansuelsmth@gmail.com> References: <20250320130054.4804-1-ansuelsmth@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250320_060152_673008_D2855AB0 X-CRM114-Status: GOOD ( 11.32 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Add USB nodes required for USB support of Airoha EN7581 with the correct define of Serdes Port and Monitor Clock for USB 2.0 calibration. Signed-off-by: Christian Marangi --- arch/arm64/boot/dts/airoha/en7581.dtsi | 49 ++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/arch/arm64/boot/dts/airoha/en7581.dtsi b/arch/arm64/boot/dts/airoha/en7581.dtsi index 26b136940917..d1cec63bb77f 100644 --- a/arch/arm64/boot/dts/airoha/en7581.dtsi +++ b/arch/arm64/boot/dts/airoha/en7581.dtsi @@ -3,7 +3,10 @@ #include #include #include +#include +#include #include +#include / { interrupt-parent = <&gic>; @@ -195,6 +198,52 @@ rng@1faa1000 { interrupts = ; }; + usb0: usb@1fab0000 { + compatible = "mediatek,mtk-xhci"; + reg = <0x0 0x1fab0000 0x0 0x3e00>, + <0x0 0x1fab3e00 0x0 0x100>; + reg-names = "mac", "ippc"; + interrupts = ; + + phys = <&usb0_phy PHY_TYPE_USB2>, <&usb0_phy PHY_TYPE_USB3>; + + status = "disabled"; + }; + + usb0_phy: phy@1fac0000 { + compatible = "airoha,an7581-usb-phy"; + reg = <0x0 0x1fac0000 0x0 0x10000>; + + airoha,scu = <&scuclk>; + airoha,usb2-monitor-clk-sel = ; + airoha,serdes-port = ; + + #phy-cells = <1>; + }; + + usb1: usb@1fad0000 { + compatible = "mediatek,mtk-xhci"; + reg = <0x0 0x1fad0000 0x0 0x3e00>, + <0x0 0x1fad3e00 0x0 0x100>; + reg-names = "mac", "ippc"; + interrupts = ; + + phys = <&usb1_phy PHY_TYPE_USB2>, <&usb1_phy PHY_TYPE_USB3>; + + status = "disabled"; + }; + + usb1_phy: phy@1fae0000 { + compatible = "airoha,an7581-usb-phy"; + reg = <0x0 0x1fae0000 0x0 0x10000>; + + airoha,scu = <&scuclk>; + airoha,usb2-monitor-clk-sel = ; + airoha,serdes-port = ; + + #phy-cells = <1>; + }; + system-controller@1fbf0200 { compatible = "airoha,en7581-gpio-sysctl", "syscon", "simple-mfd";