Skip to contentSkip to conversation

Add driver support for Eswin EIC7700 SoC SATA PHY

PATCH Superseded Yulin Lu 2 participants 6 messages Jan 6 – Jan 18

Subsystems (2)

v7 of 9 Superseded Latest is v9 →

lore
Share & tools
lore

Yulin Lu

author
#0 lore raw

v7 cover Add driver support for Eswin EIC7700 SoC SATA PHY

Updates:
v7 -> v6:
- phy-eic7700-sata.c
- Rename PHY_READY_TIMEOUT to PLL_LOCK_TIMEOUT_US with value 1000.
- Add macro PLL_LOCK_SLEEP_US set to 10.
- Add "goto disable_clk" in the eic7700_sata_phy_init function.
- Modify Copyright year from 2024 to 2026.
- Link to v6: https://lore.kernel.org/lkml/[email protected]/

v6 -> v5:
- eswin,eic7700-ahci.yaml
- Delete this file and it has already been applied in reply[1].
- eswin,eic7700-sata-phy.yaml
- Add clock and reset related properties.
- phy-eic7700-sata.c
- Map the io resource with platform_get_resource and devm_ioremap instead of devm_platform_ioremap_resource API. Because the address region of sata-phy falls into the region of hsp clock&reset which has been got by hsp clock&reset driver.
- Use regmap_read_poll_timeout in wait_for_phy_ready to replace the while loop check.
- Use devm_regmap_init_mmio and regmap_write to replace writel.
- Adapt to the clock and reset driver framework, replacing the original readl and writel. Because we are implementing the HSP layer clock and reset drivers, the corresponding clock and reset registers can be registered into the driver framework. And I have tested on the Sifive HiFive Premier P550 board.
- Link to v5: https://lore.kernel.org/lkml/[email protected]/

v5 -> v4:
- eswin,eic7700-ahci.yaml
- Add "dt-bindings: ata:" prefix to the subject.
- Wrap at 80 characters in the YAML description field.
- Link to v4: https://lore.kernel.org/lkml/[email protected]/

v4 -> v3:
- eswin,eic7700-ahci.yaml
- Fix grammatical errors in patch subject and commit message
- Add an explanation in the commit message of patch 1 for retaining the "ports-implemented" field, which Rob Herring suggested to remove
in the review comments on v2.
Link to Rob Herring's review:
https://lore.kernel.org/lkml/CAL_JsqKFotNLZZXwiy7S6K8qXLdGRAnsa-1zvZRDQBE39Gf5kg@mail.gmail.com/
Link to my question and Niklas Cassel's reply:
https://lore.kernel.org/lkml/[email protected]/
In this reply, Niklas Cassel mentioned his view:
If the ports-implemented register gets reset from ahci_platform_assert_rsts(), then it seems acceptable to
retain the ports-implemented property in the device tree.
This aligns with our design.
Link to my reply:
https://lore.kernel.org/lkml/[email protected]/
Link to Niklas Cassel's question and my further explanation:
https://lore.kernel.org/lkml/aLlYkZWBaI5Yz6fo@ryzen/
https://lore.kernel.org/lkml/[email protected]/
- eswin,eic7700-sata-phy.yaml
- Fix grammatical errors in patch subject and commit message
- Adjust the position of reg in the properties and required arrays
- Add reviewed-by tag of Krzysztof Kozlowski
- phy-eic7700-sata.c
- Correct the loop condition in wait_for_phy_ready() to use the current jiffies instead of the fixed start time
- Change the return value from -EFAULT to -ETIMEDOUT to correctly
indicate a timeout condition
- Remove redundant clock disable handling in probe error path, as SATA_SYS_CLK_EN is managed in phy_init() and phy_exit()
- Use dev_err_probe return in probe
- Reorder local variables to follow reverse Xmas tree order
- Wrap each line in the extended comments to 80 columns before splitting lines
- Adjust the position of #include <linux/io.h> for proper ordering
- Link to v3: https://lore.kernel.org/lkml/[email protected]/

