lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250926073921.1000866-5-sh86.bae@samsung.com>
Date: Fri, 26 Sep 2025 16:39:19 +0900
From: Sanghoon Bae <sh86.bae@...sung.com>
To: robh@...nel.org, krzk@...nel.org, conor+dt@...nel.org, vkoul@...nel.org,
	alim.akhtar@...sung.com, kishon@...nel.org, m.szyprowski@...sung.com,
	jh80.chung@...sung.com, shradha.t@...sung.com
Cc: krzk+dt@...nel.org, linux-kernel@...r.kernel.org,
	devicetree@...r.kernel.org, linux-samsung-soc@...r.kernel.org,
	linux-phy@...ts.infradead.org, linux-arm-kernel@...ts.infradead.org,
	sh86.bae@...sung.com
Subject: [PATCH 4/4] phy: exynos: Add PCIe PHY support for ExynosAutov920
 SoC

Add PCIe PHY support for ExynosAutov920 SoC

Signed-off-by: Sanghoon Bae <sh86.bae@...sung.com>
---
 drivers/phy/samsung/phy-exynos-pcie.c | 231 ++++++++++++++++++++++++++
 1 file changed, 231 insertions(+)

diff --git a/drivers/phy/samsung/phy-exynos-pcie.c b/drivers/phy/samsung/phy-exynos-pcie.c
index 5a55a22f9661..5b9d65f8f6c7 100644
--- a/drivers/phy/samsung/phy-exynos-pcie.c
+++ b/drivers/phy/samsung/phy-exynos-pcie.c
@@ -129,14 +129,87 @@
 #define FSD_PCIE_SYSREG_PHY_1_CMN_RSTN			BIT(1)
 #define FSD_PCIE_SYSREG_PHY_1_INIT_RSTN			BIT(3)
 
+/* Exynosautov920 register offsets and bits */
+/* EA920: PHY registers */
+#define EA920_PCIE_PHY0_COMMON_CTRL			0x1000
+#define EA920_PCIE_PHY_RTUNE_REQ			0x10000001
+#define EA920_PCIE_PHY0_GEN_CTRL_1			0x1010
+#define EA920_PCIE_PHY0_REFA_CLK_SEL_MASK		GENMASK(17, 16)
+#define EA920_PCIE_PHY0_REFB_CLK_SEL_MASK		GENMASK(19, 18)
+#define EA920_PCIE_PHY0_PHY0_SRAM_BYPASS		BIT(10)
+#define EA920_PCIE_PHY0_PHY0_SRAM_EXT_LD_DONE		BIT(11)
+#define EA920_PCIE_PHY0_REFA_B_ALT1			0x061a0060
+#define EA920_PCIE_PHY0_REFA_B_ALT0			0x06100060
+#define EA920_PCIE_PHY0_REFA_B_PAD			0x06150060
+#define EA920_PCIE_PHY0_SRAM_INIT_DONE			31
+#define EA920_PCIE_PHY_EXT_TX_ROPLL_POSTDIV_CTRL	0x11a8
+#define EA920_PCIE_PHY_ROPLL_POSTDIV_VAL		0x1249
+#define EA920_PCIE_PHY_EXT_TX_OVRD_EN_CTRL		0x11c4
+#define EA920_PCIE_PHY_ROPLL_POSTDIV_OVRD_EN_VAL	(0xf << 0)
+#define EA920_PCIE_PIPE_LANEX_LANEPLL_BYPASS		0x1384
+#define EA920_PCIE_PIPE_BYPASS_MODE_CTRL_VAL1		0x0
+#define EA920_PCIE_PIPE_BYPASS_MODE_CTRL_VAL2		0x0
+/* EA920: SOC CTRL registers */
+#define EA920_PCIE_REFCLK_CTRL_SOC_OPTION_0		0xa200
+#define EA920_PCIE_REFCLK_OPTION0_RC			0x103f5
+#define EA920_PCIE_REFCLK_CTRL_SOC_OPTION_1		0xa204
+#define EA920_PCIE_REFCLK_OPTION1_RC			0x30c00
+/* EA920: PMU registers */
+#define EA920_PCIE_PHY_4L_CONFIGURATION			0x700
+#define EA920_PCIE_PHY_2L_CONFIGURATION			0x704
+#define EA920_PCIE_PHY_CFG_EN_PHY			(0x1 << 0)
+/* EA920: GEN SYS registers */
+#define EA920_GENERAL_SS_RST_CTRL_1			0x48
+#define EA920_GENERAL_RST_PE0_SOFT_WARM_PHY_RESET	GENMASK(2, 1)
+#define EA920_GENERAL_RST_PE1_SOFT_COLD_RESET		(0x1 << 8)
+#define EA920_GENERAL_RST_PE1_SOFT_WARM_PHY_RESET	(0x3 << 9)
+#define EA920_GENERAL_RST_PE0_SOFT_WARM_RESET		(0x1 << 1)
+#define EA920_GENERAL_RST_PE1_SOFT_WARM_RESET		(0x1 << 9)
+#define EA920_GENERAL_RST_PE0_1_PHY_EN			0x808
+#define EA920_PHY_TIMEOUT				2000
+/* EA920: SYSREG registers */
+#define EA920_HSI0_PCIE_GEN5_PHY_PWRDWN_4L		0x670
+#define EA920_HSI0_PCIE_GEN5_PHY_PWRDWN_2L		0x4
+#define EA920_HSI0_PCIE_PHY_TEST_PWRDWN_MSK		BIT(0)
+#define EA920_HSI0_PCIE_PHY_TEST_PWRDUP			0x0
+#define EA920_HSI0_PCIE_PHY_TEST_PWRDWN			0x1
+#define EA920_HSI0_PCIE_GEN5_4LA_PHY_CTRL		0x828
+#define EA920_HSI0_PCIE_GEN5_2LA_PHY_CTRL		0x868
+#define EA920_HSI0_PCIE_IP_CTRL_DEV_TYPE_MSK		GENMASK(27, 24)
+#define EA920_HSI0_PCIE_IP_CTRL_DEV_TYPE_RC_A		0x4
+#define EA920_HSI0_PLL_REG0				0x600
+#define EA920_HSI0_PLL_FOUTEN_MSK			BIT(8)
+#define EA920_HSI0_PLL_FOUTEN				0x1
+#define EA920_HSI0_PLL_REG1				0x604
+#define EA920_HSI0_PLL_FOUTPOSTDIVEN_MSK		BIT(0)
+#define EA920_HSI0_PLL_FOUTPOSTDIVEN			0x1
+#define EA920_HSI0_PLL_REG2				0x608
+#define EA920_HSI0_PLL_PLLEN_MSK			BIT(24)
+#define EA920_HSI0_PLL_PLLEN				0x1
+#define EA920_HSI0_CLKBUF0_REG0				0x620
+#define EA920_HSI0_CLKBUF1_REG0				0x630
+#define EA920_HSI0_CLKBUF2_REG0				0x640
+#define EA920_HSI0_CLKBUF3_REG0				0x650
+#define EA920_HSI0_CLKBUF_IMP_CTRL_MSK			BIT(0)
+#define EA920_HSI0_CLKBUF_IMP_CTRL			0x1
+
 /* For Exynos pcie phy */
 struct exynos_pcie_phy {
 	void __iomem *base;
 	void __iomem *pcs_base;
 	struct regmap *pmureg;
 	struct regmap *fsysreg;
+	int num_lanes;
 };
 
