Linux-PHY Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/9] arm64: dts: renesas: r8a77951: Describe PCIe root ports
From: Marek Vasut @ 2026-01-18 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Marek Vasut, Conor Dooley, Geert Uytterhoeven,
	Krzysztof Kozlowski, Magnus Damm, Neil Armstrong, Rob Herring,
	Vinod Koul, Yoshihiro Shimoda, devicetree, linux-phy,
	linux-renesas-soc
In-Reply-To: <20260118135038.8033-1-marek.vasut+renesas@mailbox.org>

Add nodes which describe the root ports in the PCIe controller DT nodes.
This can be used together with the pwrctrl driver to control clock and
power supply to a PCIe slot.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Cc: devicetree@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-renesas-soc@vger.kernel.org
---
V2: No change
---
 arch/arm64/boot/dts/renesas/r8a77951.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77951.dtsi b/arch/arm64/boot/dts/renesas/r8a77951.dtsi
index 477cf37ab2434..fa702f87de6d0 100644
--- a/arch/arm64/boot/dts/renesas/r8a77951.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77951.dtsi
@@ -2826,6 +2826,16 @@ pciec0: pcie@fe000000 {
 			iommu-map = <0 &ipmmu_hc 0 1>;
 			iommu-map-mask = <0>;
 			status = "disabled";
+
+			/* PCIe bridge, Root Port */
+			pciec0_rp: pci@0,0 {
+				#address-cells = <3>;
+				#size-cells = <2>;
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				compatible = "pciclass,0604";
+				device_type = "pci";
+				ranges;
+			};
 		};
 
 		pciec1: pcie@ee800000 {
@@ -2855,6 +2865,16 @@ pciec1: pcie@ee800000 {
 			iommu-map = <0 &ipmmu_hc 1 1>;
 			iommu-map-mask = <0>;
 			status = "disabled";
+
+			/* PCIe bridge, Root Port */
+			pciec1_rp: pci@0,0 {
+				#address-cells = <3>;
+				#size-cells = <2>;
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				compatible = "pciclass,0604";
+				device_type = "pci";
+				ranges;
+			};
 		};
 
 		pciec0_ep: pcie-ep@fe000000 {
-- 
2.51.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* Re: Re: [PATCH v7 2/2] phy: eswin: Create eswin directory and add EIC7700 SATA PHY driver
From: Vinod Koul @ 2026-01-18 13:36 UTC (permalink / raw)
  To: Yulin Lu
  Cc: neil.armstrong, robh, krzk+dt, conor+dt, p.zabel, linux-phy,
	devicetree, linux-kernel, ningyu, zhengyu, linmin, huangyifeng,
	fenglin, lianghujun
In-Reply-To: <133c22d5.2674.19bc5ff735f.Coremail.luyulin@eswincomputing.com>

On 16-01-26, 16:50, Yulin Lu wrote:
> > > +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) |
> > > +	      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?

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

> 
> > > +	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);
> > > +	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.

Worth adding a comment here for that

-- 
~Vinod

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH v5 2/7] mux: Add helper functions for getting optional and selected mux-state
From: kernel test robot @ 2026-01-18 13:28 UTC (permalink / raw)
  To: Josua Mayer, Marc Kleine-Budde, Vincent Mailhol, Vinod Koul,
	Neil Armstrong, Peter Rosin, Aaro Koskinen, Andreas Kemnade,
	Kevin Hilman, Roger Quadros, Tony Lindgren, Janusz Krzysztofik,
	Vignesh R, Andi Shyti, Ulf Hansson, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
	Magnus Damm, Wolfram Sang
  Cc: oe-kbuild-all, Yazan Shhady, Jon Nettleton, Mikhail Anikin,
	linux-can, linux-phy, linux-kernel, linux-omap, linux-i2c,
	linux-mmc, devicetree
In-Reply-To: <20260118-rz-sdio-mux-v5-2-3c37e8872683@solid-run.com>

Hi Josua,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 8f0b4cce4481fb22653697cced8d0d04027cb1e8]

url:    https://github.com/intel-lab-lkp/linux/commits/Josua-Mayer/phy-can-transceiver-rename-temporary-helper-function-to-avoid-conflict/20260118-183905
base:   8f0b4cce4481fb22653697cced8d0d04027cb1e8
patch link:    https://lore.kernel.org/r/20260118-rz-sdio-mux-v5-2-3c37e8872683%40solid-run.com
patch subject: [PATCH v5 2/7] mux: Add helper functions for getting optional and selected mux-state
config: um-randconfig-r071-20260118 (https://download.01.org/0day-ci/archive/20260118/202601182117.l2nFZ5OB-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 9b8addffa70cee5b2acc5454712d9cf78ce45710)
smatch version: v0.5.0-8985-g2614ff1a
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260118/202601182117.l2nFZ5OB-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601182117.l2nFZ5OB-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/mux/core.c:774:6: warning: variable 'ret' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
     774 |         if (IS_ERR_OR_NULL(mstate))
         |             ^~~~~~~~~~~~~~~~~~~~~~
   drivers/mux/core.c:793:17: note: uninitialized use occurs here
     793 |         return ERR_PTR(ret);
         |                        ^~~
   drivers/mux/core.c:774:2: note: remove the 'if' if its condition is always false
     774 |         if (IS_ERR_OR_NULL(mstate))
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
     775 |                 goto err_mux_state_get;
         |                 ~~~~~~~~~~~~~~~~~~~~~~
   drivers/mux/core.c:767:9: note: initialize the variable 'ret' to silence this warning
     767 |         int ret;
         |                ^
         |                 = 0
   1 warning generated.


vim +774 drivers/mux/core.c

   748	
   749	/**
   750	 * __devm_mux_state_get() - Get the optional mux-state for a device,
   751	 *			    with resource management.
   752	 * @dev: The device that needs a mux-state.
   753	 * @mux_name: The name identifying the mux-state.
   754	 * @optional: Whether to return NULL and silence errors when mux doesn't exist.
   755	 * @init: Optional function pointer for mux-state object initialisation.
   756	 * @exit: Optional function pointer for mux-state object cleanup on release.
   757	 *
   758	 * Return: Pointer to the mux-state, or an ERR_PTR with a negative errno.
   759	 */
   760	static struct mux_state *__devm_mux_state_get(struct device *dev, const char *mux_name,
   761						      bool optional,
   762						      int (*init)(struct mux_state *mstate),
   763						      int (*exit)(struct mux_state *mstate))
   764	{
   765		struct devm_mux_state_state *devm_state;
   766		struct mux_state *mstate;
   767		int ret;
   768	
   769		devm_state = devres_alloc(devm_mux_state_release, sizeof(*devm_state), GFP_KERNEL);
   770		if (!devm_state)
   771			return ERR_PTR(-ENOMEM);
   772	
   773		mstate = mux_state_get(dev, mux_name, optional);
 > 774		if (IS_ERR_OR_NULL(mstate))
   775			goto err_mux_state_get;
   776	
   777		if (init) {
   778			ret = init(mstate);
   779			if (ret)
   780				goto err_mux_state_init;
   781		}
   782	
   783		devm_state->mstate = mstate;
   784		devm_state->exit = exit;
   785		devres_add(dev, devm_state);
   786	
   787		return mstate;
   788	
   789	err_mux_state_init:
   790		mux_state_put(mstate);
   791	err_mux_state_get:
   792		devres_free(devm_state);
   793		return ERR_PTR(ret);
   794	}
   795	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* [PATCH v5 7/7] mmc: host: renesas_sdhi_core: support selecting an optional mux
From: Josua Mayer @ 2026-01-18 10:29 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer
In-Reply-To: <20260118-rz-sdio-mux-v5-0-3c37e8872683@solid-run.com>

Some hardware designs route data or control signals through a mux to
support multiple devices on a single sdhi controller.

In particular SolidRun RZ/G2L/G2LC/V2L System on Module use a mux for
switching between soldered eMMC and an optional microSD on a carrier
board, e.g. for development or provisioning.

SD/SDIO/eMMC are not well suited for runtime switching between different
cards, however boot-time selection is possible and useful - in
particular considering dt overlays.

Add support for an optional SD/SDIO/eMMC mux defined in dt, and select
it during probe.

Similar functionality already exists in other places, e.g. i2c-omap.

Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/mmc/host/renesas_sdhi_core.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index 2a310a145785..f9ec78d699f4 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -26,6 +26,7 @@
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/slot-gpio.h>
 #include <linux/module.h>
+#include <linux/mux/consumer.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/pinctrl-state.h>
 #include <linux/platform_data/tmio.h>
@@ -1062,6 +1063,7 @@ int renesas_sdhi_probe(struct platform_device *pdev,
 	struct regulator_dev *rdev;
 	struct renesas_sdhi_dma *dma_priv;
 	struct device *dev = &pdev->dev;
+	struct mux_state *mux_state;
 	struct tmio_mmc_host *host;
 	struct renesas_sdhi *priv;
 	int num_irqs, irq, ret, i;
@@ -1116,6 +1118,10 @@ int renesas_sdhi_probe(struct platform_device *pdev,
 						"state_uhs");
 	}
 
+	mux_state = devm_mux_state_get_optional_selected(&pdev->dev, NULL);
+	if (IS_ERR(mux_state))
+		return PTR_ERR(mux_state);
+
 	host = tmio_mmc_host_alloc(pdev, mmc_data);
 	if (IS_ERR(host))
 		return PTR_ERR(host);

-- 
2.43.0



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH v5 6/7] dt-bindings: mmc: renesas,sdhi: Add mux-states property
From: Josua Mayer @ 2026-01-18 10:29 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer
In-Reply-To: <20260118-rz-sdio-mux-v5-0-3c37e8872683@solid-run.com>

Add mux controller support for data or control lines that are muxed
between a host and multiple cards.

There are several devices supporting a choice of eMMC or SD on a single
board by both dip switch and gpio, e.g. Renesas RZ/G2L SMARC SoM and
SolidRun RZ/G2L SoM.

In-tree dts for the Renesas boards currently rely on preprocessor macros
and gpio hogs to describe the respective cards.