v2 -> v3:
- Use full name in "From" and "Signed-off-by" fields information
- eswin,eic7700-ahci.yaml
- Remove the introduction to the reg, interrupts, phys, and phy-names fields
- Modify the usage of the clocks field in the examples
- Correct the order of dt properties
- phy-eic7700-sata.c
- Register operations use the GENMASK macro and FIELD_PREP instead of
the original bit offset method, and add "#include <linux/bitfield.h>"
- Modify some macro definition names.
- Remove the redundant initialization assignments for "ret" and "val"
- Delete ".suppress_bind_attrs = true"
- Modify the driver name
- Add "#include <linux/io.h>" to fix the robot test issue
- Link to v2: https://lore.kernel.org/lkml/[email protected]/

v2 -> v1:
- Delete the original controller driver and use ahci_dwc.c instead
- Add eswin,eic7700-ahci.yaml
- Correct the descriptions of reset, interrupt and other
hardware resources for the sata controller on EIC7700 SoC
- The clocks for both sata controller and sata PHY are controlled
via a register bit in the HSP bus and are not registered in the
clock tree. Clock are managed within the PHY driver, therefore
it is not described in this document
- Add $ref: snps,dwc-ahci-common.yaml#.
- Add eswin,eic7700-sata-phy.yaml
- Add this file to include the description of the PHY on EIC7700 SoC
- Add an eswin directory under the PHY driver path, and include the SATA
PHY driver code for EIC7700 SoC
- Link to v1: https://lore.kernel.org/all/[email protected]/

Yulin Lu (2):
dt-bindings: phy: eswin: Document the EIC7700 SoC SATA PHY
phy: eswin: Create eswin directory and add EIC7700 SATA PHY driver

 .../bindings/phy/eswin,eic7700-sata-phy.yaml  |  58 +++++
 drivers/phy/Kconfig                           |   1 +
 drivers/phy/Makefile                          |   1 +
 drivers/phy/eswin/Kconfig                     |  14 ++
 drivers/phy/eswin/Makefile                    |   2 +
 drivers/phy/eswin/phy-eic7700-sata.c          | 221 ++++++++++++++++++
 6 files changed, 297 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
 create mode 100644 drivers/phy/eswin/Kconfig
 create mode 100644 drivers/phy/eswin/Makefile
 create mode 100644 drivers/phy/eswin/phy-eic7700-sata.c
Signature · 1 line
2.25.1
author
#1 lore raw

PATCH v7 1/2 dt-bindings: phy: eswin: Document the EIC7700 SoC SATA PHY

Document the SATA PHY on the EIC7700 SoC platform, describing its usage.

---
 .../bindings/phy/eswin,eic7700-sata-phy.yaml  | 58 +++++++++++++++++++
 1 file changed, 58 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml new file +58 -0
new file mode 100644
index 000000000000..1b3f8e114ac7
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/eswin,eic7700-sata-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Eswin EIC7700 SoC SATA PHY
+
+maintainers:
+  - Yulin Lu <[email protected]>
+  - Huan He <[email protected]>
+
+properties:
+  compatible:
+    const: eswin,eic7700-sata-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: phy
+
+  resets:
+    maxItems: 2
+
+  reset-names:
+    items:
+      - const: port
+      - const: phy
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    sata-phy@50440300 {
+        compatible = "eswin,eic7700-sata-phy";
+        reg = <0x50440300 0x40>;
+        clocks = <&hspcrg 17>;
+        clock-names = "phy";
+        resets = <&hspcrg 0>, <&hspcrg 1>;
+        reset-names = "port", "phy";
+        #phy-cells = <0>;
+    };
Signature · 7 lines
2.25.1


-- 
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
author
#2 lore raw

PATCH v7 2/2 phy: eswin: Create eswin directory and add EIC7700 SATA PHY driver

In reply to Yulin Lu

Created the eswin phy driver directory and added support for the SATA phy driver on the EIC7700 SoC platform.

---
 drivers/phy/Kconfig                  |   1 +
 drivers/phy/Makefile                 |   1 +
 drivers/phy/eswin/Kconfig            |  14 ++
 drivers/phy/eswin/Makefile           |   2 +
 drivers/phy/eswin/phy-eic7700-sata.c | 221 +++++++++++++++++++++++++++
 5 files changed, 239 insertions(+)
 create mode 100644 drivers/phy/eswin/Kconfig
 create mode 100644 drivers/phy/eswin/Makefile
 create mode 100644 drivers/phy/eswin/phy-eic7700-sata.c