+static u32 exynos_pcie_phy_readl(void __iomem *base, u32 offset)
+{
+	u32 data = 0;
+
+	data = readl(base + offset);
+	return data;
+}
+
 static void exynos_pcie_phy_writel(void __iomem *base, u32 val, u32 offset)
 {
 	writel(val, base + offset);
@@ -398,6 +471,152 @@ static int fsd_pcie_phy1_init(struct phy *phy)
 	return 0;
 }
 
+static int exynosautov920_pcie_phy_init(struct phy *phy)
+{
+	struct exynos_pcie_phy *ep = phy_get_drvdata(phy);
+	u32 val;
+	int timeout;
+
+	/* PHY on */
+	if (ep->num_lanes == 4) {
+		regmap_update_bits(ep->pmureg,
+				   EA920_PCIE_PHY_4L_CONFIGURATION,
+				   BIT(0), EA920_PCIE_PHY_CFG_EN_PHY);
+		regmap_update_bits(ep->fsysreg,
+				   EA920_HSI0_PCIE_GEN5_PHY_PWRDWN_4L,
+				   EA920_HSI0_PCIE_PHY_TEST_PWRDWN_MSK,
+				   EA920_HSI0_PCIE_PHY_TEST_PWRDUP);
+
+		/* SYSREG set to RC */
+		regmap_update_bits(ep->fsysreg,
+				   EA920_HSI0_PCIE_GEN5_4LA_PHY_CTRL,
+				   EA920_HSI0_PCIE_IP_CTRL_DEV_TYPE_MSK,
+				   EA920_HSI0_PCIE_IP_CTRL_DEV_TYPE_RC_A);
+	} else if (ep->num_lanes == 2) {
+		/* In 2L phy, 4L phy pmu should isolation off first */
+		regmap_update_bits(ep->pmureg,
+				   EA920_PCIE_PHY_4L_CONFIGURATION,
+				   BIT(0), EA920_PCIE_PHY_CFG_EN_PHY);
+		regmap_update_bits(ep->pmureg,
+				   EA920_PCIE_PHY_2L_CONFIGURATION,
+				   BIT(0), EA920_PCIE_PHY_CFG_EN_PHY);
+		regmap_update_bits(ep->fsysreg,
+				   EA920_HSI0_PCIE_GEN5_PHY_PWRDWN_2L,
+				   EA920_HSI0_PCIE_PHY_TEST_PWRDWN_MSK,
+				   EA920_HSI0_PCIE_PHY_TEST_PWRDUP);
+		/* SYSREG set to RC */
+		regmap_update_bits(ep->fsysreg,
+				   EA920_HSI0_PCIE_GEN5_2LA_PHY_CTRL,
+				   EA920_HSI0_PCIE_IP_CTRL_DEV_TYPE_MSK,
+				   EA920_HSI0_PCIE_IP_CTRL_DEV_TYPE_RC_A);
+	}
+
+	/* SOC control */
+	exynos_pcie_phy_writel(ep->pcs_base, EA920_PCIE_REFCLK_OPTION0_RC,
+			       EA920_PCIE_REFCLK_CTRL_SOC_OPTION_0);
+	exynos_pcie_phy_writel(ep->pcs_base, EA920_PCIE_REFCLK_OPTION1_RC,
+			       EA920_PCIE_REFCLK_CTRL_SOC_OPTION_1);
+
+	/* PLL setting */
+	regmap_update_bits(ep->fsysreg, EA920_HSI0_PLL_REG0,
+			   EA920_HSI0_PLL_FOUTEN_MSK, EA920_HSI0_PLL_FOUTEN);
+	regmap_update_bits(ep->fsysreg, EA920_HSI0_PLL_REG1,
+			   EA920_HSI0_PLL_FOUTPOSTDIVEN_MSK,
+			   EA920_HSI0_PLL_FOUTPOSTDIVEN);
+	regmap_update_bits(ep->fsysreg, EA920_HSI0_PLL_REG2,
+			   EA920_HSI0_PLL_PLLEN_MSK, EA920_HSI0_PLL_PLLEN);
+	regmap_update_bits(ep->fsysreg, EA920_HSI0_CLKBUF0_REG0,
+			   EA920_HSI0_CLKBUF_IMP_CTRL_MSK,
+			   EA920_HSI0_CLKBUF_IMP_CTRL);
+	regmap_update_bits(ep->fsysreg, EA920_HSI0_CLKBUF1_REG0,
+			   EA920_HSI0_CLKBUF_IMP_CTRL_MSK,
+			   EA920_HSI0_CLKBUF_IMP_CTRL);
+	regmap_update_bits(ep->fsysreg, EA920_HSI0_CLKBUF2_REG0,
+			   EA920_HSI0_CLKBUF_IMP_CTRL_MSK,
+			   EA920_HSI0_CLKBUF_IMP_CTRL);
+	regmap_update_bits(ep->fsysreg,	EA920_HSI0_CLKBUF3_REG0,
+			   EA920_HSI0_CLKBUF_IMP_CTRL_MSK,
+			   EA920_HSI0_CLKBUF_IMP_CTRL);
+
+	/* REFCLK setting */
+	val = exynos_pcie_phy_readl(ep->base, EA920_PCIE_PHY0_GEN_CTRL_1);
+	exynos_pcie_phy_writel(ep->base, val &
+			       ~EA920_PCIE_PHY0_REFA_CLK_SEL_MASK,
+			       EA920_PCIE_PHY0_GEN_CTRL_1);
+	exynos_pcie_phy_writel(ep->base,
+			       val & ~EA920_PCIE_PHY0_REFB_CLK_SEL_MASK,
+			       EA920_PCIE_PHY0_GEN_CTRL_1);
+	/* wait for REF CLK source change */
+	usleep_range(100, 110);
+	exynos_pcie_phy_writel(ep->base, EA920_PCIE_PHY_RTUNE_REQ,
+			       EA920_PCIE_PHY0_COMMON_CTRL);
+	exynos_pcie_phy_writel(ep->base, EA920_PCIE_PHY_ROPLL_POSTDIV_VAL,
+			       EA920_PCIE_PHY_EXT_TX_ROPLL_POSTDIV_CTRL);
+	exynos_pcie_phy_writel(ep->base,
+			       EA920_PCIE_PHY_ROPLL_POSTDIV_OVRD_EN_VAL,
+			       EA920_PCIE_PHY_EXT_TX_OVRD_EN_CTRL);
+	exynos_pcie_phy_writel(ep->base, EA920_PCIE_PIPE_BYPASS_MODE_CTRL_VAL1,
+			       EA920_PCIE_PIPE_LANEX_LANEPLL_BYPASS);
+	exynos_pcie_phy_writel(ep->base, EA920_PCIE_PIPE_BYPASS_MODE_CTRL_VAL2,
+			       EA920_PCIE_PIPE_LANEX_LANEPLL_BYPASS);
+	exynos_pcie_phy_writel(ep->base, EA920_PCIE_PHY0_REFA_B_ALT0,
+			       EA920_PCIE_PHY0_GEN_CTRL_1);
+
+	/* PHY warm reset */
+	val = exynos_pcie_phy_readl(ep->base, EA920_GENERAL_SS_RST_CTRL_1);
+	exynos_pcie_phy_writel(ep->base, val |
+			       EA920_GENERAL_RST_PE0_SOFT_WARM_PHY_RESET,
+			       EA920_GENERAL_SS_RST_CTRL_1);
+	usleep_range(10, 12);
+	exynos_pcie_phy_writel(ep->base, val &
+			       ~EA920_GENERAL_RST_PE0_SOFT_WARM_PHY_RESET,
+			       EA920_GENERAL_SS_RST_CTRL_1);
+
+	/* Set SRAM bypass */
+	val = exynos_pcie_phy_readl(ep->base, EA920_PCIE_PHY0_GEN_CTRL_1);
+	exynos_pcie_phy_writel(ep->base, val | EA920_PCIE_PHY0_PHY0_SRAM_BYPASS,
+			       EA920_PCIE_PHY0_GEN_CTRL_1);
+
+	/* Wait SRAM init */
+	timeout = 0;
+	do {
+		udelay(1);
+		timeout++;
+		if (timeout >= EA920_PHY_TIMEOUT)
+			return -ETIME;
+	} while (!(exynos_pcie_phy_readl(ep->base,
+					 EA920_PCIE_PHY0_GEN_CTRL_1) >>
+					 EA920_PCIE_PHY0_SRAM_INIT_DONE));
+
+	timeout = 0;
+	val = exynos_pcie_phy_readl(ep->base, EA920_PCIE_PHY0_GEN_CTRL_1);
+	exynos_pcie_phy_writel(ep->base, val |
+			       EA920_PCIE_PHY0_PHY0_SRAM_EXT_LD_DONE,
+			       EA920_PCIE_PHY0_GEN_CTRL_1);
+	/* wait for PHY init done */
+	mdelay(100);
+
+	return 0;
+}
+
+static int exynosautov920_pcie_phy_exit(struct phy *phy)
+{
+	struct exynos_pcie_phy *ep = phy_get_drvdata(phy);
+
+	if (ep->num_lanes == 4)
+		regmap_update_bits(ep->fsysreg,
+				   EA920_HSI0_PCIE_GEN5_PHY_PWRDWN_4L,
+				   EA920_HSI0_PCIE_PHY_TEST_PWRDWN_MSK,
+				   EA920_HSI0_PCIE_PHY_TEST_PWRDWN);
+	else if (ep->num_lanes == 2)
+		regmap_update_bits(ep->fsysreg,
+				   EA920_HSI0_PCIE_GEN5_PHY_PWRDWN_2L,
+				   EA920_HSI0_PCIE_PHY_TEST_PWRDWN_MSK,
+				   EA920_HSI0_PCIE_PHY_TEST_PWRDWN);
+
+	return 0;
+}
+
 static const struct phy_ops fsd_phy0_ops = {
 	.init		= fsd_pcie_phy0_init,
 	.reset		= fsd_pcie_phy0_reset,
@@ -410,6 +629,12 @@ static const struct phy_ops fsd_phy1_ops = {
 	.owner		= THIS_MODULE,
 };
 
+static const struct phy_ops exynosautov920_phy_ops = {
+	.init		= exynosautov920_pcie_phy_init,
+	.exit		= exynosautov920_pcie_phy_exit,
+	.owner		= THIS_MODULE,
+};
+
 static const struct of_device_id exynos_pcie_phy_match[] = {
 	{
 		.compatible = "samsung,exynos5433-pcie-phy",
@@ -423,6 +648,10 @@ static const struct of_device_id exynos_pcie_phy_match[] = {
 		.compatible = "tesla,fsd-pcie-phy1",
 		.data = &fsd_phy1_ops,
 	},
+	{
+		.compatible = "samsung,exynosautov920-pcie-phy",
+		.data = &exynosautov920_phy_ops,
+	},
 	{},
 };
 
@@ -468,6 +697,8 @@ static int exynos_pcie_phy_probe(struct platform_device *pdev)
 
 	exynos_phy->pcs_base = devm_platform_ioremap_resource(pdev, 1);
 
+	of_property_read_u32(dev->of_node, "num-lanes", &exynos_phy->num_lanes);
+
 	phy_set_drvdata(generic_phy, exynos_phy);
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
 
-- 
2.45.2


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