By adding mux-states property to sdhi controller description, boards can
correctly describe the mux that already exists in hardware - and drivers
can coordinate between mux selection and probing for cards.

Acked-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
index c754ea71f51f..64fac0d11329 100644
--- a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
+++ b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
@@ -106,6 +106,11 @@ properties:
   iommus:
     maxItems: 1
 
+  mux-states:
+    description:
+      mux controller node to route the SD/SDIO/eMMC signals from SoC to cards.
+    maxItems: 1
+
   power-domains:
     maxItems: 1
 
@@ -275,6 +280,7 @@ examples:
         max-frequency = <195000000>;
         power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
         resets = <&cpg 314>;
+        mux-states = <&mux 0>;
     };
 
     sdhi1: mmc@ee120000 {

-- 
2.43.0



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH v5 5/7] i2c: omap: switch to new generic helper for getting selected mux-state
From: Josua Mayer @ 2026-01-18 10:29 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer
In-Reply-To: <20260118-rz-sdio-mux-v5-0-3c37e8872683@solid-run.com>

Multiplexer subsystem has added generic helper functions for getting an
already selected mux-state object.

Replace existing logic in probe with the equivalent helper function.

There is a functional difference in that the mux is now automatically
deselected on release, replacing the explicit mux_state_deselect call.

This change is only compile-tested.

Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/i2c/busses/i2c-omap.c | 24 +++++-------------------
 1 file changed, 5 insertions(+), 19 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index d9f590f0c384..f02d294db42a 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1453,27 +1453,16 @@ omap_i2c_probe(struct platform_device *pdev)
 				       (1000 * omap->speed / 8);
 	}
 
-	if (of_property_present(node, "mux-states")) {
-		struct mux_state *mux_state;
-
-		mux_state = devm_mux_state_get(&pdev->dev, NULL);
-		if (IS_ERR(mux_state)) {
-			r = PTR_ERR(mux_state);
-			dev_dbg(&pdev->dev, "failed to get I2C mux: %d\n", r);
-			goto err_put_pm;
-		}
-		omap->mux_state = mux_state;
-		r = mux_state_select(omap->mux_state);
-		if (r) {
-			dev_err(&pdev->dev, "failed to select I2C mux: %d\n", r);
-			goto err_put_pm;
-		}
+	omap->mux_state = devm_mux_state_get_optional_selected(&pdev->dev, NULL);
+	if (IS_ERR(omap->mux_state)) {
+		r = PTR_ERR(omap->mux_state);
+		goto err_put_pm;
 	}
 
 	/* reset ASAP, clearing any IRQs */
 	r = omap_i2c_init(omap);
 	if (r)
-		goto err_mux_state_deselect;
+		goto err_put_pm;
 
 	if (omap->rev < OMAP_I2C_OMAP1_REV_2)
 		r = devm_request_irq(&pdev->dev, omap->irq, omap_i2c_omap1_isr,
@@ -1515,9 +1504,6 @@ omap_i2c_probe(struct platform_device *pdev)
 
 err_unuse_clocks:
 	omap_i2c_write_reg(omap, OMAP_I2C_CON_REG, 0);
-err_mux_state_deselect:
-	if (omap->mux_state)
-		mux_state_deselect(omap->mux_state);
 err_put_pm:
 	pm_runtime_put_sync(omap->dev);
 err_disable_pm:

-- 
2.43.0



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH v5 4/7] phy: can-transceiver: drop temporary helper getting optional mux-state
From: Josua Mayer @ 2026-01-18 10:29 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer
In-Reply-To: <20260118-rz-sdio-mux-v5-0-3c37e8872683@solid-run.com>

Multiplexer subsystem has now added helpers for getting managed optional
mux-state.

Switch to the new devm_mux_state_get_optional helper.

This change is only compile-tested.

Acked-by: Vinod Koul <vkoul@kernel.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/phy/phy-can-transceiver.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index 81591d247128..2b52e47f247a 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -126,16 +126,6 @@ static const struct of_device_id can_transceiver_phy_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, can_transceiver_phy_ids);
 
-/* Temporary wrapper until the multiplexer subsystem supports optional muxes */
-static inline struct mux_state *
-temp_devm_mux_state_get_optional(struct device *dev, const char *mux_name)
-{
-	if (!of_property_present(dev->of_node, "mux-states"))
-		return NULL;
-
-	return devm_mux_state_get(dev, mux_name);
-}
-
 static struct phy *can_transceiver_phy_xlate(struct device *dev,
 					     const struct of_phandle_args *args)
 {
@@ -183,7 +173,7 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 	priv->num_ch = num_ch;
 	platform_set_drvdata(pdev, priv);
 
-	mux_state = temp_devm_mux_state_get_optional(dev, NULL);
+	mux_state = devm_mux_state_get_optional(dev, NULL);
 	if (IS_ERR(mux_state))
 		return PTR_ERR(mux_state);
 

-- 
2.43.0



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH v5 3/7] mux: add help text for MULTIPLEXER config option
From: Josua Mayer @ 2026-01-18 10:28 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer
In-Reply-To: <20260118-rz-sdio-mux-v5-0-3c37e8872683@solid-run.com>

Add help text for CONFIG_MULTIPLEXER to allow enabling this option
through the kernel configuration without explicit "select" driver
dependencies.

Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/mux/Kconfig | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig
index c68132e38138..b2e1abc7c910 100644
--- a/drivers/mux/Kconfig
+++ b/drivers/mux/Kconfig
@@ -5,6 +5,14 @@
 
 config MULTIPLEXER
 	tristate
+	help
+	  Generic Multiplexer Support.
+
+	  This framework is designed to abstract multiplexer handling for
+	  devices via various GPIO-, MMIO/Regmap or specific multiplexer
+	  controller chips.
+
+	  If unsure, say no.
 
 menu "Multiplexer drivers"
 	depends on MULTIPLEXER

-- 
2.43.0



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH v5 2/7] mux: Add helper functions for getting optional and selected mux-state
From: Josua Mayer @ 2026-01-18 10:28 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer
In-Reply-To: <20260118-rz-sdio-mux-v5-0-3c37e8872683@solid-run.com>

In-tree phy-can-transceiver driver has already implemented a local
version of devm_mux_state_get_optional.

The omap-i2c driver gets and selects an optional mux in its probe
function without using any helper.

Add new helper functions covering both aforementioned use-cases:

- mux_control_get_optional:
  Get a mux-control if specified in dt, return NULL otherwise.
- devm_mux_state_get_optional:
  Get a mux-state if specified in dt, return NULL otherwise.
- devm_mux_state_get_selected:
  Get and select a mux-state specified in dt, return error otherwise.
- devm_mux_state_get_optional_selected:
  Get and select a mux-state if specified in dt, return error or NULL.

Existing mux_get helper function is changed to take an extra argument
indicating whether the mux is optional.
In this case no error is printed, and NULL returned in case of ENOENT.

Calling code is adapted to handle NULL return case, and to pass optional
argument as required.

To support automatic deselect for _selected helper, a new structure is
created storing an exit pointer similar to clock core which is called on
release.

To facilitate code sharing between optional/mandatory/selected helpers,
a new internal helper function is added to handle quiet (optional) and
verbose (mandatory) errors, as well as storing the correct callback for
devm release: __devm_mux_state_get

Due to this structure devm_mux_state_get_*_selected can no longer print
a useful error message when select fails. Instead callers should print
errors where needed.