drivers/phy/Kconfig +1 -0
index 678dd0452f0a..6d50704917f0 100644
@@ -105,6 +105,7 @@ source "drivers/phy/allwinner/Kconfig"
 source "drivers/phy/amlogic/Kconfig"
 source "drivers/phy/broadcom/Kconfig"
 source "drivers/phy/cadence/Kconfig"
+source "drivers/phy/eswin/Kconfig"
 source "drivers/phy/freescale/Kconfig"
 source "drivers/phy/hisilicon/Kconfig"
 source "drivers/phy/ingenic/Kconfig"
drivers/phy/Makefile +1 -0
index bfb27fb5a494..482a143d3417 100644
@@ -17,6 +17,7 @@ obj-y					+= allwinner/	\
 					   amlogic/	\
 					   broadcom/	\
 					   cadence/	\
+					   eswin/	\
 					   freescale/	\
 					   hisilicon/	\
 					   ingenic/	\
drivers/phy/eswin/Kconfig new file +14 -0
new file mode 100644
index 000000000000..37447cc3af63
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Phy drivers for ESWIN platforms
+#
+config PHY_EIC7700_SATA
+	tristate "eic7700 Sata SerDes/PHY driver"
+	depends on ARCH_ESWIN || COMPILE_TEST
+	depends on HAS_IOMEM
+	select GENERIC_PHY
+	help
+	  Enable this to support SerDes/Phy found on ESWIN's
+	  EIC7700 SoC.This Phy supports SATA 1.5 Gb/s,
+	  SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds.
+	  It supports one SATA host port to accept one SATA device.
drivers/phy/eswin/Makefile new file +2 -0
new file mode 100644
index 000000000000..db08c66be812
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_PHY_EIC7700_SATA)	+= phy-eic7700-sata.o
drivers/phy/eswin/phy-eic7700-sata.c new file +221 -0

221 lines not on this page · raw message

Signature · 1 line
2.25.1
maintainer
#3 lore raw

Re: [PATCH v7 2/2] phy: eswin: Create eswin directory and add EIC7700 SATA PHY driver

Quoted 159 lines · Yulin Lu

Created the eswin phy driver directory and added support for the SATA phy driver on the EIC7700 SoC platform.

---
 drivers/phy/Kconfig                  |   1 +
 drivers/phy/Makefile                 |   1 +
 drivers/phy/eswin/Kconfig            |  14 ++
 drivers/phy/eswin/Makefile           |   2 +
 drivers/phy/eswin/phy-eic7700-sata.c | 221 +++++++++++++++++++++++++++
 5 files changed, 239 insertions(+)
 create mode 100644 drivers/phy/eswin/Kconfig
 create mode 100644 drivers/phy/eswin/Makefile
 create mode 100644 drivers/phy/eswin/phy-eic7700-sata.c
drivers/phy/Kconfig +1 -0
index 678dd0452f0a..6d50704917f0 100644
@@ -105,6 +105,7 @@ source "drivers/phy/allwinner/Kconfig"
 source "drivers/phy/amlogic/Kconfig"
 source "drivers/phy/broadcom/Kconfig"
 source "drivers/phy/cadence/Kconfig"
+source "drivers/phy/eswin/Kconfig"
 source "drivers/phy/freescale/Kconfig"
 source "drivers/phy/hisilicon/Kconfig"
 source "drivers/phy/ingenic/Kconfig"
drivers/phy/Makefile +1 -0
index bfb27fb5a494..482a143d3417 100644
@@ -17,6 +17,7 @@ obj-y					+= allwinner/	\
 					   amlogic/	\
 					   broadcom/	\
 					   cadence/	\
+					   eswin/	\
 					   freescale/	\
 					   hisilicon/	\
 					   ingenic/	\
drivers/phy/eswin/Kconfig new file +14 -0
new file mode 100644
index 000000000000..37447cc3af63
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Phy drivers for ESWIN platforms
+#
+config PHY_EIC7700_SATA
+	tristate "eic7700 Sata SerDes/PHY driver"
+	depends on ARCH_ESWIN || COMPILE_TEST
+	depends on HAS_IOMEM
+	select GENERIC_PHY
+	help
+	  Enable this to support SerDes/Phy found on ESWIN's
+	  EIC7700 SoC.This Phy supports SATA 1.5 Gb/s,
+	  SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds.
+	  It supports one SATA host port to accept one SATA device.
drivers/phy/eswin/Makefile new file +2 -0
new file mode 100644
index 000000000000..db08c66be812
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_PHY_EIC7700_SATA)	+= phy-eic7700-sata.o
drivers/phy/eswin/phy-eic7700-sata.c new file +86 -0
new file mode 100644
index 000000000000..96ae62a1b637
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ESWIN SATA PHY driver
+ *
+ * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd..
+ * All rights reserved.
+ *
+ * Authors: Yulin Lu <[email protected]>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#define SATA_AXI_LP_CTRL			0x08
+#define SATA_MPLL_CTRL				0x20
+#define SATA_P0_PHY_STAT			0x24
+#define SATA_PHY_CTRL0				0x28
+#define SATA_PHY_CTRL1				0x2c
+#define SATA_REF_CTRL				0x34
+#define SATA_REF_CTRL1				0x38
+#define SATA_LOS_IDEN				0x3c
+
+#define SATA_CLK_RST_SOURCE_PHY			BIT(0)
+#define SATA_P0_PHY_TX_AMPLITUDE_GEN1_MASK	GENMASK(6, 0)
+#define SATA_P0_PHY_TX_AMPLITUDE_GEN2_MASK	GENMASK(14, 8)
+#define SATA_P0_PHY_TX_AMPLITUDE_GEN3_MASK	GENMASK(22, 16)
+#define SATA_P0_PHY_TX_PREEMPH_GEN1_MASK	GENMASK(5, 0)
+#define SATA_P0_PHY_TX_PREEMPH_GEN2_MASK	GENMASK(13, 8)
+#define SATA_P0_PHY_TX_PREEMPH_GEN3_MASK	GENMASK(21, 16)
+#define SATA_LOS_LEVEL_MASK			GENMASK(4, 0)
+#define SATA_LOS_BIAS_MASK			GENMASK(18, 16)
+#define SATA_M_CSYSREQ				BIT(0)
+#define SATA_S_CSYSREQ				BIT(16)
+#define SATA_REF_REPEATCLK_EN			BIT(0)
+#define SATA_REF_USE_PAD			BIT(20)
+#define SATA_MPLL_MULTIPLIER_MASK		GENMASK(22, 16)
+#define SATA_P0_PHY_READY			BIT(0)
+
+#define PLL_LOCK_SLEEP_US			10
+#define PLL_LOCK_TIMEOUT_US			1000
+
+struct eic7700_sata_phy {
+	struct reset_control *rst;
+	struct regmap *regmap;
+	struct clk *clk;
+	struct phy *phy;
+};
+
+static const struct regmap_config eic7700_sata_phy_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = SATA_LOS_IDEN,
+};
+
+static int wait_for_phy_ready(struct regmap *regmap, u32 reg, u32 checkbit,
+			      u32 status)
+{
+	u32 val;
+	int ret;
+
+	ret = regmap_read_poll_timeout(regmap, reg, val,
+				       (val & checkbit) == status,
+				       PLL_LOCK_SLEEP_US, PLL_LOCK_TIMEOUT_US);
+
+	return ret;
+}
+
+static int eic7700_sata_phy_init(struct phy *phy)
+{
+	struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy);
+	u32 val;
+	int ret;
+
+	ret = clk_prepare_enable(sata_phy->clk);
+	if (ret)
+		return ret;
+

drivers/phy/eswin/phy-eic7700-sata.c line 96

Quoted 10 lines
drivers/phy/eswin/phy-eic7700-sata.c new file +10 -0
+	regmap_write(sata_phy->regmap, SATA_REF_CTRL1, SATA_CLK_RST_SOURCE_PHY);
+
+	val = FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN1_MASK, 0x42) |
+	      FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN2_MASK, 0x46) |
+	      FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN3_MASK, 0x73);
+	regmap_write(sata_phy->regmap, SATA_PHY_CTRL0, val);
+
+	val = FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN1_MASK, 0x5) |
+	      FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN2_MASK, 0x5) |
+	      FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN3_MASK, 0x8);

Where are the magic values you are writing coming from..?

Quoted 64 lines
drivers/phy/eswin/phy-eic7700-sata.c new file +64 -0
+	regmap_write(sata_phy->regmap, SATA_PHY_CTRL1, val);
+
+	val = FIELD_PREP(SATA_LOS_LEVEL_MASK, 0x9) |
+	      FIELD_PREP(SATA_LOS_BIAS_MASK, 0x2);
+	regmap_write(sata_phy->regmap, SATA_LOS_IDEN, val);
+
+	val = SATA_M_CSYSREQ | SATA_S_CSYSREQ;
+	regmap_write(sata_phy->regmap, SATA_AXI_LP_CTRL, val);
+
+	val = SATA_REF_REPEATCLK_EN | SATA_REF_USE_PAD;
+	regmap_write(sata_phy->regmap, SATA_REF_CTRL, val);
+
+	val = FIELD_PREP(SATA_MPLL_MULTIPLIER_MASK, 0x3c);
+	regmap_write(sata_phy->regmap, SATA_MPLL_CTRL, val);
+
+	usleep_range(15, 20);
+
+	ret = reset_control_deassert(sata_phy->rst);
+	if (ret)
+		goto disable_clk;
+
+	ret = wait_for_phy_ready(sata_phy->regmap, SATA_P0_PHY_STAT,
+				 SATA_P0_PHY_READY, 1);
+	if (ret < 0) {
+		dev_err(&sata_phy->phy->dev, "PHY READY check failed\n");
+		goto disable_clk;
+	}
+
+	return 0;
+
+disable_clk:
+	clk_disable_unprepare(sata_phy->clk);
+	return ret;
+}
+
+static int eic7700_sata_phy_exit(struct phy *phy)
+{
+	struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy);
+	int ret;
+
+	ret = reset_control_assert(sata_phy->rst);
+	if (ret)
+		return ret;
+
+	clk_disable_unprepare(sata_phy->clk);
+
+	return 0;
+}
+
+static const struct phy_ops eic7700_sata_phy_ops = {
+	.init		= eic7700_sata_phy_init,
+	.exit		= eic7700_sata_phy_exit,
+	.owner		= THIS_MODULE,
+};
+
+static int eic7700_sata_phy_probe(struct platform_device *pdev)
+{
+	struct eic7700_sata_phy *sata_phy;
+	struct phy_provider *phy_provider;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	void __iomem *regs;
+
+	sata_phy = devm_kzalloc(dev, sizeof(*sata_phy), GFP_KERNEL);

drivers/phy/eswin/phy-eic7700-sata.c line 170

Quoted 10 lines
drivers/phy/eswin/phy-eic7700-sata.c new file +10 -0
+	if (!sata_phy)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENOENT;
+
+	regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);

devm_platform_get_and_ioremap_resource() please

Signature · 1 line
~Vinod
author
#4 lore raw

Re: Re: [PATCH v7 2/2] phy: eswin: Create eswin directory and add EIC7700 SATA PHY driver

Quoted 14 lines
Quoted 14 lines
drivers/phy/eswin/phy-eic7700-sata.c new file +14 -0
+static int eic7700_sata_phy_init(struct phy *phy)
+{
+	struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy);
+	u32 val;
+	int ret;
+
+	ret = clk_prepare_enable(sata_phy->clk);
+	if (ret)
+		return ret;
+
+	regmap_write(sata_phy->regmap, SATA_REF_CTRL1, SATA_CLK_RST_SOURCE_PHY);
+
+	val = FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN1_MASK, 0x42) |
+	      FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN2_MASK, 0x46) |
Quoted 9 lines

drivers/phy/eswin/phy-eic7700-sata.c line 96

Quoted 6 lines
drivers/phy/eswin/phy-eic7700-sata.c new file +6 -0
+	      FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN3_MASK, 0x73);
+	regmap_write(sata_phy->regmap, SATA_PHY_CTRL0, val);
+
+	val = FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN1_MASK, 0x5) |
+	      FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN2_MASK, 0x5) |
+	      FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN3_MASK, 0x8);

Where are the magic values you are writing coming from..?

Hi Vinod,

These values set the TX preemphasis and amplitude parameters for the SATA PHY. The actual numbers come from eye‑diagram tuning results on different hardware development boards.
The current code reflects the settings for the Sifive HiFive Premier P550 board. In the next patch I plan to move these into the devicetree (DTS). Would that be acceptable?

Quoted 68 lines
Quoted 68 lines
drivers/phy/eswin/phy-eic7700-sata.c new file +68 -0
+	regmap_write(sata_phy->regmap, SATA_PHY_CTRL1, val);
+
+	val = FIELD_PREP(SATA_LOS_LEVEL_MASK, 0x9) |
+	      FIELD_PREP(SATA_LOS_BIAS_MASK, 0x2);
+	regmap_write(sata_phy->regmap, SATA_LOS_IDEN, val);
+
+	val = SATA_M_CSYSREQ | SATA_S_CSYSREQ;
+	regmap_write(sata_phy->regmap, SATA_AXI_LP_CTRL, val);
+
+	val = SATA_REF_REPEATCLK_EN | SATA_REF_USE_PAD;
+	regmap_write(sata_phy->regmap, SATA_REF_CTRL, val);
+
+	val = FIELD_PREP(SATA_MPLL_MULTIPLIER_MASK, 0x3c);
+	regmap_write(sata_phy->regmap, SATA_MPLL_CTRL, val);
+
+	usleep_range(15, 20);
+
+	ret = reset_control_deassert(sata_phy->rst);
+	if (ret)
+		goto disable_clk;
+
+	ret = wait_for_phy_ready(sata_phy->regmap, SATA_P0_PHY_STAT,
+				 SATA_P0_PHY_READY, 1);
+	if (ret < 0) {
+		dev_err(&sata_phy->phy->dev, "PHY READY check failed\n");
+		goto disable_clk;
+	}
+
+	return 0;
+
+disable_clk:
+	clk_disable_unprepare(sata_phy->clk);
+	return ret;
+}
+
+static int eic7700_sata_phy_exit(struct phy *phy)
+{
+	struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy);
+	int ret;
+
+	ret = reset_control_assert(sata_phy->rst);
+	if (ret)
+		return ret;
+
+	clk_disable_unprepare(sata_phy->clk);
+
+	return 0;
+}
+
+static const struct phy_ops eic7700_sata_phy_ops = {
+	.init		= eic7700_sata_phy_init,
+	.exit		= eic7700_sata_phy_exit,
+	.owner		= THIS_MODULE,
+};
+
+static int eic7700_sata_phy_probe(struct platform_device *pdev)
+{
+	struct eic7700_sata_phy *sata_phy;
+	struct phy_provider *phy_provider;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	void __iomem *regs;
+
+	sata_phy = devm_kzalloc(dev, sizeof(*sata_phy), GFP_KERNEL);
+	if (!sata_phy)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Quoted 9 lines

drivers/phy/eswin/phy-eic7700-sata.c line 170

Quoted 6 lines
drivers/phy/eswin/phy-eic7700-sata.c new file +6 -0
+	if (!res)
+		return -ENOENT;
+
+	regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);

devm_platform_get_and_ioremap_resource() please

As explained in my “v6 → v5” changes in the cover‑letter:
“Map the I/O resource with platform_get_resource and devm_ioremap instead of the devm_platform_ioremap_resource API,
because the address region of the SATA‑PHY falls into the region of the HSP clock & reset that has already been obtained by the HSP clock‑and‑reset driver.”
The HSP clock-and-reset driver uses devm_platform_get_and_ioremap_resource(), meaning this region has already been requested.
The HSP clock-and-reset driver is also currently being upstreamed.

Best regards,
Yulin Lu

Signature · 3 lines
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
maintainer
#5 lore raw

Re: Re: [PATCH v7 2/2] phy: eswin: Create eswin directory and add EIC7700 SATA PHY driver

Quoted 24 lines · Yulin Lu
Quoted 14 lines
Quoted 14 lines
drivers/phy/eswin/phy-eic7700-sata.c new file +14 -0
+static int eic7700_sata_phy_init(struct phy *phy)
+{
+	struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy);
+	u32 val;
+	int ret;
+
+	ret = clk_prepare_enable(sata_phy->clk);
+	if (ret)
+		return ret;
+
+	regmap_write(sata_phy->regmap, SATA_REF_CTRL1, SATA_CLK_RST_SOURCE_PHY);
+
+	val = FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN1_MASK, 0x42) |
+	      FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN2_MASK, 0x46) |
Quoted 9 lines

drivers/phy/eswin/phy-eic7700-sata.c line 96

Quoted 6 lines
drivers/phy/eswin/phy-eic7700-sata.c new file +6 -0
+	      FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN3_MASK, 0x73);
+	regmap_write(sata_phy->regmap, SATA_PHY_CTRL0, val);
+
+	val = FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN1_MASK, 0x5) |
+	      FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN2_MASK, 0x5) |
+	      FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN3_MASK, 0x8);

Where are the magic values you are writing coming from..?

Quoted 8 lines

Hi Vinod,

These values set the TX preemphasis and amplitude parameters for the SATA PHY. The actual numbers come from eye‑diagram tuning results on different hardware development boards.
The current code reflects the settings for the Sifive HiFive Premier P550 board. In the next patch I plan to move these into the devicetree (DTS). Would that be acceptable?

So this would change wrt each board the device is...? Maybe DT should be better choice. Please check with DT folks on the approach

Quoted 79 lines
Quoted 69 lines
Quoted 69 lines
drivers/phy/eswin/phy-eic7700-sata.c new file +68 -0
+	regmap_write(sata_phy->regmap, SATA_PHY_CTRL1, val);
+
+	val = FIELD_PREP(SATA_LOS_LEVEL_MASK, 0x9) |
+	      FIELD_PREP(SATA_LOS_BIAS_MASK, 0x2);
+	regmap_write(sata_phy->regmap, SATA_LOS_IDEN, val);
+
+	val = SATA_M_CSYSREQ | SATA_S_CSYSREQ;
+	regmap_write(sata_phy->regmap, SATA_AXI_LP_CTRL, val);
+
+	val = SATA_REF_REPEATCLK_EN | SATA_REF_USE_PAD;
+	regmap_write(sata_phy->regmap, SATA_REF_CTRL, val);
+
+	val = FIELD_PREP(SATA_MPLL_MULTIPLIER_MASK, 0x3c);
+	regmap_write(sata_phy->regmap, SATA_MPLL_CTRL, val);
+
+	usleep_range(15, 20);
+
+	ret = reset_control_deassert(sata_phy->rst);
+	if (ret)
+		goto disable_clk;
+
+	ret = wait_for_phy_ready(sata_phy->regmap, SATA_P0_PHY_STAT,
+				 SATA_P0_PHY_READY, 1);
+	if (ret < 0) {
+		dev_err(&sata_phy->phy->dev, "PHY READY check failed\n");
+		goto disable_clk;
+	}
+
+	return 0;
+
+disable_clk:
+	clk_disable_unprepare(sata_phy->clk);
+	return ret;
+}
+
+static int eic7700_sata_phy_exit(struct phy *phy)
+{
+	struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy);
+	int ret;
+
+	ret = reset_control_assert(sata_phy->rst);
+	if (ret)
+		return ret;
+
+	clk_disable_unprepare(sata_phy->clk);
+
+	return 0;
+}
+
+static const struct phy_ops eic7700_sata_phy_ops = {
+	.init		= eic7700_sata_phy_init,
+	.exit		= eic7700_sata_phy_exit,
+	.owner		= THIS_MODULE,
+};
+
+static int eic7700_sata_phy_probe(struct platform_device *pdev)
+{
+	struct eic7700_sata_phy *sata_phy;
+	struct phy_provider *phy_provider;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	void __iomem *regs;
+
+	sata_phy = devm_kzalloc(dev, sizeof(*sata_phy), GFP_KERNEL);
+	if (!sata_phy)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Quoted 9 lines

drivers/phy/eswin/phy-eic7700-sata.c line 170

Quoted 6 lines
drivers/phy/eswin/phy-eic7700-sata.c new file +6 -0
+	if (!res)
+		return -ENOENT;
+
+	regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);

devm_platform_get_and_ioremap_resource() please

Quoted 9 lines

As explained in my “v6 → v5” changes in the cover‑letter:
“Map the I/O resource with platform_get_resource and devm_ioremap instead of the devm_platform_ioremap_resource API,
because the address region of the SATA‑PHY falls into the region of the HSP clock & reset that has already been obtained by the HSP clock‑and‑reset driver.”
The HSP clock-and-reset driver uses devm_platform_get_and_ioremap_resource(), meaning this region has already been requested.
The HSP clock-and-reset driver is also currently being upstreamed.

Worth adding a comment here for that

Signature · 1 line
~Vinod