Commit e153fdea9db04 ("phy: can-transceiver: Re-instate "mux-states"
property presence check") noted that "mux_get() always prints an error
message in case of an error, including when the property is not present,
confusing the user."

The first error message covers the case that a mux name is not matched
in dt. The second error message is based on of_parse_phandle_with_args
return value.

In optional case no error is printed and NULL is returned.
This ensures that the new helper functions will not confuse the user
either.

With the addition of optional helper functions it became clear that
drivers should compile and link even if CONFIG_MULTIPLEXER was not enabled.
Add stubs for all symbols exported by mux core.

Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/mux/core.c           | 175 ++++++++++++++++++++++++++++++++++++-------
 include/linux/mux/consumer.h | 111 ++++++++++++++++++++++++++-
 2 files changed, 253 insertions(+), 33 deletions(-)

diff --git a/drivers/mux/core.c b/drivers/mux/core.c
index a3840fe0995f..df30f96ec076 100644
--- a/drivers/mux/core.c
+++ b/drivers/mux/core.c
@@ -46,6 +46,16 @@ static const struct class mux_class = {
 	.name = "mux",
 };
 
+/*
+ * struct devm_mux_state_state - 	Tracks managed resources for mux-state objects.
+ * @mux:				Pointer to a mux state.
+ * @exit:				An optional callback to execte before free.
+ */
+struct devm_mux_state_state {
+	struct mux_state *mstate;
+	int (*exit)(struct mux_state *mstate);
+};
+
 static DEFINE_IDA(mux_ida);
 
 static int __init mux_init(void)
@@ -522,11 +532,12 @@ static struct mux_chip *of_find_mux_chip_by_node(struct device_node *np)
  * @mux_name: The name identifying the mux-control.
  * @state: Pointer to where the requested state is returned, or NULL when
  *         the required multiplexer states are handled by other means.
+ * @optional: Whether to return NULL and silence errors when mux doesn't exist.
  *
  * Return: A pointer to the mux-control, or an ERR_PTR with a negative errno.
  */
 static struct mux_control *mux_get(struct device *dev, const char *mux_name,
-				   unsigned int *state)
+				   unsigned int *state, bool optional)
 {
 	struct device_node *np = dev->of_node;
 	struct of_phandle_args args;
@@ -542,7 +553,9 @@ static struct mux_control *mux_get(struct device *dev, const char *mux_name,
 		else
 			index = of_property_match_string(np, "mux-control-names",
 							 mux_name);
-		if (index < 0) {
+		if (index < 0 && optional) {
+			return NULL;
+		} else if (index < 0) {
 			dev_err(dev, "mux controller '%s' not found\n",
 				mux_name);
 			return ERR_PTR(index);
@@ -558,8 +571,12 @@ static struct mux_control *mux_get(struct device *dev, const char *mux_name,
 						 "mux-controls", "#mux-control-cells",
 						 index, &args);
 	if (ret) {
+		if (optional && ret == -ENOENT)
+			return NULL;
+
 		dev_err(dev, "%pOF: failed to get mux-%s %s(%i)\n",
-			np, state ? "state" : "control", mux_name ?: "", index);
+			np, state ? "state" : "control",
+			mux_name ?: "", index);
 		return ERR_PTR(ret);
 	}
 
@@ -617,10 +634,23 @@ static struct mux_control *mux_get(struct device *dev, const char *mux_name,
  */
 struct mux_control *mux_control_get(struct device *dev, const char *mux_name)
 {
-	return mux_get(dev, mux_name, NULL);
+	return mux_get(dev, mux_name, NULL, false);
 }
 EXPORT_SYMBOL_GPL(mux_control_get);
 
+/**
+ * mux_control_get_optional() - Get the optional mux-control for a device.
+ * @dev: The device that needs a mux-control.
+ * @mux_name: The name identifying the mux-control.
+ *
+ * Return: A pointer to the mux-control, an ERR_PTR with a negative errno.
+ */
+struct mux_control *mux_control_get_optional(struct device *dev, const char *mux_name)
+{
+	return mux_get(dev, mux_name, NULL, true);
+}
+EXPORT_SYMBOL_GPL(mux_control_get_optional);
+
 /**
  * mux_control_put() - Put away the mux-control for good.
  * @mux: The mux-control to put away.
@@ -657,8 +687,8 @@ struct mux_control *devm_mux_control_get(struct device *dev,
 	if (!ptr)
 		return ERR_PTR(-ENOMEM);
 
-	mux = mux_control_get(dev, mux_name);
-	if (IS_ERR(mux)) {
+	mux = mux_get(dev, mux_name, NULL, false);
+	if (IS_ERR_OR_NULL(mux)) {
 		devres_free(ptr);
 		return mux;
 	}
@@ -677,7 +707,7 @@ EXPORT_SYMBOL_GPL(devm_mux_control_get);
  *
  * Return: A pointer to the mux-state, or an ERR_PTR with a negative errno.
  */
-static struct mux_state *mux_state_get(struct device *dev, const char *mux_name)
+static struct mux_state *mux_state_get(struct device *dev, const char *mux_name, bool optional)
 {
 	struct mux_state *mstate;
 
@@ -685,12 +715,10 @@ static struct mux_state *mux_state_get(struct device *dev, const char *mux_name)
 	if (!mstate)
 		return ERR_PTR(-ENOMEM);
 
-	mstate->mux = mux_get(dev, mux_name, &mstate->state);
-	if (IS_ERR(mstate->mux)) {
-		int err = PTR_ERR(mstate->mux);
-
+	mstate->mux = mux_get(dev, mux_name, &mstate->state, optional);
+	if (IS_ERR_OR_NULL(mstate->mux)) {
 		kfree(mstate);
-		return ERR_PTR(err);
+		return ERR_CAST(mstate->mux);
 	}
 
 	return mstate;
@@ -710,41 +738,130 @@ static void mux_state_put(struct mux_state *mstate)
 
 static void devm_mux_state_release(struct device *dev, void *res)
 {
-	struct mux_state *mstate = *(struct mux_state **)res;
+	struct devm_mux_state_state *devm_state = res;
 
-	mux_state_put(mstate);
+	if (devm_state->exit)
+		devm_state->exit(devm_state->mstate);
+
+	mux_state_put(devm_state->mstate);
 }
 
 /**
- * devm_mux_state_get() - Get the mux-state for a device, with resource
- *			  management.
- * @dev: The device that needs a mux-control.
- * @mux_name: The name identifying the mux-control.
+ * __devm_mux_state_get() - Get the optional mux-state for a device,
+ *			    with resource management.
+ * @dev: The device that needs a mux-state.
+ * @mux_name: The name identifying the mux-state.
+ * @optional: Whether to return NULL and silence errors when mux doesn't exist.
+ * @init: Optional function pointer for mux-state object initialisation.
+ * @exit: Optional function pointer for mux-state object cleanup on release.
  *
  * Return: Pointer to the mux-state, or an ERR_PTR with a negative errno.
  */
-struct mux_state *devm_mux_state_get(struct device *dev,
-				     const char *mux_name)
+static struct mux_state *__devm_mux_state_get(struct device *dev, const char *mux_name,
+					      bool optional,
+					      int (*init)(struct mux_state *mstate),
+					      int (*exit)(struct mux_state *mstate))
 {
-	struct mux_state **ptr, *mstate;
+	struct devm_mux_state_state *devm_state;
+	struct mux_state *mstate;
+	int ret;
 
-	ptr = devres_alloc(devm_mux_state_release, sizeof(*ptr), GFP_KERNEL);
-	if (!ptr)
+	devm_state = devres_alloc(devm_mux_state_release, sizeof(*devm_state), GFP_KERNEL);
+	if (!devm_state)
 		return ERR_PTR(-ENOMEM);
 
-	mstate = mux_state_get(dev, mux_name);
-	if (IS_ERR(mstate)) {
-		devres_free(ptr);
-		return mstate;
+	mstate = mux_state_get(dev, mux_name, optional);
+	if (IS_ERR_OR_NULL(mstate))
+		goto err_mux_state_get;
+
+	if (init) {
+		ret = init(mstate);
+		if (ret)
+			goto err_mux_state_init;
 	}
 
-	*ptr = mstate;
-	devres_add(dev, ptr);
+	devm_state->mstate = mstate;
+	devm_state->exit = exit;
+	devres_add(dev, devm_state);
 
 	return mstate;
+
+err_mux_state_init:
+	mux_state_put(mstate);
+err_mux_state_get:
+	devres_free(devm_state);
+	return ERR_PTR(ret);
+}
+
+/**
+ * devm_mux_state_get() - Get the mux-state for a device, with resource
+ *			  management.
+ * @dev: The device that needs a mux-control.
+ * @mux_name: The name identifying the mux-control.
+ *
+ * Return: Pointer to the mux-state, or an ERR_PTR with a negative errno.
+ *
+ * The mux-state will automatically be freed on release.
+ */
+struct mux_state *devm_mux_state_get(struct device *dev, const char *mux_name)
+{
+	return __devm_mux_state_get(dev, mux_name, false, NULL, NULL);
 }
 EXPORT_SYMBOL_GPL(devm_mux_state_get);
 
+/**
+ * devm_mux_state_get_optional() - Get the optional mux-state for a device,
+ *				   with resource management.
+ * @dev: The device that needs a mux-state.
+ * @mux_name: The name identifying the mux-state.
+ *
+ * Return: Pointer to the mux-state, or an ERR_PTR with a negative errno.
+ *
+ * The mux-state will automatically be freed on release.
+ */
+struct mux_state *devm_mux_state_get_optional(struct device *dev, const char *mux_name)
+{
+	return __devm_mux_state_get(dev, mux_name, true, NULL, NULL);
+}
+EXPORT_SYMBOL_GPL(devm_mux_state_get_optional);
+
+/**
+ * devm_mux_state_get_selected() - Get the mux-state for a device, with
+ *				   resource management.
+ * @dev: The device that needs a mux-state.
+ * @mux_name: The name identifying the mux-state.
+ *
+ * Return: Pointer to the mux-state, or an ERR_PTR with a negative errno.
+ *
+ * The returned mux-state (if valid) is already selected.
+ *
+ * The mux-state will automatically be deselected and freed on release.
+ */
+struct mux_state *devm_mux_state_get_selected(struct device *dev, const char *mux_name)
+{
+	return __devm_mux_state_get(dev, mux_name, false, mux_state_select, mux_state_deselect);
+}
+EXPORT_SYMBOL_GPL(devm_mux_state_get_selected);
+
+/**
+ * devm_mux_state_get_optional_selected() - Get the optional mux-state for
+ *					    a device, with resource management.
+ * @dev: The device that needs a mux-state.
+ * @mux_name: The name identifying the mux-state.
+ *
+ * Return: Pointer to the mux-state, or an ERR_PTR with a negative errno.
+ *
+ * The returned mux-state (if valid) is already selected.
+ *
+ * The mux-state will automatically be deselected and freed on release.
+ */
+struct mux_state *devm_mux_state_get_optional_selected(struct device *dev,
+						       const char *mux_name)
+{
+	return __devm_mux_state_get(dev, mux_name, true, mux_state_select, mux_state_deselect);
+}
+EXPORT_SYMBOL_GPL(devm_mux_state_get_optional_selected);
+
 /*
  * Using subsys_initcall instead of module_init here to try to ensure - for
  * the non-modular case - that the subsystem is initialized when mux consumers
diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h
index 2e25c838f831..7d591be26b64 100644
--- a/include/linux/mux/consumer.h
+++ b/include/linux/mux/consumer.h
@@ -16,6 +16,8 @@ struct device;
 struct mux_control;
 struct mux_state;
 
+#ifdef CONFIG_MULTIPLEXER
+
 unsigned int mux_control_states(struct mux_control *mux);
 int __must_check mux_control_select_delay(struct mux_control *mux,
 					  unsigned int state,
@@ -54,11 +56,112 @@ int mux_control_deselect(struct mux_control *mux);
 int mux_state_deselect(struct mux_state *mstate);
 
 struct mux_control *mux_control_get(struct device *dev, const char *mux_name);
+struct mux_control *mux_control_get_optional(struct device *dev, const char *mux_name);
 void mux_control_put(struct mux_control *mux);
 
-struct mux_control *devm_mux_control_get(struct device *dev,
-					 const char *mux_name);
-struct mux_state *devm_mux_state_get(struct device *dev,
-				     const char *mux_name);
+struct mux_control *devm_mux_control_get(struct device *dev, const char *mux_name);
+struct mux_state *devm_mux_state_get(struct device *dev, const char *mux_name);
+struct mux_state *devm_mux_state_get_optional(struct device *dev, const char *mux_name);
+struct mux_state *devm_mux_state_get_selected(struct device *dev, const char *mux_name);
+struct mux_state *devm_mux_state_get_optional_selected(struct device *dev, const char *mux_name);
+
+#else
+
+static inline unsigned int mux_control_states(struct mux_control *mux)
+{
+	return 0;
+}
+static inline int __must_check mux_control_select_delay(struct mux_control *mux,
+							unsigned int state, unsigned int delay_us)
+{
+	return -EOPNOTSUPP;
+}
+static inline int __must_check mux_state_select_delay(struct mux_state *mstate,
+						      unsigned int delay_us)
+{
+	return -EOPNOTSUPP;
+}
+static inline int __must_check mux_control_try_select_delay(struct mux_control *mux,
+							    unsigned int state,
+							    unsigned int delay_us)
+{
+	return -EOPNOTSUPP;
+}
+static inline int __must_check mux_state_try_select_delay(struct mux_state *mstate,
+							  unsigned int delay_us)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int __must_check mux_control_select(struct mux_control *mux,
+						  unsigned int state)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int __must_check mux_state_select(struct mux_state *mstate)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int __must_check mux_control_try_select(struct mux_control *mux,
+						      unsigned int state)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int __must_check mux_state_try_select(struct mux_state *mstate)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int mux_control_deselect(struct mux_control *mux)
+{
+	return -EOPNOTSUPP;
+}
+static inline int mux_state_deselect(struct mux_state *mstate)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline struct mux_control *mux_control_get(struct device *dev, const char *mux_name)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+static inline struct mux_control *mux_control_get_optional(struct device *dev,
+							   const char *mux_name)
+{
+	return NULL;
+}
+static inline void mux_control_put(struct mux_control *mux)
+{
+	return;
+}
+
+static inline struct mux_control *devm_mux_control_get(struct device *dev, const char *mux_name)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+static inline struct mux_state *devm_mux_state_get(struct device *dev, const char *mux_name)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+static inline struct mux_state *devm_mux_state_get_optional(struct device *dev,
+							    const char *mux_name)
+{
+	return NULL;
+}
+static inline struct mux_state *devm_mux_state_get_selected(struct device *dev,
+							    const char *mux_name)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+static inline struct mux_state *devm_mux_state_get_optional_selected(struct device *dev,
+								     const char *mux_name)
+{
+	return NULL;
+}
+
+#endif /* CONFIG_MULTIPLEXER */
 
 #endif /* _LINUX_MUX_CONSUMER_H */

-- 
2.43.0



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH v5 0/7] mmc: host: renesas_sdhi_core: support configuring an optional sdio mux
From: Josua Mayer @ 2026-01-18 10:28 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer

Some Renesas SoC based boards mux SD and eMMC on a single sdio
controller, exposing user control by dip switch and software control by
gpio.

Purpose is to simplify development and provisioning by selecting boot
media at power-on, and again before starting linux.

Add binding and driver support for linking a (gpio) mux to renesas sdio
controller.

Introduce generic helper functions for getting managed and selected
mux-state objects, and switch i2c-omap and phy-can-transceiver drivers.

Cc: Yazan Shhady <yazan.shhady@solid-run.com>
Cc: Jon Nettleton <jon@solid-run.com>
Cc: Mikhail Anikin <mikhail.anikin@solid-run.com>
To: Marc Kleine-Budde <mkl@pengutronix.de>
To: Vincent Mailhol <mailhol@kernel.org>
To: Vinod Koul <vkoul@kernel.org>
To: Neil Armstrong <neil.armstrong@linaro.org>
To: Peter Rosin <peda@axentia.se>
To: Aaro Koskinen <aaro.koskinen@iki.fi>
To: Andreas Kemnade <andreas@kemnade.info>
To: Kevin Hilman <khilman@baylibre.com>
To: Roger Quadros <rogerq@kernel.org>
To: Tony Lindgren <tony@atomide.com>
To: Janusz Krzysztofik <jmkrzyszt@gmail.com>
To: Vignesh R <vigneshr@ti.com>
To: Andi Shyti <andi.shyti@kernel.org>
To: Ulf Hansson <ulf.hansson@linaro.org>
To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Conor Dooley <conor+dt@kernel.org>
To: Geert Uytterhoeven <geert+renesas@glider.be>
To: Magnus Damm <magnus.damm@gmail.com>
To: Wolfram Sang <wsa+renesas@sang-engineering.com>
Cc: linux-can@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-omap@vger.kernel.org
Cc: linux-i2c@vger.kernel.org
Cc: linux-mmc@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
Signed-off-by: Josua Mayer <josua@solid-run.com>

Changes in v5:
- implemented automatic mux deselect for devm_*_selected.
  (Reported-by: Wolfram Sang <wsa+renesas@sang-engineering.com>)
- because of semantic changes I dropped reviewed and acks from omap-i2c
  patch (Andreas Kemnade / Wolfram Sang).
- fix invalid return value in void function for mux helper stubs
  (Reported-by: kernel test robot <lkp@intel.com>)
- Link to v4: https://lore.kernel.org/r/20251229-rz-sdio-mux-v4-0-a023e55758fe@solid-run.com

Changes in v4:
- added MULTIPLEXER Kconfig help text.
- removed "select MULTIPLEXER" from renesas sdhi Kconfig, as it is
  not required for all devices using this driver.
- added stubs for all symbols exported by mux core.
  (Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>)
- refactored mux core logic to silence ENOENT errors only on optional
  code paths, keeping error printing unchanged otherwise.
  (Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>)
- picked up various reviewed- and acked-by tags
- Link to v3: https://lore.kernel.org/r/20251210-rz-sdio-mux-v3-0-ca628db56d60@solid-run.com

Changes in v3:
- updated omap-i2c and phy-can-transceiver to use new helpers.
- created generic helper functions for getting managed optional mux-state.
  (Reported-by: Rob Herring <robh@kernel.org>)
- picked up binding ack by Rob Herring.
- replaced use of "SDIO" with "SD/SDIO/eMMC" in binding document and
  commit descriptions.
  (Reported-by: Ulf Hansson <ulf.hansson@linaro.org>)
- Link to v2: https://lore.kernel.org/r/20251201-rz-sdio-mux-v2-0-bcb581b88dd7@solid-run.com

Changes in v2:
- dropped mux-controller node from dt binding example
  (Reported-by: Conor Dooley <conor@kernel.org>
- Link to v1: https://lore.kernel.org/r/20251128-rz-sdio-mux-v1-0-1ede318d160f@solid-run.com

Reported-by: 
---
Josua Mayer (7):
      phy: can-transceiver: rename temporary helper function to avoid conflict
      mux: Add helper functions for getting optional and selected mux-state
      mux: add help text for MULTIPLEXER config option
      phy: can-transceiver: drop temporary helper getting optional mux-state
      i2c: omap: switch to new generic helper for getting selected mux-state
      dt-bindings: mmc: renesas,sdhi: Add mux-states property
      mmc: host: renesas_sdhi_core: support selecting an optional mux

 .../devicetree/bindings/mmc/renesas,sdhi.yaml      |   6 +
 drivers/i2c/busses/i2c-omap.c                      |  24 +--
 drivers/mmc/host/renesas_sdhi_core.c               |   6 +
 drivers/mux/Kconfig                                |   8 +
 drivers/mux/core.c                                 | 175 +++++++++++++++++----
 drivers/phy/phy-can-transceiver.c                  |  10 --
 include/linux/mux/consumer.h                       | 111 ++++++++++++-
 7 files changed, 278 insertions(+), 62 deletions(-)
---
base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
change-id: 20251128-rz-sdio-mux-acc5137f1618

Best regards,
-- 
Josua Mayer <josua@solid-run.com>



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* [PATCH v5 1/7] phy: can-transceiver: rename temporary helper function to avoid conflict
From: Josua Mayer @ 2026-01-18 10:28 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer
In-Reply-To: <20260118-rz-sdio-mux-v5-0-3c37e8872683@solid-run.com>

Rename the temporary devm_mux_state_get_optional function to avoid
conflict with upcoming implementation in multiplexer subsystem.

Acked-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/phy/phy-can-transceiver.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index 330356706ad7..81591d247128 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -128,7 +128,7 @@ MODULE_DEVICE_TABLE(of, can_transceiver_phy_ids);
 
 /* Temporary wrapper until the multiplexer subsystem supports optional muxes */
 static inline struct mux_state *
-devm_mux_state_get_optional(struct device *dev, const char *mux_name)
+temp_devm_mux_state_get_optional(struct device *dev, const char *mux_name)
 {
 	if (!of_property_present(dev->of_node, "mux-states"))
 		return NULL;
@@ -183,7 +183,7 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 	priv->num_ch = num_ch;
 	platform_set_drvdata(pdev, priv);
 
-	mux_state = devm_mux_state_get_optional(dev, NULL);
+	mux_state = temp_devm_mux_state_get_optional(dev, NULL);
 	if (IS_ERR(mux_state))
 		return PTR_ERR(mux_state);
 

-- 
2.43.0



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* Re: [PATCH v4 7/7] mmc: host: renesas_sdhi_core: support selecting an optional mux
From: Josua Mayer @ 2026-01-18  7:33 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Magnus Damm, Marc Kleine-Budde,
	Vincent Mailhol, Vinod Koul, Kishon Vijay Abraham I, Peter Rosin,
	Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
	Tony Lindgren, Vignesh R, Janusz Krzysztofik, Andi Shyti,
	Neil Armstrong, Mikhail Anikin, Yazan Shhady, Jon Nettleton,
	linux-mmc@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
	linux-can@vger.kernel.org, linux-phy@lists.infradead.org,
	linux-omap@vger.kernel.org, linux-i2c@vger.kernel.org
In-Reply-To: <aWeC5brP_KdrCmHz@ninjato>

Hi Wolfram,

On 14/01/2026 13:49, Wolfram Sang wrote:
> Hi Josua,
>
> thanks for your work and kudos for striving for a generic solution. It
> seems worthwhile to me to add the helpers. I have questions, though:
>
>> +	priv->mux_state = devm_mux_state_get_optional_selected(&pdev->dev, NULL);
> The minor nit (which may be bike-shedding): Maybe the function name
> could be '*_select' instead of '*_selected'. To make more explicit that
> this function is actively changing the selection and not passively
> retrieving the current state?
I have no strong opinion on select vs. selected.
I merely followed the devm_clk_get_enabled/selected.
>
> The bigger thing is that with devm_* I had the expectation that
> deselection is also handled automatically...
>
>> +edselmux:
>> +	if (priv->mux_state)
>> +		mux_state_deselect(priv->mux_state);
> ... so I was a bit surprised to see this manual cleanup. Has it been
> discussed if that deselection can also be in the helpers?
I have not considered adding this, and was careful
not to imply it in the function descriptions.

At the time I felt adding helpers was growing in complexity too fast,
and I am not very familair with devres.

I agree that the general expectation is devm functions are fully managed,
in this case including deselect.

>
> Happy hacking,
>
>     Wolfram
>
>
sincerely
Josua Mayer

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: (subset) [PATCH 0/5] Fixes to Tegra USB role switching and Smaug USB role switching enablement
From: Thierry Reding @ 2026-01-17  0:25 UTC (permalink / raw)
  To: Mathias Nyman, Greg Kroah-Hartman, Thierry Reding,
	Jonathan Hunter, JC Kuo, Vinod Koul, Kishon Vijay Abraham I,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Diogo Ivo
  Cc: linux-usb, linux-tegra, linux-kernel, linux-phy, devicetree
In-Reply-To: <20251204-diogo-tegra_phy-v1-0-51a2016d0be8@tecnico.ulisboa.pt>

From: Thierry Reding <treding@nvidia.com>


On Thu, 04 Dec 2025 21:27:16 +0000, Diogo Ivo wrote:
> This patch series contains two fixes for USB role switching on the
> Tegra210 SoC, as well as enabling this feature on the Pixel C.
> 
> The first patch addresses a wrong check on the logic that disables the
> VBUS regulator.
> 
> The second patch guarantees proper ordering of events when switching PHY
> roles.
> 
> [...]

Applied, thanks!

[4/5] arm64: tegra: smaug: Complete and enable tegra-udc node
      (no commit info)
[5/5] arm64: tegra: smaug: Add usb-role-switch support
      (no commit info)

Best regards,
-- 
Thierry Reding <treding@nvidia.com>

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH v2 01/12] dt-bindings: phy: mediatek,hdmi-phy: Fix clock output names for MT8195
From: Chun-Kuang Hu @ 2026-01-17  0:24 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: Chunfeng Yun, Vinod Koul, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Chun-Kuang Hu, Philipp Zabel,
	Guillaume Ranquet, kernel, Krzysztof Kozlowski, linux-arm-kernel,
	linux-mediatek, linux-phy, devicetree, linux-kernel
In-Reply-To: <20251217-mtk-genio-evk-hdmi-support-v2-1-a994976bb39a@collabora.com>

Hi, Louis:

Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com> 於 2025年12月17日週三
上午10:19寫道:
>
> From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>
> For all of the HDMI PHYs compatible with the one found on MT8195
> the output clock has a different datasheet name and specifically
> it is called "hdmi_txpll", differently from the older HDMI PHYs
> which output block is called "hdmitx_dig_cts".
>
> Replace clock output name string check by max item number one to allow
> the new name on all of the HDMI PHY IPs that are perfectly compatible
> with MT8195.
>
> [Louis-Alexis Eyraud: split patch, addressed previous feedback from
> mailing list, and reworded description]

Applied the binding patches of this series to mediatek-drm-next [1], thanks.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-next

Regards,
Chun-Kuang.

>
> Fixes: c78fe548b062 ("dt-bindings: phy: mediatek: hdmi-phy: Add mt8195 compatible")
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
> Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
> ---
>  Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml b/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml
> index f3a8b0b745d13ffc55d391570bff20830d925ed3..10f1d9326f18dba85b92b4c88f4c0f6cdddc4c25 100644
> --- a/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml
> @@ -42,8 +42,7 @@ properties:
>        - const: pll_ref
>
>    clock-output-names:
> -    items:
> -      - const: hdmitx_dig_cts
> +    maxItems: 1
>
>    "#phy-cells":
>      const: 0
>
> --
> 2.52.0
>

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: (subset) [PATCH v7 0/3] arm64: qcom: x1e78100-lenovo-thinkpad-t14s: add support for HDMI output
From: Bjorn Andersson @ 2026-01-16 21:39 UTC (permalink / raw)
  To: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Neil Armstrong
  Cc: Xilin Wu, linux-arm-msm, linux-phy, devicetree, linux-kernel,
	Dmitry Baryshkov, Konrad Dybcio, Abel Vesa
In-Reply-To: <20251119-topic-x1e80100-hdmi-v7-0-2bee0e66cc1b@linaro.org>


On Wed, 19 Nov 2025 09:45:39 +0100, Neil Armstrong wrote:
> The Thinkpad T14s embeds a transparent 4lanes DP->HDMI transceiver
> connected to the third QMP Combo PHY 4 lanes.
> 
> The QMP USB3/DP Combo PHY hosts an USB3 phy and a DP PHY on top
> of a combo glue to route either lanes to the 4 shared physical lanes.
> 
> The routing of the lanes can be:
> - 1/2 DP + 2 USB3
> - 1/2/4 DP
> - 2 USB3
> 
> [...]

Applied, thanks!

[3/3] arm64: dts: qcom: x1e78100-lenovo-thinkpad-t14s: add HDMI nodes
      commit: a1338b39c14ddf50b841e891833786037dec6de4

Best regards,
-- 
Bjorn Andersson <andersson@kernel.org>

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH v5 2/8] arm64: dts: mediatek: mt7981b: Add PCIe and USB support
From: Rob Herring @ 2026-01-16 16:02 UTC (permalink / raw)
  To: Sjoerd Simons
  Cc: Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ryder Lee, Jianjun Wang,
	Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Lee Jones, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Lorenzo Bianconi,
	Felix Fietkau, kernel, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-pci, linux-phy, netdev, Daniel Golle,
	Bryan Hinton
In-Reply-To: <20251223-openwrt-one-network-v5-2-7d1864ea3ad5@collabora.com>

On Tue, Dec 23, 2025 at 6:38 AM Sjoerd Simons <sjoerd@collabora.com> wrote:
>
> Add device tree nodes for PCIe controller and USB3 XHCI host
> controller on MT7981B SoC. Both controllers share the USB3 PHY
> which can be configured for either USB3 or PCIe operation.
>
> The USB3 XHCI controller supports USB 2.0 and USB 3.0 SuperSpeed
> operation. The PCIe controller is compatible with PCIe Gen2
> specifications.
>
> Also add the topmisc syscon node required for USB/PCIe PHY
> multiplexing.
>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> Signed-off-by: Sjoerd Simons <sjoerd@collabora.com>
> ---
> V1 -> V2: Keep xhci reg and phys properties in single lines
> ---
>  arch/arm64/boot/dts/mediatek/mt7981b.dtsi | 80 +++++++++++++++++++++++++++++++
>  1 file changed, 80 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
> index 416096b80770..d3f37413413e 100644
> --- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
> @@ -2,6 +2,7 @@
>
>  #include <dt-bindings/clock/mediatek,mt7981-clk.h>
>  #include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/phy/phy.h>
>  #include <dt-bindings/reset/mt7986-resets.h>
>
>  / {
> @@ -223,6 +224,55 @@ auxadc: adc@1100d000 {
>                         status = "disabled";
>                 };
>
> +               xhci: usb@11200000 {
> +                       compatible = "mediatek,mt7986-xhci", "mediatek,mtk-xhci";
> +                       reg = <0 0x11200000 0 0x2e00>, <0 0x11203e00 0 0x0100>;
> +                       reg-names = "mac", "ippc";
> +                       clocks = <&infracfg CLK_INFRA_IUSB_SYS_CK>,
> +                                <&infracfg CLK_INFRA_IUSB_CK>,
> +                                <&infracfg CLK_INFRA_IUSB_133_CK>,
> +                                <&infracfg CLK_INFRA_IUSB_66M_CK>,
> +                                <&topckgen CLK_TOP_U2U3_XHCI_SEL>;
> +                       clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
> +                       interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
> +                       phys = <&u2port0 PHY_TYPE_USB2>, <&u3port0 PHY_TYPE_USB3>;
> +                       status = "disabled";
> +               };
> +
> +               pcie: pcie@11280000 {
> +                       compatible = "mediatek,mt7981-pcie",
> +                                    "mediatek,mt8192-pcie";
> +                       reg = <0 0x11280000 0 0x4000>;
> +                       reg-names = "pcie-mac";
> +                       ranges = <0x82000000 0 0x20000000
> +                                 0x0 0x20000000 0 0x10000000>;
> +                       bus-range = <0x00 0xff>;
> +                       clocks = <&infracfg CLK_INFRA_IPCIE_CK>,
> +                                <&infracfg CLK_INFRA_IPCIE_PIPE_CK>,
> +                                <&infracfg CLK_INFRA_IPCIER_CK>,
> +                                <&infracfg CLK_INFRA_IPCIEB_CK>;
> +                       clock-names = "pl_250m", "tl_26m", "peri_26m", "top_133m";
> +                       device_type = "pci";
> +                       phys = <&u3port0 PHY_TYPE_PCIE>;
> +                       phy-names = "pcie-phy";
> +                       interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
> +                       interrupt-map-mask = <0 0 0 7>;
> +                       interrupt-map = <0 0 0 1 &pcie_intc 0>,
> +                                       <0 0 0 2 &pcie_intc 1>,
> +                                       <0 0 0 3 &pcie_intc 2>,
> +                                       <0 0 0 4 &pcie_intc 3>;
> +                       #address-cells = <3>;
> +                       #interrupt-cells = <1>;
> +                       #size-cells = <2>;
> +                       status = "disabled";
> +
> +                       pcie_intc: interrupt-controller {
> +                               interrupt-controller;
> +                               #address-cells = <0>;
> +                               #interrupt-cells = <1>;
> +                       };
> +               };
> +
>                 pio: pinctrl@11d00000 {
>                         compatible = "mediatek,mt7981-pinctrl";
>                         reg = <0 0x11d00000 0 0x1000>,
> @@ -252,6 +302,36 @@ mux {
>                         };
>                 };
>
> +               topmisc: topmisc@11d10000 {
> +                       compatible = "mediatek,mt7981-topmisc", "syscon";
> +                       reg = <0 0x11d10000 0 0x10000>;
> +                       #clock-cells = <1>;

This is now a warning as the syscon.yaml binding this compatible is
defined in doesn't allow #clock-cells.

Rob

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH v3] phy: fsl-imx8mq-usb: add debugfs to access control register
From: Andrew Lunn @ 2026-01-16 15:19 UTC (permalink / raw)
  To: Xu Yang
  Cc: Frank Li, vkoul, neil.armstrong, shawnguo, kernel, festevam,
	jun.li, linux-phy, imx, linux-arm-kernel, linux-kernel
In-Reply-To: <das6ud7gep5hrcdn4bnmoyl2pb7okbxslpnawch2osaezd6xm5@psbizlufjec4>

On Fri, Jan 16, 2026 at 07:29:39PM +0800, Xu Yang wrote:
> On Thu, Jan 08, 2026 at 10:43:01AM -0500, Frank Li wrote:
> > On Thu, Jan 08, 2026 at 04:36:41PM +0800, Xu Yang wrote:
> > > The CR port is a simple 16-bit data/address parallel port that is
> > > provided for on-chip access to the control registers inside the
> > > USB 3.0 femtoPHY[1].
> > 
> > 
> > > While access to these registers is not required
> > > for normal PHY operation, this interface enables you to access
> > > some of the PHY’s diagnostic features during normal operation or
> > > to override some basic PHY control signals.
> > 
> > Simple said "Export these registers by debugfs to help PHY’s diagnostic."
> > should be enough
> 
> OK.
> 
> > 
> > >
> > > 3 debugfs files are created to read and write control registers,
> > > all use hexadecimal format:
> > > ctrl_reg_base: the register offset to write, or the start offset
> > >                to read.
> > > ctrl_reg_count: how many continuous registers to be read.
> > > ctrl_reg_value: read to show the continuous registers value from
> > >                 the offset in ctrl_reg_base, to ctrl_reg_base
> > >                 + ctrl_reg_count - 1, one line for one register.
> > >                 when write, override the register at ctrl_reg_base,
> > >                 one time can only change one 16bits register.
> > 
> > how many regs? how about create file regNNN,
> 
> >From 0x0 to 0x201F.

Rather than reinvent the wheel, could you use regmap?

https://elixir.bootlin.com/linux/v6.12.1/source/drivers/base/regmap/regmap-debugfs.c#L546

Regmap should be able to provide a debugfs interface for you, no
driver code needed.

This will also help you with the abstraction between the core generic
part of the PHY driver and the SoC integration glue. You pass the
regmap to the core driver, and the funny muxing through two registers
is hidden away from the core. If the next SoC integrated uses plan
MMIO, that SoC glue driver can instantiate an MMIO regmap.

Using regmap is a good idea for core generic drivers which can be
integrated into SoCs in different ways. It hides the SoC details
behind a well known API.

      Andrew


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: (subset) [PATCH v3 0/4] PCI: qcom: Add support for Glymur PCIe Gen5x4
From: Manivannan Sadhasivam @ 2026-01-16 13:25 UTC (permalink / raw)
  To: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Helgaas,
	Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Andersson,
	Wenbin Yao
  Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-pci,
	konrad.dybcio, qiang.yu, Prudhvi Yarlagadda, Dmitry Baryshkov
In-Reply-To: <20250825-glymur_pcie5-v3-0-5c1d1730c16f@oss.qualcomm.com>


On Mon, 25 Aug 2025 23:01:46 -0700, Wenbin Yao wrote:
> Glymur is the next generation compute SoC of Qualcomm. This patch series
> aims to add support for the fifth PCIe instance on it. The fifth PCIe
> instance on Glymur has a Gen5 4-lane PHY. Patch [1/4] documents PHY as a
> separate compatible and Patch [2/4] documents controller as a separate
> compatible. Patch [3/4] describles the new PCS offsets in a dedicated
> header file. Patch [4/4] adds configuration and compatible for PHY.
> 
> [...]

Applied, thanks!

[2/4] dt-bindings: PCI: qcom: Document the Glymur PCIe Controller
      commit: e74887035fba99ead63235740908debeb1326dad

Best regards,
-- 
Manivannan Sadhasivam <mani@kernel.org>


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH v3] phy: fsl-imx8mq-usb: add debugfs to access control register
From: Xu Yang @ 2026-01-16 11:30 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Andrew Lunn, neil.armstrong, shawnguo, kernel, festevam, jun.li,
	Frank.Li, linux-phy, imx, linux-arm-kernel, linux-kernel
In-Reply-To: <aWdkapV39bOArR-d@vaman>

On Wed, Jan 14, 2026 at 03:09:54PM +0530, Vinod Koul wrote:
> On 08-01-26, 19:24, Andrew Lunn wrote:
> > On Thu, Jan 08, 2026 at 04:36:41PM +0800, Xu Yang wrote:
> > > The CR port is a simple 16-bit data/address parallel port that is
> > > provided for on-chip access to the control registers inside the
> > > USB 3.0 femtoPHY[1]. While access to these registers is not required
> > > for normal PHY operation, this interface enables you to access
> > > some of the PHY’s diagnostic features during normal operation or
> > > to override some basic PHY control signals.
> > > 
> > > 3 debugfs files are created to read and write control registers,
> > > all use hexadecimal format:
> > > ctrl_reg_base: the register offset to write, or the start offset
> > >                to read.
> > > ctrl_reg_count: how many continuous registers to be read.
> > > ctrl_reg_value: read to show the continuous registers value from
> > >                 the offset in ctrl_reg_base, to ctrl_reg_base
> > >                 + ctrl_reg_count - 1, one line for one register.
> > >                 when write, override the register at ctrl_reg_base,
> > >                 one time can only change one 16bits register.
> > > 
> > > Link[1]: https://www.synopsys.com/dw/doc.php/phy/usb3.0/femto/phy/x652_usb3_ss14lpp_18_ns/4.07a/dwc_usb3.0_femtophy_ss14lpp_08V18V_x1_databook.pdf
> > 
> > Please don't ignore my comments to V2. Think about the code split
> > between the generic IP licensed from Synopsys and the vendor specific
> > code used for integration into the SoC. You want to avoid making a
> > mess you later need to cleanup because somebody else licensed the same
> > IP core from Synopsys, and need to put their own vendor specific
> > integration code around the generic code.
> 
> Agree with Andrew here, please do mix, splitting would be better

OK, will try.

Thanks,
Xu Yang

> 
> > 
> >     Andrew
> 
> -- 
> ~Vinod

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH v3] phy: fsl-imx8mq-usb: add debugfs to access control register
From: Xu Yang @ 2026-01-16 11:30 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: vkoul, neil.armstrong, shawnguo, kernel, festevam, jun.li,
	Frank.Li, linux-phy, imx, linux-arm-kernel, linux-kernel
In-Reply-To: <c1425564-9dca-45dc-ac5e-093150a3ff01@lunn.ch>

On Thu, Jan 08, 2026 at 07:24:31PM +0100, Andrew Lunn wrote:
> On Thu, Jan 08, 2026 at 04:36:41PM +0800, Xu Yang wrote:
> > The CR port is a simple 16-bit data/address parallel port that is
> > provided for on-chip access to the control registers inside the
> > USB 3.0 femtoPHY[1]. While access to these registers is not required
> > for normal PHY operation, this interface enables you to access
> > some of the PHY’s diagnostic features during normal operation or
> > to override some basic PHY control signals.
> > 
> > 3 debugfs files are created to read and write control registers,
> > all use hexadecimal format:
> > ctrl_reg_base: the register offset to write, or the start offset
> >                to read.
> > ctrl_reg_count: how many continuous registers to be read.
> > ctrl_reg_value: read to show the continuous registers value from
> >                 the offset in ctrl_reg_base, to ctrl_reg_base
> >                 + ctrl_reg_count - 1, one line for one register.
> >                 when write, override the register at ctrl_reg_base,
> >                 one time can only change one 16bits register.
> > 
> > Link[1]: https://www.synopsys.com/dw/doc.php/phy/usb3.0/femto/phy/x652_usb3_ss14lpp_18_ns/4.07a/dwc_usb3.0_femtophy_ss14lpp_08V18V_x1_databook.pdf
> 
> Please don't ignore my comments to V2. Think about the code split
> between the generic IP licensed from Synopsys and the vendor specific
> code used for integration into the SoC. You want to avoid making a
> mess you later need to cleanup because somebody else licensed the same
> IP core from Synopsys, and need to put their own vendor specific
> integration code around the generic code.

OK.

Thanks,
Xu Yang

> 
>     Andrew

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH v3] phy: fsl-imx8mq-usb: add debugfs to access control register
From: Xu Yang @ 2026-01-16 11:29 UTC (permalink / raw)
  To: Frank Li
  Cc: vkoul, neil.armstrong, shawnguo, kernel, festevam, jun.li,
	linux-phy, imx, linux-arm-kernel, linux-kernel
In-Reply-To: <aV/Qha0CQ+LJHo76@lizhi-Precision-Tower-5810>

On Thu, Jan 08, 2026 at 10:43:01AM -0500, Frank Li wrote:
> On Thu, Jan 08, 2026 at 04:36:41PM +0800, Xu Yang wrote:
> > The CR port is a simple 16-bit data/address parallel port that is
> > provided for on-chip access to the control registers inside the
> > USB 3.0 femtoPHY[1].
> 
> 
> > While access to these registers is not required
> > for normal PHY operation, this interface enables you to access
> > some of the PHY’s diagnostic features during normal operation or
> > to override some basic PHY control signals.
> 
> Simple said "Export these registers by debugfs to help PHY’s diagnostic."
> should be enough

OK.

> 
> >
> > 3 debugfs files are created to read and write control registers,
> > all use hexadecimal format:
> > ctrl_reg_base: the register offset to write, or the start offset
> >                to read.
> > ctrl_reg_count: how many continuous registers to be read.
> > ctrl_reg_value: read to show the continuous registers value from
> >                 the offset in ctrl_reg_base, to ctrl_reg_base
> >                 + ctrl_reg_count - 1, one line for one register.
> >                 when write, override the register at ctrl_reg_base,
> >                 one time can only change one 16bits register.
> 
> how many regs? how about create file regNNN,

From 0x0 to 0x201F.

> 
> cat/echo to regNNN?

Only regNNN seems not convenient to dump non-fixed number of registers.

> 
> or create export file
> 
> echo 100 > export, then create REG100, so can use cat/echo modify it.

If use export, it seems need a place to doc these information. It's not
straightforward to use.

> 
> 
> >
> > Link[1]: https://www.synopsys.com/dw/doc.php/phy/usb3.0/femto/phy/x652_usb3_ss14lpp_18_ns/4.07a/dwc_usb3.0_femtophy_ss14lpp_08V18V_x1_databook.pdf
> > Signed-off-by: Li Jun <jun.li@nxp.com>
> > Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
> >
> > ---
> > Changes in v3:
> >  - add documentation link of registers
> > Changes in v2:
> >  - correct copyright
> >  - add imx8mq_phy_wait_for_cr_ack() helper and use it
> >  - use DEFINE_SHOW_STORE_ATTRIBUTE()
> >  - directly create debugfs file under imx phy debugfs
> >  - remove debug_remove_files() since the phy core will handle it
> > ---
> >  drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 180 ++++++++++++++++++++-
> >  1 file changed, 178 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > index 95f9264bd0f7..e11054f6673c 100644
> > --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > @@ -1,10 +1,11 @@
> >  // SPDX-License-Identifier: GPL-2.0+
> > -/* Copyright (c) 2017 NXP. */
> > +/* Copyright 2017-2025 NXP. */
> >
> >  #include <linux/bitfield.h>
> >  #include <linux/clk.h>
> > +#include <linux/debugfs.h>
> >  #include <linux/delay.h>
> > -#include <linux/io.h>
> > +#include <linux/iopoll.h>
> >  #include <linux/module.h>
> >  #include <linux/of.h>
> >  #include <linux/phy/phy.h>
> > @@ -57,6 +58,20 @@
> >
> >  #define PHY_TUNE_DEFAULT		0xffffffff
> >
> > +/* PHY control register access */
> > +#define PHY_CTRL_REG_OFFSET_MAX		0x201f
> > +
> > +#define PHY_CRCTL			0x30
> > +#define PHY_CRCTL_DATA_IN_MASK		GENMASK(15, 0)
> > +#define PHY_CRCTL_CAP_ADDR		BIT(16)
> > +#define PHY_CRCTL_CAP_DATA		BIT(17)
> > +#define PHY_CRCTL_CR_WRITE		BIT(18)
> > +#define PHY_CRCTL_CR_READ		BIT(19)
> > +
> > +#define PHY_CRSR			0x34
> > +#define PHY_CRSR_DATA_OUT_MASK		GENMASK(15, 0)
> > +#define PHY_CRSR_CR_ACK			BIT(16)
> > +
> >  #define TCA_CLK_RST			0x00
> >  #define TCA_CLK_RST_SW			BIT(9)
> >  #define TCA_CLK_RST_REF_CLK_EN		BIT(1)
> > @@ -118,6 +133,9 @@ struct imx8mq_usb_phy {
> >  	void __iomem *base;
> >  	struct regulator *vbus;
> >  	struct tca_blk *tca;
> > +	struct dentry *debugfs;
> > +	u16 cr_access_base;
> > +	u16 cr_read_count;
> >  	u32 pcs_tx_swing_full;
> >  	u32 pcs_tx_deemph_3p5db;
> >  	u32 tx_vref_tune;
> > @@ -411,6 +429,163 @@ static u32 phy_pcs_tx_swing_full_from_property(u32 percent)
> >  	percent = min(percent, 100U);
> >
> >  	return (percent * 127) / 100;
> > +};
> > +
> > +static int imx8mq_phy_wait_for_cr_ack(struct imx8mq_usb_phy *imx_phy,
> > +				      u32 stage, u32 *data)
> > +{
> > +	void __iomem	*cr_ctrl = imx_phy->base + PHY_CRCTL;
> > +	void __iomem	*cr_sr = imx_phy->base + PHY_CRSR;
> > +	u32		val;
> > +	int		ret;
> > +
> > +	writel(readl(cr_ctrl) | stage, cr_ctrl);
> > +	/* Wait CRSR[16] == 1 */
> > +	ret = readl_poll_timeout(cr_sr, val,
> > +				 (val & PHY_CRSR_CR_ACK) == PHY_CRSR_CR_ACK,
> > +				 1, 100);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (stage == PHY_CRCTL_CR_READ)
> > +		*data = readl(cr_sr) & 0xffff;
> > +
> > +	writel(readl(cr_ctrl) & (~stage), cr_ctrl);
> > +	/* Wait CRSR[16] == 0 */
> > +	return readl_poll_timeout(cr_sr, val, (val & PHY_CRSR_CR_ACK) == 0, 1, 100);
> > +}
> > +
> > +static int imx8mq_phy_ctrl_reg_addr(struct imx8mq_usb_phy *imx_phy, u16 offset)
> > +{
> > +	void __iomem	*cr_ctrl = imx_phy->base + PHY_CRCTL;
> > +	struct device	*dev = &imx_phy->phy->dev;
> > +	int		ret;
> > +
> > +	writel(offset, cr_ctrl);
> > +	ret = imx8mq_phy_wait_for_cr_ack(imx_phy, PHY_CRCTL_CAP_ADDR, NULL);
> > +	if (ret < 0) {
> > +		dev_err(dev, "Failed to address reg 0x%04x\n", offset);
> > +		return -EIO;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int imx8mq_phy_ctrl_reg_read(struct imx8mq_usb_phy *imx_phy,
> > +				    u16 offset, u32 *val)
> > +{
> > +	struct device *dev = &imx_phy->phy->dev;
> > +	int ret;
> > +
> > +	if (offset > PHY_CTRL_REG_OFFSET_MAX) {
> > +		dev_err(dev, "Invalid reg address 0x%04x\n", offset);
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* Address stage */
> > +	ret = imx8mq_phy_ctrl_reg_addr(imx_phy, offset);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Read data stage */
> > +	ret = imx8mq_phy_wait_for_cr_ack(imx_phy, PHY_CRCTL_CR_READ, val);
> > +	if (ret < 0) {
> > +		dev_err(dev, "Failed to read reg 0x%04x\n", offset);
> > +		return -EIO;
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +static int imx8mq_phy_ctrl_reg_write(struct imx8mq_usb_phy *imx_phy,
> > +				     u16 offset, u16 val)
> > +{
> > +	struct device	*dev = &imx_phy->phy->dev;
> > +	void __iomem	*cr_ctrl = imx_phy->base + PHY_CRCTL;
> > +	int		ret;
> > +
> > +	if (offset > PHY_CTRL_REG_OFFSET_MAX) {
> > +		dev_err(dev, "Invalid reg address 0x%04x\n", offset);
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* Address stage */
> > +	ret = imx8mq_phy_ctrl_reg_addr(imx_phy, offset);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Capture data stage */
> > +	writel(val, cr_ctrl);
> > +	ret = imx8mq_phy_wait_for_cr_ack(imx_phy, PHY_CRCTL_CAP_DATA, NULL);
> > +	if (ret < 0)
> > +		goto cr_write_err;
> > +
> > +	/* Write data stage */
> > +	ret = imx8mq_phy_wait_for_cr_ack(imx_phy, PHY_CRCTL_CR_WRITE, NULL);
> > +	if (ret < 0)
> > +		goto cr_write_err;
> > +
> > +	return 0;
> > +
> > +cr_write_err:
> > +	dev_err(dev, "Failed to write reg 0x%04x\n", offset);
> > +	return -EIO;
> > +}
> > +
> > +static int ctrl_reg_value_show(struct seq_file *s, void *unused)
> > +{
> > +	struct imx8mq_usb_phy *imx_phy = s->private;
> > +	u16 base = imx_phy->cr_access_base;
> > +	u32 val;
> > +	int i, ret;
> > +
> > +	for (i = 0; i < imx_phy->cr_read_count; i++) {
> > +		ret = imx8mq_phy_ctrl_reg_read(imx_phy, base + i, &val);
> > +		if (ret < 0)
> > +			return ret;
> > +
> > +		seq_printf(s, "Control Register 0x%04x value is 0x%04x\n",
> > +			   base + i, val);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static ssize_t ctrl_reg_value_write(struct file *file, const char __user *ubuf,
> > +				    size_t count, loff_t *ppos)
> > +
> > +{
> > +	struct seq_file		*s = file->private_data;
> > +	struct imx8mq_usb_phy	*imx_phy = s->private;
> > +	u16			cr_value;
> > +	int			ret;
> > +
> > +	ret = kstrtou16_from_user(ubuf, count, 16, &cr_value);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = imx8mq_phy_ctrl_reg_write(imx_phy, imx_phy->cr_access_base, cr_value);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return count;
> > +}
> > +
> > +DEFINE_SHOW_STORE_ATTRIBUTE(ctrl_reg_value);
> > +
> > +static void imx8m_create_debug_files(struct imx8mq_usb_phy *imx_phy)
> > +{
> > +	struct dentry *debugfs = imx_phy->phy->debugfs;
> > +
> > +	debugfs_create_x16("ctrl_reg_base", 0600, debugfs,
> > +			   &imx_phy->cr_access_base);
> > +	debugfs_create_x16("ctrl_reg_count", 0600, debugfs,
> > +			   &imx_phy->cr_read_count);
> > +	debugfs_create_file("ctrl_reg_value", 0600, debugfs,
> > +			    imx_phy, &ctrl_reg_value_fops);
> > +
> > +	imx_phy->cr_access_base = 0;
> > +	imx_phy->cr_read_count = 1;
> >  }
> >
> >  static void imx8m_get_phy_tuning_data(struct imx8mq_usb_phy *imx_phy)
> > @@ -731,6 +906,7 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
> >  					"failed to get tca\n");
> >
> >  	imx8m_get_phy_tuning_data(imx_phy);
> > +	imx8m_create_debug_files(imx_phy);
> 
> where remove debug fs?

phy core will remove debug fs when call phy_release(). 

Thanks,
Xu Yang

> 
> Frank
> >
> >  	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> >
> > --
> > 2.34.1
> >

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* [PATCH v3] phy: fsl-imx8mq-usb: enable RX Termination override
From: Xu Yang @ 2026-01-16 10:18 UTC (permalink / raw)
  To: vkoul, neil.armstrong, shawnguo, kernel, festevam, jun.li,
	Frank.Li
  Cc: linux-phy, imx, linux-arm-kernel, linux-kernel

This is to resolve the problem of wakeup system by USB3 device insertion
if HSIOMIX on, in that case, the USB3 device detects RX term on so the
USB3 device doesn't downgrade to high-speed, we can't expect CONN wakeup
(for USB3) happen because the 24MHz OSC is required ON to trigger it.
Because the device works at Super-speed so DP/DM wakeup can't happen
either. Then the entire systen can't be waken up by such device attach
event.

With this override bit we can force the RX term off when enters system
suspend, and disable the override after system resume. Therefore, the
USB3 device will always downgrade to High-speed, then DP/DM wakeup can
always happen. It will correctly switch to Super-speed later when the
host reset it after the system resume back.

Signed-off-by: Li Jun <jun.li@nxp.com>
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>

---
Changes in v3:
 - remove CamelCase style in title
Changes in v2:
 - rephase the message
---
 drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
index f33eef218db1..e9c113edd470 100644
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
@@ -54,6 +54,7 @@
 #define PHY_CTRL5_PCS_TX_SWING_FULL_MASK	GENMASK(6, 0)
 
 #define PHY_CTRL6			0x18
+#define PHY_CTRL6_RXTERM_OVERRIDE_SEL	BIT(29)
 #define PHY_CTRL6_ALT_CLK_EN		BIT(1)
 #define PHY_CTRL6_ALT_CLK_SEL		BIT(0)
 
@@ -699,6 +700,7 @@ static int imx8mp_usb_phy_init(struct phy *phy)
 static int imx8mq_phy_power_on(struct phy *phy)
 {
 	struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy);
+	u32 value;
 	int ret;
 
 	ret = regulator_enable(imx_phy->vbus);
@@ -715,12 +717,23 @@ static int imx8mq_phy_power_on(struct phy *phy)
 		return ret;
 	}
 
-	return ret;
+	/* Disable rx term override */
+	value = readl(imx_phy->base + PHY_CTRL6);
+	value &= ~PHY_CTRL6_RXTERM_OVERRIDE_SEL;
+	writel(value, imx_phy->base + PHY_CTRL6);
+
+	return 0;
 }
 
 static int imx8mq_phy_power_off(struct phy *phy)
 {
 	struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy);
+	u32 value;
+
+	/* Override rx term to be 0 */
+	value = readl(imx_phy->base + PHY_CTRL6);
+	value |= PHY_CTRL6_RXTERM_OVERRIDE_SEL;
+	writel(value, imx_phy->base + PHY_CTRL6);
 
 	clk_disable_unprepare(imx_phy->alt_clk);
 	clk_disable_unprepare(imx_phy->clk);
-- 
2.34.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* Re: [PATCH v2] phy: fsl-imx8mq-usb: enable RxTermination_override_sel
From: Xu Yang @ 2026-01-16 10:07 UTC (permalink / raw)
  To: Vinod Koul
  Cc: neil.armstrong, shawnguo, kernel, festevam, jun.li, Frank.Li,
	linux-phy, imx, linux-arm-kernel, linux-kernel
In-Reply-To: <aWe_oNDOqHnQo0X2@vaman>

On Wed, Jan 14, 2026 at 09:39:04PM +0530, Vinod Koul wrote:
> On 24-12-25, 19:18, Xu Yang wrote:
> 
> What is the with the CamelCase on the patch title! We dont do that
> please

Not on purpose. It's a bit field name. Will fix the title.

Thanks,
Xu Yang

> 
> > This is to resolve the problem of wakeup system by USB3 device insertion
> > if HSIOMIX on, in that case, the USB3 device detects RX term on so the
> > USB3 device doesn't downgrade to high-speed, we can't expect CONN wakeup
> > (for USB3) happen because the 24MHz OSC is required ON to trigger it.
> > Because the device works at Super-speed so DP/DM wakeup can't happen
> > either. Then the entire systen can't be waken up by such device attach
> > event.
> > 

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: Re: [PATCH v7 2/2] phy: eswin: Create eswin directory and add EIC7700 SATA PHY driver
From: Yulin Lu @ 2026-01-16  8:50 UTC (permalink / raw)
  To: Vinod Koul
  Cc: neil.armstrong, robh, krzk+dt, conor+dt, p.zabel, linux-phy,
	devicetree, linux-kernel, ningyu, zhengyu, linmin, huangyifeng,
	fenglin, lianghujun
In-Reply-To: <aWeH5fn8nGOzjDpP@vaman>

> > +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) |
> > +	      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?

> > +	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);
> > +	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

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH] drm/msm/dp: Correct LeMans/Monaco DP phy Swing/Emphasis setting
From: Dmitry Baryshkov @ 2026-01-16  8:41 UTC (permalink / raw)
  To: Yongxing Mou
  Cc: Konrad Dybcio, Vinod Koul, Neil Armstrong, linux-arm-msm,
	linux-phy, linux-kernel
In-Reply-To: <80411ac4-6143-4c2e-bc9e-20a734f15987@oss.qualcomm.com>

On Fri, Jan 16, 2026 at 04:18:43PM +0800, Yongxing Mou wrote:
> 
> 
> On 1/14/2026 2:55 AM, Dmitry Baryshkov wrote:
> > On Tue, Jan 13, 2026 at 08:04:06PM +0800, Yongxing Mou wrote:
> > > 
> > > 
> > > On 1/9/2026 5:58 PM, Konrad Dybcio wrote:
> > > > On 1/9/26 9:30 AM, Yongxing Mou wrote:
> > > > > Currently, the LeMans/Monaco DP PHY operates in DP mode rather than eDP
> > > > > mode. Per the PHY HPG, the Swing and Emphasis settings have been corrected
> > > > > to the appropriate DP-mode values.
> > > > > 
> > > > > Additionally, the HPG specifies that the LDO value should be set to 0 when
> > > > > in DP mode. These misconfigurations can lead to link training failures on
> > > > > certain dongles.
> > > > > 
> > > > > Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
> > > > > ---
> > > > >    drivers/phy/qualcomm/phy-qcom-edp.c | 27 ++++++++++++++++++++++++---
> > > > >    1 file changed, 24 insertions(+), 3 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> > > > > index 13feab99feec..5b0d774bd715 100644
> > > > > --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> > > > > +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> > > > > @@ -122,6 +122,13 @@ static const u8 dp_swing_hbr_rbr[4][4] = {
> > > > >    	{ 0x1f, 0xff, 0xff, 0xff }
> > > > >    };
> > > > > +static const u8 dp_swing_hbr_rbr_v1[4][4] = {
> > > > > +	{ 0x07, 0x0f, 0x16, 0x1f },
> > > > > +	{ 0x11, 0x1e, 0x1f, 0xff },
> > > > > +	{ 0x16, 0x1f, 0xff, 0xff },
> > > > > +	{ 0x1f, 0xff, 0xff, 0xff }
> > > > > +};
> > > > 
> > > > For these platforms, I see 4 tables of settings:
> > > > 
> > > > (Low/High) Swing/Pre-em for (Low/High) HBR
> > > > 
> > > > None of them exactly match your change
> > > > 
> > > Emm, this table is in LeMans eDP HPG, here are 6 tables. 4 of them use for
> > > eDP mode and reset 2 tables used for DP mode. If my understanding is
> > > incorrect, please correct me. Thanks ~~~ > [...]
> > > > 
> > > > > -	ldo_config = edp->is_edp ? 0x0 : 0x1;
> > > > > +	ldo_config = !edp->is_edp ? 0x0 : 0x1;
> > > > 
> > > > You'll notice that this is further wrong, because for eDP, it should be
> > > > 0x81 at low-swing-high-HBR and 0xc1 at low-swing-low-HBR, and 0 at both
> > > > cases of high-swing
> > > > 
> > > > Please split the LDO change into a separate commit because it touches
> > > > more platforms
> > > > 
> > > > Konrad
> > > > 
> > > 
> > > Yes, you are right, here seems something not correct. i will separate this
> > > change into single one.Here are some parts I don't fully understand here.
> > > Could you please point it? How do we know whether it is in low‑swing or
> > > high‑swing. I didn’t see any logic in the current code that determines this.
> > > Also, the value in Hamoa seems not same with LeMans,it is 0x51 and 0x91.
> > > 
> > > While going through the Hamoa HPG, I noticed a potential issue.
> > > 
> > >   static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
> > > 	.aux_cfg = edp_phy_aux_cfg_v4,
> > > 	.vco_div_cfg = edp_phy_vco_div_cfg_v4,
> > > 	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,...It use
> > > dp_phy_swing_pre_emph_cfg not edp_phy_swing_pre_emph_cfg, but Hamoa really
> > > use edp-panel here.. so does this phy cfg correct here?
> > 
> > All PHYs should support eDP and DP modes, so most of the configuration
> > tables need to be updated/fixed. I tried going through all the tables,
> > but I never had time to do it in a sane and complete way. As you started
> > looking into it, would you please review programming for all chipsets
> > starting from SC8180X?
> > 
> I don't got the SC8180X PHY HPG permission now. once i got it, will check
> it's configuration and see what i can do. But first i want to correct the
> LeMans and Hamoa configuration and post the LDO change. Do you mean
> switching between the eDP and DP mode tables based on is_edp, instead of
> using a fixed table?

Based on the PHY being used in the eDP or DP modes (it is related but
not equivalent to the is_edp).

-- 
With best wishes
Dmitry

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox