From shawnguo2 at yeah.net  Sun Sep  1 01:07:01 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 1 Sep 2024 16:07:01 +0800
Subject: [PATCH v3 4/5] arm64: dts: imx95: add usb3 related nodes
In-Reply-To: <20240826070854.1948347-4-xu.yang_2@nxp.com>
References: <20240826070854.1948347-1-xu.yang_2@nxp.com>
 <20240826070854.1948347-4-xu.yang_2@nxp.com>
Message-ID: <ZtQgpYY9KjP9FUi5@dragon>

On Mon, Aug 26, 2024 at 03:08:53PM +0800, Xu Yang wrote:
> Add usb3 phy and controller nodes for imx95.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 
> ---
> Changes in v2:
>  - no changes
> Changes in v3:
>  - no changes
> ---
>  arch/arm64/boot/dts/freescale/imx95.dtsi | 43 ++++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
> index 1bbf9a0468f6..06a7c2f1e211 100644
> --- a/arch/arm64/boot/dts/freescale/imx95.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
> @@ -1188,5 +1188,48 @@ pcie1_ep: pcie-ep at 4c380000 {
>  			power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
>  			status = "disabled";
>  		};
> +
> +		usb3_phy: phy at 4c1f0040 {
> +			compatible = "fsl,imx95-usb-phy", "fsl,imx8mp-usb-phy";
> +			reg = <0x0 0x4c1f0040 0x0 0x40>,
> +			      <0x0 0x4c1fc000 0x0 0x100>;
> +			clocks = <&scmi_clk IMX95_CLK_HSIO>;
> +			clock-names = "phy";
> +			#phy-cells = <0>;
> +			power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> +			orientation-switch;
> +			status = "disabled";
> +		};
> +
> +		usb3: usb at 4c010010 {

Please try to sort nodes with unit-address in the address.

Shawn

> +			compatible = "fsl,imx95-dwc3", "fsl,imx8mp-dwc3";
> +			reg = <0x0 0x4c010010 0x0 0x04>,
> +			      <0x0 0x4c1f0000 0x0 0x20>;
> +			clocks = <&scmi_clk IMX95_CLK_HSIO>,
> +				 <&scmi_clk IMX95_CLK_32K>;
> +			clock-names = "hsio", "suspend";
> +			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
> +			#address-cells = <2>;
> +			#size-cells = <2>;
> +			ranges;
> +			power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> +			dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
> +			status = "disabled";
> +
> +			usb3_dwc3: usb at 4c100000 {
> +				compatible = "snps,dwc3";
> +				reg = <0x0 0x4c100000 0x0 0x10000>;
> +				clocks = <&scmi_clk IMX95_CLK_HSIO>,
> +					 <&scmi_clk IMX95_CLK_24M>,
> +					 <&scmi_clk IMX95_CLK_32K>;
> +				clock-names = "bus_early", "ref", "suspend";
> +				interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
> +				phys = <&usb3_phy>, <&usb3_phy>;
> +				phy-names = "usb2-phy", "usb3-phy";
> +				snps,gfladj-refclk-lpm-sel-quirk;
> +				snps,parkmode-disable-ss-quirk;
> +				iommus = <&smmu 0xe>;
> +			};
> +		};
>  	};
>  };
> -- 
> 2.34.1
> 



From vkoul at kernel.org  Sun Sep  1 09:32:54 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Sun, 1 Sep 2024 22:02:54 +0530
Subject: [PATCH v3 0/2] phy: qcom: qmp-pcie: Add support for Gen4 4-lane
 mode for X1E80100
In-Reply-To: <4ab9dcb6-4a0b-493c-943b-5de05457c592@kernel.org>
References: <20240823-x1e80100-phy-add-gen4x4-v3-0-b7765631ca01@linaro.org>
 <172495833400.405683.4328817324548517864.b4-ty@kernel.org>
 <4ab9dcb6-4a0b-493c-943b-5de05457c592@kernel.org>
Message-ID: <ZtSXNt5ZSrM2t5xK@vaman>

On 30-08-24, 12:01, Krzysztof Kozlowski wrote:
> On 29/08/2024 21:05, Vinod Koul wrote:
> > 
> > On Fri, 23 Aug 2024 10:04:14 +0300, Abel Vesa wrote:
> >> On all X Elite boards currently supported upstream, the NVMe sits
> >> on the PCIe 6. Until now that has been configured in dual lane mode
> >> only. The schematics reveal that the NVMe is actually using 4 lanes.
> >> So add support for the 4-lane mode and document the compatible for it.
> >>
> >> This patchset depends on:
> >> https://lore.kernel.org/all/20240805-phy-qcom-qmp-pcie-write-all-tbls-second-port-v3-1-6967c6bf61d1 at linaro.org/
> >>
> >> [...]
> > 
> > Applied, thanks!
> > 
> > [1/2] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the X1E80100 QMP PCIe PHY Gen4 x4
> >       commit: 0c5f4d23f77631f657b60ef660676303f7620688
> 
> Heh, we discussed yesterday on IRC that this should wait.

I must have miseed that...
 
> Why do we keep discussing things in private...

This ideally should have followed up as a reply to this thread...

-- 
~Vinod


From linux.amoon at gmail.com  Sun Sep  1 11:32:11 2024
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon,  2 Sep 2024 00:02:11 +0530
Subject: [PATCH v5 4/6] phy: rockchip-pcie: Simplify error handling with dev_err_probe()
In-Reply-To: <20240901183221.240361-1-linux.amoon@gmail.com>
References: <20240901183221.240361-1-linux.amoon@gmail.com>
Message-ID: <20240901183221.240361-5-linux.amoon@gmail.com>

Use the dev_err_probe() helper to simplify error handling during probe.
This also handle scenario, when -EDEFER is returned and useless error
is printed.

Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
v5: New patch in this series
---
 drivers/phy/rockchip/phy-rockchip-pcie.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-pcie.c b/drivers/phy/rockchip/phy-rockchip-pcie.c
index 51cc5ece0e63..51e636a1ce33 100644
--- a/drivers/phy/rockchip/phy-rockchip-pcie.c
+++ b/drivers/phy/rockchip/phy-rockchip-pcie.c
@@ -371,12 +371,9 @@ static int rockchip_pcie_phy_probe(struct platform_device *pdev)
 	mutex_init(&rk_phy->pcie_mutex);
 
 	rk_phy->phy_rst = devm_reset_control_get(dev, "phy");
-	if (IS_ERR(rk_phy->phy_rst)) {
-		if (PTR_ERR(rk_phy->phy_rst) != -EPROBE_DEFER)
-			dev_err(dev,
-				"missing phy property for reset controller\n");
-		return PTR_ERR(rk_phy->phy_rst);
-	}
+	if (IS_ERR(rk_phy->phy_rst))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rk_phy->phy_rst),
+				     "missing phy property for reset controller\n");
 
 	rk_phy->clk_pciephy_ref = devm_clk_get(dev, "refclk");
 	if (IS_ERR(rk_phy->clk_pciephy_ref)) {
-- 
2.44.0



From linux.amoon at gmail.com  Sun Sep  1 11:32:12 2024
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon,  2 Sep 2024 00:02:12 +0530
Subject: [PATCH v5 5/6] phy: rockchip-pcie: Change to use devm_clk_get_enabled() helper
In-Reply-To: <20240901183221.240361-1-linux.amoon@gmail.com>
References: <20240901183221.240361-1-linux.amoon@gmail.com>
Message-ID: <20240901183221.240361-6-linux.amoon@gmail.com>

Use devm_clk_get_enabled() instead of devm_clk_get() to make the code
cleaner and avoid calling clk_disable_unprepare(), as this is exactly
what this function does. Use the dev_err_probe() helper to simplify
error handling during probe.

Signed-off-by: Anand Moon <linux.amoon at gmail.com>
--
v5: New patch in this series
---
 drivers/phy/rockchip/phy-rockchip-pcie.c | 25 ++++++------------------
 1 file changed, 6 insertions(+), 19 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-pcie.c b/drivers/phy/rockchip/phy-rockchip-pcie.c
index 51e636a1ce33..a1b4b0323e9d 100644
--- a/drivers/phy/rockchip/phy-rockchip-pcie.c
+++ b/drivers/phy/rockchip/phy-rockchip-pcie.c
@@ -277,26 +277,16 @@ static int rockchip_pcie_phy_init(struct phy *phy)
 	if (rk_phy->init_cnt++)
 		goto err_out;
 
-	err = clk_prepare_enable(rk_phy->clk_pciephy_ref);
-	if (err) {
-		dev_err(&phy->dev, "Fail to enable pcie ref clock.\n");
-		goto err_refclk;
-	}
-
 	err = reset_control_assert(rk_phy->phy_rst);
 	if (err) {
 		dev_err(&phy->dev, "assert phy_rst err %d\n", err);
-		goto err_reset;
+		goto err_out;
 	}
 
-err_out:
 	mutex_unlock(&rk_phy->pcie_mutex);
 	return 0;
 
-err_reset:
-
-	clk_disable_unprepare(rk_phy->clk_pciephy_ref);
-err_refclk:
+err_out:
 	rk_phy->init_cnt--;
 	mutex_unlock(&rk_phy->pcie_mutex);
 	return err;
@@ -312,8 +302,6 @@ static int rockchip_pcie_phy_exit(struct phy *phy)
 	if (--rk_phy->init_cnt)
 		goto err_init_cnt;
 
-	clk_disable_unprepare(rk_phy->clk_pciephy_ref);
-
 err_init_cnt:
 	mutex_unlock(&rk_phy->pcie_mutex);
 	return 0;
@@ -375,11 +363,10 @@ static int rockchip_pcie_phy_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, PTR_ERR(rk_phy->phy_rst),
 				     "missing phy property for reset controller\n");
 
-	rk_phy->clk_pciephy_ref = devm_clk_get(dev, "refclk");
-	if (IS_ERR(rk_phy->clk_pciephy_ref)) {
-		dev_err(dev, "refclk not found.\n");
-		return PTR_ERR(rk_phy->clk_pciephy_ref);
-	}
+	rk_phy->clk_pciephy_ref = devm_clk_get_enabled(dev, "refclk");
+	if (IS_ERR(rk_phy->clk_pciephy_ref))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rk_phy->clk_pciephy_ref),
+				     "failed to get phyclk\n");
 
 	/* parse #phy-cells to see if it's legacy PHY model */
 	if (of_property_read_u32(dev->of_node, "#phy-cells", &phy_num))
-- 
2.44.0



From linux.amoon at gmail.com  Sun Sep  1 11:32:13 2024
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon,  2 Sep 2024 00:02:13 +0530
Subject: [PATCH v5 6/6] phy: rockchip-pcie: Use regmap_read_poll_timeout for PCIe reference clk PLL status
In-Reply-To: <20240901183221.240361-1-linux.amoon@gmail.com>
References: <20240901183221.240361-1-linux.amoon@gmail.com>
Message-ID: <20240901183221.240361-7-linux.amoon@gmail.com>

Replace open-coded phy PCIe reference clk PLL status polling with
regmap_read_poll_timeout API. This change simplifies the code without
altering functionality.

Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
v5: New patch in this seriese
---
 drivers/phy/rockchip/phy-rockchip-pcie.c | 56 +++++++-----------------
 1 file changed, 15 insertions(+), 41 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-pcie.c b/drivers/phy/rockchip/phy-rockchip-pcie.c
index a1b4b0323e9d..2c4d6f68f02a 100644
--- a/drivers/phy/rockchip/phy-rockchip-pcie.c
+++ b/drivers/phy/rockchip/phy-rockchip-pcie.c
@@ -162,7 +162,6 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
 	struct rockchip_pcie_phy *rk_phy = to_pcie_phy(inst);
 	int err = 0;
 	u32 status;
-	unsigned long timeout;
 
 	mutex_lock(&rk_phy->pcie_mutex);
 
@@ -191,21 +190,11 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
 	 * so we make it large enough here. And we use loop-break
 	 * method which should not be harmful.
 	 */
-	timeout = jiffies + msecs_to_jiffies(1000);
-
-	err = -EINVAL;
-	while (time_before(jiffies, timeout)) {
-		regmap_read(rk_phy->reg_base,
-			    rk_phy->phy_data->pcie_status,
-			    &status);
-		if (status & PHY_PLL_LOCKED) {
-			dev_dbg(&phy->dev, "pll locked!\n");
-			err = 0;
-			break;
-		}
-		msleep(20);
-	}
-
+	err = regmap_read_poll_timeout(rk_phy->reg_base,
+				       rk_phy->phy_data->pcie_status,
+				       status,
+				       status & PHY_PLL_LOCKED,
+				       200, 100000);
 	if (err) {
 		dev_err(&phy->dev, "pll lock timeout!\n");
 		goto err_pll_lock;
@@ -214,19 +203,11 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
 	phy_wr_cfg(rk_phy, PHY_CFG_CLK_TEST, PHY_CFG_SEPE_RATE);
 	phy_wr_cfg(rk_phy, PHY_CFG_CLK_SCC, PHY_CFG_PLL_100M);
 
-	err = -ETIMEDOUT;
-	while (time_before(jiffies, timeout)) {
-		regmap_read(rk_phy->reg_base,
-			    rk_phy->phy_data->pcie_status,
-			    &status);
-		if (!(status & PHY_PLL_OUTPUT)) {
-			dev_dbg(&phy->dev, "pll output enable done!\n");
-			err = 0;
-			break;
-		}
-		msleep(20);
-	}
-
+	err = regmap_read_poll_timeout(rk_phy->reg_base,
+				       rk_phy->phy_data->pcie_status,
+				       status,
+				       !(status & PHY_PLL_OUTPUT),
+				       200, 100000);
 	if (err) {
 		dev_err(&phy->dev, "pll output enable timeout!\n");
 		goto err_pll_lock;
@@ -236,19 +217,12 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
 		     HIWORD_UPDATE(PHY_CFG_PLL_LOCK,
 				   PHY_CFG_ADDR_MASK,
 				   PHY_CFG_ADDR_SHIFT));
-	err = -EINVAL;
-	while (time_before(jiffies, timeout)) {
-		regmap_read(rk_phy->reg_base,
-			    rk_phy->phy_data->pcie_status,
-			    &status);
-		if (status & PHY_PLL_LOCKED) {
-			dev_dbg(&phy->dev, "pll relocked!\n");
-			err = 0;
-			break;
-		}
-		msleep(20);
-	}
 
+	err = regmap_read_poll_timeout(rk_phy->reg_base,
+				       rk_phy->phy_data->pcie_status,
+				       status,
+				       status & PHY_PLL_LOCKED,
+				       200, 100000);
 	if (err) {
 		dev_err(&phy->dev, "pll relock timeout!\n");
 		goto err_pll_lock;
-- 
2.44.0



From dominique.martinet at atmark-techno.com  Sun Sep  1 14:46:18 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Mon, 2 Sep 2024 06:46:18 +0900
Subject: [RFC V3 3/3] phy: freescale: fsl-samsung-hdmi: Support dynamic
 integer
In-Reply-To: <CAHCN7x+xy+Y6o++Y5NdZaBJUsHV9Ru_2PwuH6G-2oz1juO=+rQ@mail.gmail.com>
References: <20240830032442.226031-1-aford173@gmail.com>
 <20240830032442.226031-3-aford173@gmail.com>
 <ZtFfBs4HEShmJKsi@atmark-techno.com>
 <CAHCN7x+xy+Y6o++Y5NdZaBJUsHV9Ru_2PwuH6G-2oz1juO=+rQ@mail.gmail.com>
Message-ID: <ZtTgqj3kBEc8sAjE@atmark-techno.com>

Adam Ford wrote on Fri, Aug 30, 2024 at 10:04:41AM -0500:
> > So, as far as I'm concerned I'd be happy to move forward with that and
> > will backport this to our tree/remove our kludged values, would "just"
> > need to properly pick the closest value if no exact match instead of
> > always falling back to the table (or just remove the table altogether if
> > we can test a few monitors?)
> 
> I took that step on my local build machine to remove the integer
> divider stuff from the LUT since it can be found automatically.  I
> haven't committed them yet, but I'll likely add it to the series once
> submit it without the RFC.
> 
> I am also likely to update the rounding function to look at the delta
> between the closest LUT clock value and the closest integer clock
> value and use whichever is closest to the desired value.

Sounds good, thanks!

> > I'd change cur_cfg from pointer to the struct itself like this (partial
> > patch that probably won't even apply on your branch:)
> > ----
> > diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > index 9048cdc760c2..d7124604819c 100644
> > --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > @@ -402,7 +402,7 @@ struct fsl_samsung_hdmi_phy {
> >
> >         /* clk provider */
> >         struct clk_hw hw;
> > -       const struct phy_config *cur_cfg;
> > +       struct phy_config cur_cfg;
> >  };
> >
> >  static inline struct fsl_samsung_hdmi_phy *
> > @@ -562,9 +562,9 @@ static int phy_clk_set_rate(struct clk_hw *hw,
> >         if (i < 0)
> >                 return -EINVAL;
> >
> > -       phy->cur_cfg = &phy_pll_cfg[i];
> > +       phy->cur_cfg = phy_pll_cfg[i];
> >
> > -       return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
> > +       return fsl_samsung_hdmi_phy_configure(phy, &phy->cur_cfg);
> >  }
> >
> >  static const struct clk_ops phy_clk_ops = {
> > ----
> >
> > Then you can just set it directly for calculated values.
> > But conceptually it's the same, just one less indirection.
> 
> I was thinking about that, but I wasn't sure the impact of
> un-const-ing would have on the LUT.
> 
> Using the extra indirection minimizes the impact of changes to the LUT
> and how its handled by the compiler.

The LUT has to stay const, you don't want something modifying it by
mistake; my suggestion makes cur_cfg a copy which does not need to be
const and the assignment (`phy->cur_cfg = phy_pll_cfg[i];`) is
equivalent to a memcpy -- the struct is small enough that the cost of
copying it if the value didn't match is negligible in my opinion.

With that said, I'm not saying you must do this, this just avoids using
a static value which could be problematic if there are multiple parallel
uses of the driver, go ahead with whatever you prefer for v4.
(note my approach doesn't fix the same problem if the driver is
used twice in parallel.. is it possible that e.g. one kernel thread
calls phy_clk_set_rate() while another thread checks something about the
hardware and calls phy_clk_round_rate()? If so neither approach is
correct and we can't easily skip recomputing, and it'd be better to just
have a phy_config struct on the stack instead -- on my imx8mp it takes
4.7us without -O, 0.6us with -O2 to compute; I *think* we can affort to
recompute every time...)

-- 
Dominique




From biju.das.jz at bp.renesas.com  Mon Sep  2 00:54:09 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Mon, 2 Sep 2024 07:54:09 +0000
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>

Hi Claudiu,

> -----Original Message-----
> From: Biju Das
> Sent: Saturday, August 31, 2024 6:14 AM
> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
> 
> Hi Claudiu,
> 
> > -----Original Message-----
> > From: claudiu beznea <claudiu.beznea at tuxon.dev>
> > Sent: Friday, August 30, 2024 9:23 AM
> > Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
> > RZ/G3S SoC
> >
> > Hi, Ulf,
> >
> > On 29.08.2024 18:26, Ulf Hansson wrote:
> > > On Thu, 22 Aug 2024 at 17:28, Claudiu <claudiu.beznea at tuxon.dev> wrote:
> > >>
> > >> From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> > >>
> > >> Hi,
> > >>
> > >> Series adds initial USB support for the Renesas RZ/G3S SoC.
> > >>
> > >> Series is split as follows:
> > >>
> > >> - patch 01/16           - add clock reset and power domain support for USB
> > >> - patch 02-04/16        - add reset control support for a USB signal
> > >>                           that need to be controlled before/after
> > >>                           the power to USB area is turned on/off.
> > >>
> > >>                           Philipp, Ulf, Geert, all,
> > >>
> > >>                           I detailed my approach for this in patch
> > >>                           04/16, please have a look and let me know
> > >>                           your input.
> > >
> > > I have looked briefly. Your suggested approach may work, but I have
> > > a few thoughts, see below.
> > >
> > > If I understand correctly, it is the consumer driver for the device
> > > that is attached to the USB power domain that becomes responsible
> > > for asserting/de-asserting this new signal. Right?
> >
> > Right!
> >
> > >
> > > In this regard, please note that the consumer driver doesn't really
> > > know when the power domain really gets powered-on/off. Calling
> > > pm_runtime_get|put*() is dealing with the reference counting. For
> > > example, a call to pm_runtime_get*() just makes sure that the PM
> > > domain gets-or-remains powered-on. Could this be a problem from the
> > > reset-signal point of view?
> >
> > It should be safe. From the HW manual I understand the hardware block is something like the
> following:
> >
> >
> >                   USB area
> >          +-------------------------+
> >          |                         |
> >          | PHY --->USB controller  |
> > SYSC --> |  ^                      |
> >          |  |                      |
> >          | PHY reset               |
> >          +-------------------------+
> 
> How USB PWRRDY signal is connected to USB?
> 
> USB block consists of PHY control, PHY, USB HOST and USB OTG Controller IPs.
> 
> Is it connected to top level block or connected to each IP's for turning off the USB region power?
> 
> ? Or Just PHY (HW manual mentions for AWO, the USB PWRRDY signal->USB PHY PWRRDY signal control)?

As per the update from HW team,

"SYS_USB_PWRRDY and SYS_PCIE_RST_RSM_B are used when transition from ALL_ON to AWO (or from AWO to ALL_ON).

Refer to step 8,9 in Table 41.10 Example Transition Flow Outline from ALL_ON Mode to AWO Mode.
Refer to step 9,10 in Table 41.11 Example Transition Flow Outline from AWO Mode to ALL_ON Mode.

When turning off USB PHY and PCIe PHY, if they are not controlled, PHY may break."

Do you have any plan to control this power transitions(ALL_ON to AWO and vice versa) in linux? 

Cheers,
Biju
 

From xu.yang_2 at nxp.com  Mon Sep  2 01:20:22 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Mon, 2 Sep 2024 16:20:22 +0800
Subject: [PATCH v3 3/5] phy: fsl-imx8mq-usb: add tca function driver for
 imx95
In-Reply-To: <ZtC5HqOzgDBYc8uW@vaman>
References: <20240826070854.1948347-1-xu.yang_2@nxp.com>
 <20240826070854.1948347-3-xu.yang_2@nxp.com>
 <ZtC5HqOzgDBYc8uW@vaman>
Message-ID: <20240902082022.32kg6szwuamme7hw@hippo>

On Thu, Aug 29, 2024 at 11:38:30PM +0530, Vinod Koul wrote:
> On 26-08-24, 15:08, Xu Yang wrote:
> > The i.MX95 USB3 phy has a Type-C Assist block (TCA). This block consists
> > two functional blocks (XBar assist and VBus assist) and one system
> > access interface using APB.
> > 
> > The primary functionality of XBar assist is:
> >  - switching lane for flip
> >  - moving unused lanes into lower power states.
> > 
> > This info can be get from:
> > i.MX95 RM Chapter 163.3.8 Type-C assist (TCA) block.
> > 
> > This will add support for TCA block to achieve lane switching and tca
> > lower power functionality.
> > 
> > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> > Reviewed-by: Jun Li <jun.li at nxp.com>
> > 
> > ---
> > Changes in v2:
> >  - return the value of imx95_usb_phy_get_tca()
> > Changes in v3:
> >  - no changes
> > ---
> >  drivers/phy/freescale/Kconfig              |   1 +
> >  drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 240 +++++++++++++++++++++
> >  2 files changed, 241 insertions(+)
> > 
> > diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
> > index dcd9acff6d01..81f53564ee15 100644
> > --- a/drivers/phy/freescale/Kconfig
> > +++ b/drivers/phy/freescale/Kconfig
> > @@ -5,6 +5,7 @@ if (ARCH_MXC && ARM64) || COMPILE_TEST
> >  config PHY_FSL_IMX8MQ_USB
> >  	tristate "Freescale i.MX8M USB3 PHY"
> >  	depends on OF && HAS_IOMEM
> > +	depends on TYPEC || TYPEC=n
> >  	select GENERIC_PHY
> >  	default ARCH_MXC && ARM64
> >  
> > diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > index adc6394626ce..8bd6d91951a2 100644
> > --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > @@ -10,6 +10,7 @@
> >  #include <linux/phy/phy.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/regulator/consumer.h>
> > +#include <linux/usb/typec_mux.h>
> >  
> >  #define PHY_CTRL0			0x0
> >  #define PHY_CTRL0_REF_SSP_EN		BIT(2)
> > @@ -50,11 +51,66 @@
> >  
> >  #define PHY_TUNE_DEFAULT		0xffffffff
> >  
> > +#define TCA_CLK_RST			0x00
> > +#define TCA_CLK_RST_SW			BIT(9)
> > +#define TCA_CLK_RST_REF_CLK_EN		BIT(1)
> > +#define TCA_CLK_RST_SUSPEND_CLK_EN	BIT(0)
> > +
> > +#define TCA_INTR_EN			0x04
> > +#define TCA_INTR_STS			0x08
> > +
> > +#define TCA_GCFG			0x10
> > +#define TCA_GCFG_ROLE_HSTDEV		BIT(4)
> > +#define TCA_GCFG_OP_MODE		GENMASK(1, 0)
> > +#define TCA_GCFG_OP_MODE_SYSMODE	0
> > +#define TCA_GCFG_OP_MODE_SYNCMODE	1
> > +
> > +#define TCA_TCPC			0x14
> > +#define TCA_TCPC_VALID			BIT(4)
> > +#define TCA_TCPC_LOW_POWER_EN		BIT(3)
> > +#define TCA_TCPC_ORIENTATION_NORMAL	BIT(2)
> > +#define TCA_TCPC_MUX_CONTRL		GENMASK(1, 0)
> > +#define TCA_TCPC_MUX_CONTRL_NO_CONN	0
> > +#define TCA_TCPC_MUX_CONTRL_USB_CONN	1
> > +
> > +#define TCA_SYSMODE_CFG			0x18
> > +#define TCA_SYSMODE_TCPC_DISABLE	BIT(3)
> > +#define TCA_SYSMODE_TCPC_FLIP		BIT(2)
> > +
> > +#define TCA_CTRLSYNCMODE_CFG0		0x20
> > +#define TCA_CTRLSYNCMODE_CFG1           0x20
> > +
> > +#define TCA_PSTATE			0x30
> > +#define TCA_PSTATE_CM_STS		BIT(4)
> > +#define TCA_PSTATE_TX_STS		BIT(3)
> > +#define TCA_PSTATE_RX_PLL_STS		BIT(2)
> > +#define TCA_PSTATE_PIPE0_POWER_DOWN	GENMASK(1, 0)
> > +
> > +#define TCA_GEN_STATUS			0x34
> > +#define TCA_GEN_DEV_POR			BIT(12)
> > +#define TCA_GEN_REF_CLK_SEL		BIT(8)
> > +#define TCA_GEN_TYPEC_FLIP_INVERT	BIT(4)
> > +#define TCA_GEN_PHY_TYPEC_DISABLE	BIT(3)
> > +#define TCA_GEN_PHY_TYPEC_FLIP		BIT(2)
> > +
> > +#define TCA_VBUS_CTRL			0x40
> > +#define TCA_VBUS_STATUS			0x44
> > +
> > +#define TCA_INFO			0xFC
> > +
> > +struct tca_blk {
> > +	struct typec_switch_dev *sw;
> > +	void __iomem *base;
> > +	struct mutex mutex;
> > +	enum typec_orientation orientation;
> > +};
> > +
> >  struct imx8mq_usb_phy {
> >  	struct phy *phy;
> >  	struct clk *clk;
> >  	void __iomem *base;
> >  	struct regulator *vbus;
> > +	struct tca_blk *tca;
> >  	u32 pcs_tx_swing_full;
> >  	u32 pcs_tx_deemph_3p5db;
> >  	u32 tx_vref_tune;
> > @@ -64,6 +120,170 @@ struct imx8mq_usb_phy {
> >  	u32 comp_dis_tune;
> >  };
> >  
> > +
> > +static void tca_blk_orientation_set(struct tca_blk *tca,
> > +				enum typec_orientation orientation);
> > +
> > +#ifdef CONFIG_TYPEC
> > +
> > +static int tca_blk_typec_switch_set(struct typec_switch_dev *sw,
> > +				enum typec_orientation orientation)
> > +{
> > +	struct imx8mq_usb_phy *imx_phy = typec_switch_get_drvdata(sw);
> > +	struct tca_blk *tca = imx_phy->tca;
> > +	int ret;
> > +
> > +	if (tca->orientation == orientation)
> > +		return 0;
> > +
> > +	ret = clk_prepare_enable(imx_phy->clk);
> > +	if (ret)
> > +		return ret;
> > +
> > +	tca_blk_orientation_set(tca, orientation);
> > +	clk_disable_unprepare(imx_phy->clk);
> > +
> > +	return 0;
> > +}
> > +
> > +static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device *pdev,
> > +					struct imx8mq_usb_phy *imx_phy)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct typec_switch_dev *sw;
> > +	struct typec_switch_desc sw_desc = { };
> > +
> > +	sw_desc.drvdata = imx_phy;
> > +	sw_desc.fwnode = dev->fwnode;
> > +	sw_desc.set = tca_blk_typec_switch_set;
> > +	sw_desc.name = NULL;
> > +
> > +	sw = typec_switch_register(dev, &sw_desc);
> > +	if (IS_ERR(sw)) {
> > +		dev_err(dev, "Error register tca orientation switch: %ld",
> > +				PTR_ERR(sw));
> > +		return NULL;
> > +	}
> > +
> > +	return sw;
> > +}
> > +
> > +static void tca_blk_put_typec_switch(struct typec_switch_dev *sw)
> > +{
> > +	typec_switch_unregister(sw);
> > +}
> > +
> > +#else
> > +
> > +static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device *pdev,
> > +			struct imx8mq_usb_phy *imx_phy)
> > +{
> > +	return NULL;
> > +}
> > +
> > +static void tca_blk_put_typec_switch(struct typec_switch_dev *sw) {}
> > +
> > +#endif /* CONFIG_TYPEC */
> > +
> > +static void tca_blk_orientation_set(struct tca_blk *tca,
> > +				enum typec_orientation orientation)
> > +{
> > +	u32 val;
> > +
> > +	mutex_lock(&tca->mutex);
> > +
> > +	if (orientation == TYPEC_ORIENTATION_NONE) {
> > +		/*
> > +		 * use Controller Synced Mode for TCA low power enable and
> > +		 * put PHY to USB safe state.
> > +		 */
> > +		val = readl(tca->base + TCA_GCFG);
> > +		val = FIELD_PREP(TCA_GCFG_OP_MODE, TCA_GCFG_OP_MODE_SYNCMODE);
> > +		writel(val, tca->base + TCA_GCFG);
> > +
> > +		val = readl(tca->base + TCA_TCPC);
> > +		val = TCA_TCPC_VALID | TCA_TCPC_LOW_POWER_EN;
> > +		writel(val, tca->base + TCA_TCPC);
> > +
> > +		goto out;
> > +	}
> > +
> > +	/* use System Configuration Mode for TCA mux control. */
> > +	val = readl(tca->base + TCA_GCFG);
> > +	val = FIELD_PREP(TCA_GCFG_OP_MODE, TCA_GCFG_OP_MODE_SYSMODE);
> > +	writel(val, tca->base + TCA_GCFG);
> > +
> > +	/* Disable TCA module */
> > +	val = readl(tca->base + TCA_SYSMODE_CFG);
> > +	val |= TCA_SYSMODE_TCPC_DISABLE;
> > +	writel(val, tca->base + TCA_SYSMODE_CFG);
> > +
> > +	if (orientation == TYPEC_ORIENTATION_REVERSE)
> > +		val |= TCA_SYSMODE_TCPC_FLIP;
> > +	else if (orientation == TYPEC_ORIENTATION_NORMAL)
> > +		val &= ~TCA_SYSMODE_TCPC_FLIP;
> > +
> > +	writel(val, tca->base + TCA_SYSMODE_CFG);
> > +
> > +	/* Enable TCA module */
> > +	val &= ~TCA_SYSMODE_TCPC_DISABLE;
> > +	writel(val, tca->base + TCA_SYSMODE_CFG);
> > +
> > +out:
> > +	tca->orientation = orientation;
> > +	mutex_unlock(&tca->mutex);
> > +}
> > +
> > +static void tca_blk_init(struct tca_blk *tca)
> > +{
> > +	u32 val;
> > +
> > +	/* reset XBar block */
> > +	val = readl(tca->base + TCA_CLK_RST);
> > +	val &= ~TCA_CLK_RST_SW;
> > +	writel(val, tca->base + TCA_CLK_RST);
> > +
> > +	udelay(100);
> > +
> > +	/* clear reset */
> > +	val |= TCA_CLK_RST_SW;
> > +	writel(val, tca->base + TCA_CLK_RST);
> > +
> > +	tca_blk_orientation_set(tca, tca->orientation);
> > +}
> > +
> > +static struct tca_blk *imx95_usb_phy_get_tca(struct platform_device *pdev,
> > +				struct imx8mq_usb_phy *imx_phy)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct tca_blk *tca;
> > +
> > +	tca = devm_kzalloc(dev, sizeof(*tca), GFP_KERNEL);
> > +	if (!tca)
> > +		return ERR_PTR(-ENOMEM);
> > +
> > +	tca->base = devm_platform_ioremap_resource(pdev, 1);
> > +	if (IS_ERR(tca->base))
> > +		return tca->base;
> > +
> > +	mutex_init(&tca->mutex);
> > +
> > +	tca->orientation = TYPEC_ORIENTATION_NORMAL;
> > +	tca->sw = tca_blk_get_typec_switch(pdev, imx_phy);
> > +
> > +	return tca;
> > +}
> > +
> > +static void imx95_usb_phy_put_tca(struct imx8mq_usb_phy *imx_phy)
> > +{
> > +	struct tca_blk *tca = imx_phy->tca;
> > +
> > +	if (!tca)
> > +		return;
> > +
> > +	tca_blk_put_typec_switch(tca->sw);
> > +}
> > +
> >  static u32 phy_tx_vref_tune_from_property(u32 percent)
> >  {
> >  	percent = clamp(percent, 94U, 124U);
> > @@ -315,6 +535,9 @@ static int imx8mp_usb_phy_init(struct phy *phy)
> >  
> >  	imx8m_phy_tune(imx_phy);
> >  
> > +	if (imx_phy->tca)
> > +		tca_blk_init(imx_phy->tca);
> > +
> >  	return 0;
> >  }
> >  
> > @@ -359,6 +582,8 @@ static const struct of_device_id imx8mq_usb_phy_of_match[] = {
> >  	 .data = &imx8mq_usb_phy_ops,},
> >  	{.compatible = "fsl,imx8mp-usb-phy",
> >  	 .data = &imx8mp_usb_phy_ops,},
> > +	{.compatible = "fsl,imx95-usb-phy",
> > +	 .data = &imx8mp_usb_phy_ops,},
> 
> Okay
> 
> >  	{ }
> >  };
> >  MODULE_DEVICE_TABLE(of, imx8mq_usb_phy_of_match);
> > @@ -398,6 +623,13 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
> >  
> >  	phy_set_drvdata(imx_phy->phy, imx_phy);
> >  
> > +	if (device_is_compatible(dev, "fsl,imx95-usb-phy")) {
> 
> so future version will also have this check, so are we going to increase
> this..? maybe better idea is to expand imx8mp_usb_phy_ops and add a flag
> for tca support and set that for required compatible, or make this a
> property?

Ok. It seems like a potential issue. Your advice sounds good. Will try it.

Thanks,
Xu Yang

> 
> 
> > +		imx_phy->tca = imx95_usb_phy_get_tca(pdev, imx_phy);
> > +		if (IS_ERR(imx_phy->tca))
> > +			return dev_err_probe(dev, PTR_ERR(imx_phy->tca),
> > +						"failed to get tca\n");
> > +	}
> > +
> >  	imx8m_get_phy_tuning_data(imx_phy);
> >  
> >  	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> > @@ -405,8 +637,16 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
> >  	return PTR_ERR_OR_ZERO(phy_provider);
> >  }
> >  
> > +static void imx8mq_usb_phy_remove(struct platform_device *pdev)
> > +{
> > +	struct imx8mq_usb_phy *imx_phy = platform_get_drvdata(pdev);
> > +
> > +	imx95_usb_phy_put_tca(imx_phy);
> > +}
> > +
> >  static struct platform_driver imx8mq_usb_phy_driver = {
> >  	.probe	= imx8mq_usb_phy_probe,
> > +	.remove = imx8mq_usb_phy_remove,
> >  	.driver = {
> >  		.name	= "imx8mq-usb-phy",
> >  		.of_match_table	= imx8mq_usb_phy_of_match,
> > -- 
> > 2.34.1
> 
> -- 
> ~Vinod


From xu.yang_2 at nxp.com  Mon Sep  2 01:21:26 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Mon, 2 Sep 2024 16:21:26 +0800
Subject: [PATCH v3 4/5] arm64: dts: imx95: add usb3 related nodes
In-Reply-To: <ZtQgpYY9KjP9FUi5@dragon>
References: <20240826070854.1948347-1-xu.yang_2@nxp.com>
 <20240826070854.1948347-4-xu.yang_2@nxp.com>
 <ZtQgpYY9KjP9FUi5@dragon>
Message-ID: <20240902082126.spmo5ifgzqlf7gm4@hippo>

On Sun, Sep 01, 2024 at 04:07:01PM +0800, Shawn Guo wrote:
> On Mon, Aug 26, 2024 at 03:08:53PM +0800, Xu Yang wrote:
> > Add usb3 phy and controller nodes for imx95.
> > 
> > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> > 
> > ---
> > Changes in v2:
> >  - no changes
> > Changes in v3:
> >  - no changes
> > ---
> >  arch/arm64/boot/dts/freescale/imx95.dtsi | 43 ++++++++++++++++++++++++
> >  1 file changed, 43 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
> > index 1bbf9a0468f6..06a7c2f1e211 100644
> > --- a/arch/arm64/boot/dts/freescale/imx95.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
> > @@ -1188,5 +1188,48 @@ pcie1_ep: pcie-ep at 4c380000 {
> >  			power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> >  			status = "disabled";
> >  		};
> > +
> > +		usb3_phy: phy at 4c1f0040 {
> > +			compatible = "fsl,imx95-usb-phy", "fsl,imx8mp-usb-phy";
> > +			reg = <0x0 0x4c1f0040 0x0 0x40>,
> > +			      <0x0 0x4c1fc000 0x0 0x100>;
> > +			clocks = <&scmi_clk IMX95_CLK_HSIO>;
> > +			clock-names = "phy";
> > +			#phy-cells = <0>;
> > +			power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> > +			orientation-switch;
> > +			status = "disabled";
> > +		};
> > +
> > +		usb3: usb at 4c010010 {
> 
> Please try to sort nodes with unit-address in the address.

Okay. Will fix it.

Thanks,
Xu Yang

> 
> Shawn
> 
> > +			compatible = "fsl,imx95-dwc3", "fsl,imx8mp-dwc3";
> > +			reg = <0x0 0x4c010010 0x0 0x04>,
> > +			      <0x0 0x4c1f0000 0x0 0x20>;
> > +			clocks = <&scmi_clk IMX95_CLK_HSIO>,
> > +				 <&scmi_clk IMX95_CLK_32K>;
> > +			clock-names = "hsio", "suspend";
> > +			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
> > +			#address-cells = <2>;
> > +			#size-cells = <2>;
> > +			ranges;
> > +			power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> > +			dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
> > +			status = "disabled";
> > +
> > +			usb3_dwc3: usb at 4c100000 {
> > +				compatible = "snps,dwc3";
> > +				reg = <0x0 0x4c100000 0x0 0x10000>;
> > +				clocks = <&scmi_clk IMX95_CLK_HSIO>,
> > +					 <&scmi_clk IMX95_CLK_24M>,
> > +					 <&scmi_clk IMX95_CLK_32K>;
> > +				clock-names = "bus_early", "ref", "suspend";
> > +				interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
> > +				phys = <&usb3_phy>, <&usb3_phy>;
> > +				phy-names = "usb2-phy", "usb3-phy";
> > +				snps,gfladj-refclk-lpm-sel-quirk;
> > +				snps,parkmode-disable-ss-quirk;
> > +				iommus = <&smmu 0xe>;
> > +			};
> > +		};
> >  	};
> >  };
> > -- 
> > 2.34.1
> > 
> 


From claudiu.beznea at tuxon.dev  Mon Sep  2 01:28:25 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Mon, 2 Sep 2024 11:28:25 +0300
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <90df82c1-bb09-4c91-ba7f-af328066bd43@tuxon.dev>



On 31.08.2024 08:13, Biju Das wrote:
> Hi Claudiu,
> 
>> -----Original Message-----
>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>> Sent: Friday, August 30, 2024 9:23 AM
>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
>>
>> Hi, Ulf,
>>
>> On 29.08.2024 18:26, Ulf Hansson wrote:
>>> On Thu, 22 Aug 2024 at 17:28, Claudiu <claudiu.beznea at tuxon.dev> wrote:
>>>>
>>>> From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>>>>
>>>> Hi,
>>>>
>>>> Series adds initial USB support for the Renesas RZ/G3S SoC.
>>>>
>>>> Series is split as follows:
>>>>
>>>> - patch 01/16           - add clock reset and power domain support for USB
>>>> - patch 02-04/16        - add reset control support for a USB signal
>>>>                           that need to be controlled before/after
>>>>                           the power to USB area is turned on/off.
>>>>
>>>>                           Philipp, Ulf, Geert, all,
>>>>
>>>>                           I detailed my approach for this in patch
>>>>                           04/16, please have a look and let me know
>>>>                           your input.
>>>
>>> I have looked briefly. Your suggested approach may work, but I have a
>>> few thoughts, see below.
>>>
>>> If I understand correctly, it is the consumer driver for the device
>>> that is attached to the USB power domain that becomes responsible for
>>> asserting/de-asserting this new signal. Right?
>>
>> Right!
>>
>>>
>>> In this regard, please note that the consumer driver doesn't really
>>> know when the power domain really gets powered-on/off. Calling
>>> pm_runtime_get|put*() is dealing with the reference counting. For
>>> example, a call to pm_runtime_get*() just makes sure that the PM
>>> domain gets-or-remains powered-on. Could this be a problem from the
>>> reset-signal point of view?
>>
>> It should be safe. From the HW manual I understand the hardware block is something like the following:
>>
>>
>>                   USB area
>>          +-------------------------+
>>          |                         |
>>          | PHY --->USB controller  |
>> SYSC --> |  ^                      |
>>          |  |                      |
>>          | PHY reset               |
>>          +-------------------------+
> 
> How USB PWRRDY signal is connected to USB? 

HW manual mentions this in the chapter describing the SYS_USB_PWRRDY register:

Controls PWRRDY terminal of USB

0: PWRRDY

1: PWRRDY down

When turning off the *USB region* power, set this bit to 1.

When turning on the *USB region* power, set this bit to 0

By USB region I get the that it is related to the SoC area where resides
all the USB IPs. I cannot tell more than what is in the hardware manual.


> 
> USB block consists of PHY control, PHY, USB HOST and USB OTG Controller IPs.
> 
> Is it connected to top level block or connected to each IP's for turning off the USB region power?

I cannot tell more than it is in the hardware manual.

> 
> ? Or Just PHY (HW manual mentions for AWO, the USB PWRRDY signal->USB PHY PWRRDY signal control)?
> 
> If the USBPWRRDY signal is connected across modules with this reset signal approach
> then you may need to update bindings [1] with that reset signal
> 
> [1] https://patchwork.kernel.org/project/linux-renesas-soc/patch/20240822152801.602318-12-claudiu.beznea.uj at bp.renesas.com/

If that is true, then this signal may need to be routed to the PHY for
better hardware description.

>  
> 
> Cheers,
> Biju
> 
>>
>> Where:
>> - SYSC is the system controller that controls the new signal for which
>>   I'm requesting opinions in this series
>> - PHY reset: is the block controlling the PHYs
>> - PHY: is the block controlling the USB PHYs
>> - USB controller: is the USB controller
>>
>> Currently, I passed the SYSC signal handling to the PHY reset driver; w/o PHY reset the rest of the
>> USB logic cannot work (neither PHY block nor USB controller).
>>
>> Currently, the PHY reset driver call pm_runtime_resume_and_get() in probe and pm_runtime_put() in
>> remove. The struct reset_control_ops::{assert, deassert} only set specific bits in registers (no
>> pm_runtime* calls).
>>
>> The PHY driver is taking its PHY reset in probe and release it in remove().
>> With this approach the newly introduced SYSC signal will be de-asserted/asserted only in the PHY reset
>> probe/remove (either if it is handled though PM domain or reset control signal).
>>
>> If the SYSC signal would be passed to all the blocks in the USB area (and it would be handled though
>> PM domains) it should be no problem either, AFAICT, because of reference counting the
>> pm_runtime_get|put*() is taking care of. As the PHY reset is the root node the in the devices node
>> tree for USB the reference counting should work, too (I may miss something though, please correct me
>> if I'm wrong).
>>
>> If the SYSC signal would be handled though a reset control driver (as proposed in this series) and we
>> want to pass this reference to all the blocks in the USB area then we can request the reset signal as
>> shared and, AFAIK, this is also reference counted. The devices node tree should help with the order,
>> too, if I'm not wrong.
>>
>> Thank you for looking at this,
>> Claudiu Beznea
>>
>>>
>>> [...]
>>>
>>> Kind regards
>>> Uffe


From claudiu.beznea at tuxon.dev  Mon Sep  2 01:47:24 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Mon, 2 Sep 2024 11:47:24 +0300
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>

Hi, Biju,

On 02.09.2024 10:54, Biju Das wrote:
> Hi Claudiu,
> 
>> -----Original Message-----
>> From: Biju Das
>> Sent: Saturday, August 31, 2024 6:14 AM
>> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
>>
>> Hi Claudiu,
>>
>>> -----Original Message-----
>>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>>> Sent: Friday, August 30, 2024 9:23 AM
>>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
>>> RZ/G3S SoC
>>>
>>> Hi, Ulf,
>>>
>>> On 29.08.2024 18:26, Ulf Hansson wrote:
>>>> On Thu, 22 Aug 2024 at 17:28, Claudiu <claudiu.beznea at tuxon.dev> wrote:
>>>>>
>>>>> From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>>>>>
>>>>> Hi,
>>>>>
>>>>> Series adds initial USB support for the Renesas RZ/G3S SoC.
>>>>>
>>>>> Series is split as follows:
>>>>>
>>>>> - patch 01/16           - add clock reset and power domain support for USB
>>>>> - patch 02-04/16        - add reset control support for a USB signal
>>>>>                           that need to be controlled before/after
>>>>>                           the power to USB area is turned on/off.
>>>>>
>>>>>                           Philipp, Ulf, Geert, all,
>>>>>
>>>>>                           I detailed my approach for this in patch
>>>>>                           04/16, please have a look and let me know
>>>>>                           your input.
>>>>
>>>> I have looked briefly. Your suggested approach may work, but I have
>>>> a few thoughts, see below.
>>>>
>>>> If I understand correctly, it is the consumer driver for the device
>>>> that is attached to the USB power domain that becomes responsible
>>>> for asserting/de-asserting this new signal. Right?
>>>
>>> Right!
>>>
>>>>
>>>> In this regard, please note that the consumer driver doesn't really
>>>> know when the power domain really gets powered-on/off. Calling
>>>> pm_runtime_get|put*() is dealing with the reference counting. For
>>>> example, a call to pm_runtime_get*() just makes sure that the PM
>>>> domain gets-or-remains powered-on. Could this be a problem from the
>>>> reset-signal point of view?
>>>
>>> It should be safe. From the HW manual I understand the hardware block is something like the
>> following:
>>>
>>>
>>>                   USB area
>>>          +-------------------------+
>>>          |                         |
>>>          | PHY --->USB controller  |
>>> SYSC --> |  ^                      |
>>>          |  |                      |
>>>          | PHY reset               |
>>>          +-------------------------+
>>
>> How USB PWRRDY signal is connected to USB?
>>
>> USB block consists of PHY control, PHY, USB HOST and USB OTG Controller IPs.
>>
>> Is it connected to top level block or connected to each IP's for turning off the USB region power?
>>
>> ? Or Just PHY (HW manual mentions for AWO, the USB PWRRDY signal->USB PHY PWRRDY signal control)?
> 
> As per the update from HW team,
> 
> "SYS_USB_PWRRDY and SYS_PCIE_RST_RSM_B are used when transition from ALL_ON to AWO (or from AWO to ALL_ON).
> 
> Refer to step 8,9 in Table 41.10 Example Transition Flow Outline from ALL_ON Mode to AWO Mode.
> Refer to step 9,10 in Table 41.11 Example Transition Flow Outline from AWO Mode to ALL_ON Mode.

All this is not new information.

>From experiments, we need to control these signals also when booting as
intermediary booting application may control and leave it in improper
state. W/o having SYSC signals configured properly there is no chance for
USB to work (it should be the same for PCIe but I haven't explored it yet).

> 
> When turning off USB PHY and PCIe PHY, if they are not controlled, PHY may break."

>From experiments, I know this, as this is the reason the SYSC USB PWRRDY
has been implemented in Linux and proposed in this series.

> 
> Do you have any plan to control this power transitions(ALL_ON to AWO and vice versa) in linux? 

As you know, the RZ/G3S USB PM code is already prepared. This is also
configuring these signals when going to suspend/exiting from resume. W/o
configuring properly these signals the USB is not working after a
suspend/resume cycle.

Thank you,
Claudiu Beznea


> Cheers,
> Biju
>  


From biju.das.jz at bp.renesas.com  Mon Sep  2 01:53:37 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Mon, 2 Sep 2024 08:53:37 +0000
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
Message-ID: <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>

Hi Claudiu,

> -----Original Message-----
> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> Sent: Monday, September 2, 2024 9:47 AM
> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
> 
> Hi, Biju,
> 
> On 02.09.2024 10:54, Biju Das wrote:
> > Hi Claudiu,
> >
> >> -----Original Message-----
> >> From: Biju Das
> >> Sent: Saturday, August 31, 2024 6:14 AM
> >> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas
> >> RZ/G3S SoC
> >>
> >> Hi Claudiu,
> >>
> >>> -----Original Message-----
> >>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> >>> Sent: Friday, August 30, 2024 9:23 AM
> >>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
> >>> RZ/G3S SoC
> >>>
> >>> Hi, Ulf,
> >>>
> >>> On 29.08.2024 18:26, Ulf Hansson wrote:
> >>>> On Thu, 22 Aug 2024 at 17:28, Claudiu <claudiu.beznea at tuxon.dev> wrote:
> >>>>>
> >>>>> From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> >>>>>
> >>>>> Hi,
> >>>>>
> >>>>> Series adds initial USB support for the Renesas RZ/G3S SoC.
> >>>>>
> >>>>> Series is split as follows:
> >>>>>
> >>>>> - patch 01/16           - add clock reset and power domain support for USB
> >>>>> - patch 02-04/16        - add reset control support for a USB signal
> >>>>>                           that need to be controlled before/after
> >>>>>                           the power to USB area is turned on/off.
> >>>>>
> >>>>>                           Philipp, Ulf, Geert, all,
> >>>>>
> >>>>>                           I detailed my approach for this in patch
> >>>>>                           04/16, please have a look and let me know
> >>>>>                           your input.
> >>>>
> >>>> I have looked briefly. Your suggested approach may work, but I have
> >>>> a few thoughts, see below.
> >>>>
> >>>> If I understand correctly, it is the consumer driver for the device
> >>>> that is attached to the USB power domain that becomes responsible
> >>>> for asserting/de-asserting this new signal. Right?
> >>>
> >>> Right!
> >>>
> >>>>
> >>>> In this regard, please note that the consumer driver doesn't really
> >>>> know when the power domain really gets powered-on/off. Calling
> >>>> pm_runtime_get|put*() is dealing with the reference counting. For
> >>>> example, a call to pm_runtime_get*() just makes sure that the PM
> >>>> domain gets-or-remains powered-on. Could this be a problem from the
> >>>> reset-signal point of view?
> >>>
> >>> It should be safe. From the HW manual I understand the hardware
> >>> block is something like the
> >> following:
> >>>
> >>>
> >>>                   USB area
> >>>          +-------------------------+
> >>>          |                         |
> >>>          | PHY --->USB controller  |
> >>> SYSC --> |  ^                      |
> >>>          |  |                      |
> >>>          | PHY reset               |
> >>>          +-------------------------+
> >>
> >> How USB PWRRDY signal is connected to USB?
> >>
> >> USB block consists of PHY control, PHY, USB HOST and USB OTG Controller IPs.
> >>
> >> Is it connected to top level block or connected to each IP's for turning off the USB region power?
> >>
> >> ? Or Just PHY (HW manual mentions for AWO, the USB PWRRDY signal->USB PHY PWRRDY signal control)?
> >
> > As per the update from HW team,
> >
> > "SYS_USB_PWRRDY and SYS_PCIE_RST_RSM_B are used when transition from ALL_ON to AWO (or from AWO to
> ALL_ON).
> >
> > Refer to step 8,9 in Table 41.10 Example Transition Flow Outline from ALL_ON Mode to AWO Mode.
> > Refer to step 9,10 in Table 41.11 Example Transition Flow Outline from AWO Mode to ALL_ON Mode.
> 
> All this is not new information.
> 
> From experiments, we need to control these signals also when booting as intermediary booting
> application may control and leave it in improper state. W/o having SYSC signals configured properly
> there is no chance for USB to work (it should be the same for PCIe but I haven't explored it yet).
> 
> >
> > When turning off USB PHY and PCIe PHY, if they are not controlled, PHY may break."
> 
> From experiments, I know this, as this is the reason the SYSC USB PWRRDY has been implemented in Linux
> and proposed in this series.

You mean you call reset assert for USB PWRRDY signal for system transition (AWO Mode to ALL_ON Mode)??


 
> >
> > Do you have any plan to control this power transitions(ALL_ON to AWO and vice versa) in linux?
> 
> As you know, the RZ/G3S USB PM code is already prepared. This is also configuring these signals when
> going to suspend/exiting from resume. W/o configuring properly these signals the USB is not working
> after a suspend/resume cycle.

One option is to handle SYSC USB PWRRDY signal in TF-A, if you plan to handle system transitions there??

Cheers,
Biju




From claudiu.beznea at tuxon.dev  Mon Sep  2 02:14:20 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Mon, 2 Sep 2024 12:14:20 +0300
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>



On 02.09.2024 11:53, Biju Das wrote:
> Hi Claudiu,
> 
>> -----Original Message-----
>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>> Sent: Monday, September 2, 2024 9:47 AM
>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
>>
>> Hi, Biju,
>>
>> On 02.09.2024 10:54, Biju Das wrote:
>>> Hi Claudiu,
>>>
>>>> -----Original Message-----
>>>> From: Biju Das
>>>> Sent: Saturday, August 31, 2024 6:14 AM
>>>> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas
>>>> RZ/G3S SoC
>>>>
>>>> Hi Claudiu,
>>>>
>>>>> -----Original Message-----
>>>>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>>>>> Sent: Friday, August 30, 2024 9:23 AM
>>>>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
>>>>> RZ/G3S SoC
>>>>>
>>>>> Hi, Ulf,
>>>>>
>>>>> On 29.08.2024 18:26, Ulf Hansson wrote:
>>>>>> On Thu, 22 Aug 2024 at 17:28, Claudiu <claudiu.beznea at tuxon.dev> wrote:
>>>>>>>
>>>>>>> From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> Series adds initial USB support for the Renesas RZ/G3S SoC.
>>>>>>>
>>>>>>> Series is split as follows:
>>>>>>>
>>>>>>> - patch 01/16           - add clock reset and power domain support for USB
>>>>>>> - patch 02-04/16        - add reset control support for a USB signal
>>>>>>>                           that need to be controlled before/after
>>>>>>>                           the power to USB area is turned on/off.
>>>>>>>
>>>>>>>                           Philipp, Ulf, Geert, all,
>>>>>>>
>>>>>>>                           I detailed my approach for this in patch
>>>>>>>                           04/16, please have a look and let me know
>>>>>>>                           your input.
>>>>>>
>>>>>> I have looked briefly. Your suggested approach may work, but I have
>>>>>> a few thoughts, see below.
>>>>>>
>>>>>> If I understand correctly, it is the consumer driver for the device
>>>>>> that is attached to the USB power domain that becomes responsible
>>>>>> for asserting/de-asserting this new signal. Right?
>>>>>
>>>>> Right!
>>>>>
>>>>>>
>>>>>> In this regard, please note that the consumer driver doesn't really
>>>>>> know when the power domain really gets powered-on/off. Calling
>>>>>> pm_runtime_get|put*() is dealing with the reference counting. For
>>>>>> example, a call to pm_runtime_get*() just makes sure that the PM
>>>>>> domain gets-or-remains powered-on. Could this be a problem from the
>>>>>> reset-signal point of view?
>>>>>
>>>>> It should be safe. From the HW manual I understand the hardware
>>>>> block is something like the
>>>> following:
>>>>>
>>>>>
>>>>>                   USB area
>>>>>          +-------------------------+
>>>>>          |                         |
>>>>>          | PHY --->USB controller  |
>>>>> SYSC --> |  ^                      |
>>>>>          |  |                      |
>>>>>          | PHY reset               |
>>>>>          +-------------------------+
>>>>
>>>> How USB PWRRDY signal is connected to USB?
>>>>
>>>> USB block consists of PHY control, PHY, USB HOST and USB OTG Controller IPs.
>>>>
>>>> Is it connected to top level block or connected to each IP's for turning off the USB region power?
>>>>
>>>> ? Or Just PHY (HW manual mentions for AWO, the USB PWRRDY signal->USB PHY PWRRDY signal control)?
>>>
>>> As per the update from HW team,
>>>
>>> "SYS_USB_PWRRDY and SYS_PCIE_RST_RSM_B are used when transition from ALL_ON to AWO (or from AWO to
>> ALL_ON).
>>>
>>> Refer to step 8,9 in Table 41.10 Example Transition Flow Outline from ALL_ON Mode to AWO Mode.
>>> Refer to step 9,10 in Table 41.11 Example Transition Flow Outline from AWO Mode to ALL_ON Mode.
>>
>> All this is not new information.
>>
>> From experiments, we need to control these signals also when booting as intermediary booting
>> application may control and leave it in improper state. W/o having SYSC signals configured properly
>> there is no chance for USB to work (it should be the same for PCIe but I haven't explored it yet).
>>
>>>
>>> When turning off USB PHY and PCIe PHY, if they are not controlled, PHY may break."
>>
>> From experiments, I know this, as this is the reason the SYSC USB PWRRDY has been implemented in Linux
>> and proposed in this series.
> 
> You mean you call reset assert for USB PWRRDY signal for system transition (AWO Mode to ALL_ON Mode)??

reset assert on suspend, reset de-assert on resume.

And pm_runtime_put()/pm_runtime_resume_and_get() on the version where USB
PHYRDY is provided by SYSC as a PM domain. As I mentioned in the thread
with Ulf, this is something I explored locally.

All these are internal, not published in this version. This version just
adds initial bring-up support.

> 
> 
>  
>>>
>>> Do you have any plan to control this power transitions(ALL_ON to AWO and vice versa) in linux?
>>
>> As you know, the RZ/G3S USB PM code is already prepared. This is also configuring these signals when
>> going to suspend/exiting from resume. W/o configuring properly these signals the USB is not working
>> after a suspend/resume cycle.
> 
> One option is to handle SYSC USB PWRRDY signal in TF-A, if you plan to handle system transitions there??

As I mentioned, the settings in these registers may be changed by
intermediary booting applications. Depending on that, Linux need to control
it also on probe for USB to work (it should be the same with PCIe, these
signals seems similar from HW manual description).

Thank you,
Claudiu Beznea

> 
> Cheers,
> Biju
> 
> 
> 


From biju.das.jz at bp.renesas.com  Mon Sep  2 02:18:34 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Mon, 2 Sep 2024 09:18:34 +0000
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
Message-ID: <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>

Hi Claudiu,

> -----Original Message-----
> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> Sent: Monday, September 2, 2024 10:14 AM
> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
> 
> 
> 
> On 02.09.2024 11:53, Biju Das wrote:
> > Hi Claudiu,
> >
> >> -----Original Message-----
> >> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> >> Sent: Monday, September 2, 2024 9:47 AM
> >> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
> >> RZ/G3S SoC
> >>
> >> Hi, Biju,
> >>
> >> On 02.09.2024 10:54, Biju Das wrote:
> >>> Hi Claudiu,
> >>>
> >>>> -----Original Message-----
> >>>> From: Biju Das
> >>>> Sent: Saturday, August 31, 2024 6:14 AM
> >>>> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas
> >>>> RZ/G3S SoC
> >>>>
> >>>> Hi Claudiu,
> >>>>
> >>>>> -----Original Message-----
> >>>>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> >>>>> Sent: Friday, August 30, 2024 9:23 AM
> >>>>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
> >>>>> RZ/G3S SoC
> >>>>>
> >>>>> Hi, Ulf,
> >>>>>
> >>>>> On 29.08.2024 18:26, Ulf Hansson wrote:
> >>>>>> On Thu, 22 Aug 2024 at 17:28, Claudiu <claudiu.beznea at tuxon.dev> wrote:
> >>>>>>>
> >>>>>>> From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> >>>>>>>
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> Series adds initial USB support for the Renesas RZ/G3S SoC.
> >>>>>>>
> >>>>>>> Series is split as follows:
> >>>>>>>
> >>>>>>> - patch 01/16           - add clock reset and power domain support for USB
> >>>>>>> - patch 02-04/16        - add reset control support for a USB signal
> >>>>>>>                           that need to be controlled before/after
> >>>>>>>                           the power to USB area is turned on/off.
> >>>>>>>
> >>>>>>>                           Philipp, Ulf, Geert, all,
> >>>>>>>
> >>>>>>>                           I detailed my approach for this in patch
> >>>>>>>                           04/16, please have a look and let me know
> >>>>>>>                           your input.
> >>>>>>
> >>>>>> I have looked briefly. Your suggested approach may work, but I
> >>>>>> have a few thoughts, see below.
> >>>>>>
> >>>>>> If I understand correctly, it is the consumer driver for the
> >>>>>> device that is attached to the USB power domain that becomes
> >>>>>> responsible for asserting/de-asserting this new signal. Right?
> >>>>>
> >>>>> Right!
> >>>>>
> >>>>>>
> >>>>>> In this regard, please note that the consumer driver doesn't
> >>>>>> really know when the power domain really gets powered-on/off.
> >>>>>> Calling
> >>>>>> pm_runtime_get|put*() is dealing with the reference counting. For
> >>>>>> example, a call to pm_runtime_get*() just makes sure that the PM
> >>>>>> domain gets-or-remains powered-on. Could this be a problem from
> >>>>>> the reset-signal point of view?
> >>>>>
> >>>>> It should be safe. From the HW manual I understand the hardware
> >>>>> block is something like the
> >>>> following:
> >>>>>
> >>>>>
> >>>>>                   USB area
> >>>>>          +-------------------------+
> >>>>>          |                         |
> >>>>>          | PHY --->USB controller  |
> >>>>> SYSC --> |  ^                      |
> >>>>>          |  |                      |
> >>>>>          | PHY reset               |
> >>>>>          +-------------------------+
> >>>>
> >>>> How USB PWRRDY signal is connected to USB?
> >>>>
> >>>> USB block consists of PHY control, PHY, USB HOST and USB OTG Controller IPs.
> >>>>
> >>>> Is it connected to top level block or connected to each IP's for turning off the USB region
> power?
> >>>>
> >>>> ? Or Just PHY (HW manual mentions for AWO, the USB PWRRDY signal->USB PHY PWRRDY signal control)?
> >>>
> >>> As per the update from HW team,
> >>>
> >>> "SYS_USB_PWRRDY and SYS_PCIE_RST_RSM_B are used when transition from
> >>> ALL_ON to AWO (or from AWO to
> >> ALL_ON).
> >>>
> >>> Refer to step 8,9 in Table 41.10 Example Transition Flow Outline from ALL_ON Mode to AWO Mode.
> >>> Refer to step 9,10 in Table 41.11 Example Transition Flow Outline from AWO Mode to ALL_ON Mode.
> >>
> >> All this is not new information.
> >>
> >> From experiments, we need to control these signals also when booting
> >> as intermediary booting application may control and leave it in
> >> improper state. W/o having SYSC signals configured properly there is no chance for USB to work (it
> should be the same for PCIe but I haven't explored it yet).
> >>
> >>>
> >>> When turning off USB PHY and PCIe PHY, if they are not controlled, PHY may break."
> >>
> >> From experiments, I know this, as this is the reason the SYSC USB
> >> PWRRDY has been implemented in Linux and proposed in this series.
> >
> > You mean you call reset assert for USB PWRRDY signal for system transition (AWO Mode to ALL_ON
> Mode)??
> 
> reset assert on suspend, reset de-assert on resume.
> 
> And pm_runtime_put()/pm_runtime_resume_and_get() on the version where USB PHYRDY is provided by SYSC
> as a PM domain. As I mentioned in the thread with Ulf, this is something I explored locally.
> 
> All these are internal, not published in this version. This version just adds initial bring-up
> support.
> 
> >
> >
> >
> >>>
> >>> Do you have any plan to control this power transitions(ALL_ON to AWO and vice versa) in linux?
> >>
> >> As you know, the RZ/G3S USB PM code is already prepared. This is also
> >> configuring these signals when going to suspend/exiting from resume.
> >> W/o configuring properly these signals the USB is not working after a suspend/resume cycle.
> >
> > One option is to handle SYSC USB PWRRDY signal in TF-A, if you plan to handle system transitions
> there??
> 
> As I mentioned, the settings in these registers may be changed by intermediary booting applications.
> Depending on that, Linux need to control it also on probe for USB to work (it should be the same with
> PCIe, these signals seems similar from HW manual description).

You mean system transition settings will be override by U-boot, so Linux needs to restore it back??

Cheers,
Biju

From minda.chen at starfivetech.com  Mon Sep  2 02:19:29 2024
From: minda.chen at starfivetech.com (Minda Chen)
Date: Mon, 2 Sep 2024 09:19:29 +0000
Subject: [PATCH v2 1/3] dt-bindings: phy: jh7110-usb-phy: Add sys-syscon
 property
In-Reply-To: <20240815-endless-credible-324438d164f4@spud>
References: <cover.1723472153.git.jan.kiszka@siemens.com>
 <30f3ca9f6bd788e16767b36aa22c0e9dc4d1c6a4.1723472153.git.jan.kiszka@siemens.com>
 <20240812-overstuff-skirt-7a8aabbcdc6f@spud>
 <8cdba8b0-7364-4c09-b18a-f3f59da1eae2@siemens.com>
 <20240813-haiku-pusher-f2fb037a2f49@wendy>
 <SHXPR01MB08633B523DA1F6C5632F6D9DE6802@SHXPR01MB0863.CHNPR01.prod.partner.outlook.cn>
 <20240815-endless-credible-324438d164f4@spud>
Message-ID: <SHXPR01MB08632E50DFE53BE0CFAA99ABE6922@SHXPR01MB0863.CHNPR01.prod.partner.outlook.cn>



> 
> On Thu, Aug 15, 2024 at 10:33:55AM +0000, Minda Chen wrote:
> >
> >
> > >
> > > On Tue, Aug 13, 2024 at 07:31:50AM +0200, Jan Kiszka wrote:
> > > > On 12.08.24 17:55, Conor Dooley wrote:
> > > > > On Mon, Aug 12, 2024 at 04:15:51PM +0200, Jan Kiszka wrote:
> > > > >> From: Jan Kiszka <jan.kiszka at siemens.com>
> > > > >>
> > > > >> Analogously to the PCI PHY, access to sys_syscon is needed to
> > > > >> connect the USB PHY to its controller.
> > > > >>
> > > > >> Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
> > > > >> Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
> > > > >> ---
> > > > >> CC: Rob Herring <robh at kernel.org>
> > > > >> CC: Krzysztof Kozlowski <krzk+dt at kernel.org>
> > > > >> CC: Conor Dooley <conor+dt at kernel.org>
> > > > >> ---
> > > > >>  .../bindings/phy/starfive,jh7110-usb-phy.yaml         | 11
> > > +++++++++++
> > > > >>  1 file changed, 11 insertions(+)
> > > > >>
> > > > >> diff --git
> > > > >> a/Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy
> > > > >> .yam
> > > > >> l
> > > > >> b/Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy
> > > > >> .yam l index 269e9f9f12b6..eaf0050c6f17 100644
> > > > >> ---
> > > > >> a/Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy
> > > > >> .yam
> > > > >> l
> > > > >> +++ b/Documentation/devicetree/bindings/phy/starfive,jh7110-usb
> > > > >> +++ -phy
> > > > >> +++ .yaml
> > > > >> @@ -19,6 +19,16 @@ properties:
> > > > >>    "#phy-cells":
> > > > >>      const: 0
> > > > >>
> > > > >> +  starfive,sys-syscon:
> > > > >> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> > > > >> +    items:
> > > > >> +      - items:
> > > > >> +          - description: phandle to System Register Controller
> > > sys_syscon node.
> > > > >> +          - description: PHY connect offset of
> > > SYS_SYSCONSAIF__SYSCFG register for USB PHY.
> > > > >
> > > > > Why is having a new property for this required? The devicetree
> > > > > only has a single usb phy, so isn't it sufficient to look up the
> > > > > syscon by compatible, rather than via phandle + offset?
> > > > >
> > > >
> > > > I didn't design this, I just copied it from
> > > > starfive,jh7110-pcie-phy.yaml. As that already exists, I'm neither
> > > > sure we want to change that anymore nor deviate in the pattern here.
> > >
> > > To be honest, I think some of the other users of phandle + offset on
> > > this soc were just copy-pasted without thinking about whether or not they
> were required too.
> > > This one seems like it should just be a lookup by compatible in the
> > > driver instead of by phandle. As a bonus, it will work with existing
> > > devicetrees - whereas your current implementation will fail to probe
> > > on systems that have the old devicetree, a regression for systems
> > > running with that devicetree and downstream firmware.
> > >
> > > Cheers,
> > > Conor.
> > >
> > Hi Conor
> > I know you would like to put the offset value to the code, Just set syscon in dts.
> > Just like pcie-starfive.c. right?
> 
> No, not quite. That still uses a phandle lookup, I was talking about using
> syscon_regmap_lookup_by_compatible().

Okay. Using syscon_regmap_lookup_by_compatible() can just modify the driver code only.
But syscon_regmap_lookup_by_compatible() is not exist in uboot now. If I want to enable
CONFIG_OF_UPSTREAM in uboot. I have to add this function in u-boot...


From claudiu.beznea at tuxon.dev  Mon Sep  2 03:40:41 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Mon, 2 Sep 2024 13:40:41 +0300
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>



On 02.09.2024 12:18, Biju Das wrote:
>>>>> Do you have any plan to control this power transitions(ALL_ON to AWO and vice versa) in linux?
>>>> As you know, the RZ/G3S USB PM code is already prepared. This is also
>>>> configuring these signals when going to suspend/exiting from resume.
>>>> W/o configuring properly these signals the USB is not working after a suspend/resume cycle.
>>> One option is to handle SYSC USB PWRRDY signal in TF-A, if you plan to handle system transitions
>> there??
>>
>> As I mentioned, the settings in these registers may be changed by intermediary booting applications.
>> Depending on that, Linux need to control it also on probe for USB to work (it should be the same with
>> PCIe, these signals seems similar from HW manual description).
> You mean system transition settings will be override by U-boot, so Linux needs to restore it back??

It was talking about booting...

You proposed to handle SYSC signals from TF-A in a discussion about system
power transitions:

"One option is to handle SYSC USB PWRRDY signal in TF-A,  if you plan to
handle system transitions"

(I was guessing the "system transition" statement there refers to power
states transitions, ALL_ON <-> AWO/VBAT)

and I gave the booting process as a counter example: if we handle it in
TF-A it may not be enough as these signals might be changed by intermediary
booting applications (e.g., U-Boot).

To conclude, there are 3 scenarios I see where these signals need to be
handled:
1/ booting
2/ suspend to RAM
3/ driver unbind/bind

In case of booting: if we have TF-A to set signals there might be
intermediary booting applications (e.g. U-Boot) that set these signals
also. If it leaves it in improper state and Linux wants to use USB then the
USB will not work (if Linux doesn't handle it).

In case of suspend to RAM: as TF-A is the only application in the suspend
to RAM chain, it should work handling it in TF-A.

In case of unbind/bind: currently we don't know if these signals introduces
any kind of power saving so asserting/de-asserting them in Linux may be
useful from this perspective, if any.

Either way, I think Linux should handle all that it can to make the devices
work and not rely on third party applications.

Thank you,
Claudiu Beznea

> 
> Cheers,
> Biju


From biju.das.jz at bp.renesas.com  Mon Sep  2 03:47:50 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Mon, 2 Sep 2024 10:47:50 +0000
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
Message-ID: <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>

Hi Claudiu,

> -----Original Message-----
> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> Sent: Monday, September 2, 2024 11:41 AM
> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
> 
> 
> 
> On 02.09.2024 12:18, Biju Das wrote:
> >>>>> Do you have any plan to control this power transitions(ALL_ON to AWO and vice versa) in linux?
> >>>> As you know, the RZ/G3S USB PM code is already prepared. This is
> >>>> also configuring these signals when going to suspend/exiting from resume.
> >>>> W/o configuring properly these signals the USB is not working after a suspend/resume cycle.
> >>> One option is to handle SYSC USB PWRRDY signal in TF-A, if you plan
> >>> to handle system transitions
> >> there??
> >>
> >> As I mentioned, the settings in these registers may be changed by intermediary booting
> applications.
> >> Depending on that, Linux need to control it also on probe for USB to
> >> work (it should be the same with PCIe, these signals seems similar from HW manual description).
> > You mean system transition settings will be override by U-boot, so Linux needs to restore it back??
> 
> It was talking about booting...

I am also referring to boot. Boot starts with TF-A and it has a system state.

> 
> You proposed to handle SYSC signals from TF-A in a discussion about system power transitions:
> 
> "One option is to handle SYSC USB PWRRDY signal in TF-A,  if you plan to handle system transitions"
> 
> (I was guessing the "system transition" statement there refers to power states transitions, ALL_ON <->
> AWO/VBAT)

That is correct.

> 
> and I gave the booting process as a counter example: if we handle it in TF-A it may not be enough as
> these signals might be changed by intermediary booting applications (e.g., U-Boot).

Why should U-boot override, system state signals such as USB PWRREADY? Can you please give an example.

> 
> To conclude, there are 3 scenarios I see where these signals need to be
> handled:
> 1/ booting 
> 2/ suspend to RAM
> 3/ driver unbind/bind

--> It should be OK as linux is not handling USB PWRREADY signal.

> 
> In case of booting: if we have TF-A to set signals there might be intermediary booting applications
> (e.g. U-Boot) that set these signals also. If it leaves it in improper state and Linux wants to use
> USB then the USB will not work (if Linux doesn't handle it).

That is the problem of U-boot. U-boot should not override system state signals such as USB PWRREADY.

> 
> In case of suspend to RAM: as TF-A is the only application in the suspend to RAM chain, it should work
> handling it in TF-A.

That is correct, TF-A should handle based on system state.

> 
> In case of unbind/bind: currently we don't know if these signals introduces any kind of power saving
> so asserting/de-asserting them in Linux may be useful from this perspective, if any.

These are system signals, according to me should not be used in unbind/bind.

I may be wrong.

Cheers,
Biju

From minda.chen at starfivetech.com  Mon Sep  2 04:11:26 2024
From: minda.chen at starfivetech.com (Minda Chen)
Date: Mon,  2 Sep 2024 19:11:26 +0800
Subject: [PATCH v3 0/1] Fix configuration for on-chip USB 2.0 support
Message-ID: <20240902111127.15155-1-minda.chen@starfivetech.com>

While mainline has support for the USB controller of the JH7110 since 6.5,
this never really worked, even not with latest downstream kernels by Starfive -
unless you were also using an old downstream U-Boot version. The reason for
that was a missing syscon setting that prevented the connection between USB
2.0 PHY and the controller. This series finally fixes the issue.

Changes in v2:
 - fix copy&paste mistake in error patch found by kernel test robot and Dan Carpenter

Change in v3:
 - Using syscon_regmap_lookup_by_compatible() to lookup regmap. So dts
   with no changed. Delete v2 patch1 and patch 2.

base on v6.11-rc5

Jan Kiszka (1):
  phy: starfive: jh7110-usb: Fix link configuration to controller

 drivers/phy/starfive/phy-jh7110-usb.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)


base-commit: 5be63fc19fcaa4c236b307420483578a56986a37
-- 
2.17.1



From minda.chen at starfivetech.com  Mon Sep  2 04:11:27 2024
From: minda.chen at starfivetech.com (Minda Chen)
Date: Mon,  2 Sep 2024 19:11:27 +0800
Subject: [PATCH v3 1/1] phy: starfive: jh7110-usb: Fix link configuration to controller
In-Reply-To: <20240902111127.15155-1-minda.chen@starfivetech.com>
References: <20240902111127.15155-1-minda.chen@starfivetech.com>
Message-ID: <20240902111127.15155-2-minda.chen@starfivetech.com>

From: Jan Kiszka <jan.kiszka at siemens.com>

In order to connect the USB 2.0 PHY to its controller, we also need to
set "u0_pdrstn_split_sw_usbpipe_plugen" [1]. Some downstream U-Boot
versions did that, but upstream firmware does not, and the kernel must
not rely on such behavior anyway. Failing to set this left the USB
gadget port invisible to connected hosts behind.

Link: https://doc-en.rvspace.org/JH7110/TRM/JH7110_TRM/sys_syscon.html#sys_syscon__section_b3l_fqs_wsb [1]
Fixes: 16d3a71c20cf ("phy: starfive: Add JH7110 USB 2.0 PHY driver")
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Minda Chen <minda.chen at starfivetech.com>
---
 drivers/phy/starfive/phy-jh7110-usb.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/phy/starfive/phy-jh7110-usb.c b/drivers/phy/starfive/phy-jh7110-usb.c
index 633912f8a05d..dabe59953070 100644
--- a/drivers/phy/starfive/phy-jh7110-usb.c
+++ b/drivers/phy/starfive/phy-jh7110-usb.c
@@ -10,18 +10,24 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/usb/of.h>
 
 #define USB_125M_CLK_RATE		125000000
 #define USB_LS_KEEPALIVE_OFF		0x4
 #define USB_LS_KEEPALIVE_ENABLE		BIT(4)
 
+#define USB_PDRSTN_SPLIT		BIT(17)
+#define SYSCON_USB_SPLIT_OFFSET		0x18
+
 struct jh7110_usb2_phy {
 	struct phy *phy;
 	void __iomem *regs;
+	struct regmap *sys_syscon;
 	struct clk *usb_125m_clk;
 	struct clk *app_125m;
 	enum phy_mode mode;
@@ -61,6 +67,10 @@ static int usb2_phy_set_mode(struct phy *_phy,
 		usb2_set_ls_keepalive(phy, (mode != PHY_MODE_USB_DEVICE));
 	}
 
+	/* Connect usb 2.0 phy mode */
+	regmap_update_bits(phy->sys_syscon, SYSCON_USB_SPLIT_OFFSET,
+			   USB_PDRSTN_SPLIT, USB_PDRSTN_SPLIT);
+
 	return 0;
 }
 
@@ -129,6 +139,12 @@ static int jh7110_usb_phy_probe(struct platform_device *pdev)
 	phy_set_drvdata(phy->phy, phy);
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
 
+	phy->sys_syscon =
+		syscon_regmap_lookup_by_compatible("starfive,jh7110-sys-syscon");
+	if (IS_ERR(phy->sys_syscon))
+		return dev_err_probe(dev, PTR_ERR(phy->sys_syscon),
+			"Failed to get sys-syscon\n");
+
 	return PTR_ERR_OR_ZERO(phy_provider);
 }
 
-- 
2.17.1



From aford173 at gmail.com  Mon Sep  2 14:20:11 2024
From: aford173 at gmail.com (Adam Ford)
Date: Mon, 2 Sep 2024 16:20:11 -0500
Subject: [RFC V3 3/3] phy: freescale: fsl-samsung-hdmi: Support dynamic integer
In-Reply-To: <ZtFfBs4HEShmJKsi@atmark-techno.com>
References: <20240830032442.226031-1-aford173@gmail.com> <20240830032442.226031-3-aford173@gmail.com>
 <ZtFfBs4HEShmJKsi@atmark-techno.com>
Message-ID: <CAHCN7xJL-aS+kFp2YwtSSUUMoTBqZCsXb0qvCpYQGpJVM_qJYg@mail.gmail.com>

On Fri, Aug 30, 2024 at 12:56?AM Dominique Martinet
<dominique.martinet at atmark-techno.com> wrote:
>
> Adam Ford wrote on Thu, Aug 29, 2024 at 10:24:27PM -0500:
> > There is currently a look-up table for a variety of resolutions.
> > Since the phy has the ability to dynamically calculate the values
> > necessary to use the intger divider which should allow more
> > resolutions without having to update the look-up-table.
> >
> > If the lookup table cannot find an exact match, fall back to the
> > dynamic calculator of the integer divider.
> >
> > Previously, the value of P was hard-coded to 1, this required an
> > update to the phy_pll_cfg table to add in the extra value into the
> > table, so if the value of P is calculated to be something else
> > by the PMS calculator, the calculated_phy_pll_cfg structure
> > can be used instead without having to keep track of which method
> > was used.
>
> Thank you!
>
> I've updated to v3 and we must have missed something fiddling with v1
> but our 31.5MHz-only screen turns on with this!
>
> Unfortunately among the other odd devices we support, there's one
> whose native resolution only supports 83.5MHz, and that doesn't come out
> right with the integer divider (that function returns 83.2MHz, which is
> 0.4%off)
> If we force the round/set rate functions to prefer the calculated value
> and allow that in imx8mp_hdmi_check_clk_rate (dw_hdmi-imx.c) then it
> also works, so I don't think we actually need to affine the model...
> Coming back to what Lucas replied to my initial mail HDMI would also a
> rate mismatch of ?0.5%, so the integer calculator works for all the
> frequencies we've currently added manually if we fix the check to allow
> that as well:
> 32000000: found 32000000 (100.0% match): p 1 / m 80 / s 12
> 51200000: found 51200000 (100.0% match): p 1 / m 64 / s 6
> 65000000: found 64800000 (99.6% match): p 1 / m 54 / s 4
> 71000000: found 70800000 (99.7% match): p 1 / m 59 / s 4
> 83500000: found 83200000 (99.6% match): p 1 / m 104 / s 6
>
> (only actually tested 51.2 and 83.5 here, we don't have all the hardware
> available; I'll try to play with normal monitors that support more modes
> once the patch gets further finalized)
>
>
> So, as far as I'm concerned I'd be happy to move forward with that and
> will backport this to our tree/remove our kludged values, would "just"
> need to properly pick the closest value if no exact match instead of
> always falling back to the table (or just remove the table altogether if
> we can test a few monitors?)
>
> A couple of style nitpicks below
>
> > diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > index a700a300dc6f..3fab40cde40d 100644
> > --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > @@ -16,6 +16,8 @@
> >
> >  #define PHY_REG(reg)         (reg * 4)
> >
> > +#define REG01_PMS_P_MASK     GENMASK(3, 0)
> > +#define REG03_PMS_S_MASK     GENMASK(7, 4)
> >  #define REG12_CK_DIV_MASK    GENMASK(5, 4)
> >  #define REG13_TG_CODE_LOW_MASK       GENMASK(7, 0)
> >  #define REG14_TOL_MASK               GENMASK(7, 4)
> > @@ -29,281 +31,296 @@
> >  #define REG34_PLL_LOCK               BIT(6)
> >  #define REG34_PHY_CLK_READY  BIT(5)
> >
> > -#define PHY_PLL_DIV_REGS_NUM 6
> > +#ifndef MHZ
> > +#define MHZ  (1000UL * 1000UL)
> > +#endif
> > +
> > +#define PHY_PLL_DIV_REGS_NUM 7
> >
> >  struct phy_config {
> >       u32     pixclk;
> >       u8      pll_div_regs[PHY_PLL_DIV_REGS_NUM];
> >  };
> >
> > +/*
> > + * The calculated_phy_pll_cfg only handles integer divider for PMS only,
> > + * meaning the last four entries will be fixed, but the first three will
> > + * be calculated by the PMS calculator
> > + */
> > +static struct phy_config calculated_phy_pll_cfg = {
>
> I'd change cur_cfg from pointer to the struct itself like this (partial
> patch that probably won't even apply on your branch:)
> ----
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> index 9048cdc760c2..d7124604819c 100644
> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -402,7 +402,7 @@ struct fsl_samsung_hdmi_phy {
>
>         /* clk provider */
>         struct clk_hw hw;
> -       const struct phy_config *cur_cfg;
> +       struct phy_config cur_cfg;

Wouldn't converting this from a pointer require me to do a memcpy
later?  It seems like that's more work than just pointing it to an
address.

>  };
>
>  static inline struct fsl_samsung_hdmi_phy *
> @@ -562,9 +562,9 @@ static int phy_clk_set_rate(struct clk_hw *hw,
>         if (i < 0)
>                 return -EINVAL;
>
> -       phy->cur_cfg = &phy_pll_cfg[i];
> +       phy->cur_cfg = phy_pll_cfg[i];

I think this is would have to be a memcpy instead of just an equal
statement since phy->cur_cfg  would no longer be a pointer.
>
> -       return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
> +       return fsl_samsung_hdmi_phy_configure(phy, &phy->cur_cfg);
>  }
>
>  static const struct clk_ops phy_clk_ops = {
> ----
>
> Then you can just set it directly for calculated values.
> But conceptually it's the same, just one less indirection.
>
> > @@ -406,6 +424,76 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
> >              phy->regs + PHY_REG(14));
> >  }
> >
> > +static unsigned long fsl_samsung_hdmi_phy_find_pms(unsigned long fout, u8 *p, u16 *m, u8 *s)
> > +{
> > +     unsigned long best_freq = 0;
> > +     u32 min_delta = 0xffffffff;
> > +     u8 _p, best_p;
> > +     u16 _m, best_m;
> > +     u8 _s, best_s;
> > +
> > +     /* The ref manual states the values of 'P' rannge from 1 to 11 */
>
> typo: range

Thanks.  I can fix.
>
> > +     for (_p = 1; _p <= 11; ++_p) {
> > +             for (_s = 1; _s <= 16; ++_s) {
> > +                     u64 tmp;
> > +                     u32 delta;
> > +
> > +                     /* s must be one or even */
> > +                     if (_s > 1 && (_s & 0x01) == 1)
> > +                             _s++;
> > +
> > +                     /* _s cannot be 14 per the TRM */
> > +                     if (_s == 14)
> > +                             continue;
> > +
> > +                     /*
> > +                      * TODO: Ref Manual doesn't state the range of _m
> > +                      * so this should be further refined if possible.
> > +                      * This range was set based on the original values
> > +                      * in the look-up table
> > +                      */
> > +                     tmp = (u64)fout * (_p * _s);
> > +                     do_div(tmp, 24 * MHZ);
> > +                     _m = tmp;
> > +                     if (_m < 0x30 || _m > 0x7b)
> > +                             continue;
> > +
> > +                     /*
> > +                      * Rev 2 of the Ref Manual states the
> > +                      * VCO can range between 750MHz and
> > +                      * 3GHz.  The VCO is assumed to be _m x
> > +                      * the reference frequency of 24MHz divided
> > +                      * by the prescaler, _p
> > +                      */
> > +                     tmp = (u64)_m * 24 * MHZ;
> > +                     do_div(tmp, _p);
> > +                     if (tmp < 750 * MHZ ||
> > +                         tmp > 3000 * MHZ)
> > +                             continue;
> > +
> > +                     tmp = (u64)_m * 24 * MHZ;
> > +                     do_div(tmp, _p * _s);
> > +
> > +                     delta = abs(fout - tmp);
> > +                     if (delta < min_delta) {
> > +                             best_p = _p;
> > +                             best_s = _s;
> > +                             best_m = _m;
> > +                             min_delta = delta;
> > +                             best_freq = tmp;
> > +                     }
> > +             }
> > +     }
> > +
> > +     if (best_freq) {
> > +             *p = best_p;
> > +             *m = best_m;
> > +             *s = best_s;
> > +     }
> > +
> > +     return best_freq;
> > +}
> > +
> >  static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
> >                                         const struct phy_config *cfg)
> >  {
> > @@ -419,13 +507,13 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
> >       for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
> >               writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
> >
> > -     /* set individual PLL registers PHY_REG2 ... PHY_REG7 */
> > +     /* set individual PLL registers PHY_REG1 ... PHY_REG7 */
> >       for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
> > -             writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
> > +             writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(1) + i * 4);
> >
> > -     /* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
> > +     /* High nibble of PHY_REG3 and low nibble of PHY_REG21 both contain 'S' */
> >       writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
> > -            cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
> > +            cfg->pll_div_regs[2] >> 4), phy->regs + PHY_REG(21));
> >
> >       fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
> >
> > @@ -453,29 +541,70 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
> >  static long phy_clk_round_rate(struct clk_hw *hw,
> >                              unsigned long rate, unsigned long *parent_rate)
> >  {
> > +     u32 int_div_clk;
> >       int i;
> > +     u16 m;
> > +     u8 p, s;
> > +
> > +     /* If the clock is out of range return error instead of searching */
> > +     if (rate > 297000000 || rate < 22250000)
> > +             return -EINVAL;
> >
> > +     /* Check the look-up table */
> >       for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> >               if (phy_pll_cfg[i].pixclk <= rate)
> > -                     return phy_pll_cfg[i].pixclk;
> > +                     break;
> > +     /* If the rate is an exact match, return it now */
> > +     if (rate == phy_pll_cfg[i].pixclk)
> > +             return phy_pll_cfg[i].pixclk;
> > +
> > +     /*
> > +      * The math on the lookup table shows the PMS math yields a
> > +      * frequency 5 x pixclk.
> > +      * When we check the integer divider against the desired rate,
> > +      * multiply the rate x 5 and then divide the outcome by 5.
> > +      */
> > +     int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
>
> I'd move that comment and both multiplication and division inside
> fsl_samsung_hdmi_phy_find_pms, since it's a property of the computation
> (not having the comment made me ask last time, with the comment it's
> fine -- thanks for adding these comments, very helpful.)
>
> --
> Dominique
>
>


From dominique.martinet at atmark-techno.com  Mon Sep  2 17:47:06 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Tue, 3 Sep 2024 09:47:06 +0900
Subject: [RFC V3 3/3] phy: freescale: fsl-samsung-hdmi: Support dynamic
 integer
In-Reply-To: <CAHCN7xJL-aS+kFp2YwtSSUUMoTBqZCsXb0qvCpYQGpJVM_qJYg@mail.gmail.com>
References: <20240830032442.226031-1-aford173@gmail.com>
 <20240830032442.226031-3-aford173@gmail.com>
 <ZtFfBs4HEShmJKsi@atmark-techno.com>
 <CAHCN7xJL-aS+kFp2YwtSSUUMoTBqZCsXb0qvCpYQGpJVM_qJYg@mail.gmail.com>
Message-ID: <ZtZcit7HVzzedgdk@atmark-techno.com>

Adam Ford wrote on Mon, Sep 02, 2024 at 04:20:11PM -0500:
> > -       const struct phy_config *cur_cfg;
> > +       struct phy_config cur_cfg;
> 
> Wouldn't converting this from a pointer require me to do a memcpy
> later?  It seems like that's more work than just pointing it to an
> address.
> 
> > -       phy->cur_cfg = &phy_pll_cfg[i];
> > +       phy->cur_cfg = phy_pll_cfg[i];
> 
> I think this is would have to be a memcpy instead of just an equal
> statement since phy->cur_cfg  would no longer be a pointer.

C allows copying structs like this, it's fine to write it as just an
equal.
It's not 100% equivalent, iiuc simple assignment is undefined behaviour
if the elements aren't aligned but memcpy will work even in that case,
but for us this is not a proble mand the generated code should be
identical... Also note I'm only suggesting that because the struct is
tiny (1*u32+7*u8 is less than two u64), but this code isn't meant to run
very often anyway so we should prioritize readability -- if you think
it's harder to understand than an extra pointer somewhere I have no
strong opinion; as said in the previous mail if parallel uses are
possible it'd be better kept on the stack anyway...

-- 
Dominique




From aford173 at gmail.com  Mon Sep  2 18:20:50 2024
From: aford173 at gmail.com (Adam Ford)
Date: Mon, 2 Sep 2024 20:20:50 -0500
Subject: [RFC V3 3/3] phy: freescale: fsl-samsung-hdmi: Support dynamic integer
In-Reply-To: <ZtZcit7HVzzedgdk@atmark-techno.com>
References: <20240830032442.226031-1-aford173@gmail.com> <20240830032442.226031-3-aford173@gmail.com>
 <ZtFfBs4HEShmJKsi@atmark-techno.com> <CAHCN7xJL-aS+kFp2YwtSSUUMoTBqZCsXb0qvCpYQGpJVM_qJYg@mail.gmail.com>
 <ZtZcit7HVzzedgdk@atmark-techno.com>
Message-ID: <CAHCN7xLVSq9gh9KbKbFBcZ7HT5vgv4JHdn3QTXFf5B9t86Wp_g@mail.gmail.com>

On Mon, Sep 2, 2024 at 7:47?PM Dominique Martinet
<dominique.martinet at atmark-techno.com> wrote:
>
> Adam Ford wrote on Mon, Sep 02, 2024 at 04:20:11PM -0500:
> > > -       const struct phy_config *cur_cfg;
> > > +       struct phy_config cur_cfg;
> >
> > Wouldn't converting this from a pointer require me to do a memcpy
> > later?  It seems like that's more work than just pointing it to an
> > address.
> >
> > > -       phy->cur_cfg = &phy_pll_cfg[i];
> > > +       phy->cur_cfg = phy_pll_cfg[i];
> >
> > I think this is would have to be a memcpy instead of just an equal
> > statement since phy->cur_cfg  would no longer be a pointer.
>
> C allows copying structs like this, it's fine to write it as just an
> equal.
> It's not 100% equivalent, iiuc simple assignment is undefined behaviour
> if the elements aren't aligned but memcpy will work even in that case,
> but for us this is not a proble mand the generated code should be
> identical... Also note I'm only suggesting that because the struct is
> tiny (1*u32+7*u8 is less than two u64), but this code isn't meant to run
> very often anyway so we should prioritize readability -- if you think
> it's harder to understand than an extra pointer somewhere I have no
> strong opinion; as said in the previous mail if parallel uses are
> possible it'd be better kept on the stack anyway...

Dominique,

Unless someone pushes back, I think keeping it a pointer is more
consistent with what we did before, and it's more in my style of
coding.

I have two more patches in the series.
*  One updates the round and set functions to compare the closest
values between the fractional divider and the integer divider and uses
the option with the smallest difference between the achievable value
and the desired rate if the actual value is not achievable.

* The second removes the integer divider values from the LUT since
having it there just takes up extra space and makes the LUT search
longer.

I'll send it as V4 with a cover letter describing everything I have
done and the rationale behind it without the RFC designation.

For what it's worth, adding the integer calculator added 4 entries to
my modetest list, and changing the hdmi-tx to support a clock rante of
+/- 5% added another 11 possible entries.  I have not tested them all
yet.
I likely won't do a patch for the HDMI-TX, but if you want to send a
patch increasing the tolerance, I'll likely test it as I have time.

adam

>
> --
> Dominique
>
>


From aford173 at gmail.com  Mon Sep  2 18:30:42 2024
From: aford173 at gmail.com (Adam Ford)
Date: Mon,  2 Sep 2024 20:30:42 -0500
Subject: [PATCH V4 0/5] phy: freescale: fsl-samsung-hdmi: Expand phy clock options
Message-ID: <20240903013113.139698-1-aford173@gmail.com>

Currently, there is a look-up-table to describe all the clock options the HDMI PHY
can use.  Some of these entries in the LUT are using a fractional divider which does
not have a well documented algorithm for determinging values, but the the integer
divider can use an algorithm to calculate the integer divder values dynamically
beyond those listed in the LUT and also duplicates some of the entries.

The first two patches do not do anything functionally other than simplify
some of the register accesses and de-duplicates some of the register look-ups.

The third patch adds support for the integer divider and uses it whenever the
clock request is an exact match.  Otherwise, it will use the LUT as before.
The rouding is still based on the LUT if the integer clock isn't an exact match.

The forth patch updates thes set_rate and round_rate functions to use either
the fractional clock LUT or the the integer divder mechanism to determine
which ever clock rate might be closest match.

The last patch removes the integer divider entries from the LUT since by then
it'll be comparing both the integer divider calculator and the closest value
in the LUT.

In my testing with a AOC 4K monitor, I was able to add 4 entries in my modetest
table.  I do not have an HDMI analyzer, so I just used my monitor to determine
if this series worked.

Adam Ford (5):
  phy: freescale: fsl-samsung-hdmi: Replace register defines with macro
  phy: freescale: fsl-samsung-hdmi: Simplify REG21_PMS_S_MASK lookup
  phy: freescale: fsl-samsung-hdmi: Support dynamic integer
  phy: freescale: fsl-samsung-hdmi:  Use closest divider
  phy: freescale: fsl-samsung-hdmi:  Remove unnecessary LUT entries

 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 575 ++++++++++---------
 1 file changed, 291 insertions(+), 284 deletions(-)

-- 
2.43.0



From aford173 at gmail.com  Mon Sep  2 18:30:43 2024
From: aford173 at gmail.com (Adam Ford)
Date: Mon,  2 Sep 2024 20:30:43 -0500
Subject: [PATCH V4 1/5] phy: freescale: fsl-samsung-hdmi: Replace register defines with macro
In-Reply-To: <20240903013113.139698-1-aford173@gmail.com>
References: <20240903013113.139698-1-aford173@gmail.com>
Message-ID: <20240903013113.139698-2-aford173@gmail.com>

There are 47 registers defined as PHY_REG_xx were xx goes from 00 to
47.  Simplify this by replacing them all with a macro which is passed
the register number to return the proper register offset.

Signed-off-by: Adam Ford <aford173 at gmail.com>
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 138 ++++++-------------
 1 file changed, 41 insertions(+), 97 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 9048cdc760c2..bc5d3625ece6 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -14,76 +14,20 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 
-#define PHY_REG_00		0x00
-#define PHY_REG_01		0x04
-#define PHY_REG_02		0x08
-#define PHY_REG_08		0x20
-#define PHY_REG_09		0x24
-#define PHY_REG_10		0x28
-#define PHY_REG_11		0x2c
-
-#define PHY_REG_12		0x30
-#define  REG12_CK_DIV_MASK	GENMASK(5, 4)
-
-#define PHY_REG_13		0x34
-#define  REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
-
-#define PHY_REG_14		0x38
-#define  REG14_TOL_MASK		GENMASK(7, 4)
-#define  REG14_RP_CODE_MASK	GENMASK(3, 1)
-#define  REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
-
-#define PHY_REG_15		0x3c
-#define PHY_REG_16		0x40
-#define PHY_REG_17		0x44
-#define PHY_REG_18		0x48
-#define PHY_REG_19		0x4c
-#define PHY_REG_20		0x50
-
-#define PHY_REG_21		0x54
-#define  REG21_SEL_TX_CK_INV	BIT(7)
-#define  REG21_PMS_S_MASK	GENMASK(3, 0)
-
-#define PHY_REG_22		0x58
-#define PHY_REG_23		0x5c
-#define PHY_REG_24		0x60
-#define PHY_REG_25		0x64
-#define PHY_REG_26		0x68
-#define PHY_REG_27		0x6c
-#define PHY_REG_28		0x70
-#define PHY_REG_29		0x74
-#define PHY_REG_30		0x78
-#define PHY_REG_31		0x7c
-#define PHY_REG_32		0x80
-
-/*
- * REG33 does not match the ref manual. According to Sandor Yu from NXP,
- * "There is a doc issue on the i.MX8MP latest RM"
- * REG33 is being used per guidance from Sandor
- */
-
-#define PHY_REG_33		0x84
-#define  REG33_MODE_SET_DONE	BIT(7)
-#define  REG33_FIX_DA		BIT(1)
-
-#define PHY_REG_34		0x88
-#define  REG34_PHY_READY	BIT(7)
-#define  REG34_PLL_LOCK		BIT(6)
-#define  REG34_PHY_CLK_READY	BIT(5)
-
-#define PHY_REG_35		0x8c
-#define PHY_REG_36		0x90
-#define PHY_REG_37		0x94
-#define PHY_REG_38		0x98
-#define PHY_REG_39		0x9c
-#define PHY_REG_40		0xa0
-#define PHY_REG_41		0xa4
-#define PHY_REG_42		0xa8
-#define PHY_REG_43		0xac
-#define PHY_REG_44		0xb0
-#define PHY_REG_45		0xb4
-#define PHY_REG_46		0xb8
-#define PHY_REG_47		0xbc
+#define PHY_REG(reg)		(reg * 4)
+
+#define REG12_CK_DIV_MASK	GENMASK(5, 4)
+#define REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
+#define REG14_TOL_MASK		GENMASK(7, 4)
+#define REG14_RP_CODE_MASK	GENMASK(3, 1)
+#define REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
+#define REG21_SEL_TX_CK_INV	BIT(7)
+#define REG21_PMS_S_MASK	GENMASK(3, 0)
+#define REG33_MODE_SET_DONE	BIT(7)
+#define REG33_FIX_DA		BIT(1)
+#define REG34_PHY_READY	BIT(7)
+#define REG34_PLL_LOCK		BIT(6)
+#define REG34_PHY_CLK_READY	BIT(5)
 
 #define PHY_PLL_DIV_REGS_NUM 6
 
@@ -369,29 +313,29 @@ struct reg_settings {
 };
 
 static const struct reg_settings common_phy_cfg[] = {
-	{ PHY_REG_00, 0x00 }, { PHY_REG_01, 0xd1 },
-	{ PHY_REG_08, 0x4f }, { PHY_REG_09, 0x30 },
-	{ PHY_REG_10, 0x33 }, { PHY_REG_11, 0x65 },
+	{ PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
+	{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
+	{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
 	/* REG12 pixclk specific */
 	/* REG13 pixclk specific */
 	/* REG14 pixclk specific */
-	{ PHY_REG_15, 0x80 }, { PHY_REG_16, 0x6c },
-	{ PHY_REG_17, 0xf2 }, { PHY_REG_18, 0x67 },
-	{ PHY_REG_19, 0x00 }, { PHY_REG_20, 0x10 },
+	{ PHY_REG(15), 0x80 }, { PHY_REG(16), 0x6c },
+	{ PHY_REG(17), 0xf2 }, { PHY_REG(18), 0x67 },
+	{ PHY_REG(19), 0x00 }, { PHY_REG(20), 0x10 },
 	/* REG21 pixclk specific */
-	{ PHY_REG_22, 0x30 }, { PHY_REG_23, 0x32 },
-	{ PHY_REG_24, 0x60 }, { PHY_REG_25, 0x8f },
-	{ PHY_REG_26, 0x00 }, { PHY_REG_27, 0x00 },
-	{ PHY_REG_28, 0x08 }, { PHY_REG_29, 0x00 },
-	{ PHY_REG_30, 0x00 }, { PHY_REG_31, 0x00 },
-	{ PHY_REG_32, 0x00 }, { PHY_REG_33, 0x80 },
-	{ PHY_REG_34, 0x00 }, { PHY_REG_35, 0x00 },
-	{ PHY_REG_36, 0x00 }, { PHY_REG_37, 0x00 },
-	{ PHY_REG_38, 0x00 }, { PHY_REG_39, 0x00 },
-	{ PHY_REG_40, 0x00 }, { PHY_REG_41, 0xe0 },
-	{ PHY_REG_42, 0x83 }, { PHY_REG_43, 0x0f },
-	{ PHY_REG_44, 0x3E }, { PHY_REG_45, 0xf8 },
-	{ PHY_REG_46, 0x00 }, { PHY_REG_47, 0x00 }
+	{ PHY_REG(22), 0x30 }, { PHY_REG(23), 0x32 },
+	{ PHY_REG(24), 0x60 }, { PHY_REG(25), 0x8f },
+	{ PHY_REG(26), 0x00 }, { PHY_REG(27), 0x00 },
+	{ PHY_REG(28), 0x08 }, { PHY_REG(29), 0x00 },
+	{ PHY_REG(30), 0x00 }, { PHY_REG(31), 0x00 },
+	{ PHY_REG(32), 0x00 }, { PHY_REG(33), 0x80 },
+	{ PHY_REG(34), 0x00 }, { PHY_REG(35), 0x00 },
+	{ PHY_REG(36), 0x00 }, { PHY_REG(37), 0x00 },
+	{ PHY_REG(38), 0x00 }, { PHY_REG(39), 0x00 },
+	{ PHY_REG(40), 0x00 }, { PHY_REG(41), 0xe0 },
+	{ PHY_REG(42), 0x83 }, { PHY_REG(43), 0x0f },
+	{ PHY_REG(44), 0x3E }, { PHY_REG(45), 0xf8 },
+	{ PHY_REG(46), 0x00 }, { PHY_REG(47), 0x00 }
 };
 
 struct fsl_samsung_hdmi_phy {
@@ -442,7 +386,7 @@ fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
 	}
 
 	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
-	       phy->regs + PHY_REG_21);
+	       phy->regs + PHY_REG(21));
 }
 
 static void
@@ -469,7 +413,7 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 		break;
 	}
 
-	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG_12);
+	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG(12));
 
 	/*
 	 * Calculation for the frequency lock detector target code (fld_tg_code)
@@ -489,11 +433,11 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 
 	/* FLD_TOL and FLD_RP_CODE taken from downstream driver */
 	writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),
-	       phy->regs + PHY_REG_13);
+	       phy->regs + PHY_REG(13));
 	writeb(FIELD_PREP(REG14_TOL_MASK, 2) |
 	       FIELD_PREP(REG14_RP_CODE_MASK, 2) |
 	       FIELD_PREP(REG14_TG_CODE_HIGH_MASK, fld_tg_code >> 8),
-	       phy->regs + PHY_REG_14);
+	       phy->regs + PHY_REG(14));
 }
 
 static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
@@ -503,7 +447,7 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	u8 val;
 
 	/* HDMI PHY init */
-	writeb(REG33_FIX_DA, phy->regs + PHY_REG_33);
+	writeb(REG33_FIX_DA, phy->regs + PHY_REG(33));
 
 	/* common PHY registers */
 	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
@@ -511,14 +455,14 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 
 	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
-		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG_02 + i * 4);
+		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
 
 	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
-	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG_33);
+	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));
 
-	ret = readb_poll_timeout(phy->regs + PHY_REG_34, val,
+	ret = readb_poll_timeout(phy->regs + PHY_REG(34), val,
 				 val & REG34_PLL_LOCK, 50, 20000);
 	if (ret)
 		dev_err(phy->dev, "PLL failed to lock\n");
-- 
2.43.0



From aford173 at gmail.com  Mon Sep  2 18:30:44 2024
From: aford173 at gmail.com (Adam Ford)
Date: Mon,  2 Sep 2024 20:30:44 -0500
Subject: [PATCH V4 2/5] phy: freescale: fsl-samsung-hdmi: Simplify REG21_PMS_S_MASK lookup
In-Reply-To: <20240903013113.139698-1-aford173@gmail.com>
References: <20240903013113.139698-1-aford173@gmail.com>
Message-ID: <20240903013113.139698-3-aford173@gmail.com>

The value of 'S' is writen to two places, PHY_REG3[7:4] and
PHY_REG21[3:0].  There is a lookup table which contains
the value of PHY_REG3.  Rather than using a switch statement
based on the pixel clock to search for the value of 'S' again,
just shift the contents of PHY_REG3[7:4] >> 4 and place the value
in PHY_REG21[3:0].  Doing this can eliminate an entire function.

Signed-off-by: Adam Ford <aford173 at gmail.com>
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 39 ++------------------
 1 file changed, 4 insertions(+), 35 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index bc5d3625ece6..a700a300dc6f 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -355,40 +355,6 @@ to_fsl_samsung_hdmi_phy(struct clk_hw *hw)
 	return container_of(hw, struct fsl_samsung_hdmi_phy, hw);
 }
 
-static void
-fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
-				      const struct phy_config *cfg)
-{
-	u8 div = 0x1;
-
-	switch (cfg->pixclk) {
-	case  22250000 ...  33750000:
-		div = 0xf;
-		break;
-	case  35000000 ...  40000000:
-		div = 0xb;
-		break;
-	case  43200000 ...  47500000:
-		div = 0x9;
-		break;
-	case  50349650 ...  63500000:
-		div = 0x7;
-		break;
-	case  67500000 ...  90000000:
-		div = 0x5;
-		break;
-	case  94000000 ... 148500000:
-		div = 0x3;
-		break;
-	case 154000000 ... 297000000:
-		div = 0x1;
-		break;
-	}
-
-	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
-	       phy->regs + PHY_REG(21));
-}
-
 static void
 fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 					    const struct phy_config *cfg)
@@ -457,7 +423,10 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
 		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
 
-	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
+	/* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
+	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
+	       cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
+
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
 	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));
-- 
2.43.0



From aford173 at gmail.com  Mon Sep  2 18:30:45 2024
From: aford173 at gmail.com (Adam Ford)
Date: Mon,  2 Sep 2024 20:30:45 -0500
Subject: [PATCH V4 3/5] phy: freescale: fsl-samsung-hdmi: Support dynamic integer
In-Reply-To: <20240903013113.139698-1-aford173@gmail.com>
References: <20240903013113.139698-1-aford173@gmail.com>
Message-ID: <20240903013113.139698-4-aford173@gmail.com>

There is currently a look-up table for a variety of resolutions.
Since the phy has the ability to dynamically calculate the values
necessary to use the intger divider which should allow more
resolutions without having to update the look-up-table.

If the lookup table cannot find an exact match, fall back to the
dynamic calculator of the integer divider.

Previously, the value of P was hard-coded to 1, this required an
update to the phy_pll_cfg table to add in the extra value into the
table, so if the value of P is calculated to be something else
by the PMS calculator, the calculated_phy_pll_cfg structure
can be used instead without having to keep track of which method
was used.

Signed-off-by: Adam Ford <aford173 at gmail.com>
---
V3:  Change size of pll_div_regs to include PHY_REG01 (P)
     Create calculated_phy_pll_cfg to containe the values
     Eliminate the PMS calculation from fsl_samsung_hdmi_phy_configure
     Make the LUT primary and fall back to integer calculator in
     phy_clk_round_rate.
     Check the range right away to ensure it's reaonsable rather than
     trying to find a clock only to learn it's outside the range.
     Overall added notes and comments where stuff may not be intuitive.

V2:  Update phy_clk_round_rate and phy_clk_set_rate to both support
     the integer clock PMS calculator.
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 341 +++++++++++++------
 1 file changed, 235 insertions(+), 106 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index a700a300dc6f..8822029526f0 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -16,6 +16,8 @@
 
 #define PHY_REG(reg)		(reg * 4)
 
+#define REG01_PMS_P_MASK	GENMASK(3, 0)
+#define REG03_PMS_S_MASK	GENMASK(7, 4)
 #define REG12_CK_DIV_MASK	GENMASK(5, 4)
 #define REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
 #define REG14_TOL_MASK		GENMASK(7, 4)
@@ -29,281 +31,296 @@
 #define REG34_PLL_LOCK		BIT(6)
 #define REG34_PHY_CLK_READY	BIT(5)
 
-#define PHY_PLL_DIV_REGS_NUM 6
+#ifndef MHZ
+#define MHZ	(1000UL * 1000UL)
+#endif
+
+#define PHY_PLL_DIV_REGS_NUM 7
 
 struct phy_config {
 	u32	pixclk;
 	u8	pll_div_regs[PHY_PLL_DIV_REGS_NUM];
 };
 
+/*
+ * The calculated_phy_pll_cfg only handles integer divider for PMS only,
+ * meaning the last four entries will be fixed, but the first three will
+ * be calculated by the PMS calculator
+ */
+static struct phy_config calculated_phy_pll_cfg = {
+	.pixclk = 0,
+	.pll_div_regs = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
+};
+
+/* The lookup table contains values for which the fractional divder is used */
 static const struct phy_config phy_pll_cfg[] = {
 	{
 		.pixclk = 22250000,
-		.pll_div_regs = { 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 23750000,
-		.pll_div_regs = { 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
 	}, {
 		.pixclk = 24000000,
-		.pll_div_regs = { 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 24024000,
-		.pll_div_regs = { 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
 	}, {
 		.pixclk = 25175000,
-		.pll_div_regs = { 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
 	}, {
 		.pixclk = 25200000,
-		.pll_div_regs = { 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 26750000,
-		.pll_div_regs = { 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 27000000,
-		.pll_div_regs = { 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 27027000,
-		.pll_div_regs = { 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 29500000,
-		.pll_div_regs = { 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 30750000,
-		.pll_div_regs = { 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 30888000,
-		.pll_div_regs = { 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
 	}, {
 		.pixclk = 33750000,
-		.pll_div_regs = { 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 35000000,
-		.pll_div_regs = { 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 36000000,
-		.pll_div_regs = { 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 36036000,
-		.pll_div_regs = { 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 40000000,
-		.pll_div_regs = { 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43200000,
-		.pll_div_regs = { 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43243200,
-		.pll_div_regs = { 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 44500000,
-		.pll_div_regs = { 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
 	}, {
 		.pixclk = 47000000,
-		.pll_div_regs = { 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
 	}, {
 		.pixclk = 47500000,
-		.pll_div_regs = { 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
 	}, {
 		.pixclk = 50349650,
-		.pll_div_regs = { 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
 	}, {
 		.pixclk = 50400000,
-		.pll_div_regs = { 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 53250000,
-		.pll_div_regs = { 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 53500000,
-		.pll_div_regs = { 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 54000000,
-		.pll_div_regs = { 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 54054000,
-		.pll_div_regs = { 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 59000000,
-		.pll_div_regs = { 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 59340659,
-		.pll_div_regs = { 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
 	}, {
 		.pixclk = 59400000,
-		.pll_div_regs = { 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 61500000,
-		.pll_div_regs = { 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 63500000,
-		.pll_div_regs = { 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 67500000,
-		.pll_div_regs = { 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
 	}, {
 		.pixclk = 70000000,
-		.pll_div_regs = { 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 72000000,
-		.pll_div_regs = { 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 72072000,
-		.pll_div_regs = { 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 74176000,
-		.pll_div_regs = { 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
 	}, {
 		.pixclk = 74250000,
-		.pll_div_regs = { 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
 	}, {
 		.pixclk = 78500000,
-		.pll_div_regs = { 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 80000000,
-		.pll_div_regs = { 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 82000000,
-		.pll_div_regs = { 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 82500000,
-		.pll_div_regs = { 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
 	}, {
 		.pixclk = 89000000,
-		.pll_div_regs = { 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
 	}, {
 		.pixclk = 90000000,
-		.pll_div_regs = { 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 94000000,
-		.pll_div_regs = { 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
 	}, {
 		.pixclk = 95000000,
-		.pll_div_regs = { 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
 	}, {
 		.pixclk = 98901099,
-		.pll_div_regs = { 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
 	}, {
 		.pixclk = 99000000,
-		.pll_div_regs = { 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
 	}, {
 		.pixclk = 100699300,
-		.pll_div_regs = { 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
 	}, {
 		.pixclk = 100800000,
-		.pll_div_regs = { 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 102500000,
-		.pll_div_regs = { 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
 		.pixclk = 104750000,
-		.pll_div_regs = { 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
 	}, {
 		.pixclk = 106500000,
-		.pll_div_regs = { 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 107000000,
-		.pll_div_regs = { 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 108000000,
-		.pll_div_regs = { 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 108108000,
-		.pll_div_regs = { 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 118000000,
-		.pll_div_regs = { 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 118800000,
-		.pll_div_regs = { 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 123000000,
-		.pll_div_regs = { 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 127000000,
-		.pll_div_regs = { 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 135000000,
-		.pll_div_regs = { 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 135580000,
-		.pll_div_regs = { 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
+		.pll_div_regs = { 0xd1, 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
 	}, {
 		.pixclk = 137520000,
-		.pll_div_regs = { 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
+		.pll_div_regs = { 0xd1, 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
 	}, {
 		.pixclk = 138750000,
-		.pll_div_regs = { 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
+		.pll_div_regs = { 0xd1, 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
 	}, {
 		.pixclk = 140000000,
-		.pll_div_regs = { 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
 	}, {
 		.pixclk = 144000000,
-		.pll_div_regs = { 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 148352000,
-		.pll_div_regs = { 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
 	}, {
 		.pixclk = 148500000,
-		.pll_div_regs = { 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
 	}, {
 		.pixclk = 154000000,
-		.pll_div_regs = { 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
+		.pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
 	}, {
 		.pixclk = 157000000,
-		.pll_div_regs = { 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
 	}, {
 		.pixclk = 160000000,
-		.pll_div_regs = { 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
 	}, {
 		.pixclk = 162000000,
-		.pll_div_regs = { 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
+		.pll_div_regs = { 0xd1, 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
 	}, {
 		.pixclk = 164000000,
-		.pll_div_regs = { 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
 	}, {
 		.pixclk = 165000000,
-		.pll_div_regs = { 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
 	}, {
 		.pixclk = 180000000,
-		.pll_div_regs = { 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 185625000,
-		.pll_div_regs = { 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
 	}, {
 		.pixclk = 188000000,
-		.pll_div_regs = { 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
 	}, {
 		.pixclk = 198000000,
-		.pll_div_regs = { 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
 	}, {
 		.pixclk = 205000000,
-		.pll_div_regs = { 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
 		.pixclk = 209500000,
-		.pll_div_regs = { 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
 	}, {
 		.pixclk = 213000000,
-		.pll_div_regs = { 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 216000000,
-		.pll_div_regs = { 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 216216000,
-		.pll_div_regs = { 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 237600000,
-		.pll_div_regs = { 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 254000000,
-		.pll_div_regs = { 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 277500000,
-		.pll_div_regs = { 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
+		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
 	}, {
 		.pixclk = 288000000,
-		.pll_div_regs = { 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 297000000,
-		.pll_div_regs = { 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
 	},
 };
 
@@ -313,7 +330,8 @@ struct reg_settings {
 };
 
 static const struct reg_settings common_phy_cfg[] = {
-	{ PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
+	{ PHY_REG(0), 0x00 },
+	/* PHY_REG(1-7) pix clk specific */
 	{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
 	{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
 	/* REG12 pixclk specific */
@@ -406,6 +424,76 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 	       phy->regs + PHY_REG(14));
 }
 
+static unsigned long fsl_samsung_hdmi_phy_find_pms(unsigned long fout, u8 *p, u16 *m, u8 *s)
+{
+	unsigned long best_freq = 0;
+	u32 min_delta = 0xffffffff;
+	u8 _p, best_p;
+	u16 _m, best_m;
+	u8 _s, best_s;
+
+	/* The ref manual states the values of 'P' range from 1 to 11 */
+	for (_p = 1; _p <= 11; ++_p) {
+		for (_s = 1; _s <= 16; ++_s) {
+			u64 tmp;
+			u32 delta;
+
+			/* s must be one or even */
+			if (_s > 1 && (_s & 0x01) == 1)
+				_s++;
+
+			/* _s cannot be 14 per the TRM */
+			if (_s == 14)
+				continue;
+
+			/*
+			 * TODO: Ref Manual doesn't state the range of _m
+			 * so this should be further refined if possible.
+			 * This range was set based on the original values
+			 * in the look-up table
+			 */
+			tmp = (u64)fout * (_p * _s);
+			do_div(tmp, 24 * MHZ);
+			_m = tmp;
+			if (_m < 0x30 || _m > 0x7b)
+				continue;
+
+			/*
+			 * Rev 2 of the Ref Manual states the
+			 * VCO can range between 750MHz and
+			 * 3GHz.  The VCO is assumed to be _m x
+			 * the reference frequency of 24MHz divided
+			 * by the prescaler, _p
+			 */
+			tmp = (u64)_m * 24 * MHZ;
+			do_div(tmp, _p);
+			if (tmp < 750 * MHZ ||
+			    tmp > 3000 * MHZ)
+				continue;
+
+			tmp = (u64)_m * 24 * MHZ;
+			do_div(tmp, _p * _s);
+
+			delta = abs(fout - tmp);
+			if (delta < min_delta) {
+				best_p = _p;
+				best_s = _s;
+				best_m = _m;
+				min_delta = delta;
+				best_freq = tmp;
+			}
+		}
+	}
+
+	if (best_freq) {
+		*p = best_p;
+		*m = best_m;
+		*s = best_s;
+	}
+
+	return best_freq;
+}
+
 static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 					  const struct phy_config *cfg)
 {
@@ -419,13 +507,13 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
 		writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
 
-	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
+	/* set individual PLL registers PHY_REG1 ... PHY_REG7 */
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
-		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
+		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(1) + i * 4);
 
-	/* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
+	/* High nibble of PHY_REG3 and low nibble of PHY_REG21 both contain 'S' */
 	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
-	       cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
+	       cfg->pll_div_regs[2] >> 4), phy->regs + PHY_REG(21));
 
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
@@ -453,29 +541,70 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
 static long phy_clk_round_rate(struct clk_hw *hw,
 			       unsigned long rate, unsigned long *parent_rate)
 {
+	u32 int_div_clk;
 	int i;
+	u16 m;
+	u8 p, s;
+
+	/* If the clock is out of range return error instead of searching */
+	if (rate > 297000000 || rate < 22250000)
+		return -EINVAL;
 
+	/* Check the look-up table */
 	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
 		if (phy_pll_cfg[i].pixclk <= rate)
-			return phy_pll_cfg[i].pixclk;
+			break;
+	/* If the rate is an exact match, return it now */
+	if (rate == phy_pll_cfg[i].pixclk)
+		return phy_pll_cfg[i].pixclk;
+
+	/*
+	 * The math on the lookup table shows the PMS math yields a
+	 * frequency 5 x pixclk.
+	 * When we check the integer divider against the desired rate,
+	 * multiply the rate x 5 and then divide the outcome by 5.
+	 */
+	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
 
-	return -EINVAL;
+	/* If the rate is an exact match, return it now */
+	if (int_div_clk == rate)
+		return int_div_clk;
+
+	/* Fall back to the closest value in the LUT */
+	return phy_pll_cfg[i].pixclk;
 }
 
 static int phy_clk_set_rate(struct clk_hw *hw,
 			    unsigned long rate, unsigned long parent_rate)
 {
 	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
+	u32 int_div_clk;
 	int i;
-
-	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
-		if (phy_pll_cfg[i].pixclk <= rate)
-			break;
-
-	if (i < 0)
-		return -EINVAL;
-
-	phy->cur_cfg = &phy_pll_cfg[i];
+	u16 m;
+	u8 p, s;
+
+	/* If the integer divider works, just use it */
+	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
+	if (int_div_clk == rate) {
+		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using integer divider\n");
+		calculated_phy_pll_cfg.pixclk = int_div_clk;
+		calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
+		calculated_phy_pll_cfg.pll_div_regs[1] = m;
+		calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
+		/* pll_div_regs 3-6 are fixed and pre-defined already */
+		phy->cur_cfg  = &calculated_phy_pll_cfg;
+	} else {
+		/* Otherwise, search the LUT */
+		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
+		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
+			if (phy_pll_cfg[i].pixclk <= rate)
+				break;
+
+		if (i < 0)
+			return -EINVAL;
+
+		phy->cur_cfg = &phy_pll_cfg[i];
+	}
 
 	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
 }
-- 
2.43.0



From aford173 at gmail.com  Mon Sep  2 18:30:46 2024
From: aford173 at gmail.com (Adam Ford)
Date: Mon,  2 Sep 2024 20:30:46 -0500
Subject: [PATCH V4 4/5] phy: freescale: fsl-samsung-hdmi:  Use closest divider
In-Reply-To: <20240903013113.139698-1-aford173@gmail.com>
References: <20240903013113.139698-1-aford173@gmail.com>
Message-ID: <20240903013113.139698-5-aford173@gmail.com>

Currently, if the clock values cannot be set to the exact rate,
the round_rate and set_rate functions use the closest value found in
the look-up-table.  In preparation of removing values from the LUT
that can be calculated evenly with the integer calculator, it's
necessary to ensure to check both the look-up-table and the integer
divider clock values to get the closest values to the requested
value.  It does this by measuring the difference between the
requested clock value and the closest value in both integer divider
calucator and the fractional clock look-up-table.

Which ever has the smallest difference between them is returned as
the cloesest rate.

Signed-off-by: Adam Ford <aford173 at gmail.com>
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 40 +++++++++++++++-----
 1 file changed, 31 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 8822029526f0..0bf526e282a7 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -541,7 +541,7 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
 static long phy_clk_round_rate(struct clk_hw *hw,
 			       unsigned long rate, unsigned long *parent_rate)
 {
-	u32 int_div_clk;
+	u32 int_div_clk, delta_int, delta_frac;
 	int i;
 	u16 m;
 	u8 p, s;
@@ -554,6 +554,7 @@ static long phy_clk_round_rate(struct clk_hw *hw,
 	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
 		if (phy_pll_cfg[i].pixclk <= rate)
 			break;
+
 	/* If the rate is an exact match, return it now */
 	if (rate == phy_pll_cfg[i].pixclk)
 		return phy_pll_cfg[i].pixclk;
@@ -570,15 +571,21 @@ static long phy_clk_round_rate(struct clk_hw *hw,
 	if (int_div_clk == rate)
 		return int_div_clk;
 
-	/* Fall back to the closest value in the LUT */
-	return phy_pll_cfg[i].pixclk;
+	/* Calculate the differences and use the closest one */
+	delta_frac = (rate - phy_pll_cfg[i].pixclk);
+	delta_int = (rate - int_div_clk);
+
+	if (delta_int < delta_frac)
+		return int_div_clk;
+	else
+		return phy_pll_cfg[i].pixclk;
 }
 
 static int phy_clk_set_rate(struct clk_hw *hw,
 			    unsigned long rate, unsigned long parent_rate)
 {
 	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
-	u32 int_div_clk;
+	u32 int_div_clk, delta_int, delta_frac;
 	int i;
 	u16 m;
 	u8 p, s;
@@ -593,19 +600,34 @@ static int phy_clk_set_rate(struct clk_hw *hw,
 		calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
 		/* pll_div_regs 3-6 are fixed and pre-defined already */
 		phy->cur_cfg  = &calculated_phy_pll_cfg;
+		goto done;
 	} else {
 		/* Otherwise, search the LUT */
-		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
-		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
-			if (phy_pll_cfg[i].pixclk <= rate)
+		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--) {
+			if (phy_pll_cfg[i].pixclk == rate) {
+				dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
+				phy->cur_cfg = &phy_pll_cfg[i];
+				goto done;
+			}
+
+			if (phy_pll_cfg[i].pixclk < rate)
 				break;
+		}
 
 		if (i < 0)
 			return -EINVAL;
-
-		phy->cur_cfg = &phy_pll_cfg[i];
 	}
 
+	/* Calculate the differences for each clock against the requested value */
+	delta_frac = (rate - phy_pll_cfg[i].pixclk);
+	delta_int = (rate - int_div_clk);
+
+	/* Use the value closest to the desired */
+	if (delta_int < delta_frac)
+		phy->cur_cfg  = &calculated_phy_pll_cfg;
+	else
+		phy->cur_cfg = &phy_pll_cfg[i];
+done:
 	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
 }
 
-- 
2.43.0



From aford173 at gmail.com  Mon Sep  2 18:30:47 2024
From: aford173 at gmail.com (Adam Ford)
Date: Mon,  2 Sep 2024 20:30:47 -0500
Subject: [PATCH V4 5/5] phy: freescale: fsl-samsung-hdmi:  Remove unnecessary LUT entries
In-Reply-To: <20240903013113.139698-1-aford173@gmail.com>
References: <20240903013113.139698-1-aford173@gmail.com>
Message-ID: <20240903013113.139698-6-aford173@gmail.com>

The lookup table contains entries which use the integer divider
instead of just the fractional divider.  Since the set and round
functions check both the integer divider values and the LUT values,
it's no longer necessary to keep the integer divder values in the,
as they are able to by dynamically calcuated.

Signed-off-by: Adam Ford <aford173 at gmail.com>
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 83 +++-----------------
 1 file changed, 13 insertions(+), 70 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 0bf526e282a7..7cfad4ed94f3 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -60,25 +60,16 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 23750000,
 		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
-	}, {
-		.pixclk = 24000000,
-		.pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 24024000,
 		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
 	}, {
 		.pixclk = 25175000,
 		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
-	}, {
-		.pixclk = 25200000,
-		.pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 26750000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 27000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 27027000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -96,18 +87,9 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 35000000,
 		.pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 36000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 36036000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
-	}, {
-		.pixclk = 40000000,
-		.pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
-		.pixclk = 43200000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43243200,
 		.pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
@@ -123,19 +105,13 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 50349650,
 		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
-	}, {
-		.pixclk = 50400000,
-		.pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 53250000,
 		.pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 53500000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 54000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 54054000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -144,10 +120,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 59340659,
 		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
-	}, {
-		.pixclk = 59400000,
-		.pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 61500000,
 		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -159,10 +132,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 70000000,
 		.pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 72000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 72072000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -174,10 +144,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 78500000,
 		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
-	}, {
-		.pixclk = 80000000,
-		.pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 82000000,
 		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -204,10 +171,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 100699300,
 		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
-	}, {
-		.pixclk = 100800000,
-		.pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 102500000,
 		.pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
@@ -219,19 +183,13 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 107000000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 108000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 108108000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 118000000,
 		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
-	}, {
-		.pixclk = 118800000,
-		.pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 123000000,
 		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -252,10 +210,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 140000000,
 		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
-	}, {
-		.pixclk = 144000000,
-		.pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 148352000,
 		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
 	}, {
@@ -279,9 +234,6 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 165000000,
 		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
-	}, {
-		.pixclk = 180000000,
-		.pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 185625000,
 		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
@@ -300,25 +252,16 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 213000000,
 		.pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
-	}, {
-		.pixclk = 216000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 216216000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
-	}, {
-		.pixclk = 237600000,
-		.pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 254000000,
 		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 277500000,
 		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
-	}, {
-		.pixclk = 288000000,
-		.pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 297000000,
 		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
 	},
-- 
2.43.0



From dominique.martinet at atmark-techno.com  Mon Sep  2 22:12:32 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Tue, 3 Sep 2024 14:12:32 +0900
Subject: [PATCH V4 4/5] phy: freescale: fsl-samsung-hdmi:  Use closest
 divider
In-Reply-To: <20240903013113.139698-5-aford173@gmail.com>
References: <20240903013113.139698-1-aford173@gmail.com>
 <20240903013113.139698-5-aford173@gmail.com>
Message-ID: <ZtaawD3vb8gmnVmO@atmark-techno.com>

Thank you!

Adam Ford wrote on Mon, Sep 02, 2024 at 08:30:46PM -0500:
> +	/* Calculate the differences and use the closest one */
> +	delta_frac = (rate - phy_pll_cfg[i].pixclk);
> +	delta_int = (rate - int_div_clk);

This assumes rate > whatever pixclk was found, that doesn't look true to
me for the integer calculation (`delta = abs(fout - tmp)` so it looks
like it can pick a larger value)

For the LUT, the way the lookup works is by picking the closest smaller
value so this is not a problem, but someone might come fix that later so
I'd rather just use abs() everywhere for future-proofing


That aside it looks good to me, I'll add a 0.5% tolerance patch and test
this all ASAP (might be a few days); will send the tolerance patch
properly after testing but for reference it will probably look like
this:
---
>From 12479386c955a59330232c84f4f856606c3a53e0 Mon Sep 17 00:00:00 2001
From: Dominique Martinet <dominique.martinet at atmark-techno.com>
Date: Tue, 3 Sep 2024 13:47:24 +0900
Subject: [PATCH] drm/bridge: imx8mp-hdmi-tx: allow 0.5% margin with selected clock

This allows the hdmi driver to pick e.g. 64.8MHz instead of 65Mhz when we
cannot output the exact frequency, enabling the imx8mp HDMI output to
support more modes

Signed-off-by: Dominique Martinet <dominique.martinet at atmark-techno.com>

diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c
index 13bc570c5473..9431cd5e06c3 100644
--- a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c
+++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c
@@ -23,6 +23,7 @@ imx8mp_hdmi_mode_valid(struct dw_hdmi *dw_hdmi, void *data,
 		       const struct drm_display_mode *mode)
 {
 	struct imx8mp_hdmi *hdmi = (struct imx8mp_hdmi *)data;
+	long round_rate;
 
 	if (mode->clock < 13500)
 		return MODE_CLOCK_LOW;
@@ -30,8 +31,9 @@ imx8mp_hdmi_mode_valid(struct dw_hdmi *dw_hdmi, void *data,
 	if (mode->clock > 297000)
 		return MODE_CLOCK_HIGH;
 
-	if (clk_round_rate(hdmi->pixclk, mode->clock * 1000) !=
-	    mode->clock * 1000)
+	round_rate = clk_round_rate(hdmi->pixclk, mode->clock * 1000);
+	/* accept 0.5% = 5/1000 tolerance (mode->clock is 1/1000) */
+	if (abs(round_rate - mode->clock * 1000) > mode->clock * 5)
 		return MODE_CLOCK_RANGE;
 
 	/* We don't support double-clocked and Interlaced modes */
---
--
Dominique




From sandor.yu at nxp.com  Mon Sep  2 23:07:25 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 3 Sep 2024 06:07:25 +0000
Subject: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <20240702-quartz-salamander-of-culture-eec264@houat>
References: <cover.1719903904.git.Sandor.yu@nxp.com>
 <359914108b879e995d4a39de32a33310009f0fab.1719903904.git.Sandor.yu@nxp.com>
 <20240702-quartz-salamander-of-culture-eec264@houat>
Message-ID: <PAXPR04MB94480AB0490BBF00D2BA17BBF4932@PAXPR04MB9448.eurprd04.prod.outlook.com>

Hi Maxime,

Thanks for your comments,

> -----Original Message-----
> From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On Behalf Of
> Maxime Ripard
> Sent: 2024?7?2? 21:25
> To: Sandor Yu <sandor.yu at nxp.com>
> Cc: dmitry.baryshkov at linaro.org; andrzej.hajda at intel.com;
> neil.armstrong at linaro.org; Laurent Pinchart
> <laurent.pinchart at ideasonboard.com>; jonas at kwiboo.se;
> jernej.skrabec at gmail.com; airlied at gmail.com; daniel at ffwll.ch;
> robh+dt at kernel.org; krzysztof.kozlowski+dt at linaro.org;
> shawnguo at kernel.org; s.hauer at pengutronix.de; festevam at gmail.com;
> vkoul at kernel.org; dri-devel at lists.freedesktop.org;
> devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> linux-kernel at vger.kernel.org; linux-phy at lists.infradead.org;
> kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>; Oliver Brown
> <oliver.brown at nxp.com>; alexander.stein at ew.tq-group.com;
> sam at ravnborg.org
> Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501
> DP/HDMI driver
> 
> Hi,
> 
> There's still the scrambler issue we discussed on v15, but I have some more
> comments.
> 
> On Tue, Jul 02, 2024 at 08:22:36PM GMT, Sandor Yu wrote:
> > +enum drm_connector_status cdns_mhdp8501_detect(struct
> > +cdns_mhdp8501_device *mhdp) {
> > +	u8 hpd = 0xf;
> > +
> > +	hpd = cdns_mhdp8501_read_hpd(mhdp);
> > +	if (hpd == 1)
> > +		return connector_status_connected;
> > +	else if (hpd == 0)
> > +		return connector_status_disconnected;
> > +
> > +	dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n", hpd);
> > +	return connector_status_unknown;
> > +}
> > +
> > +static void hotplug_work_func(struct work_struct *work) {
> > +	struct cdns_mhdp8501_device *mhdp = container_of(work,
> > +						     struct cdns_mhdp8501_device,
> > +						     hotplug_work.work);
> > +	enum drm_connector_status status = cdns_mhdp8501_detect(mhdp);
> > +
> > +	drm_bridge_hpd_notify(&mhdp->bridge, status);
> > +
> > +	if (status == connector_status_connected) {
> > +		/* Cable connected  */
> > +		DRM_INFO("HDMI/DP Cable Plug In\n");
> > +		enable_irq(mhdp->irq[IRQ_OUT]);
> > +	} else if (status == connector_status_disconnected) {
> > +		/* Cable Disconnected  */
> > +		DRM_INFO("HDMI/DP Cable Plug Out\n");
> > +		enable_irq(mhdp->irq[IRQ_IN]);
> > +	}
> > +}
> 
> You shouldn't play with the interrupt being enabled here: hotplug interrupts
> should always enabled.
> 
> If you can't for some reason, the reason should be documented in your driver.

iMX8MQ have two HPD interrupters, one for plugout and the other for plugin,
because they could not be masked, so we have to enable one and disable the other.
I will add more comments here.

> 
> > +	/* Mailbox protect for HDMI PHY access */
> > +	mutex_lock(&mhdp->mbox_mutex);
> > +	ret = phy_init(mhdp->phy);
> > +	mutex_unlock(&mhdp->mbox_mutex);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to initialize PHY: %d\n", ret);
> > +		goto clk_disable;
> > +	}
> > +
> > +	/* Mailbox protect for HDMI PHY access */
> > +	mutex_lock(&mhdp->mbox_mutex);
> > +	ret = phy_set_mode(mhdp->phy, phy_mode);
> > +	mutex_unlock(&mhdp->mbox_mutex);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to configure PHY: %d\n", ret);
> > +		goto clk_disable;
> > +	}
> 
> Why do you need a shared mutex between the phy and HDMI controller?

Both PHY and HDMI controller could access to the HDMI firmware by mailbox,
So add mutex to avoid race condition.

> 
> > +static enum drm_mode_status
> > +cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
> > +			       const struct drm_display_mode *mode,
> > +			       unsigned long long tmds_rate) {
> > +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +	union phy_configure_opts phy_cfg;
> > +	int ret;
> > +
> > +	phy_cfg.hdmi.tmds_char_rate = tmds_rate;
> > +
> > +	/* Mailbox protect for HDMI PHY access */
> > +	mutex_lock(&mhdp->mbox_mutex);
> > +	ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
> > +	mutex_unlock(&mhdp->mbox_mutex);
> > +	if (ret < 0)
> > +		return MODE_CLOCK_RANGE;
> > +
> > +	return MODE_OK;
> > +}
> > +
> > +static enum drm_mode_status
> > +cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
> > +			    const struct drm_display_info *info,
> > +			    const struct drm_display_mode *mode) {
> > +	unsigned long long tmds_rate;
> > +
> > +	/* We don't support double-clocked and Interlaced modes */
> > +	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
> > +	    mode->flags & DRM_MODE_FLAG_INTERLACE)
> > +		return MODE_BAD;
> > +
> > +	/* MAX support pixel clock rate 594MHz */
> > +	if (mode->clock > 594000)
> > +		return MODE_CLOCK_HIGH;
> 
> This needs to be in the tmds_char_rate_valid function
This clock rate check is covered by function tmds_char_rate_valid()
It could be removed if keep function tmds_char_rate_valid() be called by mode_valid.

> 
> > +	if (mode->hdisplay > 3840)
> > +		return MODE_BAD_HVALUE;
> > +
> > +	if (mode->vdisplay > 2160)
> > +		return MODE_BAD_VVALUE;
> > +
> > +	tmds_rate = mode->clock * 1000ULL;
> > +	return cdns_hdmi_tmds_char_rate_valid(bridge, mode, tmds_rate);
> 
> It will already be called by the core so this is redundant.

mode_valid function is use to filter the mode list in drm_helper_probe_single_connector_modes(),
if function cdns_hdmi_tmds_char_rate_valid() is not called, unsupported modes will in mode list.

> 
> > +static void cdns_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
> > +					   struct drm_bridge_state *old_state) {
> > +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +	struct drm_atomic_state *state = old_state->base.state;
> > +	struct drm_connector *connector;
> > +	struct video_info *video = &mhdp->video_info;
> > +	struct drm_crtc_state *crtc_state;
> > +	struct drm_connector_state *conn_state;
> > +	struct drm_display_mode *mode = &mhdp->mode;
> > +	union phy_configure_opts phy_cfg;
> > +	int ret;
> > +
> > +	connector = drm_atomic_get_new_connector_for_encoder(state,
> > +							     bridge->encoder);
> > +	if (WARN_ON(!connector))
> > +		return;
> > +
> > +	mhdp->curr_conn = connector;
> > +
> > +	conn_state = drm_atomic_get_new_connector_state(state, connector);
> > +	if (WARN_ON(!conn_state))
> > +		return;
> > +
> > +	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
> > +	if (WARN_ON(!crtc_state))
> > +		return;
> > +
> > +	video->color_fmt = conn_state->hdmi.output_format;
> > +	video->bpc = conn_state->hdmi.output_bpc;
> > +
> > +	drm_mode_copy(&mhdp->mode, &crtc_state->adjusted_mode);
> 
> Why do you need a copy of all these fields? You should pass the connector /
> bridge state around and not copy these fields.
> 
OK, mode will be removed, and it will replace by drm_connector_state.

> > +	/* video mode check */
> > +	if (mode->clock == 0 || mode->hdisplay == 0 || mode->vdisplay == 0)
> > +		return;
> 
> This should be checked in atomic_check, but I'm pretty sure it's redundant.
OK, It will be removed.
> 
> > +	dev_dbg(mhdp->dev, "Mode: %dx%dp%d\n",
> > +		mode->hdisplay, mode->vdisplay, mode->clock);
> > +
> > +	drm_atomic_helper_connector_hdmi_update_infoframes(connector,
> > +state);
> > +
> > +	/* Line swapping */
> > +	cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000 |
> > +mhdp->lane_mapping);
> > +
> > +	mhdp->hdmi.char_rate = drm_hdmi_compute_mode_clock(mode,
> > +							   mhdp->video_info.bpc,
> > +							   mhdp->video_info.color_fmt);
> 
> The TMDS char rate is already available in the connector_state so there no
> need to recompute it.
> 
> > +	phy_cfg.hdmi.tmds_char_rate = mhdp->hdmi.char_rate;
> 
> And you shouldn't store a copy either.
OK, variable char_rate will be removed and will use the drm_connector_state-> hdmi.tmds_char_rate

> 
> > +	/* Mailbox protect for HDMI PHY access */
> > +	mutex_lock(&mhdp->mbox_mutex);
> > +	ret = phy_configure(mhdp->phy, &phy_cfg);
> > +	mutex_unlock(&mhdp->mbox_mutex);
> > +	if (ret) {
> > +		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
> > +			__func__, ret);
> > +		return;
> > +	}
> > +
> > +	cdns_hdmi_sink_config(mhdp);
> > +
> > +	ret = cdns_hdmi_ctrl_init(mhdp);
> > +	if (ret < 0) {
> > +		dev_err(mhdp->dev, "%s, ret = %d\n", __func__, ret);
> > +		return;
> > +	}
> > +
> > +	/* Config GCP */
> > +	if (mhdp->video_info.bpc == 8)
> > +		cdns_hdmi_disable_gcp(mhdp);
> > +	else
> > +		cdns_hdmi_enable_gcp(mhdp);
> > +
> > +	ret = cdns_hdmi_mode_config(mhdp, mode, &mhdp->video_info);
> > +	if (ret < 0) {
> > +		dev_err(mhdp->dev, "CDN_API_HDMITX_SetVic_blocking ret
> = %d\n", ret);
> > +		return;
> > +	}
> > +}
> > +
> > +static int cdns_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge,
> > +					    enum hdmi_infoframe_type type) {
> > +	return 0;
> > +}
> 
> Either implement it or don't, but an empty function is dead code.
Must have function hdmi_clear_infoframe when set DRM_BRIDGE_OP_HDMI flag in &drm_bridge->ops, 
otherwise the drm_bridge_connector_init() will fail.
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/gpu/drm/drm_bridge_connector.c?h=next-20240902#n419

> 
> > +static int cdns_hdmi_bridge_write_infoframe(struct drm_bridge *bridge,
> > +					    enum hdmi_infoframe_type type,
> > +					    const u8 *buffer, size_t len) {
> > +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +
> > +	switch (type) {
> > +	case HDMI_INFOFRAME_TYPE_AVI:
> > +		cdns_hdmi_config_infoframe(mhdp, 0, len, buffer,
> HDMI_INFOFRAME_TYPE_AVI);
> > +		break;
> > +	case HDMI_INFOFRAME_TYPE_SPD:
> > +		cdns_hdmi_config_infoframe(mhdp, 1, len, buffer,
> HDMI_INFOFRAME_TYPE_SPD);
> > +		break;
> > +	case HDMI_INFOFRAME_TYPE_VENDOR:
> > +		cdns_hdmi_config_infoframe(mhdp, 2, len, buffer,
> HDMI_INFOFRAME_TYPE_VENDOR);
> > +		break;
> > +	default:
> > +		dev_dbg(mhdp->dev, "Unsupported infoframe type %x\n", type);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int cdns_hdmi_bridge_atomic_check(struct drm_bridge *bridge,
> > +					 struct drm_bridge_state *bridge_state,
> > +					 struct drm_crtc_state *crtc_state,
> > +					 struct drm_connector_state *conn_state) {
> > +	return
> drm_atomic_helper_connector_hdmi_check(conn_state->connector,
> > +conn_state->state); }
> 
> You should also call your mode_valid function here.
Function cdns_hdmi_tmds_char_rate_valid() is called in atomic_check().
Function cdns_hdmi_bridge_mode_valid is called by core, should not be called again.

Sandor
> 
> Maxime

From gregkh at linuxfoundation.org  Tue Sep  3 00:04:02 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue, 3 Sep 2024 09:04:02 +0200
Subject: [PATCH 1/6] power: supply: "usb_type" property may be written to
In-Reply-To: <20240831142039.28830-2-hdegoede@redhat.com>
References: <20240831142039.28830-1-hdegoede@redhat.com>
 <20240831142039.28830-2-hdegoede@redhat.com>
Message-ID: <2024090342-succulent-unkempt-666c@gregkh>

On Sat, Aug 31, 2024 at 04:20:34PM +0200, Hans de Goede wrote:
> According to Documentation/ABI/testing/sysfs-class-power the "usb_type"
> property is Read-Only.
> 
> For power-supplies which consume USB power such as battery charger chips,
> this is correct.
> 
> But the UCS1002 USB Port Power Controller driver which is a driver
> for a chip which is a power-source for USB-A charging ports "usb_type"
> is actually writable to configure the type of USB charger emulated
> by the USB-A port.

Ick, crazy hardware :(

> 
> Adjust the docs and the power_supply_sysfs.c code to adjust for this
> new writeable use of "usb_type":
> 
> 1. Update Documentation/ABI/testing/sysfs-class-power to document that
> "usb_type" may be writable
> 
> 2. Change the power_supply_attr type in power_supply_sysfs.c from
> POWER_SUPPLY_ATTR() into POWER_SUPPLY_ENUM_ATTR() so that the various
> usb_type string values from POWER_SUPPLY_TYPE_TEXT[] such as e.g.
> "SDP" and "USB_PD" can be written to the "usb_type" attribute instead
> of only accepting integer values.
> 
> Cc: Enric Balletbo Serra <enric.balletbo at collabora.com>
> Cc: Andrey Smirnov <andrew.smirnov at gmail.com>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Tue Sep  3 00:04:52 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue, 3 Sep 2024 09:04:52 +0200
Subject: [PATCH 6/6] power: supply: Change usb_types from an array into a
 bitmask
In-Reply-To: <20240831142039.28830-7-hdegoede@redhat.com>
References: <20240831142039.28830-1-hdegoede@redhat.com>
 <20240831142039.28830-7-hdegoede@redhat.com>
Message-ID: <2024090340-mumbo-worsening-9a55@gregkh>

On Sat, Aug 31, 2024 at 04:20:39PM +0200, Hans de Goede wrote:
> The bit_types array just hold a list of valid enum power_supply_usb_type
> values which map to 0 - 9. This can easily be represented as a bitmap.
> 
> This reduces the size of struct power_supply_desc and further reduces
> the data section size by drivers no longer needing to store the array.
> 
> This also unifies how usb_types are handled with charge_behaviours,
> which allows power_supply_show_usb_type() to be removed.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Nice!

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Tue Sep  3 00:08:52 2024
From: gregkh at linuxfoundation.org (Greg KH)
Date: Tue, 3 Sep 2024 09:08:52 +0200
Subject: [PATCH v2 3/6] dt-bindings: phy: mxs-usb-phy: add nxp,sim
 property
In-Reply-To: <20240829090935.ktc7jgd2en4qay2h@hippo>
References: <20240726113207.3393247-1-xu.yang_2@nxp.com>
 <20240726113207.3393247-3-xu.yang_2@nxp.com>
 <20240829090935.ktc7jgd2en4qay2h@hippo>
Message-ID: <2024090332-smokiness-virus-5f65@gregkh>

On Thu, Aug 29, 2024 at 05:09:35PM +0800, Xu Yang wrote:
> Hi Greg,
> 
> On Fri, Jul 26, 2024 at 07:32:04PM +0800, Xu Yang wrote:
> > i.MX7ULP need properly set System Integration Module(SIM) module to make
> > usb wakeup work well. This will add a "nxp,sim" property.
> > 
> > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> > 
> > ---
> > Changes in v2:
> >  - add else branch suggested by Rob
> > ---
> >  .../devicetree/bindings/phy/fsl,mxs-usbphy.yaml | 17 +++++++++++++++++
> >  1 file changed, 17 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml b/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml
> > index f4b1ca2fb562..ce665a2779b7 100644
> > --- a/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml
> > +++ b/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml
> > @@ -87,6 +87,12 @@ properties:
> >      maximum: 119
> >      default: 100
> >  
> > +  nxp,sim:
> > +    description:
> > +      The system integration module (SIM) provides system control and chip
> > +      configuration registers.
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +
> >  required:
> >    - compatible
> >    - reg
> > @@ -110,6 +116,17 @@ allOf:
> >        required:
> >          - fsl,anatop
> >  
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          const: fsl,imx7ulp-usbphy
> > +    then:
> > +      required:
> > +        - nxp,sim
> > +    else:
> > +      properties:
> > +        nxp,sim: false
> > +
> >  additionalProperties: false
> >  
> >  examples:
> 
> 
> Could you please pick up patch #3? Rest of the patches are mainlined.

Can you please resend it as an individual patch with the reviewed-by
added to it?

thanks,

greg k-h


From biju.das.jz at bp.renesas.com  Tue Sep  3 00:18:07 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Tue, 3 Sep 2024 07:18:07 +0000
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>

Hi Claudiu,

> -----Original Message-----
> From: Biju Das
> Sent: Monday, September 2, 2024 11:48 AM
> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
> 
> Hi Claudiu,
> 
> > -----Original Message-----
> > From: claudiu beznea <claudiu.beznea at tuxon.dev>
> > Sent: Monday, September 2, 2024 11:41 AM
> > Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
> > RZ/G3S SoC
> >
> >
> >
> > On 02.09.2024 12:18, Biju Das wrote:
> > >>>>> Do you have any plan to control this power transitions(ALL_ON to AWO and vice versa) in linux?
> > >>>> As you know, the RZ/G3S USB PM code is already prepared. This is
> > >>>> also configuring these signals when going to suspend/exiting from resume.
> > >>>> W/o configuring properly these signals the USB is not working after a suspend/resume cycle.
> > >>> One option is to handle SYSC USB PWRRDY signal in TF-A, if you
> > >>> plan to handle system transitions
> > >> there??
> > >>
> > >> As I mentioned, the settings in these registers may be changed by
> > >> intermediary booting
> > applications.
> > >> Depending on that, Linux need to control it also on probe for USB
> > >> to work (it should be the same with PCIe, these signals seems similar from HW manual
> description).
> > > You mean system transition settings will be override by U-boot, so Linux needs to restore it
> back??
> >
> > It was talking about booting...
> 
> I am also referring to boot. Boot starts with TF-A and it has a system state.
> 
> >
> > You proposed to handle SYSC signals from TF-A in a discussion about system power transitions:
> >
> > "One option is to handle SYSC USB PWRRDY signal in TF-A,  if you plan to handle system transitions"
> >
> > (I was guessing the "system transition" statement there refers to
> > power states transitions, ALL_ON <->
> > AWO/VBAT)
> 
> That is correct.
> 
> >
> > and I gave the booting process as a counter example: if we handle it
> > in TF-A it may not be enough as these signals might be changed by intermediary booting applications
> (e.g., U-Boot).
> 
> Why should U-boot override, system state signals such as USB PWRREADY? Can you please give an example.
> 
> >
> > To conclude, there are 3 scenarios I see where these signals need to
> > be
> > handled:
> > 1/ booting
> > 2/ suspend to RAM
> > 3/ driver unbind/bind
> 
> --> It should be OK as linux is not handling USB PWRREADY signal.
> 
> >
> > In case of booting: if we have TF-A to set signals there might be
> > intermediary booting applications (e.g. U-Boot) that set these signals
> > also. If it leaves it in improper state and Linux wants to use USB then the USB will not work (if
> Linux doesn't handle it).
> 
> That is the problem of U-boot. U-boot should not override system state signals such as USB PWRREADY.
> 
> >
> > In case of suspend to RAM: as TF-A is the only application in the
> > suspend to RAM chain, it should work handling it in TF-A.
> 
> That is correct, TF-A should handle based on system state.
> 
> >
> > In case of unbind/bind: currently we don't know if these signals
> > introduces any kind of power saving so asserting/de-asserting them in Linux may be useful from this
> perspective, if any.
> 
> These are system signals, according to me should not be used in unbind/bind.
> 
> I may be wrong.

Just to add the below are the 4 system states (power mode) for this LSI.

If I understand correctly, we need to configure USB PWRRDY signal
only when there is a transition from ALL_ON to AWO mode and vice versa.
as you see on AWO mode only CM-33 is active.

? ALL_OFF mode: All CPUs and peripheral modules can not be worked.
? ALL_ON mode: All CPUs and peripheral modules can be worked.
? AWO mode: Cortex-M33 and peripheral modules in PD_VCC and PD_VBATT domain can be worked.
? VBATT mode: Only RTC, tamper detection and backup registers can be worked.

System manager which is controlling both CA-55 and CM-33, will set USB PWRRDY signal
based on system state.

Since we don't have system manager for controlling both CA-55 and CM-33
Probably from CA-55 perspective, TF-A should be sufficient.

During boot clr USB PWR READY signal in TF-A.
STR case, suspend set USB PWR READY signal in TF-A.
STR case, resume clr USB PWR READY signal in TF-A.

I am not expert in this area. I may be wrong.

Maybe we need to get an opinion from Power experts in Linux.

Cheers,
Biju

From xu.yang_2 at nxp.com  Tue Sep  3 00:35:09 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Tue, 3 Sep 2024 15:35:09 +0800
Subject: [PATCH v2 3/6] dt-bindings: phy: mxs-usb-phy: add nxp,sim
 property
In-Reply-To: <2024090332-smokiness-virus-5f65@gregkh>
References: <20240726113207.3393247-1-xu.yang_2@nxp.com>
 <20240726113207.3393247-3-xu.yang_2@nxp.com>
 <20240829090935.ktc7jgd2en4qay2h@hippo>
 <2024090332-smokiness-virus-5f65@gregkh>
Message-ID: <20240903073509.7fb6izjnbhtiocjn@hippo>

On Tue, Sep 03, 2024 at 09:08:52AM +0200, Greg KH wrote:
> On Thu, Aug 29, 2024 at 05:09:35PM +0800, Xu Yang wrote:
> > Hi Greg,
> > 
> > On Fri, Jul 26, 2024 at 07:32:04PM +0800, Xu Yang wrote:
> > > i.MX7ULP need properly set System Integration Module(SIM) module to make
> > > usb wakeup work well. This will add a "nxp,sim" property.
> > > 
> > > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> > > 
> > > ---
> > > Changes in v2:
> > >  - add else branch suggested by Rob
> > > ---
> > >  .../devicetree/bindings/phy/fsl,mxs-usbphy.yaml | 17 +++++++++++++++++
> > >  1 file changed, 17 insertions(+)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml b/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml
> > > index f4b1ca2fb562..ce665a2779b7 100644
> > > --- a/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml
> > > +++ b/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml
> > > @@ -87,6 +87,12 @@ properties:
> > >      maximum: 119
> > >      default: 100
> > >  
> > > +  nxp,sim:
> > > +    description:
> > > +      The system integration module (SIM) provides system control and chip
> > > +      configuration registers.
> > > +    $ref: /schemas/types.yaml#/definitions/phandle
> > > +
> > >  required:
> > >    - compatible
> > >    - reg
> > > @@ -110,6 +116,17 @@ allOf:
> > >        required:
> > >          - fsl,anatop
> > >  
> > > +  - if:
> > > +      properties:
> > > +        compatible:
> > > +          const: fsl,imx7ulp-usbphy
> > > +    then:
> > > +      required:
> > > +        - nxp,sim
> > > +    else:
> > > +      properties:
> > > +        nxp,sim: false
> > > +
> > >  additionalProperties: false
> > >  
> > >  examples:
> > 
> > 
> > Could you please pick up patch #3? Rest of the patches are mainlined.
> 
> Can you please resend it as an individual patch with the reviewed-by
> added to it?

Sure. Will do it later.

Thanks,
Xu Yang


From m.felsch at pengutronix.de  Tue Sep  3 00:47:51 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Tue, 3 Sep 2024 09:47:51 +0200
Subject: [PATCH V4 1/5] phy: freescale: fsl-samsung-hdmi: Replace
 register defines with macro
In-Reply-To: <20240903013113.139698-2-aford173@gmail.com>
References: <20240903013113.139698-1-aford173@gmail.com>
 <20240903013113.139698-2-aford173@gmail.com>
Message-ID: <20240903074751.nacchml6trk6si6s@pengutronix.de>

Hi Adam,

thanks for the patch.

On 24-09-02, Adam Ford wrote:
> There are 47 registers defined as PHY_REG_xx were xx goes from 00 to
> 47.  Simplify this by replacing them all with a macro which is passed
> the register number to return the proper register offset.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> ---
>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 138 ++++++-------------
>  1 file changed, 41 insertions(+), 97 deletions(-)
> 
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> index 9048cdc760c2..bc5d3625ece6 100644
> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -14,76 +14,20 @@
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  
> -#define PHY_REG_00		0x00
> -#define PHY_REG_01		0x04
> -#define PHY_REG_02		0x08
> -#define PHY_REG_08		0x20
> -#define PHY_REG_09		0x24
> -#define PHY_REG_10		0x28
> -#define PHY_REG_11		0x2c
> -
> -#define PHY_REG_12		0x30
> -#define  REG12_CK_DIV_MASK	GENMASK(5, 4)
> -
> -#define PHY_REG_13		0x34
> -#define  REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
> -
> -#define PHY_REG_14		0x38
> -#define  REG14_TOL_MASK		GENMASK(7, 4)
> -#define  REG14_RP_CODE_MASK	GENMASK(3, 1)
> -#define  REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
> -
> -#define PHY_REG_15		0x3c
> -#define PHY_REG_16		0x40
> -#define PHY_REG_17		0x44
> -#define PHY_REG_18		0x48
> -#define PHY_REG_19		0x4c
> -#define PHY_REG_20		0x50
> -
> -#define PHY_REG_21		0x54
> -#define  REG21_SEL_TX_CK_INV	BIT(7)
> -#define  REG21_PMS_S_MASK	GENMASK(3, 0)
> -
> -#define PHY_REG_22		0x58
> -#define PHY_REG_23		0x5c
> -#define PHY_REG_24		0x60
> -#define PHY_REG_25		0x64
> -#define PHY_REG_26		0x68
> -#define PHY_REG_27		0x6c
> -#define PHY_REG_28		0x70
> -#define PHY_REG_29		0x74
> -#define PHY_REG_30		0x78
> -#define PHY_REG_31		0x7c
> -#define PHY_REG_32		0x80
> -
> -/*
> - * REG33 does not match the ref manual. According to Sandor Yu from NXP,
> - * "There is a doc issue on the i.MX8MP latest RM"
> - * REG33 is being used per guidance from Sandor
> - */

Can we keep this comment please.

> -#define PHY_REG_33		0x84
> -#define  REG33_MODE_SET_DONE	BIT(7)
> -#define  REG33_FIX_DA		BIT(1)
> -
> -#define PHY_REG_34		0x88
> -#define  REG34_PHY_READY	BIT(7)
> -#define  REG34_PLL_LOCK		BIT(6)
> -#define  REG34_PHY_CLK_READY	BIT(5)
> -
> -#define PHY_REG_35		0x8c
> -#define PHY_REG_36		0x90
> -#define PHY_REG_37		0x94
> -#define PHY_REG_38		0x98
> -#define PHY_REG_39		0x9c
> -#define PHY_REG_40		0xa0
> -#define PHY_REG_41		0xa4
> -#define PHY_REG_42		0xa8
> -#define PHY_REG_43		0xac
> -#define PHY_REG_44		0xb0
> -#define PHY_REG_45		0xb4
> -#define PHY_REG_46		0xb8
> -#define PHY_REG_47		0xbc
> +#define PHY_REG(reg)		(reg * 4)
> +
> +#define REG12_CK_DIV_MASK	GENMASK(5, 4)

> +#define REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)

> +#define REG14_TOL_MASK		GENMASK(7, 4)
> +#define REG14_RP_CODE_MASK	GENMASK(3, 1)
> +#define REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)

> +#define REG21_SEL_TX_CK_INV	BIT(7)
> +#define REG21_PMS_S_MASK	GENMASK(3, 0)

> +#define REG33_MODE_SET_DONE	BIT(7)
> +#define REG33_FIX_DA		BIT(1)

> +#define REG34_PHY_READY	BIT(7)
> +#define REG34_PLL_LOCK		BIT(6)
> +#define REG34_PHY_CLK_READY	BIT(5)

Also please add newlines in between different reg defines like I did
above. The comment which we should keep should be put above
REG_33_MODE_SET_DONE. The rest LGTM.

Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>

>  #define PHY_PLL_DIV_REGS_NUM 6
>  
> @@ -369,29 +313,29 @@ struct reg_settings {
>  };
>  
>  static const struct reg_settings common_phy_cfg[] = {
> -	{ PHY_REG_00, 0x00 }, { PHY_REG_01, 0xd1 },
> -	{ PHY_REG_08, 0x4f }, { PHY_REG_09, 0x30 },
> -	{ PHY_REG_10, 0x33 }, { PHY_REG_11, 0x65 },
> +	{ PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
> +	{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
> +	{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
>  	/* REG12 pixclk specific */
>  	/* REG13 pixclk specific */
>  	/* REG14 pixclk specific */
> -	{ PHY_REG_15, 0x80 }, { PHY_REG_16, 0x6c },
> -	{ PHY_REG_17, 0xf2 }, { PHY_REG_18, 0x67 },
> -	{ PHY_REG_19, 0x00 }, { PHY_REG_20, 0x10 },
> +	{ PHY_REG(15), 0x80 }, { PHY_REG(16), 0x6c },
> +	{ PHY_REG(17), 0xf2 }, { PHY_REG(18), 0x67 },
> +	{ PHY_REG(19), 0x00 }, { PHY_REG(20), 0x10 },
>  	/* REG21 pixclk specific */
> -	{ PHY_REG_22, 0x30 }, { PHY_REG_23, 0x32 },
> -	{ PHY_REG_24, 0x60 }, { PHY_REG_25, 0x8f },
> -	{ PHY_REG_26, 0x00 }, { PHY_REG_27, 0x00 },
> -	{ PHY_REG_28, 0x08 }, { PHY_REG_29, 0x00 },
> -	{ PHY_REG_30, 0x00 }, { PHY_REG_31, 0x00 },
> -	{ PHY_REG_32, 0x00 }, { PHY_REG_33, 0x80 },
> -	{ PHY_REG_34, 0x00 }, { PHY_REG_35, 0x00 },
> -	{ PHY_REG_36, 0x00 }, { PHY_REG_37, 0x00 },
> -	{ PHY_REG_38, 0x00 }, { PHY_REG_39, 0x00 },
> -	{ PHY_REG_40, 0x00 }, { PHY_REG_41, 0xe0 },
> -	{ PHY_REG_42, 0x83 }, { PHY_REG_43, 0x0f },
> -	{ PHY_REG_44, 0x3E }, { PHY_REG_45, 0xf8 },
> -	{ PHY_REG_46, 0x00 }, { PHY_REG_47, 0x00 }
> +	{ PHY_REG(22), 0x30 }, { PHY_REG(23), 0x32 },
> +	{ PHY_REG(24), 0x60 }, { PHY_REG(25), 0x8f },
> +	{ PHY_REG(26), 0x00 }, { PHY_REG(27), 0x00 },
> +	{ PHY_REG(28), 0x08 }, { PHY_REG(29), 0x00 },
> +	{ PHY_REG(30), 0x00 }, { PHY_REG(31), 0x00 },
> +	{ PHY_REG(32), 0x00 }, { PHY_REG(33), 0x80 },
> +	{ PHY_REG(34), 0x00 }, { PHY_REG(35), 0x00 },
> +	{ PHY_REG(36), 0x00 }, { PHY_REG(37), 0x00 },
> +	{ PHY_REG(38), 0x00 }, { PHY_REG(39), 0x00 },
> +	{ PHY_REG(40), 0x00 }, { PHY_REG(41), 0xe0 },
> +	{ PHY_REG(42), 0x83 }, { PHY_REG(43), 0x0f },
> +	{ PHY_REG(44), 0x3E }, { PHY_REG(45), 0xf8 },
> +	{ PHY_REG(46), 0x00 }, { PHY_REG(47), 0x00 }
>  };
>  
>  struct fsl_samsung_hdmi_phy {
> @@ -442,7 +386,7 @@ fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
>  	}
>  
>  	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
> -	       phy->regs + PHY_REG_21);
> +	       phy->regs + PHY_REG(21));
>  }
>  
>  static void
> @@ -469,7 +413,7 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
>  		break;
>  	}
>  
> -	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG_12);
> +	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG(12));
>  
>  	/*
>  	 * Calculation for the frequency lock detector target code (fld_tg_code)
> @@ -489,11 +433,11 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
>  
>  	/* FLD_TOL and FLD_RP_CODE taken from downstream driver */
>  	writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),
> -	       phy->regs + PHY_REG_13);
> +	       phy->regs + PHY_REG(13));
>  	writeb(FIELD_PREP(REG14_TOL_MASK, 2) |
>  	       FIELD_PREP(REG14_RP_CODE_MASK, 2) |
>  	       FIELD_PREP(REG14_TG_CODE_HIGH_MASK, fld_tg_code >> 8),
> -	       phy->regs + PHY_REG_14);
> +	       phy->regs + PHY_REG(14));
>  }
>  
>  static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
> @@ -503,7 +447,7 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
>  	u8 val;
>  
>  	/* HDMI PHY init */
> -	writeb(REG33_FIX_DA, phy->regs + PHY_REG_33);
> +	writeb(REG33_FIX_DA, phy->regs + PHY_REG(33));
>  
>  	/* common PHY registers */
>  	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
> @@ -511,14 +455,14 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
>  
>  	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
>  	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
> -		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG_02 + i * 4);
> +		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
>  
>  	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
>  	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
>  
> -	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG_33);
> +	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));
>  
> -	ret = readb_poll_timeout(phy->regs + PHY_REG_34, val,
> +	ret = readb_poll_timeout(phy->regs + PHY_REG(34), val,
>  				 val & REG34_PLL_LOCK, 50, 20000);
>  	if (ret)
>  		dev_err(phy->dev, "PLL failed to lock\n");
> -- 
> 2.43.0
> 
> 


From m.felsch at pengutronix.de  Tue Sep  3 00:57:30 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Tue, 3 Sep 2024 09:57:30 +0200
Subject: [PATCH V4 2/5] phy: freescale: fsl-samsung-hdmi: Simplify
 REG21_PMS_S_MASK lookup
In-Reply-To: <20240903013113.139698-3-aford173@gmail.com>
References: <20240903013113.139698-1-aford173@gmail.com>
 <20240903013113.139698-3-aford173@gmail.com>
Message-ID: <20240903075730.3323moqlc37ykeas@pengutronix.de>

Hi Adam,

On 24-09-02, Adam Ford wrote:
> The value of 'S' is writen to two places, PHY_REG3[7:4] and
> PHY_REG21[3:0].  There is a lookup table which contains
> the value of PHY_REG3.  Rather than using a switch statement
> based on the pixel clock to search for the value of 'S' again,
> just shift the contents of PHY_REG3[7:4] >> 4 and place the value
> in PHY_REG21[3:0].  Doing this can eliminate an entire function.

Good catch!

> Signed-off-by: Adam Ford <aford173 at gmail.com>

Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>

> ---
>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 39 ++------------------
>  1 file changed, 4 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> index bc5d3625ece6..a700a300dc6f 100644
> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -355,40 +355,6 @@ to_fsl_samsung_hdmi_phy(struct clk_hw *hw)
>  	return container_of(hw, struct fsl_samsung_hdmi_phy, hw);
>  }
>  
> -static void
> -fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
> -				      const struct phy_config *cfg)
> -{
> -	u8 div = 0x1;
> -
> -	switch (cfg->pixclk) {
> -	case  22250000 ...  33750000:
> -		div = 0xf;
> -		break;
> -	case  35000000 ...  40000000:
> -		div = 0xb;
> -		break;
> -	case  43200000 ...  47500000:
> -		div = 0x9;
> -		break;
> -	case  50349650 ...  63500000:
> -		div = 0x7;
> -		break;
> -	case  67500000 ...  90000000:
> -		div = 0x5;
> -		break;
> -	case  94000000 ... 148500000:
> -		div = 0x3;
> -		break;
> -	case 154000000 ... 297000000:
> -		div = 0x1;
> -		break;
> -	}
> -
> -	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
> -	       phy->regs + PHY_REG(21));
> -}
> -
>  static void
>  fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
>  					    const struct phy_config *cfg)
> @@ -457,7 +423,10 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
>  	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
>  		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
>  
> -	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
> +	/* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
> +	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
> +	       cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
> +
>  	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
>  
>  	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));
> -- 
> 2.43.0
> 
> 


From xu.yang_2 at nxp.com  Tue Sep  3 00:58:09 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Tue,  3 Sep 2024 15:58:09 +0800
Subject: [PATCH v3 1/2] dt-bindings: phy: mxs-usb-phy: add nxp,sim property
Message-ID: <20240903075810.1196928-1-xu.yang_2@nxp.com>

i.MX7ULP need properly set System Integration Module(SIM) module to make
usb wakeup work well. This will add a "nxp,sim" property.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - add else branch suggested by Rob
Changes in v3:
 - add Rb tag
---
 .../devicetree/bindings/phy/fsl,mxs-usbphy.yaml | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml b/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml
index f4b1ca2fb562..ce665a2779b7 100644
--- a/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml
+++ b/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml
@@ -87,6 +87,12 @@ properties:
     maximum: 119
     default: 100
 
+  nxp,sim:
+    description:
+      The system integration module (SIM) provides system control and chip
+      configuration registers.
+    $ref: /schemas/types.yaml#/definitions/phandle
+
 required:
   - compatible
   - reg
@@ -110,6 +116,17 @@ allOf:
       required:
         - fsl,anatop
 
+  - if:
+      properties:
+        compatible:
+          const: fsl,imx7ulp-usbphy
+    then:
+      required:
+        - nxp,sim
+    else:
+      properties:
+        nxp,sim: false
+
 additionalProperties: false
 
 examples:
-- 
2.34.1



From xu.yang_2 at nxp.com  Tue Sep  3 00:58:10 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Tue,  3 Sep 2024 15:58:10 +0800
Subject: [PATCH v3 2/2] ARM: dts: imx7ulp: add "nxp,sim" property for usbphy1
In-Reply-To: <20240903075810.1196928-1-xu.yang_2@nxp.com>
References: <20240903075810.1196928-1-xu.yang_2@nxp.com>
Message-ID: <20240903075810.1196928-2-xu.yang_2@nxp.com>

i.MX7ULP need properly set System Integration Module(SIM) module to make
usb wakeup work well. This will add a "nxp,sim" property for usbphy1.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - no changes
Changes in v3:
 - no changes
---
 arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi b/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
index ac338320ac1d..b093f2a447ae 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
@@ -214,6 +214,7 @@ usbphy1: usb-phy at 40350000 {
 			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&pcc2 IMX7ULP_CLK_USB_PHY>;
 			#phy-cells = <0>;
+			nxp,sim = <&sim>;
 		};
 
 		usdhc0: mmc at 40370000 {
-- 
2.34.1



From josua at solid-run.com  Tue Sep  3 01:04:48 2024
From: josua at solid-run.com (Josua Mayer)
Date: Tue, 3 Sep 2024 08:04:48 +0000
Subject: [PATCH] phy: mvebu-cp110-utmi: support swapping d+/d- lanes by
 dts property
In-Reply-To: <Zq--_WIgaPXPiYRQ@matsya>
References: <20240704-mvebu-utmi-phy-v1-1-9d3c8eea46e5@solid-run.com>
 <Zq--_WIgaPXPiYRQ@matsya>
Message-ID: <ae576164-f60d-4048-96aa-4f21117f5f4d@solid-run.com>

Hi Vinod,

Thank you for looking at my patch!

Am 04.08.24 um 20:48 schrieb Vinod Koul:
> On 04-07-24, 16:57, Josua Mayer wrote:
>> CP11x UTMI PHY supports swapping D+/D- signals via digital control
>> register 1.
>>
>> Add support for the "swap-dx-lanes" device-tree property, which lists
>> the port-ids that should swap D+ and D-.
>> The property is evaluated in probe and applied before power-on
>> during mvebu_cp110_utmi_port_setup.
> It fails my build tests
I will rebase on v6.11-rc1, compile-test and then submit a new version.
>
> drivers/phy/marvell/phy-mvebu-cp110-utmi.c:
> In function ?mvebu_cp110_utmi_phy_probe?:
> drivers/phy/marvell/phy-mvebu-cp110-utmi.c:361:89:
> error: macro "of_property_for_each_u32" passed 5 arguments, but takes
> just 3
>    361 |                 of_property_for_each_u32(dev->of_node,
> "swap-dx-lanes", prop, p, swap_dx)
>        |
> ^
> In file included from
> drivers/phy/marvell/phy-mvebu-cp110-utmi.c:15:
> include/linux/of.h:1432: note:
> macro "of_property_for_each_u32" defined here
>   1432 | #define of_property_for_each_u32(np, propname, u)
> \
>        |
> drivers/phy/marvell/phy-mvebu-cp110-utmi.c:361:17:
> error: ?of_property_for_each_u32? undeclared (first use in this
> function); did you mean ?of_property_read_u32??
>    361 |                 of_property_for_each_u32(dev->of_node,
> "swap-dx-lanes", prop, p, swap_dx)
>        |                 ^~~~~~~~~~~~~~~~~~~~~~~~
>        |                 of_property_read_u32
> drivers/phy/marvell/phy-mvebu-cp110-utmi.c:361:17:
> note: each undeclared identifier is reported only once for each function
> it appears in
> drivers/phy/marvell/phy-mvebu-cp110-utmi.c:361:41:
> error: expected ?;? before ?if?
>    361 |                 of_property_for_each_u32(dev->of_node,
> "swap-dx-lanes", prop, p, swap_dx)
>        |                                         ^
>        |                                         ;
>    362 |                         if (swap_dx == port_id)
>        |                         ~~
> drivers/phy/marvell/phy-mvebu-cp110-utmi.c:301:13:
> error: unused variable ?swap_dx? [-Werror=unused-variable]
>    301 |         u32 swap_dx = 0;
>        |             ^~~~~~~
> drivers/phy/marvell/phy-mvebu-cp110-utmi.c:299:23:
> error: unused variable ?p? [-Werror=unused-variable]
>    299 |         const __be32 *p;
>        |                       ^
> drivers/phy/marvell/phy-mvebu-cp110-utmi.c:298:26:
> error: unused variable ?prop? [-Werror=unused-variable]
>    298 |         struct property *prop;
>        |                          ^~~~
> cc1: all warnings being treated as errors
>
>
>> Signed-off-by: Josua Mayer <josua at solid-run.com>
>> ---
>>   drivers/phy/marvell/phy-mvebu-cp110-utmi.c | 17 +++++++++++++++++
>>   1 file changed, 17 insertions(+)
>>
>> diff --git a/drivers/phy/marvell/phy-mvebu-cp110-utmi.c b/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
>> index 4922a5f3327d..5e403f842e9a 100644
>> --- a/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
>> +++ b/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
>> @@ -62,6 +62,8 @@
>>   #define   SQ_AMP_CAL_MASK			GENMASK(2, 0)
>>   #define   SQ_AMP_CAL_VAL			1
>>   #define   SQ_AMP_CAL_EN				BIT(3)
>> +#define UTMI_DIG_CTRL1_REG			0x20
>> +#define   SWAP_DPDM				BIT(15)
>>   #define UTMI_CTRL_STATUS0_REG			0x24
>>   #define   SUSPENDM				BIT(22)
>>   #define   TEST_SEL				BIT(25)
>> @@ -104,6 +106,7 @@ struct mvebu_cp110_utmi_port {
>>   	struct mvebu_cp110_utmi *priv;
>>   	u32 id;
>>   	enum usb_dr_mode dr_mode;
>> +	bool swap_dx;
>>   };
>>   
>>   static void mvebu_cp110_utmi_port_setup(struct mvebu_cp110_utmi_port *port)
>> @@ -159,6 +162,13 @@ static void mvebu_cp110_utmi_port_setup(struct mvebu_cp110_utmi_port *port)
>>   	reg &= ~(VDAT_MASK | VSRC_MASK);
>>   	reg |= (VDAT_VAL << VDAT_OFFSET) | (VSRC_VAL << VSRC_OFFSET);
>>   	writel(reg, PORT_REGS(port) + UTMI_CHGDTC_CTRL_REG);
>> +
>> +	/* Swap D+/D- */
>> +	reg = readl(PORT_REGS(port) + UTMI_DIG_CTRL1_REG);
>> +	reg &= ~(SWAP_DPDM);
>> +	if (port->swap_dx)
>> +		reg |= SWAP_DPDM;
>> +	writel(reg, PORT_REGS(port) + UTMI_DIG_CTRL1_REG);
>>   }
>>   
>>   static int mvebu_cp110_utmi_phy_power_off(struct phy *phy)
>> @@ -285,7 +295,10 @@ static int mvebu_cp110_utmi_phy_probe(struct platform_device *pdev)
>>   	struct mvebu_cp110_utmi *utmi;
>>   	struct phy_provider *provider;
>>   	struct device_node *child;
>> +	struct property *prop;
>> +	const __be32 *p;
>>   	u32 usb_devices = 0;
>> +	u32 swap_dx = 0;
>>   
>>   	utmi = devm_kzalloc(dev, sizeof(*utmi), GFP_KERNEL);
>>   	if (!utmi)
>> @@ -345,6 +358,10 @@ static int mvebu_cp110_utmi_phy_probe(struct platform_device *pdev)
>>   			}
>>   		}
>>   
>> +		of_property_for_each_u32(dev->of_node, "swap-dx-lanes", prop, p, swap_dx)
>> +			if (swap_dx == port_id)
>> +				port->swap_dx = 1;
>> +
>>   		/* Retrieve PHY capabilities */
>>   		utmi->ops = &mvebu_cp110_utmi_phy_ops;
>>   
>>
>> ---
>> base-commit: 4de480264948cbf2b08a72c39ee122a9f9761e03
>> change-id: 20240704-mvebu-utmi-phy-84aa3bf3957d
>>
>> Sincerely,
>> -- 
>> Josua Mayer <josua at solid-run.com>



From hdegoede at redhat.com  Tue Sep  3 01:27:08 2024
From: hdegoede at redhat.com (Hans de Goede)
Date: Tue, 3 Sep 2024 10:27:08 +0200
Subject: [PATCH 6/6] power: supply: Change usb_types from an array into a
 bitmask
In-Reply-To: <2024090340-mumbo-worsening-9a55@gregkh>
References: <20240831142039.28830-1-hdegoede@redhat.com>
 <20240831142039.28830-7-hdegoede@redhat.com>
 <2024090340-mumbo-worsening-9a55@gregkh>
Message-ID: <6f4e23ce-2f32-44fc-93d9-ab7d0867b0ee@redhat.com>

Hi Greg,

Thank you for the reviews.

On 9/3/24 9:04 AM, Greg Kroah-Hartman wrote:
> On Sat, Aug 31, 2024 at 04:20:39PM +0200, Hans de Goede wrote:
>> The bit_types array just hold a list of valid enum power_supply_usb_type
>> values which map to 0 - 9. This can easily be represented as a bitmap.
>>
>> This reduces the size of struct power_supply_desc and further reduces
>> the data section size by drivers no longer needing to store the array.
>>
>> This also unifies how usb_types are handled with charge_behaviours,
>> which allows power_supply_show_usb_type() to be removed.
>>
>> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> 
> Nice!
> 
> Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>

I assume this also counts as an ack for merging this through
the linux-power-supply tree ?

Regards,

Hans





From mripard at kernel.org  Tue Sep  3 01:28:09 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 3 Sep 2024 10:28:09 +0200
Subject: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <PAXPR04MB94480AB0490BBF00D2BA17BBF4932@PAXPR04MB9448.eurprd04.prod.outlook.com>
References: <cover.1719903904.git.Sandor.yu@nxp.com>
 <359914108b879e995d4a39de32a33310009f0fab.1719903904.git.Sandor.yu@nxp.com>
 <20240702-quartz-salamander-of-culture-eec264@houat>
 <PAXPR04MB94480AB0490BBF00D2BA17BBF4932@PAXPR04MB9448.eurprd04.prod.outlook.com>
Message-ID: <20240903-gay-capable-hound-3cbef2@houat>

On Tue, Sep 03, 2024 at 06:07:25AM GMT, Sandor Yu wrote:
> Hi Maxime,
> 
> Thanks for your comments,
> 
> > -----Original Message-----
> > From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On Behalf Of
> > Maxime Ripard
> > Sent: 2024?7?2? 21:25
> > To: Sandor Yu <sandor.yu at nxp.com>
> > Cc: dmitry.baryshkov at linaro.org; andrzej.hajda at intel.com;
> > neil.armstrong at linaro.org; Laurent Pinchart
> > <laurent.pinchart at ideasonboard.com>; jonas at kwiboo.se;
> > jernej.skrabec at gmail.com; airlied at gmail.com; daniel at ffwll.ch;
> > robh+dt at kernel.org; krzysztof.kozlowski+dt at linaro.org;
> > shawnguo at kernel.org; s.hauer at pengutronix.de; festevam at gmail.com;
> > vkoul at kernel.org; dri-devel at lists.freedesktop.org;
> > devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > linux-kernel at vger.kernel.org; linux-phy at lists.infradead.org;
> > kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>; Oliver Brown
> > <oliver.brown at nxp.com>; alexander.stein at ew.tq-group.com;
> > sam at ravnborg.org
> > Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501
> > DP/HDMI driver
> > 
> > Hi,
> > 
> > There's still the scrambler issue we discussed on v15, but I have some more
> > comments.
> > 
> > On Tue, Jul 02, 2024 at 08:22:36PM GMT, Sandor Yu wrote:
> > > +enum drm_connector_status cdns_mhdp8501_detect(struct
> > > +cdns_mhdp8501_device *mhdp) {
> > > +	u8 hpd = 0xf;
> > > +
> > > +	hpd = cdns_mhdp8501_read_hpd(mhdp);
> > > +	if (hpd == 1)
> > > +		return connector_status_connected;
> > > +	else if (hpd == 0)
> > > +		return connector_status_disconnected;
> > > +
> > > +	dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n", hpd);
> > > +	return connector_status_unknown;
> > > +}
> > > +
> > > +static void hotplug_work_func(struct work_struct *work) {
> > > +	struct cdns_mhdp8501_device *mhdp = container_of(work,
> > > +						     struct cdns_mhdp8501_device,
> > > +						     hotplug_work.work);
> > > +	enum drm_connector_status status = cdns_mhdp8501_detect(mhdp);
> > > +
> > > +	drm_bridge_hpd_notify(&mhdp->bridge, status);
> > > +
> > > +	if (status == connector_status_connected) {
> > > +		/* Cable connected  */
> > > +		DRM_INFO("HDMI/DP Cable Plug In\n");
> > > +		enable_irq(mhdp->irq[IRQ_OUT]);
> > > +	} else if (status == connector_status_disconnected) {
> > > +		/* Cable Disconnected  */
> > > +		DRM_INFO("HDMI/DP Cable Plug Out\n");
> > > +		enable_irq(mhdp->irq[IRQ_IN]);
> > > +	}
> > > +}
> > 
> > You shouldn't play with the interrupt being enabled here: hotplug interrupts
> > should always enabled.
> > 
> > If you can't for some reason, the reason should be documented in your driver.
> 
> iMX8MQ have two HPD interrupters, one for plugout and the other for plugin,
> because they could not be masked, so we have to enable one and disable the other.
> I will add more comments here.

Right, but why do you need to enable and disable them? Do you get
spurious interrupts?

> > 
> > > +	/* Mailbox protect for HDMI PHY access */
> > > +	mutex_lock(&mhdp->mbox_mutex);
> > > +	ret = phy_init(mhdp->phy);
> > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > +	if (ret) {
> > > +		dev_err(dev, "Failed to initialize PHY: %d\n", ret);
> > > +		goto clk_disable;
> > > +	}
> > > +
> > > +	/* Mailbox protect for HDMI PHY access */
> > > +	mutex_lock(&mhdp->mbox_mutex);
> > > +	ret = phy_set_mode(mhdp->phy, phy_mode);
> > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > +	if (ret) {
> > > +		dev_err(dev, "Failed to configure PHY: %d\n", ret);
> > > +		goto clk_disable;
> > > +	}
> > 
> > Why do you need a shared mutex between the phy and HDMI controller?
> 
> Both PHY and HDMI controller could access to the HDMI firmware by mailbox,
> So add mutex to avoid race condition.

That should be handled at either the phy or mailbox level, not in your
hdmi driver.

> > 
> > > +static enum drm_mode_status
> > > +cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
> > > +			       const struct drm_display_mode *mode,
> > > +			       unsigned long long tmds_rate) {
> > > +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > > +	union phy_configure_opts phy_cfg;
> > > +	int ret;
> > > +
> > > +	phy_cfg.hdmi.tmds_char_rate = tmds_rate;
> > > +
> > > +	/* Mailbox protect for HDMI PHY access */
> > > +	mutex_lock(&mhdp->mbox_mutex);
> > > +	ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
> > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > +	if (ret < 0)
> > > +		return MODE_CLOCK_RANGE;
> > > +
> > > +	return MODE_OK;
> > > +}
> > > +
> > > +static enum drm_mode_status
> > > +cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
> > > +			    const struct drm_display_info *info,
> > > +			    const struct drm_display_mode *mode) {
> > > +	unsigned long long tmds_rate;
> > > +
> > > +	/* We don't support double-clocked and Interlaced modes */
> > > +	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
> > > +	    mode->flags & DRM_MODE_FLAG_INTERLACE)
> > > +		return MODE_BAD;
> > > +
> > > +	/* MAX support pixel clock rate 594MHz */
> > > +	if (mode->clock > 594000)
> > > +		return MODE_CLOCK_HIGH;
> > 
> > This needs to be in the tmds_char_rate_valid function
> This clock rate check is covered by function tmds_char_rate_valid()
> It could be removed if keep function tmds_char_rate_valid() be called by mode_valid.

Yeah, it's not something you should have to duplicate.

> > 
> > > +	if (mode->hdisplay > 3840)
> > > +		return MODE_BAD_HVALUE;
> > > +
> > > +	if (mode->vdisplay > 2160)
> > > +		return MODE_BAD_VVALUE;
> > > +
> > > +	tmds_rate = mode->clock * 1000ULL;
> > > +	return cdns_hdmi_tmds_char_rate_valid(bridge, mode, tmds_rate);
> > 
> > It will already be called by the core so this is redundant.
> 
> mode_valid function is use to filter the mode list in drm_helper_probe_single_connector_modes(),
> if function cdns_hdmi_tmds_char_rate_valid() is not called, unsupported modes will in mode list.

It's probably something we should deal with in the core somehow. I'm not
entirely sure how to reconcile drm_bridge_connector and the hdmi
framework there, but we should at the very least provide a mode_valid
helper for bridges.

> > 
> > > +static void cdns_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
> > > +					   struct drm_bridge_state *old_state) {
> > > +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > > +	struct drm_atomic_state *state = old_state->base.state;
> > > +	struct drm_connector *connector;
> > > +	struct video_info *video = &mhdp->video_info;
> > > +	struct drm_crtc_state *crtc_state;
> > > +	struct drm_connector_state *conn_state;
> > > +	struct drm_display_mode *mode = &mhdp->mode;
> > > +	union phy_configure_opts phy_cfg;
> > > +	int ret;
> > > +
> > > +	connector = drm_atomic_get_new_connector_for_encoder(state,
> > > +							     bridge->encoder);
> > > +	if (WARN_ON(!connector))
> > > +		return;
> > > +
> > > +	mhdp->curr_conn = connector;
> > > +
> > > +	conn_state = drm_atomic_get_new_connector_state(state, connector);
> > > +	if (WARN_ON(!conn_state))
> > > +		return;
> > > +
> > > +	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
> > > +	if (WARN_ON(!crtc_state))
> > > +		return;
> > > +
> > > +	video->color_fmt = conn_state->hdmi.output_format;
> > > +	video->bpc = conn_state->hdmi.output_bpc;
> > > +
> > > +	drm_mode_copy(&mhdp->mode, &crtc_state->adjusted_mode);
> > 
> > Why do you need a copy of all these fields? You should pass the connector /
> > bridge state around and not copy these fields.
> > 
> OK, mode will be removed, and it will replace by drm_connector_state.
> 
> > > +	/* video mode check */
> > > +	if (mode->clock == 0 || mode->hdisplay == 0 || mode->vdisplay == 0)
> > > +		return;
> > 
> > This should be checked in atomic_check, but I'm pretty sure it's redundant.
> OK, It will be removed.
> > 
> > > +	dev_dbg(mhdp->dev, "Mode: %dx%dp%d\n",
> > > +		mode->hdisplay, mode->vdisplay, mode->clock);
> > > +
> > > +	drm_atomic_helper_connector_hdmi_update_infoframes(connector,
> > > +state);
> > > +
> > > +	/* Line swapping */
> > > +	cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000 |
> > > +mhdp->lane_mapping);
> > > +
> > > +	mhdp->hdmi.char_rate = drm_hdmi_compute_mode_clock(mode,
> > > +							   mhdp->video_info.bpc,
> > > +							   mhdp->video_info.color_fmt);
> > 
> > The TMDS char rate is already available in the connector_state so there no
> > need to recompute it.
> > 
> > > +	phy_cfg.hdmi.tmds_char_rate = mhdp->hdmi.char_rate;
> > 
> > And you shouldn't store a copy either.
> OK, variable char_rate will be removed and will use the drm_connector_state-> hdmi.tmds_char_rate
> 
> > 
> > > +	/* Mailbox protect for HDMI PHY access */
> > > +	mutex_lock(&mhdp->mbox_mutex);
> > > +	ret = phy_configure(mhdp->phy, &phy_cfg);
> > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > +	if (ret) {
> > > +		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
> > > +			__func__, ret);
> > > +		return;
> > > +	}
> > > +
> > > +	cdns_hdmi_sink_config(mhdp);
> > > +
> > > +	ret = cdns_hdmi_ctrl_init(mhdp);
> > > +	if (ret < 0) {
> > > +		dev_err(mhdp->dev, "%s, ret = %d\n", __func__, ret);
> > > +		return;
> > > +	}
> > > +
> > > +	/* Config GCP */
> > > +	if (mhdp->video_info.bpc == 8)
> > > +		cdns_hdmi_disable_gcp(mhdp);
> > > +	else
> > > +		cdns_hdmi_enable_gcp(mhdp);
> > > +
> > > +	ret = cdns_hdmi_mode_config(mhdp, mode, &mhdp->video_info);
> > > +	if (ret < 0) {
> > > +		dev_err(mhdp->dev, "CDN_API_HDMITX_SetVic_blocking ret
> > = %d\n", ret);
> > > +		return;
> > > +	}
> > > +}
> > > +
> > > +static int cdns_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge,
> > > +					    enum hdmi_infoframe_type type) {
> > > +	return 0;
> > > +}
> > 
> > Either implement it or don't, but an empty function is dead code.
> Must have function hdmi_clear_infoframe when set DRM_BRIDGE_OP_HDMI flag in &drm_bridge->ops, 
> otherwise the drm_bridge_connector_init() will fail.
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/gpu/drm/drm_bridge_connector.c?h=next-20240902#n419

That's a strong hint that you should implement it, not workaround it :)

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 273 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20240903/dbff393e/attachment.sig>

From gregkh at linuxfoundation.org  Tue Sep  3 01:32:12 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue, 3 Sep 2024 10:32:12 +0200
Subject: [PATCH 6/6] power: supply: Change usb_types from an array into a
 bitmask
In-Reply-To: <6f4e23ce-2f32-44fc-93d9-ab7d0867b0ee@redhat.com>
References: <20240831142039.28830-1-hdegoede@redhat.com>
 <20240831142039.28830-7-hdegoede@redhat.com>
 <2024090340-mumbo-worsening-9a55@gregkh>
 <6f4e23ce-2f32-44fc-93d9-ab7d0867b0ee@redhat.com>
Message-ID: <2024090308-retying-playpen-cc51@gregkh>

On Tue, Sep 03, 2024 at 10:27:08AM +0200, Hans de Goede wrote:
> Hi Greg,
> 
> Thank you for the reviews.
> 
> On 9/3/24 9:04 AM, Greg Kroah-Hartman wrote:
> > On Sat, Aug 31, 2024 at 04:20:39PM +0200, Hans de Goede wrote:
> >> The bit_types array just hold a list of valid enum power_supply_usb_type
> >> values which map to 0 - 9. This can easily be represented as a bitmap.
> >>
> >> This reduces the size of struct power_supply_desc and further reduces
> >> the data section size by drivers no longer needing to store the array.
> >>
> >> This also unifies how usb_types are handled with charge_behaviours,
> >> which allows power_supply_show_usb_type() to be removed.
> >>
> >> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> > 
> > Nice!
> > 
> > Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> 
> I assume this also counts as an ack for merging this through
> the linux-power-supply tree ?

Yes please.


From josua at solid-run.com  Tue Sep  3 01:41:54 2024
From: josua at solid-run.com (Josua Mayer)
Date: Tue, 03 Sep 2024 11:41:54 +0300
Subject: [PATCH v2] phy: mvebu-cp110-utmi: support swapping d+/d- lanes by
 dts property
Message-ID: <20240903-mvebu-utmi-phy-v2-1-7f49c131fad0@solid-run.com>

CP11x UTMI PHY supports swapping D+/D- signals via digital control
register 1.

Add support for the "swap-dx-lanes" device-tree property, which lists
the port-ids that should swap D+ and D-.
The property is evaluated in probe and applied before power-on
during mvebu_cp110_utmi_port_setup.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
Changes in v2:
- fixed compile error introduced with v6.11-rc1:
  parameters of of_property_for_each_u32 were changed from 5 to 3.
  (Reported-by: Vinod Koul <vkoul at kernel.org>)
- rebased on v6.11-rc1
- Link to v1: https://lore.kernel.org/r/20240704-mvebu-utmi-phy-v1-1-9d3c8eea46e5 at solid-run.com
---
 drivers/phy/marvell/phy-mvebu-cp110-utmi.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/phy/marvell/phy-mvebu-cp110-utmi.c b/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
index 4922a5f3327d..12d619d9cf97 100644
--- a/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
+++ b/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
@@ -62,6 +62,8 @@
 #define   SQ_AMP_CAL_MASK			GENMASK(2, 0)
 #define   SQ_AMP_CAL_VAL			1
 #define   SQ_AMP_CAL_EN				BIT(3)
+#define UTMI_DIG_CTRL1_REG			0x20
+#define   SWAP_DPDM				BIT(15)
 #define UTMI_CTRL_STATUS0_REG			0x24
 #define   SUSPENDM				BIT(22)
 #define   TEST_SEL				BIT(25)
@@ -104,6 +106,7 @@ struct mvebu_cp110_utmi_port {
 	struct mvebu_cp110_utmi *priv;
 	u32 id;
 	enum usb_dr_mode dr_mode;
+	bool swap_dx;
 };
 
 static void mvebu_cp110_utmi_port_setup(struct mvebu_cp110_utmi_port *port)
@@ -159,6 +162,13 @@ static void mvebu_cp110_utmi_port_setup(struct mvebu_cp110_utmi_port *port)
 	reg &= ~(VDAT_MASK | VSRC_MASK);
 	reg |= (VDAT_VAL << VDAT_OFFSET) | (VSRC_VAL << VSRC_OFFSET);
 	writel(reg, PORT_REGS(port) + UTMI_CHGDTC_CTRL_REG);
+
+	/* Swap D+/D- */
+	reg = readl(PORT_REGS(port) + UTMI_DIG_CTRL1_REG);
+	reg &= ~(SWAP_DPDM);
+	if (port->swap_dx)
+		reg |= SWAP_DPDM;
+	writel(reg, PORT_REGS(port) + UTMI_DIG_CTRL1_REG);
 }
 
 static int mvebu_cp110_utmi_phy_power_off(struct phy *phy)
@@ -286,6 +296,7 @@ static int mvebu_cp110_utmi_phy_probe(struct platform_device *pdev)
 	struct phy_provider *provider;
 	struct device_node *child;
 	u32 usb_devices = 0;
+	u32 swap_dx = 0;
 
 	utmi = devm_kzalloc(dev, sizeof(*utmi), GFP_KERNEL);
 	if (!utmi)
@@ -345,6 +356,10 @@ static int mvebu_cp110_utmi_phy_probe(struct platform_device *pdev)
 			}
 		}
 
+		of_property_for_each_u32(dev->of_node, "swap-dx-lanes", swap_dx)
+			if (swap_dx == port_id)
+				port->swap_dx = 1;
+
 		/* Retrieve PHY capabilities */
 		utmi->ops = &mvebu_cp110_utmi_phy_ops;
 

---
base-commit: 8400291e289ee6b2bf9779ff1c83a291501f017b
change-id: 20240704-mvebu-utmi-phy-84aa3bf3957d

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



From conor at kernel.org  Tue Sep  3 02:42:30 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 3 Sep 2024 10:42:30 +0100
Subject: [PATCH v2 1/3] dt-bindings: phy: jh7110-usb-phy: Add sys-syscon
 property
In-Reply-To: <SHXPR01MB08632E50DFE53BE0CFAA99ABE6922@SHXPR01MB0863.CHNPR01.prod.partner.outlook.cn>
References: <cover.1723472153.git.jan.kiszka@siemens.com>
 <30f3ca9f6bd788e16767b36aa22c0e9dc4d1c6a4.1723472153.git.jan.kiszka@siemens.com>
 <20240812-overstuff-skirt-7a8aabbcdc6f@spud>
 <8cdba8b0-7364-4c09-b18a-f3f59da1eae2@siemens.com>
 <20240813-haiku-pusher-f2fb037a2f49@wendy>
 <SHXPR01MB08633B523DA1F6C5632F6D9DE6802@SHXPR01MB0863.CHNPR01.prod.partner.outlook.cn>
 <20240815-endless-credible-324438d164f4@spud>
 <SHXPR01MB08632E50DFE53BE0CFAA99ABE6922@SHXPR01MB0863.CHNPR01.prod.partner.outlook.cn>
Message-ID: <20240903-gating-shamrock-c0d4415d1eb3@squawk>

On Mon, Sep 02, 2024 at 09:19:29AM +0000, Minda Chen wrote:
> 
> 
> > 
> > On Thu, Aug 15, 2024 at 10:33:55AM +0000, Minda Chen wrote:
> > >
> > >
> > > >
> > > > On Tue, Aug 13, 2024 at 07:31:50AM +0200, Jan Kiszka wrote:
> > > > > On 12.08.24 17:55, Conor Dooley wrote:
> > > > > > On Mon, Aug 12, 2024 at 04:15:51PM +0200, Jan Kiszka wrote:
> > > > > >> From: Jan Kiszka <jan.kiszka at siemens.com>
> > > > > >>
> > > > > >> Analogously to the PCI PHY, access to sys_syscon is needed to
> > > > > >> connect the USB PHY to its controller.
> > > > > >>
> > > > > >> Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
> > > > > >> Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
> > > > > >> ---
> > > > > >> CC: Rob Herring <robh at kernel.org>
> > > > > >> CC: Krzysztof Kozlowski <krzk+dt at kernel.org>
> > > > > >> CC: Conor Dooley <conor+dt at kernel.org>
> > > > > >> ---
> > > > > >>  .../bindings/phy/starfive,jh7110-usb-phy.yaml         | 11
> > > > +++++++++++
> > > > > >>  1 file changed, 11 insertions(+)
> > > > > >>
> > > > > >> diff --git
> > > > > >> a/Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy
> > > > > >> .yam
> > > > > >> l
> > > > > >> b/Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy
> > > > > >> .yam l index 269e9f9f12b6..eaf0050c6f17 100644
> > > > > >> ---
> > > > > >> a/Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy
> > > > > >> .yam
> > > > > >> l
> > > > > >> +++ b/Documentation/devicetree/bindings/phy/starfive,jh7110-usb
> > > > > >> +++ -phy
> > > > > >> +++ .yaml
> > > > > >> @@ -19,6 +19,16 @@ properties:
> > > > > >>    "#phy-cells":
> > > > > >>      const: 0
> > > > > >>
> > > > > >> +  starfive,sys-syscon:
> > > > > >> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> > > > > >> +    items:
> > > > > >> +      - items:
> > > > > >> +          - description: phandle to System Register Controller
> > > > sys_syscon node.
> > > > > >> +          - description: PHY connect offset of
> > > > SYS_SYSCONSAIF__SYSCFG register for USB PHY.
> > > > > >
> > > > > > Why is having a new property for this required? The devicetree
> > > > > > only has a single usb phy, so isn't it sufficient to look up the
> > > > > > syscon by compatible, rather than via phandle + offset?
> > > > > >
> > > > >
> > > > > I didn't design this, I just copied it from
> > > > > starfive,jh7110-pcie-phy.yaml. As that already exists, I'm neither
> > > > > sure we want to change that anymore nor deviate in the pattern here.
> > > >
> > > > To be honest, I think some of the other users of phandle + offset on
> > > > this soc were just copy-pasted without thinking about whether or not they
> > were required too.
> > > > This one seems like it should just be a lookup by compatible in the
> > > > driver instead of by phandle. As a bonus, it will work with existing
> > > > devicetrees - whereas your current implementation will fail to probe
> > > > on systems that have the old devicetree, a regression for systems
> > > > running with that devicetree and downstream firmware.
> > > >
> > > > Cheers,
> > > > Conor.
> > > >
> > > Hi Conor
> > > I know you would like to put the offset value to the code, Just set syscon in dts.
> > > Just like pcie-starfive.c. right?
> > 
> > No, not quite. That still uses a phandle lookup, I was talking about using
> > syscon_regmap_lookup_by_compatible().
> 
> Okay. Using syscon_regmap_lookup_by_compatible() can just modify the driver code only.
> But syscon_regmap_lookup_by_compatible() is not exist in uboot now. If I want to enable
> CONFIG_OF_UPSTREAM in uboot. I have to add this function in u-boot...

You can use
	node = ofnode_by_compatible(ofnode_null(), "foo");
	*regmap = syscon_node_to_regmap(node);
in U-Boot.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20240903/f7c1680c/attachment.sig>

From claudiu.beznea at tuxon.dev  Tue Sep  3 03:19:44 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Tue, 3 Sep 2024 13:19:44 +0300
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <4cb2f788-1ba6-40f6-a48d-1fd2e5293aa8@tuxon.dev>



On 02.09.2024 13:47, Biju Das wrote:
> Hi Claudiu,
> 
>> -----Original Message-----
>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>> Sent: Monday, September 2, 2024 11:41 AM
>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
>>
>>
>>
>> On 02.09.2024 12:18, Biju Das wrote:
>>>>>>> Do you have any plan to control this power transitions(ALL_ON to AWO and vice versa) in linux?
>>>>>> As you know, the RZ/G3S USB PM code is already prepared. This is
>>>>>> also configuring these signals when going to suspend/exiting from resume.
>>>>>> W/o configuring properly these signals the USB is not working after a suspend/resume cycle.
>>>>> One option is to handle SYSC USB PWRRDY signal in TF-A, if you plan
>>>>> to handle system transitions
>>>> there??
>>>>
>>>> As I mentioned, the settings in these registers may be changed by intermediary booting
>> applications.
>>>> Depending on that, Linux need to control it also on probe for USB to
>>>> work (it should be the same with PCIe, these signals seems similar from HW manual description).
>>> You mean system transition settings will be override by U-boot, so Linux needs to restore it back??
>>
>> It was talking about booting...
> 
> I am also referring to boot. Boot starts with TF-A and it has a system state.
> 
>>
>> You proposed to handle SYSC signals from TF-A in a discussion about system power transitions:
>>
>> "One option is to handle SYSC USB PWRRDY signal in TF-A,  if you plan to handle system transitions"
>>
>> (I was guessing the "system transition" statement there refers to power states transitions, ALL_ON <->
>> AWO/VBAT)
> 
> That is correct.
> 
>>
>> and I gave the booting process as a counter example: if we handle it in TF-A it may not be enough as
>> these signals might be changed by intermediary booting applications (e.g., U-Boot).
> 
> Why should U-boot override, system state signals such as USB PWRREADY? Can you please give an example.

I didn't say *should* but *might* and I was referring to a hypothetical
situation where any used application (bootloader) might trigger this signal
for whatever reason. My point was to let Linux to handle all the settings
that it can do for a particular functionality. The resisters in SYSC
address space controlling these signals are accessible to normal world
compared to others in the SYSC address spaces.

> 
>>
>> To conclude, there are 3 scenarios I see where these signals need to be
>> handled:
>> 1/ booting 
>> 2/ suspend to RAM
>> 3/ driver unbind/bind
> 
> --> It should be OK as linux is not handling USB PWRREADY signal.
> 
>>
>> In case of booting: if we have TF-A to set signals there might be intermediary booting applications
>> (e.g. U-Boot) that set these signals also. If it leaves it in improper state and Linux wants to use
>> USB then the USB will not work (if Linux doesn't handle it).
> 
> That is the problem of U-boot. U-boot should not override system state signals such as USB PWRREADY.

U-Boot can also use USB as well.

> 
>>
>> In case of suspend to RAM: as TF-A is the only application in the suspend to RAM chain, it should work
>> handling it in TF-A.
> 
> That is correct, TF-A should handle based on system state.
> 
>>
>> In case of unbind/bind: currently we don't know if these signals introduces any kind of power saving
>> so asserting/de-asserting them in Linux may be useful from this perspective, if any.
> 
> These are system signals, according to me should not be used in unbind/bind.

It can be done whatever way. I would just prefer to work for all scenarios.

Thank you,
Claudiu Beznea

> 
> I may be wrong.
> 
> Cheers,
> Biju


From claudiu.beznea at tuxon.dev  Tue Sep  3 03:25:21 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Tue, 3 Sep 2024 13:25:21 +0300
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <fbfa9179-2f52-429f-8b69-f7f4064e796b@tuxon.dev>



On 03.09.2024 10:18, Biju Das wrote:
> Hi Claudiu,
> 
>> -----Original Message-----
>> From: Biju Das
>> Sent: Monday, September 2, 2024 11:48 AM
>> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
>>
>> Hi Claudiu,
>>
>>> -----Original Message-----
>>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>>> Sent: Monday, September 2, 2024 11:41 AM
>>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
>>> RZ/G3S SoC
>>>
>>>
>>>
>>> On 02.09.2024 12:18, Biju Das wrote:
>>>>>>>> Do you have any plan to control this power transitions(ALL_ON to AWO and vice versa) in linux?
>>>>>>> As you know, the RZ/G3S USB PM code is already prepared. This is
>>>>>>> also configuring these signals when going to suspend/exiting from resume.
>>>>>>> W/o configuring properly these signals the USB is not working after a suspend/resume cycle.
>>>>>> One option is to handle SYSC USB PWRRDY signal in TF-A, if you
>>>>>> plan to handle system transitions
>>>>> there??
>>>>>
>>>>> As I mentioned, the settings in these registers may be changed by
>>>>> intermediary booting
>>> applications.
>>>>> Depending on that, Linux need to control it also on probe for USB
>>>>> to work (it should be the same with PCIe, these signals seems similar from HW manual
>> description).
>>>> You mean system transition settings will be override by U-boot, so Linux needs to restore it
>> back??
>>>
>>> It was talking about booting...
>>
>> I am also referring to boot. Boot starts with TF-A and it has a system state.
>>
>>>
>>> You proposed to handle SYSC signals from TF-A in a discussion about system power transitions:
>>>
>>> "One option is to handle SYSC USB PWRRDY signal in TF-A,  if you plan to handle system transitions"
>>>
>>> (I was guessing the "system transition" statement there refers to
>>> power states transitions, ALL_ON <->
>>> AWO/VBAT)
>>
>> That is correct.
>>
>>>
>>> and I gave the booting process as a counter example: if we handle it
>>> in TF-A it may not be enough as these signals might be changed by intermediary booting applications
>> (e.g., U-Boot).
>>
>> Why should U-boot override, system state signals such as USB PWRREADY? Can you please give an example.
>>
>>>
>>> To conclude, there are 3 scenarios I see where these signals need to
>>> be
>>> handled:
>>> 1/ booting
>>> 2/ suspend to RAM
>>> 3/ driver unbind/bind
>>
>> --> It should be OK as linux is not handling USB PWRREADY signal.
>>
>>>
>>> In case of booting: if we have TF-A to set signals there might be
>>> intermediary booting applications (e.g. U-Boot) that set these signals
>>> also. If it leaves it in improper state and Linux wants to use USB then the USB will not work (if
>> Linux doesn't handle it).
>>
>> That is the problem of U-boot. U-boot should not override system state signals such as USB PWRREADY.
>>
>>>
>>> In case of suspend to RAM: as TF-A is the only application in the
>>> suspend to RAM chain, it should work handling it in TF-A.
>>
>> That is correct, TF-A should handle based on system state.
>>
>>>
>>> In case of unbind/bind: currently we don't know if these signals
>>> introduces any kind of power saving so asserting/de-asserting them in Linux may be useful from this
>> perspective, if any.
>>
>> These are system signals, according to me should not be used in unbind/bind.
>>
>> I may be wrong.
> 
> Just to add the below are the 4 system states (power mode) for this LSI.
> 
> If I understand correctly, we need to configure USB PWRRDY signal
> only when there is a transition from ALL_ON to AWO mode and vice versa.
> as you see on AWO mode only CM-33 is active.
> 
> ? ALL_OFF mode: All CPUs and peripheral modules can not be worked.
> ? ALL_ON mode: All CPUs and peripheral modules can be worked.
> ? AWO mode: Cortex-M33 and peripheral modules in PD_VCC and PD_VBATT domain can be worked.
> ? VBATT mode: Only RTC, tamper detection and backup registers can be worked.
> 
> System manager which is controlling both CA-55 and CM-33, will set USB PWRRDY signal
> based on system state.
> 
> Since we don't have system manager for controlling both CA-55 and CM-33
> Probably from CA-55 perspective, TF-A should be sufficient.
> 
> During boot clr USB PWR READY signal in TF-A.
> STR case, suspend set USB PWR READY signal in TF-A.
> STR case, resume clr USB PWR READY signal in TF-A.

As I said previously, it can be done in different ways. My point was to let
Linux set what it needs for all it's devices to work. I think the way to go
forward is a maintainer decision.

Thank you,
Claudiu Beznea

> 
> I am not expert in this area. I may be wrong.
> 
> Maybe we need to get an opinion from Power experts in Linux.
> 
> Cheers,
> Biju


From biju.das.jz at bp.renesas.com  Tue Sep  3 03:31:47 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Tue, 3 Sep 2024 10:31:47 +0000
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <fbfa9179-2f52-429f-8b69-f7f4064e796b@tuxon.dev>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <fbfa9179-2f52-429f-8b69-f7f4064e796b@tuxon.dev>
Message-ID: <TYCPR01MB11332EF1A8D064C491D8F261286932@TYCPR01MB11332.jpnprd01.prod.outlook.com>

Hi Claudiu,

> -----Original Message-----
> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> Sent: Tuesday, September 3, 2024 11:25 AM
> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
> 
> 
> 
> On 03.09.2024 10:18, Biju Das wrote:
> > Hi Claudiu,
> >
> >> -----Original Message-----
> >> From: Biju Das
> >> Sent: Monday, September 2, 2024 11:48 AM
> >> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas
> >> RZ/G3S SoC
> >>
> >> Hi Claudiu,
> >>
> >>> -----Original Message-----
> >>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> >>> Sent: Monday, September 2, 2024 11:41 AM
> >>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
> >>> RZ/G3S SoC
> >>>
> >>>
> >>>
> >>> On 02.09.2024 12:18, Biju Das wrote:
> >>>>>>>> Do you have any plan to control this power transitions(ALL_ON to AWO and vice versa) in
> linux?
> >>>>>>> As you know, the RZ/G3S USB PM code is already prepared. This is
> >>>>>>> also configuring these signals when going to suspend/exiting from resume.
> >>>>>>> W/o configuring properly these signals the USB is not working after a suspend/resume cycle.
> >>>>>> One option is to handle SYSC USB PWRRDY signal in TF-A, if you
> >>>>>> plan to handle system transitions
> >>>>> there??
> >>>>>
> >>>>> As I mentioned, the settings in these registers may be changed by
> >>>>> intermediary booting
> >>> applications.
> >>>>> Depending on that, Linux need to control it also on probe for USB
> >>>>> to work (it should be the same with PCIe, these signals seems
> >>>>> similar from HW manual
> >> description).
> >>>> You mean system transition settings will be override by U-boot, so
> >>>> Linux needs to restore it
> >> back??
> >>>
> >>> It was talking about booting...
> >>
> >> I am also referring to boot. Boot starts with TF-A and it has a system state.
> >>
> >>>
> >>> You proposed to handle SYSC signals from TF-A in a discussion about system power transitions:
> >>>
> >>> "One option is to handle SYSC USB PWRRDY signal in TF-A,  if you plan to handle system
> transitions"
> >>>
> >>> (I was guessing the "system transition" statement there refers to
> >>> power states transitions, ALL_ON <->
> >>> AWO/VBAT)
> >>
> >> That is correct.
> >>
> >>>
> >>> and I gave the booting process as a counter example: if we handle it
> >>> in TF-A it may not be enough as these signals might be changed by
> >>> intermediary booting applications
> >> (e.g., U-Boot).
> >>
> >> Why should U-boot override, system state signals such as USB PWRREADY? Can you please give an
> example.
> >>
> >>>
> >>> To conclude, there are 3 scenarios I see where these signals need to
> >>> be
> >>> handled:
> >>> 1/ booting
> >>> 2/ suspend to RAM
> >>> 3/ driver unbind/bind
> >>
> >> --> It should be OK as linux is not handling USB PWRREADY signal.
> >>
> >>>
> >>> In case of booting: if we have TF-A to set signals there might be
> >>> intermediary booting applications (e.g. U-Boot) that set these
> >>> signals also. If it leaves it in improper state and Linux wants to
> >>> use USB then the USB will not work (if
> >> Linux doesn't handle it).
> >>
> >> That is the problem of U-boot. U-boot should not override system state signals such as USB
> PWRREADY.
> >>
> >>>
> >>> In case of suspend to RAM: as TF-A is the only application in the
> >>> suspend to RAM chain, it should work handling it in TF-A.
> >>
> >> That is correct, TF-A should handle based on system state.
> >>
> >>>
> >>> In case of unbind/bind: currently we don't know if these signals
> >>> introduces any kind of power saving so asserting/de-asserting them
> >>> in Linux may be useful from this
> >> perspective, if any.
> >>
> >> These are system signals, according to me should not be used in unbind/bind.
> >>
> >> I may be wrong.
> >
> > Just to add the below are the 4 system states (power mode) for this LSI.
> >
> > If I understand correctly, we need to configure USB PWRRDY signal only
> > when there is a transition from ALL_ON to AWO mode and vice versa.
> > as you see on AWO mode only CM-33 is active.
> >
> > ? ALL_OFF mode: All CPUs and peripheral modules can not be worked.
> > ? ALL_ON mode: All CPUs and peripheral modules can be worked.
> > ? AWO mode: Cortex-M33 and peripheral modules in PD_VCC and PD_VBATT domain can be worked.
> > ? VBATT mode: Only RTC, tamper detection and backup registers can be worked.
> >
> > System manager which is controlling both CA-55 and CM-33, will set USB
> > PWRRDY signal based on system state.
> >
> > Since we don't have system manager for controlling both CA-55 and
> > CM-33 Probably from CA-55 perspective, TF-A should be sufficient.
> >
> > During boot clr USB PWR READY signal in TF-A.
> > STR case, suspend set USB PWR READY signal in TF-A.
> > STR case, resume clr USB PWR READY signal in TF-A.
> 
> As I said previously, it can be done in different ways. My point was to let Linux set what it needs
> for all it's devices to work. I think the way to go forward is a maintainer decision.


I agree, there can be n number of solution for a problem.

Since you modelled system state signal (USB PWRRDY) as reset control signal, it is reset/DT maintainer's decision
to say the final word whether this signal fits in reset system framework or not?

Cheers,
biju

From ulf.hansson at linaro.org  Tue Sep  3 03:35:12 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 3 Sep 2024 12:35:12 +0200
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <CAPDyKFrkkASq7rfRN=9sEet-p8T8t+f__PdnSNRN3bMNipnNNw@mail.gmail.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev> <CAPDyKFrVS2vpsJqTvjKCJ7ADqXc4D4k2eeCBsaK4T+=pXDnKUA@mail.gmail.com>
 <fa9b3449-ea3e-4482-b7eb-96999445cea5@tuxon.dev> <CAPDyKFrkkASq7rfRN=9sEet-p8T8t+f__PdnSNRN3bMNipnNNw@mail.gmail.com>
Message-ID: <CAPDyKFpLnREr4C=wZ7o8Lb-CZbQa4Nr2VTuYdZHZ26Rcb1Masg@mail.gmail.com>

On Sat, 31 Aug 2024 at 12:32, Ulf Hansson <ulf.hansson at linaro.org> wrote:
>
> [...]
>
> > >
> > > If not, there are two other options that can be considered I think.
> > > *) Using the genpd on/off notifiers, to really allow the consumer
> > > driver of the reset-control to know when the PM domain gets turned
> > > on/off.
> > > **) Move the entire reset handling into the PM domain provider, as it
> > > obviously knows when the domain is getting turned on/off.
> >
> > This option is what I've explored, tested on my side.
> >
> > I explored it in 2 ways:
> >
> > 1/ SYSC modeled as an individual PM domain provider (this is more
> >    appropriate to how HW manual described the hardware) with this the PHY
> >    reset DT node would have to get 2 PM domains handlers (one for the
> >    current PM domain provider and the other one for SYSC):
> >
> > +               phyrst: usbphy-ctrl at 11e00000 {
> > +                       compatible = "renesas,r9a08g045-usbphy-ctrl";
> > +                       reg = <0 0x11e00000 0 0x10000>;
> > +                       clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>;
> > +                       resets = <&cpg R9A08G045_USB_PRESETN>;
> > +                       power-domain-names = "cpg", "sysc";
> > +                       power-domains = <&cpg R9A08G045_PD_USB_PHY>, <&sysc
> > R9A08G045_SYSC_PD_USB>;
> > +                       #reset-cells = <1>;
> > +                       status = "disabled";
> > +
> > +                       usb0_vbus_otg: regulator-vbus {
> > +                               regulator-name = "vbus";
> > +                       };
> > +               };
> > +
>
> According to what you have described earlier/above, modelling the SYSC
> as a PM domain provider seems like a better description of the HW to
> me. Although, as I said earlier, if you prefer the reset approach, I
> would not object to that.

Following the discussion I believe I should take this back. If I
understand correctly, SYSC signal seems best to be modelled as a
reset.

 Although, it looks like the USB PM domain provider should rather be
the consumer of that reset, instead of having the reset being consumed
by the consumers of the USB PM domain.

Did that make sense?

[...]

Kind regards
Uffe


From claudiu.beznea at tuxon.dev  Tue Sep  3 03:58:15 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Tue, 3 Sep 2024 13:58:15 +0300
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <CAPDyKFpLnREr4C=wZ7o8Lb-CZbQa4Nr2VTuYdZHZ26Rcb1Masg@mail.gmail.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <CAPDyKFrVS2vpsJqTvjKCJ7ADqXc4D4k2eeCBsaK4T+=pXDnKUA@mail.gmail.com>
 <fa9b3449-ea3e-4482-b7eb-96999445cea5@tuxon.dev>
 <CAPDyKFrkkASq7rfRN=9sEet-p8T8t+f__PdnSNRN3bMNipnNNw@mail.gmail.com>
 <CAPDyKFpLnREr4C=wZ7o8Lb-CZbQa4Nr2VTuYdZHZ26Rcb1Masg@mail.gmail.com>
Message-ID: <da4c57ff-de2b-418f-ba2c-e83c1d399b94@tuxon.dev>



On 03.09.2024 13:35, Ulf Hansson wrote:
> On Sat, 31 Aug 2024 at 12:32, Ulf Hansson <ulf.hansson at linaro.org> wrote:
>>
>> [...]
>>
>>>>
>>>> If not, there are two other options that can be considered I think.
>>>> *) Using the genpd on/off notifiers, to really allow the consumer
>>>> driver of the reset-control to know when the PM domain gets turned
>>>> on/off.
>>>> **) Move the entire reset handling into the PM domain provider, as it
>>>> obviously knows when the domain is getting turned on/off.
>>>
>>> This option is what I've explored, tested on my side.
>>>
>>> I explored it in 2 ways:
>>>
>>> 1/ SYSC modeled as an individual PM domain provider (this is more
>>>    appropriate to how HW manual described the hardware) with this the PHY
>>>    reset DT node would have to get 2 PM domains handlers (one for the
>>>    current PM domain provider and the other one for SYSC):
>>>
>>> +               phyrst: usbphy-ctrl at 11e00000 {
>>> +                       compatible = "renesas,r9a08g045-usbphy-ctrl";
>>> +                       reg = <0 0x11e00000 0 0x10000>;
>>> +                       clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>;
>>> +                       resets = <&cpg R9A08G045_USB_PRESETN>;
>>> +                       power-domain-names = "cpg", "sysc";
>>> +                       power-domains = <&cpg R9A08G045_PD_USB_PHY>, <&sysc
>>> R9A08G045_SYSC_PD_USB>;
>>> +                       #reset-cells = <1>;
>>> +                       status = "disabled";
>>> +
>>> +                       usb0_vbus_otg: regulator-vbus {
>>> +                               regulator-name = "vbus";
>>> +                       };
>>> +               };
>>> +
>>
>> According to what you have described earlier/above, modelling the SYSC
>> as a PM domain provider seems like a better description of the HW to
>> me. Although, as I said earlier, if you prefer the reset approach, I
>> would not object to that.
> 
> Following the discussion I believe I should take this back. If I
> understand correctly, SYSC signal seems best to be modelled as a
> reset.
> 
>  Although, it looks like the USB PM domain provider should rather be
> the consumer of that reset, instead of having the reset being consumed
> by the consumers of the USB PM domain.

The PM domain provider for USB is the provider for the rest of IPs. To work
like this the SYSC these signals should be handled in the USB domains power
on/off function. It's not impossible to have it implemented like this but
it will complicate a bit the code, AFAICT. This will not describe the
hardware, also.

With the information that we had up to yesterday, the connection b/w HW
blocks was something as follows:

                 USB area
              +--------------------------+
      sig     | PHY -> USB controller X  |
SYSC -------->|  ^                       |
              |  |                       |
              | PHY reset                |
              +--------------------------+

In this implementation the SYSC signal was connected to PHY reset block as
it is the root of the devices used in the USB setup and no USB
functionality can exist w/o the PHY reset being setup.

There is a new information arrived just yesterday from hardware team saying
this about SYSC signals: "When turning off USB PHY and PCIe PHY, if they
are not controlled, PHY may break" which may means that it is just
connected to the PHYs not to the USB area/region or PCIe area/region as
initially expressed in HW manual.

With that the HW connection b/w the USB devices and SYSC might become
something like:

                 USB area
              +--------------------------+
     sig   +--->PHY -> USB controller X  |
SYSC ------+  |  ^                       |
              |  |                       |
              | PHY reset                |
              +--------------------------+

I haven't got the chance to test this topology, though.

With this new information would you be OK to still have it as a reset
signal and connected only to the PHY driver ?

Thank you,
Claudiu Beznea

> 
> Did that make sense?
> 
> [...]
> 
> Kind regards
> Uffe


From claudiu.beznea at tuxon.dev  Tue Sep  3 04:00:11 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Tue, 3 Sep 2024 14:00:11 +0300
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <TYCPR01MB11332EF1A8D064C491D8F261286932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <fbfa9179-2f52-429f-8b69-f7f4064e796b@tuxon.dev>
 <TYCPR01MB11332EF1A8D064C491D8F261286932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
Message-ID: <f7c57e76-b890-491f-880d-62d060b7b31e@tuxon.dev>



On 03.09.2024 13:31, Biju Das wrote:
>>> During boot clr USB PWR READY signal in TF-A.
>>> STR case, suspend set USB PWR READY signal in TF-A.
>>> STR case, resume clr USB PWR READY signal in TF-A.
>> As I said previously, it can be done in different ways. My point was to let Linux set what it needs
>> for all it's devices to work. I think the way to go forward is a maintainer decision.
> 
> I agree, there can be n number of solution for a problem.
> 
> Since you modelled system state signal (USB PWRRDY) as reset control signal, it is reset/DT maintainer's decision
> to say the final word whether this signal fits in reset system framework or not?

I was thinking:
1/ Geert would be the best to say if he considers it OK to handle this
   in Linux
2/ if OK, then we should get approval from Ulf and Philipp on the power
   domain or reset approaches

Thank you,
Claudiu Beznea

> 
> Cheers,
> biju


From biju.das.jz at bp.renesas.com  Tue Sep  3 04:07:06 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Tue, 3 Sep 2024 11:07:06 +0000
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <f7c57e76-b890-491f-880d-62d060b7b31e@tuxon.dev>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <fbfa9179-2f52-429f-8b69-f7f4064e796b@tuxon.dev>
 <TYCPR01MB11332EF1A8D064C491D8F261286932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <f7c57e76-b890-491f-880d-62d060b7b31e@tuxon.dev>
Message-ID: <TYCPR01MB11332BE2EDB318950B9C7B54C86932@TYCPR01MB11332.jpnprd01.prod.outlook.com>

Hi Claudiu,

> -----Original Message-----
> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> Sent: Tuesday, September 3, 2024 12:00 PM
> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
> 
> 
> 
> On 03.09.2024 13:31, Biju Das wrote:
> >>> During boot clr USB PWR READY signal in TF-A.
> >>> STR case, suspend set USB PWR READY signal in TF-A.
> >>> STR case, resume clr USB PWR READY signal in TF-A.
> >> As I said previously, it can be done in different ways. My point was
> >> to let Linux set what it needs for all it's devices to work. I think the way to go forward is a
> maintainer decision.
> >
> > I agree, there can be n number of solution for a problem.
> >
> > Since you modelled system state signal (USB PWRRDY) as reset control
> > signal, it is reset/DT maintainer's decision to say the final word whether this signal fits in reset
> system framework or not?
> 
> I was thinking:
> 1/ Geert would be the best to say if he considers it OK to handle this
>    in Linux

I agree Geert is the right person for taking SYSTEM decisions,
since the signal is used only during state transitions
(Table 41.6.4 AWO to ALL_ON and 41.6.3 ALL_ON to AWO)


> 2/ if OK, then we should get approval from Ulf and Philipp on the power
>    domain or reset approaches

Ok.

Cheers,
Biju

From konradybcio at kernel.org  Tue Sep  3 04:13:10 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Tue, 03 Sep 2024 13:13:10 +0200
Subject: [PATCH] phy: qcom: qmp: Fix lecacy-legacy typo
Message-ID: <20240903-topic-qmp_typo-v1-1-781e81799992@quicinc.com>

From: Konrad Dybcio <quic_kdybcio at quicinc.com>

Introduced in Commit b3982f2144e1 ("phy: qcom-qmp-combo: restructure
PHY creation"). No functional changes.

Signed-off-by: Konrad Dybcio <quic_kdybcio at quicinc.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index a8adc3214bfe..0198dc21ae56 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -3483,7 +3483,7 @@ static int qmp_combo_typec_switch_register(struct qmp_combo *qmp)
 }
 #endif
 
-static int qmp_combo_parse_dt_lecacy_dp(struct qmp_combo *qmp, struct device_node *np)
+static int qmp_combo_parse_dt_legacy_dp(struct qmp_combo *qmp, struct device_node *np)
 {
 	struct device *dev = qmp->dev;
 
@@ -3510,7 +3510,7 @@ static int qmp_combo_parse_dt_lecacy_dp(struct qmp_combo *qmp, struct device_nod
 	return 0;
 }
 
-static int qmp_combo_parse_dt_lecacy_usb(struct qmp_combo *qmp, struct device_node *np)
+static int qmp_combo_parse_dt_legacy_usb(struct qmp_combo *qmp, struct device_node *np)
 {
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
 	struct device *dev = qmp->dev;
@@ -3576,11 +3576,11 @@ static int qmp_combo_parse_dt_legacy(struct qmp_combo *qmp, struct device_node *
 	if (IS_ERR(qmp->dp_serdes))
 		return PTR_ERR(qmp->dp_serdes);
 
-	ret = qmp_combo_parse_dt_lecacy_usb(qmp, usb_np);
+	ret = qmp_combo_parse_dt_legacy_usb(qmp, usb_np);
 	if (ret)
 		return ret;
 
-	ret = qmp_combo_parse_dt_lecacy_dp(qmp, dp_np);
+	ret = qmp_combo_parse_dt_legacy_dp(qmp, dp_np);
 	if (ret)
 		return ret;
 

---
base-commit: ecc768a84f0b8e631986f9ade3118fa37852fef0
change-id: 20240903-topic-qmp_typo-7aad0f296d7a

Best regards,
-- 
Konrad Dybcio <quic_kdybcio at quicinc.com>



From ulf.hansson at linaro.org  Tue Sep  3 04:50:07 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 3 Sep 2024 13:50:07 +0200
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <da4c57ff-de2b-418f-ba2c-e83c1d399b94@tuxon.dev>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev> <CAPDyKFrVS2vpsJqTvjKCJ7ADqXc4D4k2eeCBsaK4T+=pXDnKUA@mail.gmail.com>
 <fa9b3449-ea3e-4482-b7eb-96999445cea5@tuxon.dev> <CAPDyKFrkkASq7rfRN=9sEet-p8T8t+f__PdnSNRN3bMNipnNNw@mail.gmail.com>
 <CAPDyKFpLnREr4C=wZ7o8Lb-CZbQa4Nr2VTuYdZHZ26Rcb1Masg@mail.gmail.com> <da4c57ff-de2b-418f-ba2c-e83c1d399b94@tuxon.dev>
Message-ID: <CAPDyKFpkCYuK=T6ZGzJ=V67Jj7C6CSKv1GH1W_apWs2rKF4q-g@mail.gmail.com>

On Tue, 3 Sept 2024 at 12:58, claudiu beznea <claudiu.beznea at tuxon.dev> wrote:
>
>
>
> On 03.09.2024 13:35, Ulf Hansson wrote:
> > On Sat, 31 Aug 2024 at 12:32, Ulf Hansson <ulf.hansson at linaro.org> wrote:
> >>
> >> [...]
> >>
> >>>>
> >>>> If not, there are two other options that can be considered I think.
> >>>> *) Using the genpd on/off notifiers, to really allow the consumer
> >>>> driver of the reset-control to know when the PM domain gets turned
> >>>> on/off.
> >>>> **) Move the entire reset handling into the PM domain provider, as it
> >>>> obviously knows when the domain is getting turned on/off.
> >>>
> >>> This option is what I've explored, tested on my side.
> >>>
> >>> I explored it in 2 ways:
> >>>
> >>> 1/ SYSC modeled as an individual PM domain provider (this is more
> >>>    appropriate to how HW manual described the hardware) with this the PHY
> >>>    reset DT node would have to get 2 PM domains handlers (one for the
> >>>    current PM domain provider and the other one for SYSC):
> >>>
> >>> +               phyrst: usbphy-ctrl at 11e00000 {
> >>> +                       compatible = "renesas,r9a08g045-usbphy-ctrl";
> >>> +                       reg = <0 0x11e00000 0 0x10000>;
> >>> +                       clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>;
> >>> +                       resets = <&cpg R9A08G045_USB_PRESETN>;
> >>> +                       power-domain-names = "cpg", "sysc";
> >>> +                       power-domains = <&cpg R9A08G045_PD_USB_PHY>, <&sysc
> >>> R9A08G045_SYSC_PD_USB>;
> >>> +                       #reset-cells = <1>;
> >>> +                       status = "disabled";
> >>> +
> >>> +                       usb0_vbus_otg: regulator-vbus {
> >>> +                               regulator-name = "vbus";
> >>> +                       };
> >>> +               };
> >>> +
> >>
> >> According to what you have described earlier/above, modelling the SYSC
> >> as a PM domain provider seems like a better description of the HW to
> >> me. Although, as I said earlier, if you prefer the reset approach, I
> >> would not object to that.
> >
> > Following the discussion I believe I should take this back. If I
> > understand correctly, SYSC signal seems best to be modelled as a
> > reset.
> >
> >  Although, it looks like the USB PM domain provider should rather be
> > the consumer of that reset, instead of having the reset being consumed
> > by the consumers of the USB PM domain.
>
> The PM domain provider for USB is the provider for the rest of IPs. To work
> like this the SYSC these signals should be handled in the USB domains power
> on/off function. It's not impossible to have it implemented like this but
> it will complicate a bit the code, AFAICT. This will not describe the
> hardware, also.
>
> With the information that we had up to yesterday, the connection b/w HW
> blocks was something as follows:
>
>                  USB area
>               +--------------------------+
>       sig     | PHY -> USB controller X  |
> SYSC -------->|  ^                       |
>               |  |                       |
>               | PHY reset                |
>               +--------------------------+
>
> In this implementation the SYSC signal was connected to PHY reset block as
> it is the root of the devices used in the USB setup and no USB
> functionality can exist w/o the PHY reset being setup.
>
> There is a new information arrived just yesterday from hardware team saying
> this about SYSC signals: "When turning off USB PHY and PCIe PHY, if they
> are not controlled, PHY may break" which may means that it is just
> connected to the PHYs not to the USB area/region or PCIe area/region as
> initially expressed in HW manual.
>
> With that the HW connection b/w the USB devices and SYSC might become
> something like:
>
>                  USB area
>               +--------------------------+
>      sig   +--->PHY -> USB controller X  |
> SYSC ------+  |  ^                       |
>               |  |                       |
>               | PHY reset                |
>               +--------------------------+
>
> I haven't got the chance to test this topology, though.
>
> With this new information would you be OK to still have it as a reset
> signal and connected only to the PHY driver ?

As long as it's a better description of the HW, I am fine with that too.

Although, please note that pm_runtime_get|put() doesn't give you full
controll of how the USB PM domain is being powered. So in that case,
it sounds like you need to use the genpd on/off notifiers too.

Kind regards
Uffe


From biju.das.jz at bp.renesas.com  Tue Sep  3 05:00:59 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Tue, 3 Sep 2024 12:00:59 +0000
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <TYCPR01MB11332BE2EDB318950B9C7B54C86932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <CAPDyKFrS4Dhd7DZa2zz=oPro1TiTJFix0awzzzp8Qatm-8Z2Ug@mail.gmail.com>
 <99bef301-9f6c-4797-b47e-c83e56dfbda9@tuxon.dev>
 <TY3PR01MB1134652F9587CFA0ADE851CA486902@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <fbfa9179-2f52-429f-8b69-f7f4064e796b@tuxon.dev>
 <TYCPR01MB11332EF1A8D064C491D8F261286932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <f7c57e76-b890-491f-880d-62d060b7b31e@tuxon.dev>
 <TYCPR01MB11332BE2EDB318950B9C7B54C86932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
Message-ID: <TY3PR01MB113469FC8A9F49D9B1FA432FD86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>



> -----Original Message-----
> From: Biju Das <biju.das.jz at bp.renesas.com>
> Sent: Tuesday, September 3, 2024 12:07 PM
> To: Claudiu.Beznea <claudiu.beznea at tuxon.dev>; Ulf Hansson <ulf.hansson at linaro.org>
> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org; krzk+dt at kernel.org; conor+dt at kernel.org;
> p.zabel at pengutronix.de; geert+renesas at glider.be; magnus.damm at gmail.com; gregkh at linuxfoundation.org;
> mturquette at baylibre.com; sboyd at kernel.org; Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>;
> linux-phy at lists.infradead.org; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-
> renesas-soc at vger.kernel.org; linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
> 
> Hi Claudiu,
> 
> > -----Original Message-----
> > From: claudiu beznea <claudiu.beznea at tuxon.dev>
> > Sent: Tuesday, September 3, 2024 12:00 PM
> > Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
> > RZ/G3S SoC
> >
> >
> >
> > On 03.09.2024 13:31, Biju Das wrote:
> > >>> During boot clr USB PWR READY signal in TF-A.
> > >>> STR case, suspend set USB PWR READY signal in TF-A.
> > >>> STR case, resume clr USB PWR READY signal in TF-A.
> > >> As I said previously, it can be done in different ways. My point
> > >> was to let Linux set what it needs for all it's devices to work. I
> > >> think the way to go forward is a
> > maintainer decision.
> > >
> > > I agree, there can be n number of solution for a problem.
> > >
> > > Since you modelled system state signal (USB PWRRDY) as reset control
> > > signal, it is reset/DT maintainer's decision to say the final word
> > > whether this signal fits in reset
> > system framework or not?
> >
> > I was thinking:
> > 1/ Geert would be the best to say if he considers it OK to handle this
> >    in Linux
> 
> I agree Geert is the right person for taking SYSTEM decisions, since the signal is used only during
> state transitions (Table 41.6.4 AWO to ALL_ON and 41.6.3 ALL_ON to AWO)

One more info, as per [1], this USB PWRRDY signal setting to be before Linux kernel boots.

All clocks/reset happens after setting USB PWRRDY signal

https://pasteboard.co/qbz021q7KPyi.png

Cheers,
Biju

From dmitry.baryshkov at linaro.org  Tue Sep  3 05:03:07 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 3 Sep 2024 15:03:07 +0300
Subject: [PATCH] phy: qcom: qmp: Fix lecacy-legacy typo
In-Reply-To: <20240903-topic-qmp_typo-v1-1-781e81799992@quicinc.com>
References: <20240903-topic-qmp_typo-v1-1-781e81799992@quicinc.com>
Message-ID: <CAA8EJpp_O4B+eciQ9h8nPdiVxy4CTD8nE+WiYbDmUUSuhvwvMg@mail.gmail.com>

On Tue, 3 Sept 2024 at 14:13, Konrad Dybcio <konradybcio at kernel.org> wrote:
>
> From: Konrad Dybcio <quic_kdybcio at quicinc.com>
>
> Introduced in Commit b3982f2144e1 ("phy: qcom-qmp-combo: restructure
> PHY creation"). No functional changes.
>
> Signed-off-by: Konrad Dybcio <quic_kdybcio at quicinc.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From christian.bruel at foss.st.com  Tue Sep  3 05:12:58 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Tue, 3 Sep 2024 14:12:58 +0200
Subject: [PATCH v5 0/5] Add STM32MP25 USB3/PCIE COMBOPHY driver 
Message-ID: <20240903121303.2953150-1-christian.bruel@foss.st.com>

Changes in v5:
   - Drop syscfg phandle and change driver to use lookup_by_compatible
   - Use clk_bulk API and drop stm32_combophy_enable/disable_clocks
   - Reorder required: list.
   - Fix access-controllers maxItems
   
Changes in v4:
   - "#phy-cells": Drop type item description since it is specified
     by user node phandle.
   - Rename stm32-combophy.yaml to match compatible
   - Drop wakeup-source from bindings (should be generic)
   - Alphabetically reorder required: list.
   - Drop "Reviewed-by" since those previous changes

Changes in v3:
   - Reorder MAINTAINERS patch

Changes in v2:
   - Reorder entries
   - Rename clock_names and reset_names bindings
   - Rename and clarify rx-equalizer binding 

Christian Bruel (5):
  dt-bindings: phy: Add STM32MP25 COMBOPHY bindings
  phy: stm32: Add support for STM32MP25 COMBOPHY.
  MAINTAINERS: add entry for ST STM32MP25 COMBOPHY driver
  arm64: dts: st: Add combophy node on stm32mp251
  arm64: dts: st: Enable COMBOPHY on the stm32mp257f-ev1 board

 .../bindings/phy/st,stm32mp25-combophy.yaml   | 119 ++++
 MAINTAINERS                                   |   6 +
 arch/arm64/boot/dts/st/stm32mp251.dtsi        |  16 +
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts    |  14 +
 drivers/phy/st/Kconfig                        |  11 +
 drivers/phy/st/Makefile                       |   1 +
 drivers/phy/st/phy-stm32-combophy.c           | 590 ++++++++++++++++++
 7 files changed, 757 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
 create mode 100644 drivers/phy/st/phy-stm32-combophy.c

-- 
2.34.1



From christian.bruel at foss.st.com  Tue Sep  3 05:12:59 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Tue, 3 Sep 2024 14:12:59 +0200
Subject: [PATCH v5 1/5] dt-bindings: phy: Add STM32MP25 COMBOPHY bindings
In-Reply-To: <20240903121303.2953150-1-christian.bruel@foss.st.com>
References: <20240903121303.2953150-1-christian.bruel@foss.st.com>
Message-ID: <20240903121303.2953150-2-christian.bruel@foss.st.com>

Document the bindings for STM32 COMBOPHY interface, used to support
the PCIe and USB3 stm32mp25 drivers.
Following entries can be used to tune caracterisation parameters
 - st,output-micro-ohms and st,output-vswing-microvolt bindings entries
to tune the impedance and voltage swing using discrete simulation results
 - st,rx-equalizer register to set the internal rx equalizer filter value.

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 .../bindings/phy/st,stm32mp25-combophy.yaml   | 119 ++++++++++++++++++
 1 file changed, 119 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml

diff --git a/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml b/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
new file mode 100644
index 000000000000..a2e82c0bb56b
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/st,stm32mp25-combophy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32MP25 USB3/PCIe COMBOPHY
+
+maintainers:
+  - Christian Bruel <christian.bruel at foss.st.com>
+
+description:
+  Single lane PHY shared (exclusive) between the USB3 and PCIe controllers.
+  Supports 5Gbit/s for USB3 and PCIe gen2 or 2.5Gbit/s for PCIe gen1.
+
+properties:
+  compatible:
+    const: st,stm32mp25-combophy
+
+  reg:
+    maxItems: 1
+
+  "#phy-cells":
+    const: 1
+
+  clocks:
+    minItems: 2
+    items:
+      - description: apb Bus clock mandatory to access registers.
+      - description: ker Internal RCC reference clock for USB3 or PCIe
+      - description: pad Optional on board clock input for PCIe only. Typically an
+                     external 100Mhz oscillator wired on dedicated CLKIN pad. Used as reference
+                     clock input instead of the ker
+
+  clock-names:
+    minItems: 2
+    items:
+      - const: apb
+      - const: ker
+      - const: pad
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    const: phy
+
+  power-domains:
+    maxItems: 1
+
+  wakeup-source: true
+
+  interrupts:
+    maxItems: 1
+    description: interrupt used for wakeup
+
+  access-controllers:
+    maxItems: 1
+    description: Phandle to the rifsc device to check access right.
+
+  st,ssc-on:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      A property whose presence indicates that the Spread Spectrum Clocking is active.
+
+  st,rx-equalizer:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 7
+    default: 2
+    description:
+      A 3 bit value to tune the RX fixed equalizer setting for optimal eye compliance
+
+  st,output-micro-ohms:
+    minimum: 3999000
+    maximum: 6090000
+    default: 4968000
+    description:
+      A value property to tune the Single Ended Output Impedance, simulations results
+      at 25C for a VDDP=0.8V. The hardware accepts discrete values in this range.
+
+  st,output-vswing-microvolt:
+    minimum: 442000
+    maximum: 803000
+    default: 803000
+    description:
+      A value property in microvolt to tune the Single Ended Output Voltage Swing to change the
+      Vlo, Vhi for a VDDP = 0.8V. The hardware accepts discrete values in this range.
+
+required:
+  - compatible
+  - reg
+  - "#phy-cells"
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/reset/st,stm32mp25-rcc.h>
+
+    phy at 480c0000 {
+        compatible = "st,stm32mp25-combophy";
+        reg = <0x480c0000 0x1000>;
+        #phy-cells = <1>;
+        clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>;
+        clock-names = "apb", "ker";
+        resets = <&rcc USB3PCIEPHY_R>;
+        reset-names = "phy";
+        access-controllers = <&rifsc 67>;
+        power-domains = <&CLUSTER_PD>;
+        wakeup-source;
+        interrupts-extended = <&exti1 45 IRQ_TYPE_EDGE_FALLING>;
+    };
-- 
2.34.1



From christian.bruel at foss.st.com  Tue Sep  3 05:13:02 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Tue, 3 Sep 2024 14:13:02 +0200
Subject: [PATCH v5 4/5] arm64: dts: st: Add combophy node on stm32mp251
In-Reply-To: <20240903121303.2953150-1-christian.bruel@foss.st.com>
References: <20240903121303.2953150-1-christian.bruel@foss.st.com>
Message-ID: <20240903121303.2953150-5-christian.bruel@foss.st.com>

Add support for COMBOPHY which is used either by the USB3 and PCIe
controller.
USB3 or PCIe mode is done with phy_set_mode().
PCIe internal reference clock can be generated from the internal clock
source or optionnaly from an external 100Mhz pad.

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp251.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 1167cf63d7e8..b596afec1b6e 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -7,6 +7,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset/st,stm32mp25-rcc.h>
 #include <dt-bindings/regulator/st,stm32mp25-regulator.h>
+#include <dt-bindings/phy/phy.h>
 
 / {
 	#address-cells = <2>;
@@ -518,6 +519,21 @@ i2c8: i2c at 46040000 {
 				status = "disabled";
 			};
 
+			combophy: phy at 480c0000 {
+				compatible = "st,stm32mp25-combophy";
+				reg = <0x480c0000 0x1000>;
+				#phy-cells = <1>;
+				clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>;
+				clock-names = "apb", "ker";
+				resets = <&rcc USB3PCIEPHY_R>;
+				reset-names = "phy";
+				access-controllers = <&rifsc 67>;
+				power-domains = <&CLUSTER_PD>;
+				wakeup-source;
+				interrupts-extended = <&exti1 45 IRQ_TYPE_EDGE_FALLING>;
+				status = "disabled";
+			};
+
 			sdmmc1: mmc at 48220000 {
 				compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell";
 				arm,primecell-periphid = <0x00353180>;
-- 
2.34.1



From christian.bruel at foss.st.com  Tue Sep  3 05:13:01 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Tue, 3 Sep 2024 14:13:01 +0200
Subject: [PATCH v5 3/5] MAINTAINERS: add entry for ST STM32MP25 COMBOPHY driver
In-Reply-To: <20240903121303.2953150-1-christian.bruel@foss.st.com>
References: <20240903121303.2953150-1-christian.bruel@foss.st.com>
Message-ID: <20240903121303.2953150-4-christian.bruel@foss.st.com>

Add myself as STM32MP25 COMBOPHY maintainer

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index a70b7c9c3533..b922a5637b16 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21931,6 +21931,12 @@ F:	arch/m68k/kernel/*sun3*
 F:	arch/m68k/sun3*/
 F:	drivers/net/ethernet/i825xx/sun3*
 
+STMICROELECTRONICS STMP32MP25 USB3/PCIE COMBOPHY DRIVER
+M:	Christian Bruel <christian.bruel at foss.st.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
+F:	drivers/phy/st/phy-stm32-combophy.c
+
 SUN4I LOW RES ADC ATTACHED TABLET KEYS DRIVER
 M:	Hans de Goede <hdegoede at redhat.com>
 L:	linux-input at vger.kernel.org
-- 
2.34.1



From christian.bruel at foss.st.com  Tue Sep  3 05:13:00 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Tue, 3 Sep 2024 14:13:00 +0200
Subject: [PATCH v5 2/5] phy: stm32: Add support for STM32MP25 COMBOPHY.
In-Reply-To: <20240903121303.2953150-1-christian.bruel@foss.st.com>
References: <20240903121303.2953150-1-christian.bruel@foss.st.com>
Message-ID: <20240903121303.2953150-3-christian.bruel@foss.st.com>

Addition of the COMBOPHY driver found on STM32MP25 platforms

This single lane PHY is shared (exclusive) between the USB3 and PCIE
controllers.
Supports 5Gbit/s for PCIE gen2 or 2.5Gbit/s for PCIE gen1.

Supports wakeup-source capability to wakeup system using remote-wakeup
capable USB device

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 drivers/phy/st/Kconfig              |  11 +
 drivers/phy/st/Makefile             |   1 +
 drivers/phy/st/phy-stm32-combophy.c | 590 ++++++++++++++++++++++++++++
 3 files changed, 602 insertions(+)
 create mode 100644 drivers/phy/st/phy-stm32-combophy.c

diff --git a/drivers/phy/st/Kconfig b/drivers/phy/st/Kconfig
index 3fc3d0781fb8..304614b6dabf 100644
--- a/drivers/phy/st/Kconfig
+++ b/drivers/phy/st/Kconfig
@@ -33,6 +33,17 @@ config PHY_STIH407_USB
 	  Enable this support to enable the picoPHY device used by USB2
 	  and USB3 controllers on STMicroelectronics STiH407 SoC families.
 
+config PHY_STM32_COMBOPHY
+	tristate "STMicroelectronics COMBOPHY driver for STM32MP25"
+	depends on ARCH_STM32 || COMPILE_TEST
+	select GENERIC_PHY
+	help
+	  Enable this to support the COMBOPHY device used by USB3 or PCIe
+	  controllers on STMicroelectronics STM32MP25 SoC.
+	  This driver controls the COMBOPHY block to generate the PCIe 100Mhz
+	  reference clock from either the external clock generator or HSE
+	  internal SoC clock source.
+
 config PHY_STM32_USBPHYC
 	tristate "STMicroelectronics STM32 USB HS PHY Controller driver"
 	depends on ARCH_STM32 || COMPILE_TEST
diff --git a/drivers/phy/st/Makefile b/drivers/phy/st/Makefile
index c862dd937b64..cb80e954ea9f 100644
--- a/drivers/phy/st/Makefile
+++ b/drivers/phy/st/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_PHY_MIPHY28LP) 		+= phy-miphy28lp.o
 obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)	+= phy-spear1310-miphy.o
 obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)	+= phy-spear1340-miphy.o
 obj-$(CONFIG_PHY_STIH407_USB)		+= phy-stih407-usb.o
+obj-$(CONFIG_PHY_STM32_COMBOPHY)	+= phy-stm32-combophy.o
 obj-$(CONFIG_PHY_STM32_USBPHYC) 	+= phy-stm32-usbphyc.o
diff --git a/drivers/phy/st/phy-stm32-combophy.c b/drivers/phy/st/phy-stm32-combophy.c
new file mode 100644
index 000000000000..305ba124d092
--- /dev/null
+++ b/drivers/phy/st/phy-stm32-combophy.c
@@ -0,0 +1,590 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * STMicroelectronics COMBOPHY STM32MP25 Controller driver.
+ *
+ * Copyright (C) 2024 STMicroelectronics
+ * Author: Christian Bruel <christian.bruel at foss.st.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <dt-bindings/phy/phy.h>
+
+#define SYSCFG_COMBOPHY_CR1 0x4c00
+#define SYSCFG_COMBOPHY_CR2 0x4c04
+#define SYSCFG_COMBOPHY_CR4 0x4c0c
+#define SYSCFG_COMBOPHY_CR5 0x4c10
+#define SYSCFG_COMBOPHY_SR  0x4c14
+#define SYSCFG_PCIEPRGCR    0x6080
+
+/* SYSCFG PCIEPRGCR */
+#define STM32MP25_PCIEPRGCR_EN	  BIT(0)
+#define STM32MP25_PCIEPRG_IMPCTRL_OHM     GENMASK(3, 1)
+#define STM32MP25_PCIEPRG_IMPCTRL_VSWING  GENMASK(5, 4)
+
+/* SYSCFG SYSCFG_COMBOPHY_SR */
+#define STM32MP25_PIPE0_PHYSTATUS BIT(1)
+
+/* SYSCFG CR1 */
+#define SYSCFG_COMBOPHY_CR1_REFUSEPAD BIT(0)
+#define SYSCFG_COMBOPHY_CR1_MPLLMULT GENMASK(7, 1)
+#define SYSCFG_COMBOPHY_CR1_REFCLKSEL GENMASK(16, 8)
+#define SYSCFG_COMBOPHY_CR1_REFCLKDIV2 BIT(17)
+#define SYSCFG_COMBOPHY_CR1_REFSSPEN BIT(18)
+#define SYSCFG_COMBOPHY_CR1_SSCEN BIT(19)
+
+/* SYSCFG CR4 */
+#define SYSCFG_COMBOPHY_CR4_RX0_EQ GENMASK(2, 0)
+
+#define MPLLMULT_19_2 (0x02u << 1)
+#define MPLLMULT_20   (0x7du << 1)
+#define MPLLMULT_24   (0x68u << 1)
+#define MPLLMULT_25   (0x64u << 1)
+#define MPLLMULT_26   (0x60u << 1)
+#define MPLLMULT_38_4 (0x41u << 1)
+#define MPLLMULT_48   (0x6cu << 1)
+#define MPLLMULT_50   (0x32u << 1)
+#define MPLLMULT_52   (0x30u << 1)
+#define MPLLMULT_100  (0x19u << 1)
+
+#define REFCLKSEL_0   0
+#define REFCLKSEL_1   (0x108u << 8)
+
+#define REFCLDIV_0    0
+
+/* SYSCFG CR2 */
+#define SYSCFG_COMBOPHY_CR2_MODESEL GENMASK(1, 0)
+#define SYSCFG_COMBOPHY_CR2_ISO_DIS BIT(15)
+
+#define COMBOPHY_MODESEL_PCIE 0
+#define COMBOPHY_MODESEL_USB  3
+
+/* SYSCFG CR5 */
+#define SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS BIT(12)
+
+#define COMBOPHY_SUP_ANA_MPLL_LOOP_CTL 0xc0
+#define COMBOPHY_PROP_CNTRL GENMASK(7, 4)
+
+/* Required apb/ker clocks first, optional pad last. */
+static const char * const combophy_clks[] = {"apb", "ker", "pad"};
+#define APB_CLK 0
+#define KER_CLK 1
+#define PAD_CLK 2
+
+struct stm32_combophy {
+	struct phy *phy;
+	struct regmap *regmap;
+	struct device *dev;
+	void __iomem *base;
+	struct reset_control *phy_reset;
+	struct clk_bulk_data clks[ARRAY_SIZE(combophy_clks)];
+	int num_clks;
+	bool have_pad_clk;
+	unsigned int type;
+	bool is_init;
+	int irq_wakeup;
+};
+
+struct clk_impedance  {
+	u32 microohm;
+	u32 vswing[4];
+};
+
+/*
+ * lookup table to hold the settings needed for a ref clock frequency
+ * impedance, the offset is used to set the IMP_CTL and DE_EMP bit of the
+ * PRG_IMP_CTRL register. Use ordered discrete values in the table
+ */
+static const struct clk_impedance imp_lookup[] = {
+	{ 6090000, { 442000, 564000, 684000, 802000 } },
+	{ 5662000, { 528000, 621000, 712000, 803000 } },
+	{ 5292000, { 491000, 596000, 700000, 802000 } },
+	{ 4968000, { 558000, 640000, 722000, 803000 } },
+	{ 4684000, { 468000, 581000, 692000, 802000 } },
+	{ 4429000, { 554000, 613000, 717000, 803000 } },
+	{ 4204000, { 511000, 609000, 706000, 802000 } },
+	{ 3999000, { 571000, 648000, 726000, 803000 } }
+};
+
+static int stm32_impedance_tune(struct stm32_combophy *combophy)
+{
+	u8 imp_size = ARRAY_SIZE(imp_lookup);
+	u8 vswing_size = ARRAY_SIZE(imp_lookup[0].vswing);
+	u8 imp_of, vswing_of;
+	u32 max_imp = imp_lookup[0].microohm;
+	u32 min_imp = imp_lookup[imp_size - 1].microohm;
+	u32 max_vswing = imp_lookup[imp_size - 1].vswing[vswing_size - 1];
+	u32 min_vswing = imp_lookup[0].vswing[0];
+	u32 val;
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,output-micro-ohms", &val)) {
+		if (val < min_imp || val > max_imp) {
+			dev_err(combophy->dev, "Invalid value %u for output ohm\n", val);
+			return -EINVAL;
+		}
+
+		for (imp_of = 0; imp_of < ARRAY_SIZE(imp_lookup); imp_of++)
+			if (imp_lookup[imp_of].microohm <= val)
+				break;
+
+		dev_dbg(combophy->dev, "Set %u micro-ohms output impedance\n",
+			imp_lookup[imp_of].microohm);
+
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRG_IMPCTRL_OHM,
+				   FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_OHM, imp_of));
+	} else {
+		regmap_read(combophy->regmap, SYSCFG_PCIEPRGCR, &val);
+		imp_of = FIELD_GET(STM32MP25_PCIEPRG_IMPCTRL_OHM, val);
+	}
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,output-vswing-microvolt", &val)) {
+		if (val < min_vswing || val > max_vswing) {
+			dev_err(combophy->dev, "Invalid value %u for output vswing\n", val);
+			return -EINVAL;
+		}
+
+		for (vswing_of = 0; vswing_of < ARRAY_SIZE(imp_lookup[imp_of].vswing); vswing_of++)
+			if (imp_lookup[imp_of].vswing[vswing_of] >= val)
+				break;
+
+		dev_dbg(combophy->dev, "Set %u microvolt swing\n",
+			 imp_lookup[imp_of].vswing[vswing_of]);
+
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRG_IMPCTRL_VSWING,
+				   FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of));
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_pll_init(struct stm32_combophy *combophy)
+{
+	int ret;
+	u32 refclksel, pllmult, propcntrl, val;
+	u32 clk_rate;
+	struct clk *clk;
+
+	if (combophy->have_pad_clk)
+		clk = combophy->clks[PAD_CLK].clk;
+	else
+		clk = combophy->clks[KER_CLK].clk;
+
+	clk_rate = clk_get_rate(clk);
+
+	reset_control_assert(combophy->phy_reset);
+
+	dev_dbg(combophy->dev, "%s pll init rate %d\n",
+		combophy->have_pad_clk ? "External" : "Ker", clk_rate);
+
+	/*
+	 * vddcombophy is interconnected with vddcore. Isolation bit should be unset
+	 * before using the ComboPHY.
+	 */
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, SYSCFG_COMBOPHY_CR2_ISO_DIS);
+
+	if (combophy->type != PHY_TYPE_PCIE)
+		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+				   SYSCFG_COMBOPHY_CR1_REFSSPEN, SYSCFG_COMBOPHY_CR1_REFSSPEN);
+
+	if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRGCR_EN, STM32MP25_PCIEPRGCR_EN);
+
+	if (of_property_present(combophy->dev->of_node, "st,ssc-on")) {
+		dev_dbg(combophy->dev, "Enabling clock with SSC\n");
+		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+				   SYSCFG_COMBOPHY_CR1_SSCEN, SYSCFG_COMBOPHY_CR1_SSCEN);
+	}
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,rx-equalizer", &val)) {
+		dev_dbg(combophy->dev, "Set RX equalizer %u\n", val);
+		if (val > SYSCFG_COMBOPHY_CR4_RX0_EQ) {
+			dev_err(combophy->dev, "Invalid value %u for rx0 equalizer\n", val);
+			return -EINVAL;
+		}
+
+		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR4,
+			   SYSCFG_COMBOPHY_CR4_RX0_EQ, val);
+	}
+
+	if (combophy->type == PHY_TYPE_PCIE) {
+		ret = stm32_impedance_tune(combophy);
+		if (ret) {
+			reset_control_deassert(combophy->phy_reset);
+			goto out;
+		}
+
+		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+				   SYSCFG_COMBOPHY_CR1_REFUSEPAD,
+				   combophy->have_pad_clk ? SYSCFG_COMBOPHY_CR1_REFUSEPAD : 0);
+	}
+
+	switch (clk_rate) {
+	case 100000000:
+		pllmult = MPLLMULT_100;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0x8u << 4;
+		break;
+	case 19200000:
+		pllmult = MPLLMULT_19_2;
+		refclksel = REFCLKSEL_1;
+		propcntrl = 0x8u << 4;
+		break;
+	case 25000000:
+		pllmult = MPLLMULT_25;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0xeu << 4;
+		break;
+	case 24000000:
+		pllmult = MPLLMULT_24;
+		refclksel = REFCLKSEL_1;
+		propcntrl = 0xeu << 4;
+		break;
+	case 20000000:
+		pllmult = MPLLMULT_20;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0xeu << 4;
+		break;
+	default:
+		dev_err(combophy->dev, "Invalid rate 0x%x\n", clk_rate);
+		reset_control_deassert(combophy->phy_reset);
+		ret = -EINVAL;
+		goto out;
+	};
+
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+			   SYSCFG_COMBOPHY_CR1_REFCLKDIV2, REFCLDIV_0);
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+			   SYSCFG_COMBOPHY_CR1_REFCLKSEL, refclksel);
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+			   SYSCFG_COMBOPHY_CR1_MPLLMULT, pllmult);
+
+	/*
+	 * Force elasticity buffer to be tuned for the reference clock as
+	 * the separated clock model is not supported
+	 */
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR5,
+			   SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS, SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS);
+
+	reset_control_deassert(combophy->phy_reset);
+
+	ret = regmap_read_poll_timeout(combophy->regmap, SYSCFG_COMBOPHY_SR, val,
+				       !(val & STM32MP25_PIPE0_PHYSTATUS),
+				       10, 1000);
+	if (ret) {
+		dev_err(combophy->dev, "timeout, cannot lock PLL\n");
+		goto out;
+	}
+
+	if (combophy->type == PHY_TYPE_PCIE) {
+		val = readl_relaxed(combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
+		val &= ~COMBOPHY_PROP_CNTRL;
+		val |= propcntrl;
+		writel_relaxed(val, combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
+	}
+
+	return 0;
+
+out:
+	if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRGCR_EN, 0);
+
+	if (combophy->type != PHY_TYPE_PCIE)
+		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+				   SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
+
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
+
+	return ret;
+}
+
+static struct phy *stm32_combophy_xlate(struct device *dev,
+					const struct of_phandle_args *args)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+	unsigned int type;
+
+	if (args->args_count != 1) {
+		dev_err(dev, "invalid number of cells in 'phy' property\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	type = args->args[0];
+	if (type != PHY_TYPE_USB3 && type != PHY_TYPE_PCIE) {
+		dev_err(dev, "unsupported device type: %d\n", type);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (combophy->have_pad_clk && type != PHY_TYPE_PCIE) {
+		dev_err(dev, "Invalid use of clk_pad for USB3 mode\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	combophy->type = type;
+
+	return combophy->phy;
+}
+
+static int stm32_combophy_set_mode(struct stm32_combophy *combophy)
+{
+	int type = combophy->type;
+	u32 val;
+
+	switch (type) {
+	case PHY_TYPE_PCIE:
+		dev_dbg(combophy->dev, "setting PCIe ComboPHY\n");
+		val = COMBOPHY_MODESEL_PCIE;
+		break;
+	case PHY_TYPE_USB3:
+		dev_dbg(combophy->dev, "setting USB3 ComboPHY\n");
+		val = COMBOPHY_MODESEL_USB;
+		break;
+	default:
+		dev_err(combophy->dev, "Invalid PHY mode %d\n", type);
+		return -EINVAL;
+	}
+
+	return regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+				  SYSCFG_COMBOPHY_CR2_MODESEL, val);
+}
+
+static int stm32_combophy_suspend_noirq(struct device *dev)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+
+	/*
+	 * Clocks should be turned off since it is not needed for
+	 * wakeup capability. In case usb-remote wakeup is not enabled,
+	 * combo-phy is already turned off by HCD driver using exit callback
+	 */
+	if (combophy->is_init) {
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+
+		/* since wakeup is enabled for ctrl */
+		enable_irq_wake(combophy->irq_wakeup);
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_resume_noirq(struct device *dev)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+	int ret;
+
+	/*
+	 * If clocks was turned off by suspend call for wakeup then needs
+	 * to be turned back ON in resume. In case usb-remote wakeup is not
+	 * enabled, clocks already turned ON by HCD driver using init callback
+	 */
+	if (combophy->is_init) {
+		/* since wakeup was enabled for ctrl */
+		disable_irq_wake(combophy->irq_wakeup);
+
+		ret = clk_bulk_prepare_enable(combophy->num_clks, combophy->clks);
+		if (ret) {
+			dev_err(dev, "can't enable clocks (%d)\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_exit(struct phy *phy)
+{
+	struct stm32_combophy *combophy = phy_get_drvdata(phy);
+	struct device *dev = combophy->dev;
+
+	combophy->is_init = false;
+
+	if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRGCR_EN, 0);
+
+	if (combophy->type != PHY_TYPE_PCIE)
+		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+				   SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
+
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
+
+	clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+
+	pm_runtime_put_noidle(dev);
+
+	return 0;
+}
+
+static int stm32_combophy_init(struct phy *phy)
+{
+	struct stm32_combophy *combophy = phy_get_drvdata(phy);
+	struct device *dev = combophy->dev;
+	int ret;
+
+	pm_runtime_get_noresume(dev);
+
+	ret = clk_bulk_prepare_enable(combophy->num_clks, combophy->clks);
+	if (ret) {
+		dev_err(dev, "can't enable clocks (%d)\n", ret);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	ret = stm32_combophy_set_mode(combophy);
+	if (ret) {
+		dev_err(dev, "combophy mode not set\n");
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	ret = stm32_combophy_pll_init(combophy);
+	if (ret) {
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	pm_runtime_disable(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+
+	combophy->is_init = true;
+
+	return ret;
+}
+
+static const struct phy_ops stm32_combophy_phy_data = {
+	.init = stm32_combophy_init,
+	.exit = stm32_combophy_exit,
+	.owner = THIS_MODULE
+};
+
+static irqreturn_t stm32_combophy_irq_wakeup_handler(int irq, void *dev_id)
+{
+	return IRQ_HANDLED;
+}
+
+static int stm32_combophy_get_clocks(struct stm32_combophy *combophy)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(combophy_clks); i++)
+		combophy->clks[i].id = combophy_clks[i];
+
+	combophy->num_clks = ARRAY_SIZE(combophy_clks) - 1;
+
+	ret = devm_clk_bulk_get(combophy->dev, combophy->num_clks, combophy->clks);
+	if (ret)
+		return ret;
+
+	ret = devm_clk_bulk_get_optional(combophy->dev, 1, combophy->clks + combophy->num_clks);
+	if (ret)
+		return ret;
+
+	if (combophy->clks[combophy->num_clks].clk != NULL) {
+		combophy->have_pad_clk = true;
+		combophy->num_clks++;
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_probe(struct platform_device *pdev)
+{
+	struct stm32_combophy *combophy;
+	struct device *dev = &pdev->dev;
+	struct phy_provider *phy_provider;
+	int ret, irq;
+
+	combophy = devm_kzalloc(dev, sizeof(*combophy), GFP_KERNEL);
+	if (!combophy)
+		return -ENOMEM;
+
+	combophy->dev = dev;
+
+	dev_set_drvdata(dev, combophy);
+
+	combophy->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(combophy->base))
+		return PTR_ERR(combophy->base);
+
+	if (stm32_combophy_get_clocks(combophy))
+		return ret;
+
+	combophy->phy_reset = devm_reset_control_get(dev, "phy");
+	if (IS_ERR(combophy->phy_reset))
+		return dev_err_probe(dev, PTR_ERR(combophy->phy_reset),
+				     "Failed to get PHY reset\n");
+
+	combophy->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg");
+	if (IS_ERR(combophy->regmap))
+		return dev_err_probe(dev, PTR_ERR(combophy->regmap),
+				     "No syscfg specified\n");
+
+	combophy->phy = devm_phy_create(dev, NULL, &stm32_combophy_phy_data);
+	if (IS_ERR(combophy->phy))
+		return dev_err_probe(dev, PTR_ERR(combophy->phy),
+				     "failed to create PCIe/USB3 ComboPHY\n");
+
+	if (device_property_read_bool(dev, "wakeup-source")) {
+		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return dev_err_probe(dev, irq, "failed to get IRQ\n");
+		combophy->irq_wakeup = irq;
+
+		ret = devm_request_threaded_irq(dev, combophy->irq_wakeup, NULL,
+						stm32_combophy_irq_wakeup_handler, IRQF_ONESHOT,
+						NULL, NULL);
+		if (ret)
+			return dev_err_probe(dev, ret, "unable to request wake IRQ %d\n",
+						 combophy->irq_wakeup);
+	}
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to enable pm runtime\n");
+
+	phy_set_drvdata(combophy->phy, combophy);
+
+	phy_provider = devm_of_phy_provider_register(dev, stm32_combophy_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct dev_pm_ops stm32_combophy_pm_ops = {
+	NOIRQ_SYSTEM_SLEEP_PM_OPS(stm32_combophy_suspend_noirq,
+				  stm32_combophy_resume_noirq)
+};
+
+static const struct of_device_id stm32_combophy_of_match[] = {
+	{ .compatible = "st,stm32mp25-combophy", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, stm32_combophy_of_match);
+
+static struct platform_driver stm32_combophy_driver = {
+	.probe = stm32_combophy_probe,
+	.driver = {
+		   .name = "stm32-combophy",
+		   .of_match_table = stm32_combophy_of_match,
+		   .pm = pm_sleep_ptr(&stm32_combophy_pm_ops)
+	}
+};
+
+module_platform_driver(stm32_combophy_driver);
+
+MODULE_AUTHOR("Christian Bruel <christian.bruel at foss.st.com>");
+MODULE_DESCRIPTION("STM32MP25 Combophy USB3/PCIe controller driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From christian.bruel at foss.st.com  Tue Sep  3 05:13:03 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Tue, 3 Sep 2024 14:13:03 +0200
Subject: [PATCH v5 5/5] arm64: dts: st: Enable COMBOPHY on the stm32mp257f-ev1 board
In-Reply-To: <20240903121303.2953150-1-christian.bruel@foss.st.com>
References: <20240903121303.2953150-1-christian.bruel@foss.st.com>
Message-ID: <20240903121303.2953150-6-christian.bruel@foss.st.com>

Enable the COMBOPHY with external pad clock on stm32mp257f-ev1
board, to be used for the PCIe clock provider.

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
index 214191a8322b..bcf84d533cb2 100644
--- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
+++ b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
@@ -27,6 +27,14 @@ chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
+	clocks {
+		pad_clk: pad-clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+		};
+	};
+
 	memory at 80000000 {
 		device_type = "memory";
 		reg = <0x0 0x80000000 0x1 0x0>;
@@ -50,6 +58,12 @@ &arm_wdt {
 	status = "okay";
 };
 
+&combophy {
+	clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>, <&pad_clk>;
+	clock-names = "apb", "ker", "pad";
+	status = "okay";
+};
+
 &ethernet2 {
 	pinctrl-names = "default", "sleep";
 	pinctrl-0 = <&eth2_rgmii_pins_a>;
-- 
2.34.1



From claudiu.beznea at tuxon.dev  Tue Sep  3 05:25:55 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Tue, 3 Sep 2024 15:25:55 +0300
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <TY3PR01MB113469FC8A9F49D9B1FA432FD86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <fbfa9179-2f52-429f-8b69-f7f4064e796b@tuxon.dev>
 <TYCPR01MB11332EF1A8D064C491D8F261286932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <f7c57e76-b890-491f-880d-62d060b7b31e@tuxon.dev>
 <TYCPR01MB11332BE2EDB318950B9C7B54C86932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <TY3PR01MB113469FC8A9F49D9B1FA432FD86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <0b73544b-0253-43b9-b631-6578b48eaca8@tuxon.dev>



On 03.09.2024 15:00, Biju Das wrote:
> 
> 
>> -----Original Message-----
>> From: Biju Das <biju.das.jz at bp.renesas.com>
>> Sent: Tuesday, September 3, 2024 12:07 PM
>> To: Claudiu.Beznea <claudiu.beznea at tuxon.dev>; Ulf Hansson <ulf.hansson at linaro.org>
>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org; krzk+dt at kernel.org; conor+dt at kernel.org;
>> p.zabel at pengutronix.de; geert+renesas at glider.be; magnus.damm at gmail.com; gregkh at linuxfoundation.org;
>> mturquette at baylibre.com; sboyd at kernel.org; Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>;
>> linux-phy at lists.infradead.org; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-
>> renesas-soc at vger.kernel.org; linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
>> clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
>>
>> Hi Claudiu,
>>
>>> -----Original Message-----
>>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>>> Sent: Tuesday, September 3, 2024 12:00 PM
>>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
>>> RZ/G3S SoC
>>>
>>>
>>>
>>> On 03.09.2024 13:31, Biju Das wrote:
>>>>>> During boot clr USB PWR READY signal in TF-A.
>>>>>> STR case, suspend set USB PWR READY signal in TF-A.
>>>>>> STR case, resume clr USB PWR READY signal in TF-A.
>>>>> As I said previously, it can be done in different ways. My point
>>>>> was to let Linux set what it needs for all it's devices to work. I
>>>>> think the way to go forward is a
>>> maintainer decision.
>>>>
>>>> I agree, there can be n number of solution for a problem.
>>>>
>>>> Since you modelled system state signal (USB PWRRDY) as reset control
>>>> signal, it is reset/DT maintainer's decision to say the final word
>>>> whether this signal fits in reset
>>> system framework or not?
>>>
>>> I was thinking:
>>> 1/ Geert would be the best to say if he considers it OK to handle this
>>>    in Linux
>>
>> I agree Geert is the right person for taking SYSTEM decisions, since the signal is used only during
>> state transitions (Table 41.6.4 AWO to ALL_ON and 41.6.3 ALL_ON to AWO)
> 
> One more info, as per [1], this USB PWRRDY signal setting to be before Linux kernel boots.

The "controlled by" column mentions CA-55 on PWRRDY signal control line and
it is b/w steps "DDR exits from retention mode" and  "clock start settings
for system bus and peripheral modules". AFAICT, after DDR exists retention
mode Linux is ready to run.

E.g. on resume Linux doesn't sets the clocks of all peripheral in sequence
and then runs the rest of settings for each peripheral, in turn it sets the
clock of one peripheral along with all the other necessary peripheral
settings and then continues with the rest of peripherals (including their
clocks).

> 
> All clocks/reset happens after setting USB PWRRDY signal
> 
> https://pasteboard.co/qbz021q7KPyi.png
> 
> Cheers,
> Biju


From biju.das.jz at bp.renesas.com  Tue Sep  3 05:37:58 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Tue, 3 Sep 2024 12:37:58 +0000
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <0b73544b-0253-43b9-b631-6578b48eaca8@tuxon.dev>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <TY3PR01MB113467275C519B729FCAB1ACB86922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5556d176-cca7-492c-ba21-48256d5d6338@tuxon.dev>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <fbfa9179-2f52-429f-8b69-f7f4064e796b@tuxon.dev>
 <TYCPR01MB11332EF1A8D064C491D8F261286932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <f7c57e76-b890-491f-880d-62d060b7b31e@tuxon.dev>
 <TYCPR01MB11332BE2EDB318950B9C7B54C86932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <TY3PR01MB113469FC8A9F49D9B1FA432FD86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <0b73544b-0253-43b9-b631-6578b48eaca8@tuxon.dev>
Message-ID: <TY3PR01MB1134689573A785E91A9041E1886932@TY3PR01MB11346.jpnprd01.prod.outlook.com>



> -----Original Message-----
> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> Sent: Tuesday, September 3, 2024 1:26 PM
> To: Biju Das <biju.das.jz at bp.renesas.com>; Ulf Hansson <ulf.hansson at linaro.org>
> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org; krzk+dt at kernel.org; conor+dt at kernel.org;
> p.zabel at pengutronix.de; geert+renesas at glider.be; magnus.damm at gmail.com; gregkh at linuxfoundation.org;
> mturquette at baylibre.com; sboyd at kernel.org; Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>;
> linux-phy at lists.infradead.org; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-
> renesas-soc at vger.kernel.org; linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
> 
> 
> 
> On 03.09.2024 15:00, Biju Das wrote:
> >
> >
> >> -----Original Message-----
> >> From: Biju Das <biju.das.jz at bp.renesas.com>
> >> Sent: Tuesday, September 3, 2024 12:07 PM
> >> To: Claudiu.Beznea <claudiu.beznea at tuxon.dev>; Ulf Hansson
> >> <ulf.hansson at linaro.org>
> >> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> >> krzk+dt at kernel.org; conor+dt at kernel.org; p.zabel at pengutronix.de;
> >> geert+renesas at glider.be; magnus.damm at gmail.com;
> >> gregkh at linuxfoundation.org; mturquette at baylibre.com;
> >> sboyd at kernel.org; Yoshihiro Shimoda
> >> <yoshihiro.shimoda.uh at renesas.com>;
> >> linux-phy at lists.infradead.org; devicetree at vger.kernel.org;
> >> linux-kernel at vger.kernel.org; linux- renesas-soc at vger.kernel.org;
> >> linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> >> linux- clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu Beznea
> >> <claudiu.beznea.uj at bp.renesas.com>
> >> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas
> >> RZ/G3S SoC
> >>
> >> Hi Claudiu,
> >>
> >>> -----Original Message-----
> >>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> >>> Sent: Tuesday, September 3, 2024 12:00 PM
> >>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
> >>> RZ/G3S SoC
> >>>
> >>>
> >>>
> >>> On 03.09.2024 13:31, Biju Das wrote:
> >>>>>> During boot clr USB PWR READY signal in TF-A.
> >>>>>> STR case, suspend set USB PWR READY signal in TF-A.
> >>>>>> STR case, resume clr USB PWR READY signal in TF-A.
> >>>>> As I said previously, it can be done in different ways. My point
> >>>>> was to let Linux set what it needs for all it's devices to work. I
> >>>>> think the way to go forward is a
> >>> maintainer decision.
> >>>>
> >>>> I agree, there can be n number of solution for a problem.
> >>>>
> >>>> Since you modelled system state signal (USB PWRRDY) as reset
> >>>> control signal, it is reset/DT maintainer's decision to say the
> >>>> final word whether this signal fits in reset
> >>> system framework or not?
> >>>
> >>> I was thinking:
> >>> 1/ Geert would be the best to say if he considers it OK to handle this
> >>>    in Linux
> >>
> >> I agree Geert is the right person for taking SYSTEM decisions, since
> >> the signal is used only during state transitions (Table 41.6.4 AWO to
> >> ALL_ON and 41.6.3 ALL_ON to AWO)
> >
> > One more info, as per [1], this USB PWRRDY signal setting to be before Linux kernel boots.
> 
> The "controlled by" column mentions CA-55 on PWRRDY signal control line and it is b/w steps "DDR exits
> from retention mode" and  "clock start settings for system bus and peripheral modules". AFAICT, after
> DDR exists retention mode Linux is ready to run.

DDR retention exit happens in TF-A and it jumps into reset code where it executes BL2 in TF_A. Bl2 checks for warm or cold reset.
If it is warm reset, it sets required minimal clocks/resets and pass the control to linux by calling the
SMC callback handler. Which in turn calls resume(step 11-->14) path.

Step 8, Cortex-A55 Exit from DDR retention mode (when using) Setting for exiting form DDR retention mode
Step 9, Cortex-A55 USB PHY PWRRDY signal control (if use USB) SYS_USB_PWRRDY
Step 10, Cortex-A55 PCIe RST_RSM_B signal control (if use PCIe) SYS_PCIE_RST_RSM_B
Step 11, Cortex-A55 Clock start setting for system bus and desired peripheral modules in PD_ISOVCC CPG_CLKON_***ep 
(***: GIC600, MHU, SDHI, USB, ETH, DDR, PCI,AXI_COM_BUS, PERI_COM, AXI_TZCDDR,
OTFDE_DDR)
Step 12, Cortex-A55 Release reset setting for system bus and desired peripheral modules in PD_ISOVCC CPG_RST_***
(***: GIC600, MHU, SDHI, USB, ETH, DDR, PCI, AXI_COM_BUS, PERI_COM, AXI_TZCDDR,OTFDE_DDR)
Step 13, Cortex-A55 Release MSTOP bit for system bus and desired peripheral modules in PD_ISOVCC CPG_BUS_***_MSTOP
(***: ACPU, PERI_COM, PERI_DDR, TZCDDR),
CPG_MHU_MSTOP.
Step14) Cortex-A55 Clock start setting and reset release setting for Cortex-M33_FPU (if use Cortex-M33_FPU)
CPG_CLKON_CM33, CPG_RST_CM33

Cheers,
Biju

From claudiu.beznea at tuxon.dev  Tue Sep  3 05:57:13 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Tue, 3 Sep 2024 15:57:13 +0300
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <TY3PR01MB1134689573A785E91A9041E1886932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <fbfa9179-2f52-429f-8b69-f7f4064e796b@tuxon.dev>
 <TYCPR01MB11332EF1A8D064C491D8F261286932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <f7c57e76-b890-491f-880d-62d060b7b31e@tuxon.dev>
 <TYCPR01MB11332BE2EDB318950B9C7B54C86932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <TY3PR01MB113469FC8A9F49D9B1FA432FD86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <0b73544b-0253-43b9-b631-6578b48eaca8@tuxon.dev>
 <TY3PR01MB1134689573A785E91A9041E1886932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <5bcdc677-e61e-4312-a19b-57b4600685d3@tuxon.dev>



On 03.09.2024 15:37, Biju Das wrote:
> 
> 
>> -----Original Message-----
>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>> Sent: Tuesday, September 3, 2024 1:26 PM
>> To: Biju Das <biju.das.jz at bp.renesas.com>; Ulf Hansson <ulf.hansson at linaro.org>
>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org; krzk+dt at kernel.org; conor+dt at kernel.org;
>> p.zabel at pengutronix.de; geert+renesas at glider.be; magnus.damm at gmail.com; gregkh at linuxfoundation.org;
>> mturquette at baylibre.com; sboyd at kernel.org; Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>;
>> linux-phy at lists.infradead.org; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-
>> renesas-soc at vger.kernel.org; linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
>> clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
>>
>>
>>
>> On 03.09.2024 15:00, Biju Das wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Biju Das <biju.das.jz at bp.renesas.com>
>>>> Sent: Tuesday, September 3, 2024 12:07 PM
>>>> To: Claudiu.Beznea <claudiu.beznea at tuxon.dev>; Ulf Hansson
>>>> <ulf.hansson at linaro.org>
>>>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
>>>> krzk+dt at kernel.org; conor+dt at kernel.org; p.zabel at pengutronix.de;
>>>> geert+renesas at glider.be; magnus.damm at gmail.com;
>>>> gregkh at linuxfoundation.org; mturquette at baylibre.com;
>>>> sboyd at kernel.org; Yoshihiro Shimoda
>>>> <yoshihiro.shimoda.uh at renesas.com>;
>>>> linux-phy at lists.infradead.org; devicetree at vger.kernel.org;
>>>> linux-kernel at vger.kernel.org; linux- renesas-soc at vger.kernel.org;
>>>> linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>>>> linux- clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu Beznea
>>>> <claudiu.beznea.uj at bp.renesas.com>
>>>> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas
>>>> RZ/G3S SoC
>>>>
>>>> Hi Claudiu,
>>>>
>>>>> -----Original Message-----
>>>>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>>>>> Sent: Tuesday, September 3, 2024 12:00 PM
>>>>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
>>>>> RZ/G3S SoC
>>>>>
>>>>>
>>>>>
>>>>> On 03.09.2024 13:31, Biju Das wrote:
>>>>>>>> During boot clr USB PWR READY signal in TF-A.
>>>>>>>> STR case, suspend set USB PWR READY signal in TF-A.
>>>>>>>> STR case, resume clr USB PWR READY signal in TF-A.
>>>>>>> As I said previously, it can be done in different ways. My point
>>>>>>> was to let Linux set what it needs for all it's devices to work. I
>>>>>>> think the way to go forward is a
>>>>> maintainer decision.
>>>>>>
>>>>>> I agree, there can be n number of solution for a problem.
>>>>>>
>>>>>> Since you modelled system state signal (USB PWRRDY) as reset
>>>>>> control signal, it is reset/DT maintainer's decision to say the
>>>>>> final word whether this signal fits in reset
>>>>> system framework or not?
>>>>>
>>>>> I was thinking:
>>>>> 1/ Geert would be the best to say if he considers it OK to handle this
>>>>>    in Linux
>>>>
>>>> I agree Geert is the right person for taking SYSTEM decisions, since
>>>> the signal is used only during state transitions (Table 41.6.4 AWO to
>>>> ALL_ON and 41.6.3 ALL_ON to AWO)
>>>
>>> One more info, as per [1], this USB PWRRDY signal setting to be before Linux kernel boots.
>>
>> The "controlled by" column mentions CA-55 on PWRRDY signal control line and it is b/w steps "DDR exits
>> from retention mode" and  "clock start settings for system bus and peripheral modules". AFAICT, after
>> DDR exists retention mode Linux is ready to run.
> 
> DDR retention exit happens in TF-A and it jumps into reset code where it executes BL2 in TF_A. Bl2 checks for warm or cold reset.
> If it is warm reset, it sets required minimal clocks/resets and pass the control to linux by calling the
> SMC callback handler. Which in turn calls resume(step 11-->14) path.

Is this from HW manual or some specific documentation? I'm referring at
"resume" == "steps 11-->14"

> 
> Step 8, Cortex-A55 Exit from DDR retention mode (when using) Setting for exiting form DDR retention mode
> Step 9, Cortex-A55 USB PHY PWRRDY signal control (if use USB) SYS_USB_PWRRDY
> Step 10, Cortex-A55 PCIe RST_RSM_B signal control (if use PCIe) SYS_PCIE_RST_RSM_B

Note *if use*: how does the TF-A know if USB/PCIe is used by Linux? The
documentation mention to set it *if use*. Same note is on ALL_ON to VBATT
transition documentation (namely "if using USB", "if using PCIe"). If TF-A
will do this it should set this signals unconditionally. It will not be
something wrong though. We don't know at the moment what this involves in
terms of power consumption, if it means something...

> Step 11, Cortex-A55 Clock start setting for system bus and desired peripheral modules in PD_ISOVCC CPG_CLKON_***ep 
> (***: GIC600, MHU, SDHI, USB, ETH, DDR, PCI,AXI_COM_BUS, PERI_COM, AXI_TZCDDR,
> OTFDE_DDR)
> Step 12, Cortex-A55 Release reset setting for system bus and desired peripheral modules in PD_ISOVCC CPG_RST_***
> (***: GIC600, MHU, SDHI, USB, ETH, DDR, PCI, AXI_COM_BUS, PERI_COM, AXI_TZCDDR,OTFDE_DDR)
> Step 13, Cortex-A55 Release MSTOP bit for system bus and desired peripheral modules in PD_ISOVCC CPG_BUS_***_MSTOP
> (***: ACPU, PERI_COM, PERI_DDR, TZCDDR),
> CPG_MHU_MSTOP.
> Step14) Cortex-A55 Clock start setting and reset release setting for Cortex-M33_FPU (if use Cortex-M33_FPU)
> CPG_CLKON_CM33, CPG_RST_CM33
> 
> Cheers,
> Biju


From christian.bruel at foss.st.com  Tue Sep  3 06:02:02 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Tue, 3 Sep 2024 15:02:02 +0200
Subject: [PATCH v4 2/5] phy: stm32: Add support for STM32MP25 COMBOPHY.
In-Reply-To: <ZtCyb7AzLmuUoBGT@vaman>
References: <20240828143452.1407532-1-christian.bruel@foss.st.com>
 <20240828143452.1407532-3-christian.bruel@foss.st.com>
 <ZtCyb7AzLmuUoBGT@vaman>
Message-ID: <eff25350-be52-4d3e-91d2-422314c190c8@foss.st.com>



On 8/29/24 19:39, Vinod Koul wrote:
> On 28-08-24, 16:34, Christian Bruel wrote:
>> Addition of the COMBOPHY driver found on STM32MP25 platforms
>>
>> This single lane PHY is shared (exclusive) between the USB3 and PCIE
>> controllers.
>> Supports 5Gbit/s for PCIE gen2 or 2.5Gbit/s for PCIE gen1.
>>
>> Supports wakeup-source capability to wakeup system using remote-wakeup
>> capable USB device
>>
>> Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
>> ---
>>   drivers/phy/st/Kconfig              |  11 +
>>   drivers/phy/st/Makefile             |   1 +
>>   drivers/phy/st/phy-stm32-combophy.c | 607 ++++++++++++++++++++++++++++
>>   3 files changed, 619 insertions(+)
>>   create mode 100644 drivers/phy/st/phy-stm32-combophy.c
>>
>> diff --git a/drivers/phy/st/Kconfig b/drivers/phy/st/Kconfig
>> index 3fc3d0781fb8..304614b6dabf 100644
>> --- a/drivers/phy/st/Kconfig
>> +++ b/drivers/phy/st/Kconfig
>> @@ -33,6 +33,17 @@ config PHY_STIH407_USB
>>   	  Enable this support to enable the picoPHY device used by USB2
>>   	  and USB3 controllers on STMicroelectronics STiH407 SoC families.
>>   
>> +config PHY_STM32_COMBOPHY
>> +	tristate "STMicroelectronics COMBOPHY driver for STM32MP25"
>> +	depends on ARCH_STM32 || COMPILE_TEST
>> +	select GENERIC_PHY
>> +	help
>> +	  Enable this to support the COMBOPHY device used by USB3 or PCIe
>> +	  controllers on STMicroelectronics STM32MP25 SoC.
>> +	  This driver controls the COMBOPHY block to generate the PCIe 100Mhz
>> +	  reference clock from either the external clock generator or HSE
>> +	  internal SoC clock source.
>> +
>>   config PHY_STM32_USBPHYC
>>   	tristate "STMicroelectronics STM32 USB HS PHY Controller driver"
>>   	depends on ARCH_STM32 || COMPILE_TEST
>> diff --git a/drivers/phy/st/Makefile b/drivers/phy/st/Makefile
>> index c862dd937b64..cb80e954ea9f 100644
>> --- a/drivers/phy/st/Makefile
>> +++ b/drivers/phy/st/Makefile
>> @@ -3,4 +3,5 @@ obj-$(CONFIG_PHY_MIPHY28LP) 		+= phy-miphy28lp.o
>>   obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)	+= phy-spear1310-miphy.o
>>   obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)	+= phy-spear1340-miphy.o
>>   obj-$(CONFIG_PHY_STIH407_USB)		+= phy-stih407-usb.o
>> +obj-$(CONFIG_PHY_STM32_COMBOPHY)	+= phy-stm32-combophy.o
>>   obj-$(CONFIG_PHY_STM32_USBPHYC) 	+= phy-stm32-usbphyc.o
>> diff --git a/drivers/phy/st/phy-stm32-combophy.c b/drivers/phy/st/phy-stm32-combophy.c
>> new file mode 100644
>> index 000000000000..7cd4193b0277
>> --- /dev/null
>> +++ b/drivers/phy/st/phy-stm32-combophy.c
>> @@ -0,0 +1,607 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * STMicroelectronics COMBOPHY STM32MP25 Controller driver.
>> + *
>> + * Copyright (C) 2024 STMicroelectronics
>> + * Author: Christian Bruel <christian.bruel at foss.st.com>
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/phy/phy.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/regmap.h>
>> +#include <linux/reset.h>
>> +#include <dt-bindings/phy/phy.h>
>> +
>> +#define SYSCFG_COMBOPHY_CR1 0x4C00
>> +#define SYSCFG_COMBOPHY_CR2 0x4C04
>> +#define SYSCFG_COMBOPHY_CR4 0x4C0C
>> +#define SYSCFG_COMBOPHY_CR5 0x4C10
>> +#define SYSCFG_COMBOPHY_SR  0x4C14
> 
> Lowercase hex values please
> 
>> +#define SYSCFG_PCIEPRGCR    0x6080
>> +
>> +/* SYSCFG PCIEPRGCR */
>> +#define STM32MP25_PCIEPRGCR_EN	  BIT(0)
>> +#define STM32MP25_PCIEPRG_IMPCTRL_OHM     GENMASK(3, 1)
>> +#define STM32MP25_PCIEPRG_IMPCTRL_VSWING  GENMASK(5, 4)
>> +
>> +/* SYSCFG SYSCFG_COMBOPHY_SR */
>> +#define STM32MP25_PIPE0_PHYSTATUS BIT(1)
>> +
>> +/* SYSCFG CR1 */
>> +#define SYSCFG_COMBOPHY_CR1_REFUSEPAD BIT(0)
>> +#define SYSCFG_COMBOPHY_CR1_MPLLMULT GENMASK(7, 1)
>> +#define SYSCFG_COMBOPHY_CR1_REFCLKSEL GENMASK(16, 8)
>> +#define SYSCFG_COMBOPHY_CR1_REFCLKDIV2 BIT(17)
>> +#define SYSCFG_COMBOPHY_CR1_REFSSPEN BIT(18)
>> +#define SYSCFG_COMBOPHY_CR1_SSCEN BIT(19)
>> +
>> +/* SYSCFG CR4 */
>> +#define SYSCFG_COMBOPHY_CR4_RX0_EQ GENMASK(2, 0)
>> +
>> +#define MPLLMULT_19_2 (0x02u << 1)
>> +#define MPLLMULT_20   (0x7Du << 1)
>> +#define MPLLMULT_24   (0x68u << 1)
>> +#define MPLLMULT_25   (0x64u << 1)
>> +#define MPLLMULT_26   (0x60u << 1)
>> +#define MPLLMULT_38_4 (0x41u << 1)
>> +#define MPLLMULT_48   (0x6Cu << 1)
>> +#define MPLLMULT_50   (0x32u << 1)
>> +#define MPLLMULT_52   (0x30u << 1)
>> +#define MPLLMULT_100  (0x19u << 1)
>> +
>> +#define REFCLKSEL_0   0
>> +#define REFCLKSEL_1   (0x108u << 8)
>> +
>> +#define REFCLDIV_0    0
>> +
>> +/* SYSCFG CR2 */
>> +#define SYSCFG_COMBOPHY_CR2_MODESEL GENMASK(1, 0)
>> +#define SYSCFG_COMBOPHY_CR2_ISO_DIS BIT(15)
>> +
>> +#define COMBOPHY_MODESEL_PCIE 0
>> +#define COMBOPHY_MODESEL_USB  3
>> +
>> +/* SYSCFG CR5 */
>> +#define SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS BIT(12)
>> +
>> +#define COMBOPHY_SUP_ANA_MPLL_LOOP_CTL 0xC0
>> +#define COMBOPHY_PROP_CNTRL GENMASK(7, 4)
>> +
>> +struct stm32_combophy {
>> +	struct phy *phy;
>> +	struct regmap *regmap;
>> +	struct device *dev;
>> +	void __iomem *base;
>> +	struct reset_control *phy_reset;
>> +	struct clk *phy_clk;
>> +	struct clk *pad_clk;
>> +	struct clk *ker_clk;
>> +	unsigned int type;
>> +	bool is_init;
>> +	int irq_wakeup;
>> +};
>> +
>> +struct clk_impedance  {
>> +	u32 microohm;
>> +	u32 vswing[4];
>> +};
>> +
>> +/*
>> + * lookup table to hold the settings needed for a ref clock frequency
>> + * impedance, the offset is used to set the IMP_CTL and DE_EMP bit of the
>> + * PRG_IMP_CTRL register
>> + */
>> +static const struct clk_impedance imp_lookup[] = {
>> +	{ 6090000, { 442000, 564000, 684000, 802000 } },
>> +	{ 5662000, { 528000, 621000, 712000, 803000 } },
>> +	{ 5292000, { 491000, 596000, 700000, 802000 } },
>> +	{ 4968000, { 558000, 640000, 722000, 803000 } },
>> +	{ 4684000, { 468000, 581000, 692000, 802000 } },
>> +	{ 4429000, { 554000, 613000, 717000, 803000 } },
>> +	{ 4204000, { 511000, 609000, 706000, 802000 } },
>> +	{ 3999000, { 571000, 648000, 726000, 803000 } }
>> +};
>> +
>> +static int stm32_impedance_tune(struct stm32_combophy *combophy)
>> +{
>> +	u8 imp_size = ARRAY_SIZE(imp_lookup);
>> +	u8 vswing_size = ARRAY_SIZE(imp_lookup[0].vswing);
>> +	u8 imp_of, vswing_of;
>> +	u32 max_imp = imp_lookup[0].microohm;
>> +	u32 min_imp = imp_lookup[imp_size - 1].microohm;
> 
> table is ordered, pls mention that in comments somewhere
> 
>> +	u32 max_vswing = imp_lookup[imp_size - 1].vswing[vswing_size - 1];
>> +	u32 min_vswing = imp_lookup[0].vswing[0];
>> +	u32 val;
>> +
>> +	if (!of_property_read_u32(combophy->dev->of_node, "st,output-micro-ohms", &val)) {
>> +		if (val < min_imp || val > max_imp) {
>> +			dev_err(combophy->dev, "Invalid value %u for output ohm\n", val);
>> +			return -EINVAL;
>> +		}
>> +
>> +		for (imp_of = 0 ; imp_of < ARRAY_SIZE(imp_lookup); imp_of++)
>> +			if (imp_lookup[imp_of].microohm <= val)
>> +				break;
>> +
>> +		dev_dbg(combophy->dev, "Set %u micro-ohms output impedance\n",
>> +			imp_lookup[imp_of].microohm);
>> +
>> +		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
>> +				   STM32MP25_PCIEPRG_IMPCTRL_OHM,
>> +				   FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_OHM, imp_of));
>> +	} else {
>> +		regmap_read(combophy->regmap, SYSCFG_PCIEPRGCR, &val);
>> +		imp_of = FIELD_GET(STM32MP25_PCIEPRG_IMPCTRL_OHM, val);
>> +	}
>> +
>> +	if (!of_property_read_u32(combophy->dev->of_node, "st,output-vswing-microvolt", &val)) {
>> +		if (val < min_vswing || val > max_vswing) {
>> +			dev_err(combophy->dev, "Invalid value %u for output vswing\n", val);
>> +			return -EINVAL;
>> +		}
>> +
>> +		for (vswing_of = 0 ; vswing_of < ARRAY_SIZE(imp_lookup[imp_of].vswing); vswing_of++)
>> +			if (imp_lookup[imp_of].vswing[vswing_of] >= val)
>> +				break;
>> +
>> +		dev_dbg(combophy->dev, "Set %u microvolt swing\n",
>> +			 imp_lookup[imp_of].vswing[vswing_of]);
>> +
>> +		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
>> +				   STM32MP25_PCIEPRG_IMPCTRL_VSWING,
>> +				   FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of));
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int stm32_combophy_pll_init(struct stm32_combophy *combophy)
>> +{
>> +	int ret;
>> +	u32 refclksel, pllmult, propcntrl, val;
>> +	u32 clk_rate;
>> +
>> +	if (combophy->pad_clk)
>> +		clk_rate = clk_get_rate(combophy->pad_clk);
>> +	else
>> +		clk_rate = clk_get_rate(combophy->ker_clk);
>> +
>> +	reset_control_assert(combophy->phy_reset);
>> +
>> +	dev_dbg(combophy->dev, "%s pll init rate %d\n",
>> +		combophy->pad_clk ? "External" : "Ker", clk_rate);
>> +
>> +	/*
>> +	 * vddcombophy is interconnected with vddcore. Isolation bit should be unset
>> +	 * before using the ComboPHY.
>> +	 */
>> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
>> +			   SYSCFG_COMBOPHY_CR2_ISO_DIS, SYSCFG_COMBOPHY_CR2_ISO_DIS);
>> +
>> +	if (combophy->type != PHY_TYPE_PCIE)
>> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
>> +				   SYSCFG_COMBOPHY_CR1_REFSSPEN, SYSCFG_COMBOPHY_CR1_REFSSPEN);
>> +
>> +	if (combophy->type == PHY_TYPE_PCIE && !combophy->pad_clk)
>> +		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
>> +				   STM32MP25_PCIEPRGCR_EN, STM32MP25_PCIEPRGCR_EN);
>> +
>> +	if (of_property_read_bool(combophy->dev->of_node, "st,ssc-on")) {
>> +		dev_dbg(combophy->dev, "Enabling clock with SSC\n");
>> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
>> +				   SYSCFG_COMBOPHY_CR1_SSCEN, SYSCFG_COMBOPHY_CR1_SSCEN);
>> +	}
>> +
>> +	if (!of_property_read_u32(combophy->dev->of_node, "st,rx-equalizer", &val)) {
>> +		dev_dbg(combophy->dev, "Set RX equalizer %u\n", val);
>> +		if (val > SYSCFG_COMBOPHY_CR4_RX0_EQ) {
>> +			dev_err(combophy->dev, "Invalid value %u for rx0 equalizer\n", val);
>> +			return -EINVAL;
>> +		}
>> +
>> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR4,
>> +			   SYSCFG_COMBOPHY_CR4_RX0_EQ, val);
>> +	}
>> +
>> +	if (combophy->type == PHY_TYPE_PCIE) {
>> +		ret = stm32_impedance_tune(combophy);
>> +		if (ret) {
>> +			reset_control_deassert(combophy->phy_reset);
>> +			goto out;
>> +		}
>> +
>> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
>> +				   SYSCFG_COMBOPHY_CR1_REFUSEPAD,
>> +				   combophy->pad_clk ? SYSCFG_COMBOPHY_CR1_REFUSEPAD : 0);
>> +	}
>> +
>> +	switch (clk_rate) {
>> +	case 100000000:
>> +		pllmult = MPLLMULT_100;
>> +		refclksel = REFCLKSEL_0;
>> +		propcntrl = 0x8u << 4;
>> +		break;
>> +	case 19200000:
>> +		pllmult = MPLLMULT_19_2;
>> +		refclksel = REFCLKSEL_1;
>> +		propcntrl = 0x8u << 4;
>> +		break;
>> +	case 25000000:
>> +		pllmult = MPLLMULT_25;
>> +		refclksel = REFCLKSEL_0;
>> +		propcntrl = 0xEu << 4;
>> +		break;
>> +	case 24000000:
>> +		pllmult = MPLLMULT_24;
>> +		refclksel = REFCLKSEL_1;
>> +		propcntrl = 0xEu << 4;
>> +		break;
>> +	case 20000000:
>> +		pllmult = MPLLMULT_20;
>> +		refclksel = REFCLKSEL_0;
>> +		propcntrl = 0xEu << 4;
>> +		break;
>> +	default:
>> +		dev_err(combophy->dev, "Invalid rate 0x%x\n", clk_rate);
>> +		reset_control_deassert(combophy->phy_reset);
>> +		ret = -EINVAL;
>> +		goto out;
>> +	};
>> +
>> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
>> +			   SYSCFG_COMBOPHY_CR1_REFCLKDIV2, REFCLDIV_0);
>> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
>> +			   SYSCFG_COMBOPHY_CR1_REFCLKSEL, refclksel);
>> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
>> +			   SYSCFG_COMBOPHY_CR1_MPLLMULT, pllmult);
>> +
>> +	/*
>> +	 * Force elasticity buffer to be tuned for the reference clock as
>> +	 * the separated clock model is not supported
>> +	 */
>> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR5,
>> +			   SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS, SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS);
>> +
>> +	reset_control_deassert(combophy->phy_reset);
>> +
>> +	ret = regmap_read_poll_timeout(combophy->regmap, SYSCFG_COMBOPHY_SR, val,
>> +				       !(val & STM32MP25_PIPE0_PHYSTATUS),
>> +				       10, 1000);
>> +	if (ret) {
>> +		dev_err(combophy->dev, "timeout, cannot lock PLL\n");
>> +		goto out;
>> +	}
>> +
>> +	if (combophy->type == PHY_TYPE_PCIE) {
>> +		val = readl_relaxed(combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
>> +		val &= ~COMBOPHY_PROP_CNTRL;
>> +		val |= propcntrl;
>> +		writel_relaxed(val, combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
>> +	}
>> +
>> +	return 0;
>> +
>> +out:
>> +	if (combophy->type == PHY_TYPE_PCIE && !combophy->pad_clk)
>> +		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
>> +				   STM32MP25_PCIEPRGCR_EN, 0);
>> +
>> +	if (combophy->type != PHY_TYPE_PCIE)
>> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
>> +				   SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
>> +
>> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
>> +			   SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
>> +
>> +	return ret;
>> +}
>> +
>> +static struct phy *stm32_combophy_xlate(struct device *dev,
>> +					const struct of_phandle_args *args)
>> +{
>> +	struct stm32_combophy *combophy = dev_get_drvdata(dev);
>> +	unsigned int type;
>> +
>> +	if (args->args_count != 1) {
>> +		dev_err(dev, "invalid number of cells in 'phy' property\n");
>> +		return ERR_PTR(-EINVAL);
>> +	}
>> +
>> +	type = args->args[0];
>> +	if (type != PHY_TYPE_USB3 && type != PHY_TYPE_PCIE) {
>> +		dev_err(dev, "unsupported device type: %d\n", type);
>> +		return ERR_PTR(-EINVAL);
>> +	}
>> +
>> +	if (combophy->pad_clk && type != PHY_TYPE_PCIE) {
>> +		dev_err(dev, "Invalid use of clk_pad for USB3 mode\n");
>> +		return ERR_PTR(-EINVAL);
>> +	}
>> +
>> +	combophy->type = type;
>> +
>> +	return combophy->phy;
>> +}
>> +
>> +static int stm32_combophy_set_mode(struct stm32_combophy *combophy)
>> +{
>> +	int type = combophy->type;
>> +	u32 val;
>> +
>> +	switch (type) {
>> +	case PHY_TYPE_PCIE:
>> +		dev_dbg(combophy->dev, "setting PCIe ComboPHY\n");
>> +		val = COMBOPHY_MODESEL_PCIE;
>> +		break;
>> +	case PHY_TYPE_USB3:
>> +		dev_dbg(combophy->dev, "setting USB3 ComboPHY\n");
>> +		val = COMBOPHY_MODESEL_USB;
>> +		break;
>> +	default:
>> +		dev_err(combophy->dev, "Invalid PHY mode %d\n", type);
>> +		return -EINVAL;
>> +	}
>> +
>> +	return regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
>> +				  SYSCFG_COMBOPHY_CR2_MODESEL, val);
>> +}
>> +
>> +static int stm32_combophy_enable_clocks(struct stm32_combophy *combophy)
>> +{
>> +	int ret;
>> +
>> +	ret = clk_prepare_enable(combophy->phy_clk);
>> +	if (ret) {
>> +		dev_err(combophy->dev, "Core clock enable failed %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	ret = clk_prepare_enable(combophy->ker_clk);
>> +	if (ret) {
>> +		dev_err(combophy->dev, "ker_usb3pcie clock enable failed %d\n", ret);
>> +		clk_disable_unprepare(combophy->phy_clk);
>> +		return ret;
>> +	}
>> +
>> +	if (combophy->pad_clk) {
>> +		ret = clk_prepare_enable(combophy->pad_clk);
>> +		if (ret) {
>> +			dev_err(combophy->dev, "External clock enable failed %d\n", ret);
>> +			clk_disable_unprepare(combophy->ker_clk);
>> +			clk_disable_unprepare(combophy->phy_clk);
>> +			return ret;
>> +		}
>> +	}
> 
> Can you use bulk_prepare for this?

Yes, need a twist a little bit to handle optional and required clocks 
together but that's better.

thanks,

Christian
> 


From biju.das.jz at bp.renesas.com  Tue Sep  3 06:09:01 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Tue, 3 Sep 2024 13:09:01 +0000
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <5bcdc677-e61e-4312-a19b-57b4600685d3@tuxon.dev>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <fbfa9179-2f52-429f-8b69-f7f4064e796b@tuxon.dev>
 <TYCPR01MB11332EF1A8D064C491D8F261286932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <f7c57e76-b890-491f-880d-62d060b7b31e@tuxon.dev>
 <TYCPR01MB11332BE2EDB318950B9C7B54C86932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <TY3PR01MB113469FC8A9F49D9B1FA432FD86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <0b73544b-0253-43b9-b631-6578b48eaca8@tuxon.dev>
 <TY3PR01MB1134689573A785E91A9041E1886932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5bcdc677-e61e-4312-a19b-57b4600685d3@tuxon.dev>
Message-ID: <TY3PR01MB11346FAC6022C81ED8B9B2DC386932@TY3PR01MB11346.jpnprd01.prod.outlook.com>

Hi Claudiu,

> -----Original Message-----
> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> Sent: Tuesday, September 3, 2024 1:57 PM
-
> clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
> 
> 
> 
> On 03.09.2024 15:37, Biju Das wrote:
> >
> >
> >> -----Original Message-----
> >> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> >> Sent: Tuesday, September 3, 2024 1:26 PM
> >> To: Biju Das <biju.das.jz at bp.renesas.com>; Ulf Hansson
> >> <ulf.hansson at linaro.org>
> >> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> >> krzk+dt at kernel.org; conor+dt at kernel.org; p.zabel at pengutronix.de;
> >> geert+renesas at glider.be; magnus.damm at gmail.com;
> >> gregkh at linuxfoundation.org; mturquette at baylibre.com;
> >> sboyd at kernel.org; Yoshihiro Shimoda
> >> <yoshihiro.shimoda.uh at renesas.com>;
> >> linux-phy at lists.infradead.org; devicetree at vger.kernel.org;
> >> linux-kernel at vger.kernel.org; linux- renesas-soc at vger.kernel.org;
> >> linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> >> linux- clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu Beznea
> >> <claudiu.beznea.uj at bp.renesas.com>
> >> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
> >> RZ/G3S SoC
> >>
> >>
> >>
> >> On 03.09.2024 15:00, Biju Das wrote:
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Biju Das <biju.das.jz at bp.renesas.com>
> >>>> Sent: Tuesday, September 3, 2024 12:07 PM
> >>>> To: Claudiu.Beznea <claudiu.beznea at tuxon.dev>; Ulf Hansson
> >>>> <ulf.hansson at linaro.org>
> >>>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> >>>> krzk+dt at kernel.org; conor+dt at kernel.org; p.zabel at pengutronix.de;
> >>>> geert+renesas at glider.be; magnus.damm at gmail.com;
> >>>> gregkh at linuxfoundation.org; mturquette at baylibre.com;
> >>>> sboyd at kernel.org; Yoshihiro Shimoda
> >>>> <yoshihiro.shimoda.uh at renesas.com>;
> >>>> linux-phy at lists.infradead.org; devicetree at vger.kernel.org;
> >>>> linux-kernel at vger.kernel.org; linux- renesas-soc at vger.kernel.org;
> >>>> linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> >>>> linux- clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu
> >>>> Beznea <claudiu.beznea.uj at bp.renesas.com>
> >>>> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas
> >>>> RZ/G3S SoC
> >>>>
> >>>> Hi Claudiu,
> >>>>
> >>>>> -----Original Message-----
> >>>>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> >>>>> Sent: Tuesday, September 3, 2024 12:00 PM
> >>>>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
> >>>>> RZ/G3S SoC
> >>>>>
> >>>>>
> >>>>>
> >>>>> On 03.09.2024 13:31, Biju Das wrote:
> >>>>>>>> During boot clr USB PWR READY signal in TF-A.
> >>>>>>>> STR case, suspend set USB PWR READY signal in TF-A.
> >>>>>>>> STR case, resume clr USB PWR READY signal in TF-A.
> >>>>>>> As I said previously, it can be done in different ways. My point
> >>>>>>> was to let Linux set what it needs for all it's devices to work.
> >>>>>>> I think the way to go forward is a
> >>>>> maintainer decision.
> >>>>>>
> >>>>>> I agree, there can be n number of solution for a problem.
> >>>>>>
> >>>>>> Since you modelled system state signal (USB PWRRDY) as reset
> >>>>>> control signal, it is reset/DT maintainer's decision to say the
> >>>>>> final word whether this signal fits in reset
> >>>>> system framework or not?
> >>>>>
> >>>>> I was thinking:
> >>>>> 1/ Geert would be the best to say if he considers it OK to handle this
> >>>>>    in Linux
> >>>>
> >>>> I agree Geert is the right person for taking SYSTEM decisions,
> >>>> since the signal is used only during state transitions (Table
> >>>> 41.6.4 AWO to ALL_ON and 41.6.3 ALL_ON to AWO)
> >>>
> >>> One more info, as per [1], this USB PWRRDY signal setting to be before Linux kernel boots.
> >>
> >> The "controlled by" column mentions CA-55 on PWRRDY signal control
> >> line and it is b/w steps "DDR exits from retention mode" and  "clock
> >> start settings for system bus and peripheral modules". AFAICT, after DDR exists retention mode
> Linux is ready to run.
> >
> > DDR retention exit happens in TF-A and it jumps into reset code where it executes BL2 in TF_A. Bl2
> checks for warm or cold reset.
> > If it is warm reset, it sets required minimal clocks/resets and pass
> > the control to linux by calling the SMC callback handler. Which in turn calls resume(step 11-->14)
> path.
> 
> Is this from HW manual or some specific documentation? I'm referring at "resume" == "steps 11-->14"
> 
> >
> > Step 8, Cortex-A55 Exit from DDR retention mode (when using) Setting
> > for exiting form DDR retention mode Step 9, Cortex-A55 USB PHY PWRRDY
> > signal control (if use USB) SYS_USB_PWRRDY Step 10, Cortex-A55 PCIe
> > RST_RSM_B signal control (if use PCIe) SYS_PCIE_RST_RSM_B
> 
> Note *if use*: how does the TF-A know if USB/PCIe is used by Linux? The documentation mention to set
> it *if use*. Same note is on ALL_ON to VBATT transition documentation (namely "if using USB", "if
> using PCIe"). If TF-A will do this it should set this signals unconditionally. It will not be
> something wrong though. We don't know at the moment what this involves in terms of power consumption,
> if it means something...

You mean, you modelled this as reset signal just to reduce power consumption by calling runtime PM
calls to turn on/off this signal??

Does will it have any system stability issue as hardware manual says to do it at very early stage
before starting any clocks/resets?? Have you checked with hardware team?

Cheers,
Biju

From peda at axentia.se  Tue Sep  3 06:17:14 2024
From: peda at axentia.se (Peter Rosin)
Date: Tue, 3 Sep 2024 15:17:14 +0200
Subject: [PATCH v4 04/18] mux: add mux_chip_resume() function
In-Reply-To: <20240102-j7200-pcie-s2r-v4-4-6f1f53390c85@bootlin.com>
References: <20240102-j7200-pcie-s2r-v4-0-6f1f53390c85@bootlin.com>
 <20240102-j7200-pcie-s2r-v4-4-6f1f53390c85@bootlin.com>
Message-ID: <dd42f526-6da7-87f8-ad4c-bf18af41c665@axentia.se>

Hi!

Sorry for being unresponsive.

2024-03-04 at 16:35, Thomas Richard wrote:
> The mux_chip_resume() function restores a mux_chip using the cached state
> of each mux.
> 
> Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
> ---
>  drivers/mux/core.c         | 29 +++++++++++++++++++++++++++++
>  include/linux/mux/driver.h |  1 +
>  2 files changed, 30 insertions(+)
> 
> diff --git a/drivers/mux/core.c b/drivers/mux/core.c
> index 775816112932..0742aa2a7c73 100644
> --- a/drivers/mux/core.c
> +++ b/drivers/mux/core.c
> @@ -215,6 +215,35 @@ void mux_chip_free(struct mux_chip *mux_chip)
>  }
>  EXPORT_SYMBOL_GPL(mux_chip_free);
>  
> +/**
> + * mux_chip_resume() - restores the mux-chip state
> + * @mux_chip: The mux-chip to resume.
> + *
> + * Restores the mux-chip state.
> + *
> + * Return: Zero on success or a negative errno on error.
> + */
> +int mux_chip_resume(struct mux_chip *mux_chip)
> +{
> +	int ret, i;
> +
> +	for (i = 0; i < mux_chip->controllers; ++i) {
> +		struct mux_control *mux = &mux_chip->mux[i];
> +
> +		if (mux->cached_state == MUX_CACHE_UNKNOWN)
> +			continue;
> +
> +		ret = mux_control_set(mux, mux->cached_state);

mux_control_set() is an internal helper. It is called from
__mux_control_select() and mux_control_deselect() (and on init...)

In all those cases, there is no race to reach the mux_control_set()
function, by means of the mux->lock semaphore (or the mux not being
"published" yet).

I fail to see how resume is safe when mux->lock is ignored?

Cheers,
Peter

> +		if (ret < 0) {
> +			dev_err(&mux_chip->dev, "unable to restore state\n");
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(mux_chip_resume);
> +
>  static void devm_mux_chip_release(struct device *dev, void *res)
>  {
>  	struct mux_chip *mux_chip = *(struct mux_chip **)res;
> diff --git a/include/linux/mux/driver.h b/include/linux/mux/driver.h
> index 18824064f8c0..2a7e5ec5d540 100644
> --- a/include/linux/mux/driver.h
> +++ b/include/linux/mux/driver.h
> @@ -88,6 +88,7 @@ struct mux_chip *mux_chip_alloc(struct device *dev,
>  int mux_chip_register(struct mux_chip *mux_chip);
>  void mux_chip_unregister(struct mux_chip *mux_chip);
>  void mux_chip_free(struct mux_chip *mux_chip);
> +int mux_chip_resume(struct mux_chip *mux_chip);
>  
>  struct mux_chip *devm_mux_chip_alloc(struct device *dev,
>  				     unsigned int controllers,
> 


From biju.das.jz at bp.renesas.com  Tue Sep  3 06:45:04 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Tue, 3 Sep 2024 13:45:04 +0000
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <5bcdc677-e61e-4312-a19b-57b4600685d3@tuxon.dev>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <TY3PR01MB113464D53083F4C8A5DBBA36586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <590a4fb2-24b2-432b-92db-534c5a52ed0b@tuxon.dev>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <fbfa9179-2f52-429f-8b69-f7f4064e796b@tuxon.dev>
 <TYCPR01MB11332EF1A8D064C491D8F261286932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <f7c57e76-b890-491f-880d-62d060b7b31e@tuxon.dev>
 <TYCPR01MB11332BE2EDB318950B9C7B54C86932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <TY3PR01MB113469FC8A9F49D9B1FA432FD86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <0b73544b-0253-43b9-b631-6578b48eaca8@tuxon.dev>
 <TY3PR01MB1134689573A785E91A9041E1886932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5bcdc677-e61e-4312-a19b-57b4600685d3@tuxon.dev>
Message-ID: <TY3PR01MB1134690F9D37E3BB4814D864386932@TY3PR01MB11346.jpnprd01.prod.outlook.com>

Hi Claudiu,

> -----Original Message-----
> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> Sent: Tuesday, September 3, 2024 1:57 PM
> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
> 
> 
> 
> On 03.09.2024 15:37, Biju Das wrote:
> >
> >
> >> -----Original Message-----
> >> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> >> Sent: Tuesday, September 3, 2024 1:26 PM
> >> To: Biju Das <biju.das.jz at bp.renesas.com>; Ulf Hansson
> >> <ulf.hansson at linaro.org>
> >> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> >> krzk+dt at kernel.org; conor+dt at kernel.org; p.zabel at pengutronix.de;
> >> geert+renesas at glider.be; magnus.damm at gmail.com;
> >> gregkh at linuxfoundation.org; mturquette at baylibre.com;
> >> sboyd at kernel.org; Yoshihiro Shimoda
> >> <yoshihiro.shimoda.uh at renesas.com>;
> >> linux-phy at lists.infradead.org; devicetree at vger.kernel.org;
> >> linux-kernel at vger.kernel.org; linux- renesas-soc at vger.kernel.org;
> >> linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> >> linux- clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu Beznea
> >> <claudiu.beznea.uj at bp.renesas.com>
> >> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
> >> RZ/G3S SoC
> >>
> >>
> >>
> >> On 03.09.2024 15:00, Biju Das wrote:
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Biju Das <biju.das.jz at bp.renesas.com>
> >>>> Sent: Tuesday, September 3, 2024 12:07 PM
> >>>> To: Claudiu.Beznea <claudiu.beznea at tuxon.dev>; Ulf Hansson
> >>>> <ulf.hansson at linaro.org>
> >>>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> >>>> krzk+dt at kernel.org; conor+dt at kernel.org; p.zabel at pengutronix.de;
> >>>> geert+renesas at glider.be; magnus.damm at gmail.com;
> >>>> gregkh at linuxfoundation.org; mturquette at baylibre.com;
> >>>> sboyd at kernel.org; Yoshihiro Shimoda
> >>>> <yoshihiro.shimoda.uh at renesas.com>;
> >>>> linux-phy at lists.infradead.org; devicetree at vger.kernel.org;
> >>>> linux-kernel at vger.kernel.org; linux- renesas-soc at vger.kernel.org;
> >>>> linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> >>>> linux- clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu
> >>>> Beznea <claudiu.beznea.uj at bp.renesas.com>
> >>>> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas
> >>>> RZ/G3S SoC
> >>>>
> >>>> Hi Claudiu,
> >>>>
> >>>>> -----Original Message-----
> >>>>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> >>>>> Sent: Tuesday, September 3, 2024 12:00 PM
> >>>>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
> >>>>> RZ/G3S SoC
> >>>>>
> >>>>>
> >>>>>
> >>>>> On 03.09.2024 13:31, Biju Das wrote:
> >>>>>>>> During boot clr USB PWR READY signal in TF-A.
> >>>>>>>> STR case, suspend set USB PWR READY signal in TF-A.
> >>>>>>>> STR case, resume clr USB PWR READY signal in TF-A.
> >>>>>>> As I said previously, it can be done in different ways. My point
> >>>>>>> was to let Linux set what it needs for all it's devices to work.
> >>>>>>> I think the way to go forward is a
> >>>>> maintainer decision.
> >>>>>>
> >>>>>> I agree, there can be n number of solution for a problem.
> >>>>>>
> >>>>>> Since you modelled system state signal (USB PWRRDY) as reset
> >>>>>> control signal, it is reset/DT maintainer's decision to say the
> >>>>>> final word whether this signal fits in reset
> >>>>> system framework or not?
> >>>>>
> >>>>> I was thinking:
> >>>>> 1/ Geert would be the best to say if he considers it OK to handle this
> >>>>>    in Linux
> >>>>
> >>>> I agree Geert is the right person for taking SYSTEM decisions,
> >>>> since the signal is used only during state transitions (Table
> >>>> 41.6.4 AWO to ALL_ON and 41.6.3 ALL_ON to AWO)
> >>>
> >>> One more info, as per [1], this USB PWRRDY signal setting to be before Linux kernel boots.
> >>
> >> The "controlled by" column mentions CA-55 on PWRRDY signal control
> >> line and it is b/w steps "DDR exits from retention mode" and  "clock
> >> start settings for system bus and peripheral modules". AFAICT, after DDR exists retention mode
> Linux is ready to run.
> >
> > DDR retention exit happens in TF-A and it jumps into reset code where it executes BL2 in TF_A. Bl2
> checks for warm or cold reset.
> > If it is warm reset, it sets required minimal clocks/resets and pass
> > the control to linux by calling the SMC callback handler. Which in turn calls resume(step 11-->14)
> path.
> 
> Is this from HW manual or some specific documentation? I'm referring at "resume" == "steps 11-->14"
> 
> >
> > Step 8, Cortex-A55 Exit from DDR retention mode (when using) Setting
> > for exiting form DDR retention mode Step 9, Cortex-A55 USB PHY PWRRDY
> > signal control (if use USB) SYS_USB_PWRRDY Step 10, Cortex-A55 PCIe
> > RST_RSM_B signal control (if use PCIe) SYS_PCIE_RST_RSM_B
> 
> Note *if use*: how does the TF-A know if USB/PCIe is used by Linux? The documentation mention to set
> it *if use*. Same note is on ALL_ON to VBATT transition documentation (namely "if using USB", "if
> using PCIe"). If TF-A will do this it should set this signals unconditionally. It will not be
> something wrong though. We don't know at the moment what this involves in terms of power consumption,
> if it means something...

IIUC,
The only information we have is,

"SYS_USB_PWRRDY and SYS_PCIE_RST_RSM_B are used when transition from ALL_ON to AWO (or from AWO to ALL_ON).
"When turning off USB PHY and PCIe PHY, if they are not controlled, PHY may break"

ALL_ON to AWO_MODE state transition: 
USB/PCIe are part of PD_ISOVCC power domain and before turning PD_ISOVCC to off,
we need to set USBPWRRDY signal.

AWO_MODE to ALL_ON state transition:

Turn on PD_ISOVCC first, then clr USBPWRRDY signal for USB usage in linux.

Maybe we need to ask hw team, exact usage of USBPWRRDY signal other than state transition.

Cheers,
Biju



From claudiu.beznea at tuxon.dev  Tue Sep  3 07:46:03 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Tue, 3 Sep 2024 17:46:03 +0300
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <TY3PR01MB11346FAC6022C81ED8B9B2DC386932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <fbfa9179-2f52-429f-8b69-f7f4064e796b@tuxon.dev>
 <TYCPR01MB11332EF1A8D064C491D8F261286932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <f7c57e76-b890-491f-880d-62d060b7b31e@tuxon.dev>
 <TYCPR01MB11332BE2EDB318950B9C7B54C86932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <TY3PR01MB113469FC8A9F49D9B1FA432FD86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <0b73544b-0253-43b9-b631-6578b48eaca8@tuxon.dev>
 <TY3PR01MB1134689573A785E91A9041E1886932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5bcdc677-e61e-4312-a19b-57b4600685d3@tuxon.dev>
 <TY3PR01MB11346FAC6022C81ED8B9B2DC386932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <7ffb6419-b8f0-4940-99d9-7779eec9bbb7@tuxon.dev>



On 03.09.2024 16:09, Biju Das wrote:
> Hi Claudiu,
> 
>> -----Original Message-----
>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>> Sent: Tuesday, September 3, 2024 1:57 PM
> -
>> clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
>>
>>
>>
>> On 03.09.2024 15:37, Biju Das wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>>>> Sent: Tuesday, September 3, 2024 1:26 PM
>>>> To: Biju Das <biju.das.jz at bp.renesas.com>; Ulf Hansson
>>>> <ulf.hansson at linaro.org>
>>>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
>>>> krzk+dt at kernel.org; conor+dt at kernel.org; p.zabel at pengutronix.de;
>>>> geert+renesas at glider.be; magnus.damm at gmail.com;
>>>> gregkh at linuxfoundation.org; mturquette at baylibre.com;
>>>> sboyd at kernel.org; Yoshihiro Shimoda
>>>> <yoshihiro.shimoda.uh at renesas.com>;
>>>> linux-phy at lists.infradead.org; devicetree at vger.kernel.org;
>>>> linux-kernel at vger.kernel.org; linux- renesas-soc at vger.kernel.org;
>>>> linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>>>> linux- clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu Beznea
>>>> <claudiu.beznea.uj at bp.renesas.com>
>>>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
>>>> RZ/G3S SoC
>>>>
>>>>
>>>>
>>>> On 03.09.2024 15:00, Biju Das wrote:
>>>>>
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Biju Das <biju.das.jz at bp.renesas.com>
>>>>>> Sent: Tuesday, September 3, 2024 12:07 PM
>>>>>> To: Claudiu.Beznea <claudiu.beznea at tuxon.dev>; Ulf Hansson
>>>>>> <ulf.hansson at linaro.org>
>>>>>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
>>>>>> krzk+dt at kernel.org; conor+dt at kernel.org; p.zabel at pengutronix.de;
>>>>>> geert+renesas at glider.be; magnus.damm at gmail.com;
>>>>>> gregkh at linuxfoundation.org; mturquette at baylibre.com;
>>>>>> sboyd at kernel.org; Yoshihiro Shimoda
>>>>>> <yoshihiro.shimoda.uh at renesas.com>;
>>>>>> linux-phy at lists.infradead.org; devicetree at vger.kernel.org;
>>>>>> linux-kernel at vger.kernel.org; linux- renesas-soc at vger.kernel.org;
>>>>>> linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>>>>>> linux- clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu
>>>>>> Beznea <claudiu.beznea.uj at bp.renesas.com>
>>>>>> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas
>>>>>> RZ/G3S SoC
>>>>>>
>>>>>> Hi Claudiu,
>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>>>>>>> Sent: Tuesday, September 3, 2024 12:00 PM
>>>>>>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
>>>>>>> RZ/G3S SoC
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 03.09.2024 13:31, Biju Das wrote:
>>>>>>>>>> During boot clr USB PWR READY signal in TF-A.
>>>>>>>>>> STR case, suspend set USB PWR READY signal in TF-A.
>>>>>>>>>> STR case, resume clr USB PWR READY signal in TF-A.
>>>>>>>>> As I said previously, it can be done in different ways. My point
>>>>>>>>> was to let Linux set what it needs for all it's devices to work.
>>>>>>>>> I think the way to go forward is a
>>>>>>> maintainer decision.
>>>>>>>>
>>>>>>>> I agree, there can be n number of solution for a problem.
>>>>>>>>
>>>>>>>> Since you modelled system state signal (USB PWRRDY) as reset
>>>>>>>> control signal, it is reset/DT maintainer's decision to say the
>>>>>>>> final word whether this signal fits in reset
>>>>>>> system framework or not?
>>>>>>>
>>>>>>> I was thinking:
>>>>>>> 1/ Geert would be the best to say if he considers it OK to handle this
>>>>>>>    in Linux
>>>>>>
>>>>>> I agree Geert is the right person for taking SYSTEM decisions,
>>>>>> since the signal is used only during state transitions (Table
>>>>>> 41.6.4 AWO to ALL_ON and 41.6.3 ALL_ON to AWO)
>>>>>
>>>>> One more info, as per [1], this USB PWRRDY signal setting to be before Linux kernel boots.
>>>>
>>>> The "controlled by" column mentions CA-55 on PWRRDY signal control
>>>> line and it is b/w steps "DDR exits from retention mode" and  "clock
>>>> start settings for system bus and peripheral modules". AFAICT, after DDR exists retention mode
>> Linux is ready to run.
>>>
>>> DDR retention exit happens in TF-A and it jumps into reset code where it executes BL2 in TF_A. Bl2
>> checks for warm or cold reset.
>>> If it is warm reset, it sets required minimal clocks/resets and pass
>>> the control to linux by calling the SMC callback handler. Which in turn calls resume(step 11-->14)
>> path.
>>
>> Is this from HW manual or some specific documentation? I'm referring at "resume" == "steps 11-->14"

You branched the discussion, there was at least this question that I've
asked you above that interested me.

>>
>>>
>>> Step 8, Cortex-A55 Exit from DDR retention mode (when using) Setting
>>> for exiting form DDR retention mode Step 9, Cortex-A55 USB PHY PWRRDY
>>> signal control (if use USB) SYS_USB_PWRRDY Step 10, Cortex-A55 PCIe
>>> RST_RSM_B signal control (if use PCIe) SYS_PCIE_RST_RSM_B
>>
>> Note *if use*: how does the TF-A know if USB/PCIe is used by Linux? The documentation mention to set
>> it *if use*. Same note is on ALL_ON to VBATT transition documentation (namely "if using USB", "if
>> using PCIe"). If TF-A will do this it should set this signals unconditionally. It will not be
>> something wrong though. We don't know at the moment what this involves in terms of power consumption,
>> if it means something...
> 
> You mean, you modelled this as reset signal just to reduce power consumption by calling runtime PM
> calls to turn on/off this signal??

In this series it is though a reset control driver.

The internal BSP propose the control of this signal though SMC calls in
each individual USB driver; I think the hardware team was checked for this;
I may be wrong, as I don't have this insight.

As you know, the initial control of these bits in the BSP was though SMC
calls and you propose to have a separate Linux driver to control this after
finding that these registers are accessible in normal world. As a result,
this series, with reset approach, which you were against, but I felt this
was the best way (I know) to describe the hardware and the relation b/w
hardware blocks. To conclude, you initially proposed me internally to have
it in Linux.

To answer your question, the answer is no, I didn't try to just model
something fancy just to be fancy. I did it based on what is proposed in BSP
as this may have been checked with hardware team and I did tests around
this. And considering this best describes the HW and the relation b/w
individual hardware blocks and in this way Linux can have at its hand all
the resources it needs w/o relying on third parties. And from the HW manual
description my understanding was that this is possible. I never said that
this solution is the best. I'm just adding information here as I requested
help from maintainers to guide on the proper direction.

You were adding information to sustain your TF-A idea, too.

> 
> Does will it have any system stability issue as hardware manual says to do it at very early stage
> before starting any clocks/resets?? Have you checked with hardware team?

All the implementation of this is based on what has been proposed on BSP,
the same approach was proposed there, meaning the control of these signals
was done on probe/remove, suspend/resume in Linux.


> 
> Cheers,
> Biju


From claudiu.beznea at tuxon.dev  Tue Sep  3 07:48:18 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Tue, 3 Sep 2024 17:48:18 +0300
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <TY3PR01MB1134690F9D37E3BB4814D864386932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <fbfa9179-2f52-429f-8b69-f7f4064e796b@tuxon.dev>
 <TYCPR01MB11332EF1A8D064C491D8F261286932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <f7c57e76-b890-491f-880d-62d060b7b31e@tuxon.dev>
 <TYCPR01MB11332BE2EDB318950B9C7B54C86932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <TY3PR01MB113469FC8A9F49D9B1FA432FD86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <0b73544b-0253-43b9-b631-6578b48eaca8@tuxon.dev>
 <TY3PR01MB1134689573A785E91A9041E1886932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5bcdc677-e61e-4312-a19b-57b4600685d3@tuxon.dev>
 <TY3PR01MB1134690F9D37E3BB4814D864386932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <d64243fe-48ea-4cb5-b6d6-e9f820e1b8a3@tuxon.dev>



On 03.09.2024 16:45, Biju Das wrote:
> Hi Claudiu,
> 
>> -----Original Message-----
>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>> Sent: Tuesday, September 3, 2024 1:57 PM
>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
>>
>>
>>
>> On 03.09.2024 15:37, Biju Das wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>>>> Sent: Tuesday, September 3, 2024 1:26 PM
>>>> To: Biju Das <biju.das.jz at bp.renesas.com>; Ulf Hansson
>>>> <ulf.hansson at linaro.org>
>>>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
>>>> krzk+dt at kernel.org; conor+dt at kernel.org; p.zabel at pengutronix.de;
>>>> geert+renesas at glider.be; magnus.damm at gmail.com;
>>>> gregkh at linuxfoundation.org; mturquette at baylibre.com;
>>>> sboyd at kernel.org; Yoshihiro Shimoda
>>>> <yoshihiro.shimoda.uh at renesas.com>;
>>>> linux-phy at lists.infradead.org; devicetree at vger.kernel.org;
>>>> linux-kernel at vger.kernel.org; linux- renesas-soc at vger.kernel.org;
>>>> linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>>>> linux- clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu Beznea
>>>> <claudiu.beznea.uj at bp.renesas.com>
>>>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
>>>> RZ/G3S SoC
>>>>
>>>>
>>>>
>>>> On 03.09.2024 15:00, Biju Das wrote:
>>>>>
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Biju Das <biju.das.jz at bp.renesas.com>
>>>>>> Sent: Tuesday, September 3, 2024 12:07 PM
>>>>>> To: Claudiu.Beznea <claudiu.beznea at tuxon.dev>; Ulf Hansson
>>>>>> <ulf.hansson at linaro.org>
>>>>>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
>>>>>> krzk+dt at kernel.org; conor+dt at kernel.org; p.zabel at pengutronix.de;
>>>>>> geert+renesas at glider.be; magnus.damm at gmail.com;
>>>>>> gregkh at linuxfoundation.org; mturquette at baylibre.com;
>>>>>> sboyd at kernel.org; Yoshihiro Shimoda
>>>>>> <yoshihiro.shimoda.uh at renesas.com>;
>>>>>> linux-phy at lists.infradead.org; devicetree at vger.kernel.org;
>>>>>> linux-kernel at vger.kernel.org; linux- renesas-soc at vger.kernel.org;
>>>>>> linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>>>>>> linux- clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu
>>>>>> Beznea <claudiu.beznea.uj at bp.renesas.com>
>>>>>> Subject: RE: [PATCH 00/16] Add initial USB support for the Renesas
>>>>>> RZ/G3S SoC
>>>>>>
>>>>>> Hi Claudiu,
>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
>>>>>>> Sent: Tuesday, September 3, 2024 12:00 PM
>>>>>>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
>>>>>>> RZ/G3S SoC
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 03.09.2024 13:31, Biju Das wrote:
>>>>>>>>>> During boot clr USB PWR READY signal in TF-A.
>>>>>>>>>> STR case, suspend set USB PWR READY signal in TF-A.
>>>>>>>>>> STR case, resume clr USB PWR READY signal in TF-A.
>>>>>>>>> As I said previously, it can be done in different ways. My point
>>>>>>>>> was to let Linux set what it needs for all it's devices to work.
>>>>>>>>> I think the way to go forward is a
>>>>>>> maintainer decision.
>>>>>>>>
>>>>>>>> I agree, there can be n number of solution for a problem.
>>>>>>>>
>>>>>>>> Since you modelled system state signal (USB PWRRDY) as reset
>>>>>>>> control signal, it is reset/DT maintainer's decision to say the
>>>>>>>> final word whether this signal fits in reset
>>>>>>> system framework or not?
>>>>>>>
>>>>>>> I was thinking:
>>>>>>> 1/ Geert would be the best to say if he considers it OK to handle this
>>>>>>>    in Linux
>>>>>>
>>>>>> I agree Geert is the right person for taking SYSTEM decisions,
>>>>>> since the signal is used only during state transitions (Table
>>>>>> 41.6.4 AWO to ALL_ON and 41.6.3 ALL_ON to AWO)
>>>>>
>>>>> One more info, as per [1], this USB PWRRDY signal setting to be before Linux kernel boots.
>>>>
>>>> The "controlled by" column mentions CA-55 on PWRRDY signal control
>>>> line and it is b/w steps "DDR exits from retention mode" and  "clock
>>>> start settings for system bus and peripheral modules". AFAICT, after DDR exists retention mode
>> Linux is ready to run.
>>>
>>> DDR retention exit happens in TF-A and it jumps into reset code where it executes BL2 in TF_A. Bl2
>> checks for warm or cold reset.
>>> If it is warm reset, it sets required minimal clocks/resets and pass
>>> the control to linux by calling the SMC callback handler. Which in turn calls resume(step 11-->14)
>> path.
>>
>> Is this from HW manual or some specific documentation? I'm referring at "resume" == "steps 11-->14"
>>
>>>
>>> Step 8, Cortex-A55 Exit from DDR retention mode (when using) Setting
>>> for exiting form DDR retention mode Step 9, Cortex-A55 USB PHY PWRRDY
>>> signal control (if use USB) SYS_USB_PWRRDY Step 10, Cortex-A55 PCIe
>>> RST_RSM_B signal control (if use PCIe) SYS_PCIE_RST_RSM_B
>>
>> Note *if use*: how does the TF-A know if USB/PCIe is used by Linux? The documentation mention to set
>> it *if use*. Same note is on ALL_ON to VBATT transition documentation (namely "if using USB", "if
>> using PCIe"). If TF-A will do this it should set this signals unconditionally. It will not be
>> something wrong though. We don't know at the moment what this involves in terms of power consumption,
>> if it means something...
> 
> IIUC,
> The only information we have is,
> 
> "SYS_USB_PWRRDY and SYS_PCIE_RST_RSM_B are used when transition from ALL_ON to AWO (or from AWO to ALL_ON).
> "When turning off USB PHY and PCIe PHY, if they are not controlled, PHY may break"
> 
> ALL_ON to AWO_MODE state transition: 
> USB/PCIe are part of PD_ISOVCC power domain and before turning PD_ISOVCC to off,
> we need to set USBPWRRDY signal.
> 
> AWO_MODE to ALL_ON state transition:
> 
> Turn on PD_ISOVCC first, then clr USBPWRRDY signal for USB usage in linux.
> 
> Maybe we need to ask hw team, exact usage of USBPWRRDY signal other than state transition.

As you may already know, this is open for quite some time and is ongoing.

> 
> Cheers,
> Biju
> 
> 


From robh at kernel.org  Tue Sep  3 07:52:47 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 3 Sep 2024 09:52:47 -0500
Subject: [PATCH v5 1/5] dt-bindings: phy: Add STM32MP25 COMBOPHY bindings
In-Reply-To: <20240903121303.2953150-2-christian.bruel@foss.st.com>
References: <20240903121303.2953150-1-christian.bruel@foss.st.com>
 <20240903121303.2953150-2-christian.bruel@foss.st.com>
Message-ID: <172537516622.996858.7295101990196127870.robh@kernel.org>


On Tue, 03 Sep 2024 14:12:59 +0200, Christian Bruel wrote:
> Document the bindings for STM32 COMBOPHY interface, used to support
> the PCIe and USB3 stm32mp25 drivers.
> Following entries can be used to tune caracterisation parameters
>  - st,output-micro-ohms and st,output-vswing-microvolt bindings entries
> to tune the impedance and voltage swing using discrete simulation results
>  - st,rx-equalizer register to set the internal rx equalizer filter value.
> 
> Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
> ---
>  .../bindings/phy/st,stm32mp25-combophy.yaml   | 119 ++++++++++++++++++
>  1 file changed, 119 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
> 

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>



From biju.das.jz at bp.renesas.com  Tue Sep  3 08:30:43 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Tue, 3 Sep 2024 15:30:43 +0000
Subject: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <7ffb6419-b8f0-4940-99d9-7779eec9bbb7@tuxon.dev>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <TY3PR01MB11346505565B81AD2894E035586922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <35dc7414-f5bd-4ed4-bfa1-f723f4f0078c@tuxon.dev>
 <TY3PR01MB11346A4814F83FE296A1DED8886922@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <TY3PR01MB1134648BF51F1B52BFE34DD6D86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <fbfa9179-2f52-429f-8b69-f7f4064e796b@tuxon.dev>
 <TYCPR01MB11332EF1A8D064C491D8F261286932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <f7c57e76-b890-491f-880d-62d060b7b31e@tuxon.dev>
 <TYCPR01MB11332BE2EDB318950B9C7B54C86932@TYCPR01MB11332.jpnprd01.prod.outlook.com>
 <TY3PR01MB113469FC8A9F49D9B1FA432FD86932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <0b73544b-0253-43b9-b631-6578b48eaca8@tuxon.dev>
 <TY3PR01MB1134689573A785E91A9041E1886932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <5bcdc677-e61e-4312-a19b-57b4600685d3@tuxon.dev>
 <TY3PR01MB11346FAC6022C81ED8B9B2DC386932@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <7ffb6419-b8f0-4940-99d9-7779eec9bbb7@tuxon.dev>
Message-ID: <TY3PR01MB11346676D07F8434BBD68E62786932@TY3PR01MB11346.jpnprd01.prod.outlook.com>


Hi Claudiu,

> -----Original Message-----
> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> Sent: Tuesday, September 3, 2024 3:46 PM


> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas RZ/G3S SoC
> 
> 
> 
> On 03.09.2024 16:09, Biju Das wrote:
> > Hi Claudiu,
> >
> >> -----Original Message-----
> >> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> >> Sent: Tuesday, September 3, 2024 1:57 PM
> > -
> >> clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu Beznea
> >> <claudiu.beznea.uj at bp.renesas.com>
> >> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
> >> RZ/G3S SoC
> >>
> >>
> >>
> >> On 03.09.2024 15:37, Biju Das wrote:
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> >>>> Sent: Tuesday, September 3, 2024 1:26 PM
> >>>> To: Biju Das <biju.das.jz at bp.renesas.com>; Ulf Hansson
> >>>> <ulf.hansson at linaro.org>
> >>>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> >>>> krzk+dt at kernel.org; conor+dt at kernel.org; p.zabel at pengutronix.de;
> >>>> geert+renesas at glider.be; magnus.damm at gmail.com;
> >>>> gregkh at linuxfoundation.org; mturquette at baylibre.com;
> >>>> sboyd at kernel.org; Yoshihiro Shimoda
> >>>> <yoshihiro.shimoda.uh at renesas.com>;
> >>>> linux-phy at lists.infradead.org; devicetree at vger.kernel.org;
> >>>> linux-kernel at vger.kernel.org; linux- renesas-soc at vger.kernel.org;
> >>>> linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> >>>> linux- clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu
> >>>> Beznea <claudiu.beznea.uj at bp.renesas.com>
> >>>> Subject: Re: [PATCH 00/16] Add initial USB support for the Renesas
> >>>> RZ/G3S SoC
> >>>>
> >>>>
> >>>>
> >>>> On 03.09.2024 15:00, Biju Das wrote:
> >>>>>
> >>>>>
> >>>>>> -----Original Message-----
> >>>>>> From: Biju Das <biju.das.jz at bp.renesas.com>
> >>>>>> Sent: Tuesday, September 3, 2024 12:07 PM
> >>>>>> To: Claudiu.Beznea <claudiu.beznea at tuxon.dev>; Ulf Hansson
> >>>>>> <ulf.hansson at linaro.org>
> >>>>>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> >>>>>> krzk+dt at kernel.org; conor+dt at kernel.org; p.zabel at pengutronix.de;
> >>>>>> geert+renesas at glider.be; magnus.damm at gmail.com;
> >>>>>> gregkh at linuxfoundation.org; mturquette at baylibre.com;
> >>>>>> sboyd at kernel.org; Yoshihiro Shimoda
> >>>>>> <yoshihiro.shimoda.uh at renesas.com>;
> >>>>>> linux-phy at lists.infradead.org; devicetree at vger.kernel.org;
> >>>>>> linux-kernel at vger.kernel.org; linux- renesas-soc at vger.kernel.org;
> >>>>>> linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> >>>>>> linux- clk at vger.kernel.org; linux-pm at vger.kernel.org; Claudiu
> >>>>>> Beznea <claudiu.beznea.uj at bp.renesas.com>
> >>>>>> Subject: RE: [PATCH 00/16] Add initial USB support for the
> >>>>>> Renesas RZ/G3S SoC
> >>>>>>
> >>>>>> Hi Claudiu,
> >>>>>>
> >>>>>>> -----Original Message-----
> >>>>>>> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> >>>>>>> Sent: Tuesday, September 3, 2024 12:00 PM
> >>>>>>> Subject: Re: [PATCH 00/16] Add initial USB support for the
> >>>>>>> Renesas RZ/G3S SoC
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> On 03.09.2024 13:31, Biju Das wrote:
> >>>>>>>>>> During boot clr USB PWR READY signal in TF-A.
> >>>>>>>>>> STR case, suspend set USB PWR READY signal in TF-A.
> >>>>>>>>>> STR case, resume clr USB PWR READY signal in TF-A.
> >>>>>>>>> As I said previously, it can be done in different ways. My
> >>>>>>>>> point was to let Linux set what it needs for all it's devices to work.
> >>>>>>>>> I think the way to go forward is a
> >>>>>>> maintainer decision.
> >>>>>>>>
> >>>>>>>> I agree, there can be n number of solution for a problem.
> >>>>>>>>
> >>>>>>>> Since you modelled system state signal (USB PWRRDY) as reset
> >>>>>>>> control signal, it is reset/DT maintainer's decision to say the
> >>>>>>>> final word whether this signal fits in reset
> >>>>>>> system framework or not?
> >>>>>>>
> >>>>>>> I was thinking:
> >>>>>>> 1/ Geert would be the best to say if he considers it OK to handle this
> >>>>>>>    in Linux
> >>>>>>
> >>>>>> I agree Geert is the right person for taking SYSTEM decisions,
> >>>>>> since the signal is used only during state transitions (Table
> >>>>>> 41.6.4 AWO to ALL_ON and 41.6.3 ALL_ON to AWO)
> >>>>>
> >>>>> One more info, as per [1], this USB PWRRDY signal setting to be before Linux kernel boots.
> >>>>
> >>>> The "controlled by" column mentions CA-55 on PWRRDY signal control
> >>>> line and it is b/w steps "DDR exits from retention mode" and
> >>>> "clock start settings for system bus and peripheral modules".
> >>>> AFAICT, after DDR exists retention mode
> >> Linux is ready to run.
> >>>
> >>> DDR retention exit happens in TF-A and it jumps into reset code
> >>> where it executes BL2 in TF_A. Bl2
> >> checks for warm or cold reset.
> >>> If it is warm reset, it sets required minimal clocks/resets and pass
> >>> the control to linux by calling the SMC callback handler. Which in
> >>> turn calls resume(step 11-->14)
> >> path.
> >>
> >> Is this from HW manual or some specific documentation? I'm referring at "resume" == "steps 11-->14"
> 
> You branched the discussion, there was at least this question that I've asked you above that
> interested me.

if there is DDR retention exit involved,
Step 11->14 is just like resume path, for each IP it need clock , reset and restore registers from DDR backup.

> 
> >>
> >>>
> >>> Step 8, Cortex-A55 Exit from DDR retention mode (when using) Setting
> >>> for exiting form DDR retention mode Step 9, Cortex-A55 USB PHY
> >>> PWRRDY signal control (if use USB) SYS_USB_PWRRDY Step 10,
> >>> Cortex-A55 PCIe RST_RSM_B signal control (if use PCIe)
> >>> SYS_PCIE_RST_RSM_B
> >>
> >> Note *if use*: how does the TF-A know if USB/PCIe is used by Linux?
> >> The documentation mention to set it *if use*. Same note is on ALL_ON
> >> to VBATT transition documentation (namely "if using USB", "if using
> >> PCIe"). If TF-A will do this it should set this signals
> >> unconditionally. It will not be something wrong though. We don't know at the moment what this
> involves in terms of power consumption, if it means something...
> >
> > You mean, you modelled this as reset signal just to reduce power
> > consumption by calling runtime PM calls to turn on/off this signal??
> 
> In this series it is though a reset control driver.
> 
> The internal BSP propose the control of this signal though SMC calls in each individual USB driver; I
> think the hardware team was checked for this; I may be wrong, as I don't have this insight.
> 
> As you know, the initial control of these bits in the BSP was though SMC calls and you propose to have
> a separate Linux driver to control this after finding that these registers are accessible in normal
> world. As a result, this series, with reset approach, which you were against, but I felt this was the
> best way (I know) to describe the hardware and the relation b/w hardware blocks. To conclude, you
> initially proposed me internally to have it in Linux.

I agree, I proposed to have Linux SYSC driver instead of calling SMC calls from PHY control driver(Reset)

Currently we explored 4 approaches to avoid SMC calls from PHY control driver.

1) modelling this as reset signal
2) power domain approach 
3) set this in SYSC driver during early boot.
4) handle this in TF-A.

> 
> To answer your question, the answer is no, I didn't try to just model something fancy just to be
> fancy. I did it based on what is proposed in BSP as this may have been checked with hardware team and
> I did tests around this. And considering this best describes the HW and the relation b/w individual
> hardware blocks and in this way Linux can have at its hand all the resources it needs w/o relying on
> third parties. And from the HW manual description my understanding was that this is possible. I never
> said that this solution is the best. I'm just adding information here as I requested help from
> maintainers to guide on the proper direction.
> 
> You were adding information to sustain your TF-A idea, too.

This is just an option based on the hardware manual tables where SYSC signal is turned on 
just after DDR retention exit and before starting the clocks/resets.

> 
> >
> > Does will it have any system stability issue as hardware manual says
> > to do it at very early stage before starting any clocks/resets?? Have you checked with hardware
> team?
> 
> All the implementation of this is based on what has been proposed on BSP, the same approach was
> proposed there, meaning the control of these signals was done on probe/remove, suspend/resume in
> Linux.

Based on Hardware manual state transition tables, USBPWRRDY signal is set before starting clocks/reset of the IPs.
If there is no stability issue with BSP approach, then there is no harm in what you have implemented.

Cheers,
Biju


From lkp at intel.com  Tue Sep  3 10:50:57 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 4 Sep 2024 01:50:57 +0800
Subject: [PATCH v2] phy: mvebu-cp110-utmi: support swapping d+/d- lanes
 by dts property
In-Reply-To: <20240903-mvebu-utmi-phy-v2-1-7f49c131fad0@solid-run.com>
References: <20240903-mvebu-utmi-phy-v2-1-7f49c131fad0@solid-run.com>
Message-ID: <202409040139.hNh9K4iF-lkp@intel.com>

Hi Josua,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 8400291e289ee6b2bf9779ff1c83a291501f017b]

url:    https://github.com/intel-lab-lkp/linux/commits/Josua-Mayer/phy-mvebu-cp110-utmi-support-swapping-d-d-lanes-by-dts-property/20240903-164826
base:   8400291e289ee6b2bf9779ff1c83a291501f017b
patch link:    https://lore.kernel.org/r/20240903-mvebu-utmi-phy-v2-1-7f49c131fad0%40solid-run.com
patch subject: [PATCH v2] phy: mvebu-cp110-utmi: support swapping d+/d- lanes by dts property
config: arc-randconfig-r071-20240903 (https://download.01.org/0day-ci/archive/20240904/202409040139.hNh9K4iF-lkp at intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240904/202409040139.hNh9K4iF-lkp at 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 at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409040139.hNh9K4iF-lkp at intel.com/

All warnings (new ones prefixed by >>):

>> drivers/phy/marvell/phy-mvebu-cp110-utmi.c:110: warning: Function parameter or struct member 'swap_dx' not described in 'mvebu_cp110_utmi_port'


vim +110 drivers/phy/marvell/phy-mvebu-cp110-utmi.c

2fc989f74b8dac Konstantin Porotchkin 2021-03-07   97  
2fc989f74b8dac Konstantin Porotchkin 2021-03-07   98  /**
2fc989f74b8dac Konstantin Porotchkin 2021-03-07   99   * struct mvebu_cp110_utmi_port - PHY port data
2fc989f74b8dac Konstantin Porotchkin 2021-03-07  100   *
2fc989f74b8dac Konstantin Porotchkin 2021-03-07  101   * @priv: PHY driver data
2fc989f74b8dac Konstantin Porotchkin 2021-03-07  102   * @id: PHY port ID
2fc989f74b8dac Konstantin Porotchkin 2021-03-07  103   * @dr_mode: PHY connection: USB_DR_MODE_HOST or USB_DR_MODE_PERIPHERAL
2fc989f74b8dac Konstantin Porotchkin 2021-03-07  104   */
2fc989f74b8dac Konstantin Porotchkin 2021-03-07  105  struct mvebu_cp110_utmi_port {
2fc989f74b8dac Konstantin Porotchkin 2021-03-07  106  	struct mvebu_cp110_utmi *priv;
2fc989f74b8dac Konstantin Porotchkin 2021-03-07  107  	u32 id;
2fc989f74b8dac Konstantin Porotchkin 2021-03-07  108  	enum usb_dr_mode dr_mode;
7208af25e8a67e Josua Mayer           2024-09-03  109  	bool swap_dx;
2fc989f74b8dac Konstantin Porotchkin 2021-03-07 @110  };
2fc989f74b8dac Konstantin Porotchkin 2021-03-07  111  

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


From sebastian.reichel at collabora.com  Tue Sep  3 14:57:58 2024
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Tue, 03 Sep 2024 23:57:58 +0200
Subject: [PATCH 0/6] power: supply: Change usb_types from an array into
 a bitmask
In-Reply-To: <20240831142039.28830-1-hdegoede@redhat.com>
References: <20240831142039.28830-1-hdegoede@redhat.com>
Message-ID: <172540067821.972525.3472424402904819549.b4-ty@collabora.com>


On Sat, 31 Aug 2024 16:20:33 +0200, Hans de Goede wrote:
> When support for the "charge_behaviour" property was added the list of
> available values was made a bitmask in power_supply_desc.
> 
> "usb_types" is very similar in that:
> 1. It is an enum
> 2. The list of available values is stored in power_supply_desc
> 3. When shown it shows all available values, with the active one surrounded
>    by square brackets.
> 
> [...]

Applied, thanks!

[1/6] power: supply: "usb_type" property may be written to
      commit: 0d9af1e1c93b6a89f3fb6dcbafa5bc78892cb94f
[2/6] power: supply: ucs1002: Adjust ucs1002_set_usb_type() to accept string values
      commit: 83a4c42df75e8f6ff671fa9fbe7d4c79b98626de
[3/6] power: supply: rt9467-charger: Remove "usb_type" property write support
      commit: 03ec41c1670aedfbd126f541c4acbb8e69d4cd0c
[4/6] power: supply: sysfs: Add power_supply_show_enum_with_available() helper
      commit: a6456d43e9abebb5d7866e5edae3024188273306
[5/6] power: supply: sysfs: Move power_supply_show_enum_with_available() up
      commit: 322900ac7d82be0475466f81946b6484cd1936bd
[6/6] power: supply: Change usb_types from an array into a bitmask
      commit: 364ea7ccaef917a3068236a19a4b31a0623b561a

Best regards,
-- 
Sebastian Reichel <sebastian.reichel at collabora.com>



From sre at kernel.org  Tue Sep  3 15:04:24 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Wed, 4 Sep 2024 00:04:24 +0200
Subject: [PATCH 0/6] power: supply: Change usb_types from an array into a
 bitmask
In-Reply-To: <20240831142039.28830-1-hdegoede@redhat.com>
References: <20240831142039.28830-1-hdegoede@redhat.com>
Message-ID: <ez5ja55dl7w7ynq2wv4efsvvqtk4xyalf4k6agtsuhpgrtlpg3@d6ghlle4cu2q>

Hi,

On Sat, Aug 31, 2024 at 04:20:33PM GMT, Hans de Goede wrote:
> When support for the "charge_behaviour" property was added the list of
> available values was made a bitmask in power_supply_desc.
> 
> "usb_types" is very similar in that:
> 1. It is an enum
> 2. The list of available values is stored in power_supply_desc
> 3. When shown it shows all available values, with the active one surrounded
>    by square brackets.
> 
> But "usb_types" uses an array with valid enum values instead of a bitmask.
> This uses more memory then the bitmap approach and it makes it impossible
> to have a shared generic show() function for properties which show
> available values, with the active one surrounded by square brackets.
> 
> This patch-set moves "usb_types" over to a bitmask in power_supply_desc
> to indicate the available values.
> 
> Patches 1 - 3:
> 
> It turns out that the ucs1002-power driver contained a surprise in that
> it supports writing to "usb_type" even though the ABI doc says it is
> read-only. Since we cannot break shipped userspace API, the ship has sailed
> on this one. The first patch documents that writing "usb_type" is allowed,
> but only for power-supply devices which provide USB power rather then
> consume it.
> 
> Enum properties accept writing the FOO_TEXT[] string values, passing
> the enum value matching the FOO_TEXT entry to set_property(), the second
> patch adjusts ucs1002_set_usb_type() to directly accept enum values.
> 
> The rt9467 driver was another driver which allowed writing to "usb_type"
> but there the use made no sense, so it is simply dropped.
> 
> Patches 4 - 6:
> 
> These patches implement the actual moving of usb_types to a bitmask.
> 
> Patch 6 is a bit of a bigbang patch moving all drivers over in one go,
> touching a couple of drivers outside drivers/power/supply: 1 in
> drivers/extcon/ 1 in drivers/phy/ and 5 in drivers/usb/typec/ since
> the changes outside of drivers/power/supply are small I've chosen to
> make all the changes in one go rather then have some sort of
> intermediate state where both ways are supported.
> 
> For merging this I believe it would be best for an immutable branch / tag
> to be created on the linux-power-supply tree and then send a pull-request
> to the extcon, phy and usb-typec maintainers to merge the tag.
> 
> extcon, phy and typec maintainers can you please give your Acked-by for
> patch 6/6 for merging these changes through the linux-power-supply tree?
> 
> This set is based on top of the latest linux-power-supply/for-next.

As we are quite close before the merge window I just took it with
just the Ack from Greg. The changes in PHY and Extcon are quite
small. I did prepare an immutable branch in case it is needed by
any of the other involved trees:

The following changes since commit 8400291e289ee6b2bf9779ff1c83a291501f017b:

  Linux 6.11-rc1 (2024-07-28 14:19:55 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git tags/ib-psy-usb-types-signed

for you to fetch changes up to 364ea7ccaef917a3068236a19a4b31a0623b561a:

  power: supply: Change usb_types from an array into a bitmask (2024-09-03 23:20:28 +0200)

----------------------------------------------------------------
Immutable branch for usb_types change for v6.12

Changing usb_types type from array to bitmap in the power_supply_desc
struct requires updating power-supply drivers living in different
subsystem, so it is handled via an immutable branch.

----------------------------------------------------------------
Hans de Goede (6):
      power: supply: "usb_type" property may be written to
      power: supply: ucs1002: Adjust ucs1002_set_usb_type() to accept string values
      power: supply: rt9467-charger: Remove "usb_type" property write support
      power: supply: sysfs: Add power_supply_show_enum_with_available() helper
      power: supply: sysfs: Move power_supply_show_enum_with_available() up
      power: supply: Change usb_types from an array into a bitmask

 Documentation/ABI/testing/sysfs-class-power     |  7 ++-
 drivers/extcon/extcon-intel-cht-wc.c            | 15 ++----
 drivers/phy/ti/phy-tusb1210.c                   | 11 ++---
 drivers/power/supply/axp20x_usb_power.c         | 13 ++---
 drivers/power/supply/bq256xx_charger.c          | 15 ++----
 drivers/power/supply/cros_usbpd-charger.c       | 22 +++------
 drivers/power/supply/lenovo_yoga_c630_battery.c |  7 +--
 drivers/power/supply/mp2629_charger.c           | 15 ++----
 drivers/power/supply/mt6360_charger.c           | 13 ++---
 drivers/power/supply/mt6370-charger.c           | 13 ++---
 drivers/power/supply/power_supply_core.c        |  4 --
 drivers/power/supply/power_supply_sysfs.c       | 66 ++++++++-----------------
 drivers/power/supply/qcom_battmgr.c             | 37 +++++++-------
 drivers/power/supply/qcom_pmi8998_charger.c     | 13 ++---
 drivers/power/supply/rk817_charger.c            |  9 +---
 drivers/power/supply/rn5t618_power.c            | 13 ++---
 drivers/power/supply/rt9467-charger.c           | 16 ++----
 drivers/power/supply/rt9471.c                   | 15 ++----
 drivers/power/supply/ucs1002_power.c            | 26 +++++-----
 drivers/usb/typec/anx7411.c                     | 11 ++---
 drivers/usb/typec/rt1719.c                      | 11 ++---
 drivers/usb/typec/tcpm/tcpm.c                   | 11 ++---
 drivers/usb/typec/tipd/core.c                   |  9 +---
 drivers/usb/typec/ucsi/psy.c                    | 11 ++---
 include/linux/power_supply.h                    |  3 +-
 25 files changed, 132 insertions(+), 254 deletions(-)

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20240904/5691d401/attachment.sig>

From aford173 at gmail.com  Tue Sep  3 19:32:39 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue,  3 Sep 2024 21:32:39 -0500
Subject: [PATCH V5 0/5] phy: freescale: fsl-samsung-hdmi: Expand phy clock options
Message-ID: <20240904023310.163371-1-aford173@gmail.com>


Currently, there is a look-up-table to describe all the clock options the HDMI PHY
can use.  Some of these entries in the LUT are using a fractional divider which does
not have a well documented algorithm for determinging values, but the the integer
divider can use an algorithm to calculate the integer divder values dynamically
beyond those listed in the LUT and also duplicates some of the entries.

The first two patches do not do anything functionally other than simplify
some of the register accesses and de-duplicates some of the register look-ups.

The third patch adds support for the integer divider and uses it whenever the
clock request is an exact match.  Otherwise, it will use the LUT as before.
The rouding is still based on the LUT if the integer clock isn't an exact match.

The forth patch updates thes set_rate and round_rate functions to use either
the fractional clock LUT or the the integer divder mechanism to determine
which ever clock rate might be closest match.

The last patch removes the integer divider entries from the LUT since by then
it'll be comparing both the integer divider calculator and the closest value
in the LUT.

In my testing with a AOC 4K monitor, I was able to add 4 entries in my modetest
table.  I do not have an HDMI analyzer, so I just used my monitor to determine
if this series worked.

Adam Ford (5):
  phy: freescale: fsl-samsung-hdmi: Replace register defines with macro
  phy: freescale: fsl-samsung-hdmi: Simplify REG21_PMS_S_MASK lookup
  phy: freescale: fsl-samsung-hdmi: Support dynamic integer
  phy: freescale: fsl-samsung-hdmi: Use closest divider
  phy: freescale: fsl-samsung-hdmi: Remove unnecessary LUT entries

 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 570 ++++++++++---------
 1 file changed, 293 insertions(+), 277 deletions(-)

  V5 Updates patch 1 of 5 for whitespace and comment updates
      Patches 1 and 2 add RB tags
      No functional changes from V4
-- 
2.43.0



From aford173 at gmail.com  Tue Sep  3 19:32:40 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue,  3 Sep 2024 21:32:40 -0500
Subject: [PATCH V5 1/5] phy: freescale: fsl-samsung-hdmi: Replace register defines with macro
In-Reply-To: <20240904023310.163371-1-aford173@gmail.com>
References: <20240904023310.163371-1-aford173@gmail.com>
Message-ID: <20240904023310.163371-2-aford173@gmail.com>

There are 47 registers defined as PHY_REG_xx were xx goes from 00 to
47.  Simplify this by replacing them all with a macro which is passed
the register number to return the proper register offset.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
---
V5:  Restore comment about REG33.
     Add spacing between the REG entries to easier readability
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 133 ++++++-------------
 1 file changed, 43 insertions(+), 90 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 9048cdc760c2..acea7008aefc 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -14,76 +14,29 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 
-#define PHY_REG_00		0x00
-#define PHY_REG_01		0x04
-#define PHY_REG_02		0x08
-#define PHY_REG_08		0x20
-#define PHY_REG_09		0x24
-#define PHY_REG_10		0x28
-#define PHY_REG_11		0x2c
-
-#define PHY_REG_12		0x30
-#define  REG12_CK_DIV_MASK	GENMASK(5, 4)
-
-#define PHY_REG_13		0x34
-#define  REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
-
-#define PHY_REG_14		0x38
-#define  REG14_TOL_MASK		GENMASK(7, 4)
-#define  REG14_RP_CODE_MASK	GENMASK(3, 1)
-#define  REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
-
-#define PHY_REG_15		0x3c
-#define PHY_REG_16		0x40
-#define PHY_REG_17		0x44
-#define PHY_REG_18		0x48
-#define PHY_REG_19		0x4c
-#define PHY_REG_20		0x50
-
-#define PHY_REG_21		0x54
-#define  REG21_SEL_TX_CK_INV	BIT(7)
-#define  REG21_PMS_S_MASK	GENMASK(3, 0)
-
-#define PHY_REG_22		0x58
-#define PHY_REG_23		0x5c
-#define PHY_REG_24		0x60
-#define PHY_REG_25		0x64
-#define PHY_REG_26		0x68
-#define PHY_REG_27		0x6c
-#define PHY_REG_28		0x70
-#define PHY_REG_29		0x74
-#define PHY_REG_30		0x78
-#define PHY_REG_31		0x7c
-#define PHY_REG_32		0x80
+#define PHY_REG(reg)		(reg * 4)
 
+#define REG12_CK_DIV_MASK	GENMASK(5, 4)
+
+#define REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
+
+#define REG14_TOL_MASK		GENMASK(7, 4)
+#define REG14_RP_CODE_MASK	GENMASK(3, 1)
+#define REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
+
+#define REG21_SEL_TX_CK_INV	BIT(7)
+#define REG21_PMS_S_MASK	GENMASK(3, 0)
 /*
  * REG33 does not match the ref manual. According to Sandor Yu from NXP,
  * "There is a doc issue on the i.MX8MP latest RM"
  * REG33 is being used per guidance from Sandor
  */
+#define REG33_MODE_SET_DONE	BIT(7)
+#define REG33_FIX_DA		BIT(1)
 
-#define PHY_REG_33		0x84
-#define  REG33_MODE_SET_DONE	BIT(7)
-#define  REG33_FIX_DA		BIT(1)
-
-#define PHY_REG_34		0x88
-#define  REG34_PHY_READY	BIT(7)
-#define  REG34_PLL_LOCK		BIT(6)
-#define  REG34_PHY_CLK_READY	BIT(5)
-
-#define PHY_REG_35		0x8c
-#define PHY_REG_36		0x90
-#define PHY_REG_37		0x94
-#define PHY_REG_38		0x98
-#define PHY_REG_39		0x9c
-#define PHY_REG_40		0xa0
-#define PHY_REG_41		0xa4
-#define PHY_REG_42		0xa8
-#define PHY_REG_43		0xac
-#define PHY_REG_44		0xb0
-#define PHY_REG_45		0xb4
-#define PHY_REG_46		0xb8
-#define PHY_REG_47		0xbc
+#define REG34_PHY_READY	BIT(7)
+#define REG34_PLL_LOCK		BIT(6)
+#define REG34_PHY_CLK_READY	BIT(5)
 
 #define PHY_PLL_DIV_REGS_NUM 6
 
@@ -369,29 +322,29 @@ struct reg_settings {
 };
 
 static const struct reg_settings common_phy_cfg[] = {
-	{ PHY_REG_00, 0x00 }, { PHY_REG_01, 0xd1 },
-	{ PHY_REG_08, 0x4f }, { PHY_REG_09, 0x30 },
-	{ PHY_REG_10, 0x33 }, { PHY_REG_11, 0x65 },
+	{ PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
+	{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
+	{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
 	/* REG12 pixclk specific */
 	/* REG13 pixclk specific */
 	/* REG14 pixclk specific */
-	{ PHY_REG_15, 0x80 }, { PHY_REG_16, 0x6c },
-	{ PHY_REG_17, 0xf2 }, { PHY_REG_18, 0x67 },
-	{ PHY_REG_19, 0x00 }, { PHY_REG_20, 0x10 },
+	{ PHY_REG(15), 0x80 }, { PHY_REG(16), 0x6c },
+	{ PHY_REG(17), 0xf2 }, { PHY_REG(18), 0x67 },
+	{ PHY_REG(19), 0x00 }, { PHY_REG(20), 0x10 },
 	/* REG21 pixclk specific */
-	{ PHY_REG_22, 0x30 }, { PHY_REG_23, 0x32 },
-	{ PHY_REG_24, 0x60 }, { PHY_REG_25, 0x8f },
-	{ PHY_REG_26, 0x00 }, { PHY_REG_27, 0x00 },
-	{ PHY_REG_28, 0x08 }, { PHY_REG_29, 0x00 },
-	{ PHY_REG_30, 0x00 }, { PHY_REG_31, 0x00 },
-	{ PHY_REG_32, 0x00 }, { PHY_REG_33, 0x80 },
-	{ PHY_REG_34, 0x00 }, { PHY_REG_35, 0x00 },
-	{ PHY_REG_36, 0x00 }, { PHY_REG_37, 0x00 },
-	{ PHY_REG_38, 0x00 }, { PHY_REG_39, 0x00 },
-	{ PHY_REG_40, 0x00 }, { PHY_REG_41, 0xe0 },
-	{ PHY_REG_42, 0x83 }, { PHY_REG_43, 0x0f },
-	{ PHY_REG_44, 0x3E }, { PHY_REG_45, 0xf8 },
-	{ PHY_REG_46, 0x00 }, { PHY_REG_47, 0x00 }
+	{ PHY_REG(22), 0x30 }, { PHY_REG(23), 0x32 },
+	{ PHY_REG(24), 0x60 }, { PHY_REG(25), 0x8f },
+	{ PHY_REG(26), 0x00 }, { PHY_REG(27), 0x00 },
+	{ PHY_REG(28), 0x08 }, { PHY_REG(29), 0x00 },
+	{ PHY_REG(30), 0x00 }, { PHY_REG(31), 0x00 },
+	{ PHY_REG(32), 0x00 }, { PHY_REG(33), 0x80 },
+	{ PHY_REG(34), 0x00 }, { PHY_REG(35), 0x00 },
+	{ PHY_REG(36), 0x00 }, { PHY_REG(37), 0x00 },
+	{ PHY_REG(38), 0x00 }, { PHY_REG(39), 0x00 },
+	{ PHY_REG(40), 0x00 }, { PHY_REG(41), 0xe0 },
+	{ PHY_REG(42), 0x83 }, { PHY_REG(43), 0x0f },
+	{ PHY_REG(44), 0x3E }, { PHY_REG(45), 0xf8 },
+	{ PHY_REG(46), 0x00 }, { PHY_REG(47), 0x00 }
 };
 
 struct fsl_samsung_hdmi_phy {
@@ -442,7 +395,7 @@ fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
 	}
 
 	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
-	       phy->regs + PHY_REG_21);
+	       phy->regs + PHY_REG(21));
 }
 
 static void
@@ -469,7 +422,7 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 		break;
 	}
 
-	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG_12);
+	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG(12));
 
 	/*
 	 * Calculation for the frequency lock detector target code (fld_tg_code)
@@ -489,11 +442,11 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 
 	/* FLD_TOL and FLD_RP_CODE taken from downstream driver */
 	writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),
-	       phy->regs + PHY_REG_13);
+	       phy->regs + PHY_REG(13));
 	writeb(FIELD_PREP(REG14_TOL_MASK, 2) |
 	       FIELD_PREP(REG14_RP_CODE_MASK, 2) |
 	       FIELD_PREP(REG14_TG_CODE_HIGH_MASK, fld_tg_code >> 8),
-	       phy->regs + PHY_REG_14);
+	       phy->regs + PHY_REG(14));
 }
 
 static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
@@ -503,7 +456,7 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	u8 val;
 
 	/* HDMI PHY init */
-	writeb(REG33_FIX_DA, phy->regs + PHY_REG_33);
+	writeb(REG33_FIX_DA, phy->regs + PHY_REG(33));
 
 	/* common PHY registers */
 	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
@@ -511,14 +464,14 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 
 	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
-		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG_02 + i * 4);
+		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
 
 	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
-	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG_33);
+	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));
 
-	ret = readb_poll_timeout(phy->regs + PHY_REG_34, val,
+	ret = readb_poll_timeout(phy->regs + PHY_REG(34), val,
 				 val & REG34_PLL_LOCK, 50, 20000);
 	if (ret)
 		dev_err(phy->dev, "PLL failed to lock\n");
-- 
2.43.0



From aford173 at gmail.com  Tue Sep  3 19:32:41 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue,  3 Sep 2024 21:32:41 -0500
Subject: [PATCH V5 2/5] phy: freescale: fsl-samsung-hdmi: Simplify REG21_PMS_S_MASK lookup
In-Reply-To: <20240904023310.163371-1-aford173@gmail.com>
References: <20240904023310.163371-1-aford173@gmail.com>
Message-ID: <20240904023310.163371-3-aford173@gmail.com>

The value of 'S' is writen to two places, PHY_REG3[7:4] and
PHY_REG21[3:0].  There is a lookup table which contains
the value of PHY_REG3.  Rather than using a switch statement
based on the pixel clock to search for the value of 'S' again,
just shift the contents of PHY_REG3[7:4] >> 4 and place the value
in PHY_REG21[3:0].  Doing this can eliminate an entire function.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
---
V5:  No Change
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 39 ++------------------
 1 file changed, 4 insertions(+), 35 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index acea7008aefc..4f6874226f9a 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -364,40 +364,6 @@ to_fsl_samsung_hdmi_phy(struct clk_hw *hw)
 	return container_of(hw, struct fsl_samsung_hdmi_phy, hw);
 }
 
-static void
-fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
-				      const struct phy_config *cfg)
-{
-	u8 div = 0x1;
-
-	switch (cfg->pixclk) {
-	case  22250000 ...  33750000:
-		div = 0xf;
-		break;
-	case  35000000 ...  40000000:
-		div = 0xb;
-		break;
-	case  43200000 ...  47500000:
-		div = 0x9;
-		break;
-	case  50349650 ...  63500000:
-		div = 0x7;
-		break;
-	case  67500000 ...  90000000:
-		div = 0x5;
-		break;
-	case  94000000 ... 148500000:
-		div = 0x3;
-		break;
-	case 154000000 ... 297000000:
-		div = 0x1;
-		break;
-	}
-
-	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
-	       phy->regs + PHY_REG(21));
-}
-
 static void
 fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 					    const struct phy_config *cfg)
@@ -466,7 +432,10 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
 		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
 
-	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
+	/* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
+	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
+	       cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
+
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
 	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));
-- 
2.43.0



From aford173 at gmail.com  Tue Sep  3 19:32:42 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue,  3 Sep 2024 21:32:42 -0500
Subject: [PATCH V5 3/5] phy: freescale: fsl-samsung-hdmi: Support dynamic integer
In-Reply-To: <20240904023310.163371-1-aford173@gmail.com>
References: <20240904023310.163371-1-aford173@gmail.com>
Message-ID: <20240904023310.163371-4-aford173@gmail.com>

There is currently a look-up table for a variety of resolutions.
Since the phy has the ability to dynamically calculate the values
necessary to use the intger divider which should allow more
resolutions without having to update the look-up-table.

If the lookup table cannot find an exact match, fall back to the
dynamic calculator of the integer divider.

Previously, the value of P was hard-coded to 1, this required an
update to the phy_pll_cfg table to add in the extra value into the
table, so if the value of P is calculated to be something else
by the PMS calculator, the calculated_phy_pll_cfg structure
can be used instead without having to keep track of which method
was used.

Signed-off-by: Adam Ford <aford173 at gmail.com>
---
V5:  No Change
V4:  No Change
V3:  Change size of pll_div_regs to include PHY_REG01 (P)
     Create calculated_phy_pll_cfg to containe the values
     Eliminate the PMS calculation from fsl_samsung_hdmi_phy_configure
     Make the LUT primary and fall back to integer calculator in
     phy_clk_round_rate.
     Check the range right away to ensure it's reaonsable rather than
     trying to find a clock only to learn it's outside the range.
     Overall added notes and comments where stuff may not be intuitive.

V2:  Update phy_clk_round_rate and phy_clk_set_rate to both support
     the integer clock PMS calculator.
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 341 +++++++++++++------
 1 file changed, 235 insertions(+), 106 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 4f6874226f9a..8f2c0082aa12 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -16,6 +16,8 @@
 
 #define PHY_REG(reg)		(reg * 4)
 
+#define REG01_PMS_P_MASK	GENMASK(3, 0)
+#define REG03_PMS_S_MASK	GENMASK(7, 4)
 #define REG12_CK_DIV_MASK	GENMASK(5, 4)
 
 #define REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
@@ -38,281 +40,296 @@
 #define REG34_PLL_LOCK		BIT(6)
 #define REG34_PHY_CLK_READY	BIT(5)
 
-#define PHY_PLL_DIV_REGS_NUM 6
+#ifndef MHZ
+#define MHZ	(1000UL * 1000UL)
+#endif
+
+#define PHY_PLL_DIV_REGS_NUM 7
 
 struct phy_config {
 	u32	pixclk;
 	u8	pll_div_regs[PHY_PLL_DIV_REGS_NUM];
 };
 
+/*
+ * The calculated_phy_pll_cfg only handles integer divider for PMS only,
+ * meaning the last four entries will be fixed, but the first three will
+ * be calculated by the PMS calculator
+ */
+static struct phy_config calculated_phy_pll_cfg = {
+	.pixclk = 0,
+	.pll_div_regs = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
+};
+
+/* The lookup table contains values for which the fractional divder is used */
 static const struct phy_config phy_pll_cfg[] = {
 	{
 		.pixclk = 22250000,
-		.pll_div_regs = { 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 23750000,
-		.pll_div_regs = { 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
 	}, {
 		.pixclk = 24000000,
-		.pll_div_regs = { 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 24024000,
-		.pll_div_regs = { 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
 	}, {
 		.pixclk = 25175000,
-		.pll_div_regs = { 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
 	}, {
 		.pixclk = 25200000,
-		.pll_div_regs = { 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 26750000,
-		.pll_div_regs = { 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 27000000,
-		.pll_div_regs = { 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 27027000,
-		.pll_div_regs = { 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 29500000,
-		.pll_div_regs = { 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 30750000,
-		.pll_div_regs = { 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 30888000,
-		.pll_div_regs = { 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
 	}, {
 		.pixclk = 33750000,
-		.pll_div_regs = { 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 35000000,
-		.pll_div_regs = { 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 36000000,
-		.pll_div_regs = { 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 36036000,
-		.pll_div_regs = { 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 40000000,
-		.pll_div_regs = { 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43200000,
-		.pll_div_regs = { 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43243200,
-		.pll_div_regs = { 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 44500000,
-		.pll_div_regs = { 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
 	}, {
 		.pixclk = 47000000,
-		.pll_div_regs = { 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
 	}, {
 		.pixclk = 47500000,
-		.pll_div_regs = { 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
 	}, {
 		.pixclk = 50349650,
-		.pll_div_regs = { 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
 	}, {
 		.pixclk = 50400000,
-		.pll_div_regs = { 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 53250000,
-		.pll_div_regs = { 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 53500000,
-		.pll_div_regs = { 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 54000000,
-		.pll_div_regs = { 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 54054000,
-		.pll_div_regs = { 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 59000000,
-		.pll_div_regs = { 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 59340659,
-		.pll_div_regs = { 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
 	}, {
 		.pixclk = 59400000,
-		.pll_div_regs = { 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 61500000,
-		.pll_div_regs = { 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 63500000,
-		.pll_div_regs = { 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 67500000,
-		.pll_div_regs = { 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
 	}, {
 		.pixclk = 70000000,
-		.pll_div_regs = { 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 72000000,
-		.pll_div_regs = { 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 72072000,
-		.pll_div_regs = { 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 74176000,
-		.pll_div_regs = { 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
 	}, {
 		.pixclk = 74250000,
-		.pll_div_regs = { 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
 	}, {
 		.pixclk = 78500000,
-		.pll_div_regs = { 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 80000000,
-		.pll_div_regs = { 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 82000000,
-		.pll_div_regs = { 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 82500000,
-		.pll_div_regs = { 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
 	}, {
 		.pixclk = 89000000,
-		.pll_div_regs = { 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
 	}, {
 		.pixclk = 90000000,
-		.pll_div_regs = { 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 94000000,
-		.pll_div_regs = { 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
 	}, {
 		.pixclk = 95000000,
-		.pll_div_regs = { 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
 	}, {
 		.pixclk = 98901099,
-		.pll_div_regs = { 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
 	}, {
 		.pixclk = 99000000,
-		.pll_div_regs = { 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
 	}, {
 		.pixclk = 100699300,
-		.pll_div_regs = { 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
 	}, {
 		.pixclk = 100800000,
-		.pll_div_regs = { 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 102500000,
-		.pll_div_regs = { 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
 		.pixclk = 104750000,
-		.pll_div_regs = { 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
 	}, {
 		.pixclk = 106500000,
-		.pll_div_regs = { 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 107000000,
-		.pll_div_regs = { 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 108000000,
-		.pll_div_regs = { 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 108108000,
-		.pll_div_regs = { 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 118000000,
-		.pll_div_regs = { 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 118800000,
-		.pll_div_regs = { 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 123000000,
-		.pll_div_regs = { 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 127000000,
-		.pll_div_regs = { 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 135000000,
-		.pll_div_regs = { 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 135580000,
-		.pll_div_regs = { 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
+		.pll_div_regs = { 0xd1, 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
 	}, {
 		.pixclk = 137520000,
-		.pll_div_regs = { 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
+		.pll_div_regs = { 0xd1, 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
 	}, {
 		.pixclk = 138750000,
-		.pll_div_regs = { 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
+		.pll_div_regs = { 0xd1, 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
 	}, {
 		.pixclk = 140000000,
-		.pll_div_regs = { 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
 	}, {
 		.pixclk = 144000000,
-		.pll_div_regs = { 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 148352000,
-		.pll_div_regs = { 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
 	}, {
 		.pixclk = 148500000,
-		.pll_div_regs = { 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
 	}, {
 		.pixclk = 154000000,
-		.pll_div_regs = { 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
+		.pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
 	}, {
 		.pixclk = 157000000,
-		.pll_div_regs = { 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
 	}, {
 		.pixclk = 160000000,
-		.pll_div_regs = { 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
 	}, {
 		.pixclk = 162000000,
-		.pll_div_regs = { 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
+		.pll_div_regs = { 0xd1, 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
 	}, {
 		.pixclk = 164000000,
-		.pll_div_regs = { 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
 	}, {
 		.pixclk = 165000000,
-		.pll_div_regs = { 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
 	}, {
 		.pixclk = 180000000,
-		.pll_div_regs = { 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 185625000,
-		.pll_div_regs = { 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
 	}, {
 		.pixclk = 188000000,
-		.pll_div_regs = { 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
 	}, {
 		.pixclk = 198000000,
-		.pll_div_regs = { 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
 	}, {
 		.pixclk = 205000000,
-		.pll_div_regs = { 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
 		.pixclk = 209500000,
-		.pll_div_regs = { 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
 	}, {
 		.pixclk = 213000000,
-		.pll_div_regs = { 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 216000000,
-		.pll_div_regs = { 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 216216000,
-		.pll_div_regs = { 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 237600000,
-		.pll_div_regs = { 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 254000000,
-		.pll_div_regs = { 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 277500000,
-		.pll_div_regs = { 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
+		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
 	}, {
 		.pixclk = 288000000,
-		.pll_div_regs = { 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 297000000,
-		.pll_div_regs = { 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
 	},
 };
 
@@ -322,7 +339,8 @@ struct reg_settings {
 };
 
 static const struct reg_settings common_phy_cfg[] = {
-	{ PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
+	{ PHY_REG(0), 0x00 },
+	/* PHY_REG(1-7) pix clk specific */
 	{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
 	{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
 	/* REG12 pixclk specific */
@@ -415,6 +433,76 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 	       phy->regs + PHY_REG(14));
 }
 
+static unsigned long fsl_samsung_hdmi_phy_find_pms(unsigned long fout, u8 *p, u16 *m, u8 *s)
+{
+	unsigned long best_freq = 0;
+	u32 min_delta = 0xffffffff;
+	u8 _p, best_p;
+	u16 _m, best_m;
+	u8 _s, best_s;
+
+	/* The ref manual states the values of 'P' range from 1 to 11 */
+	for (_p = 1; _p <= 11; ++_p) {
+		for (_s = 1; _s <= 16; ++_s) {
+			u64 tmp;
+			u32 delta;
+
+			/* s must be one or even */
+			if (_s > 1 && (_s & 0x01) == 1)
+				_s++;
+
+			/* _s cannot be 14 per the TRM */
+			if (_s == 14)
+				continue;
+
+			/*
+			 * TODO: Ref Manual doesn't state the range of _m
+			 * so this should be further refined if possible.
+			 * This range was set based on the original values
+			 * in the look-up table
+			 */
+			tmp = (u64)fout * (_p * _s);
+			do_div(tmp, 24 * MHZ);
+			_m = tmp;
+			if (_m < 0x30 || _m > 0x7b)
+				continue;
+
+			/*
+			 * Rev 2 of the Ref Manual states the
+			 * VCO can range between 750MHz and
+			 * 3GHz.  The VCO is assumed to be _m x
+			 * the reference frequency of 24MHz divided
+			 * by the prescaler, _p
+			 */
+			tmp = (u64)_m * 24 * MHZ;
+			do_div(tmp, _p);
+			if (tmp < 750 * MHZ ||
+			    tmp > 3000 * MHZ)
+				continue;
+
+			tmp = (u64)_m * 24 * MHZ;
+			do_div(tmp, _p * _s);
+
+			delta = abs(fout - tmp);
+			if (delta < min_delta) {
+				best_p = _p;
+				best_s = _s;
+				best_m = _m;
+				min_delta = delta;
+				best_freq = tmp;
+			}
+		}
+	}
+
+	if (best_freq) {
+		*p = best_p;
+		*m = best_m;
+		*s = best_s;
+	}
+
+	return best_freq;
+}
+
 static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 					  const struct phy_config *cfg)
 {
@@ -428,13 +516,13 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
 		writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
 
-	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
+	/* set individual PLL registers PHY_REG1 ... PHY_REG7 */
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
-		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
+		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(1) + i * 4);
 
-	/* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
+	/* High nibble of PHY_REG3 and low nibble of PHY_REG21 both contain 'S' */
 	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
-	       cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
+	       cfg->pll_div_regs[2] >> 4), phy->regs + PHY_REG(21));
 
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
@@ -462,29 +550,70 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
 static long phy_clk_round_rate(struct clk_hw *hw,
 			       unsigned long rate, unsigned long *parent_rate)
 {
+	u32 int_div_clk;
 	int i;
+	u16 m;
+	u8 p, s;
+
+	/* If the clock is out of range return error instead of searching */
+	if (rate > 297000000 || rate < 22250000)
+		return -EINVAL;
 
+	/* Check the look-up table */
 	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
 		if (phy_pll_cfg[i].pixclk <= rate)
-			return phy_pll_cfg[i].pixclk;
+			break;
+	/* If the rate is an exact match, return it now */
+	if (rate == phy_pll_cfg[i].pixclk)
+		return phy_pll_cfg[i].pixclk;
+
+	/*
+	 * The math on the lookup table shows the PMS math yields a
+	 * frequency 5 x pixclk.
+	 * When we check the integer divider against the desired rate,
+	 * multiply the rate x 5 and then divide the outcome by 5.
+	 */
+	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
 
-	return -EINVAL;
+	/* If the rate is an exact match, return it now */
+	if (int_div_clk == rate)
+		return int_div_clk;
+
+	/* Fall back to the closest value in the LUT */
+	return phy_pll_cfg[i].pixclk;
 }
 
 static int phy_clk_set_rate(struct clk_hw *hw,
 			    unsigned long rate, unsigned long parent_rate)
 {
 	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
+	u32 int_div_clk;
 	int i;
-
-	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
-		if (phy_pll_cfg[i].pixclk <= rate)
-			break;
-
-	if (i < 0)
-		return -EINVAL;
-
-	phy->cur_cfg = &phy_pll_cfg[i];
+	u16 m;
+	u8 p, s;
+
+	/* If the integer divider works, just use it */
+	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
+	if (int_div_clk == rate) {
+		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using integer divider\n");
+		calculated_phy_pll_cfg.pixclk = int_div_clk;
+		calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
+		calculated_phy_pll_cfg.pll_div_regs[1] = m;
+		calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
+		/* pll_div_regs 3-6 are fixed and pre-defined already */
+		phy->cur_cfg  = &calculated_phy_pll_cfg;
+	} else {
+		/* Otherwise, search the LUT */
+		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
+		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
+			if (phy_pll_cfg[i].pixclk <= rate)
+				break;
+
+		if (i < 0)
+			return -EINVAL;
+
+		phy->cur_cfg = &phy_pll_cfg[i];
+	}
 
 	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
 }
-- 
2.43.0



From aford173 at gmail.com  Tue Sep  3 19:32:43 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue,  3 Sep 2024 21:32:43 -0500
Subject: [PATCH V5 4/5] phy: freescale: fsl-samsung-hdmi: Use closest divider
In-Reply-To: <20240904023310.163371-1-aford173@gmail.com>
References: <20240904023310.163371-1-aford173@gmail.com>
Message-ID: <20240904023310.163371-5-aford173@gmail.com>

Currently, if the clock values cannot be set to the exact rate,
the round_rate and set_rate functions use the closest value found in
the look-up-table.  In preparation of removing values from the LUT
that can be calculated evenly with the integer calculator, it's
necessary to ensure to check both the look-up-table and the integer
divider clock values to get the closest values to the requested
value.  It does this by measuring the difference between the
requested clock value and the closest value in both integer divider
calucator and the fractional clock look-up-table.

Which ever has the smallest difference between them is returned as
the cloesest rate.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Signed-off-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
---
V5:  No Change
V4:  New to series
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 40 +++++++++++++++-----
 1 file changed, 31 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 8f2c0082aa12..56b08e684179 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -550,7 +550,7 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
 static long phy_clk_round_rate(struct clk_hw *hw,
 			       unsigned long rate, unsigned long *parent_rate)
 {
-	u32 int_div_clk;
+	u32 int_div_clk, delta_int, delta_frac;
 	int i;
 	u16 m;
 	u8 p, s;
@@ -563,6 +563,7 @@ static long phy_clk_round_rate(struct clk_hw *hw,
 	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
 		if (phy_pll_cfg[i].pixclk <= rate)
 			break;
+
 	/* If the rate is an exact match, return it now */
 	if (rate == phy_pll_cfg[i].pixclk)
 		return phy_pll_cfg[i].pixclk;
@@ -579,15 +580,21 @@ static long phy_clk_round_rate(struct clk_hw *hw,
 	if (int_div_clk == rate)
 		return int_div_clk;
 
-	/* Fall back to the closest value in the LUT */
-	return phy_pll_cfg[i].pixclk;
+	/* Calculate the differences and use the closest one */
+	delta_frac = (rate - phy_pll_cfg[i].pixclk);
+	delta_int = (rate - int_div_clk);
+
+	if (delta_int < delta_frac)
+		return int_div_clk;
+	else
+		return phy_pll_cfg[i].pixclk;
 }
 
 static int phy_clk_set_rate(struct clk_hw *hw,
 			    unsigned long rate, unsigned long parent_rate)
 {
 	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
-	u32 int_div_clk;
+	u32 int_div_clk, delta_int, delta_frac;
 	int i;
 	u16 m;
 	u8 p, s;
@@ -602,19 +609,34 @@ static int phy_clk_set_rate(struct clk_hw *hw,
 		calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
 		/* pll_div_regs 3-6 are fixed and pre-defined already */
 		phy->cur_cfg  = &calculated_phy_pll_cfg;
+		goto done;
 	} else {
 		/* Otherwise, search the LUT */
-		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
-		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
-			if (phy_pll_cfg[i].pixclk <= rate)
+		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--) {
+			if (phy_pll_cfg[i].pixclk == rate) {
+				dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
+				phy->cur_cfg = &phy_pll_cfg[i];
+				goto done;
+			}
+
+			if (phy_pll_cfg[i].pixclk < rate)
 				break;
+		}
 
 		if (i < 0)
 			return -EINVAL;
-
-		phy->cur_cfg = &phy_pll_cfg[i];
 	}
 
+	/* Calculate the differences for each clock against the requested value */
+	delta_frac = (rate - phy_pll_cfg[i].pixclk);
+	delta_int = (rate - int_div_clk);
+
+	/* Use the value closest to the desired */
+	if (delta_int < delta_frac)
+		phy->cur_cfg  = &calculated_phy_pll_cfg;
+	else
+		phy->cur_cfg = &phy_pll_cfg[i];
+done:
 	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
 }
 
-- 
2.43.0



From aford173 at gmail.com  Tue Sep  3 19:32:44 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue,  3 Sep 2024 21:32:44 -0500
Subject: [PATCH V5 5/5] phy: freescale: fsl-samsung-hdmi: Remove unnecessary LUT entries
In-Reply-To: <20240904023310.163371-1-aford173@gmail.com>
References: <20240904023310.163371-1-aford173@gmail.com>
Message-ID: <20240904023310.163371-6-aford173@gmail.com>

The lookup table contains entries which use the integer divider
instead of just the fractional divider.  Since the set and round
functions check both the integer divider values and the LUT values,
it's no longer necessary to keep the integer divder values in the,
as they are able to by dynamically calcuated.

Signed-off-by: Adam Ford <aford173 at gmail.com>
---
V5: No Change

V4:  New to series
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 83 +++-----------------
 1 file changed, 13 insertions(+), 70 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 56b08e684179..a37d7b989552 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -69,25 +69,16 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 23750000,
 		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
-	}, {
-		.pixclk = 24000000,
-		.pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 24024000,
 		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
 	}, {
 		.pixclk = 25175000,
 		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
-	}, {
-		.pixclk = 25200000,
-		.pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 26750000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 27000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 27027000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -105,18 +96,9 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 35000000,
 		.pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 36000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 36036000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
-	}, {
-		.pixclk = 40000000,
-		.pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
-		.pixclk = 43200000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43243200,
 		.pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
@@ -132,19 +114,13 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 50349650,
 		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
-	}, {
-		.pixclk = 50400000,
-		.pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 53250000,
 		.pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 53500000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 54000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 54054000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -153,10 +129,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 59340659,
 		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
-	}, {
-		.pixclk = 59400000,
-		.pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 61500000,
 		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -168,10 +141,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 70000000,
 		.pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 72000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 72072000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -183,10 +153,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 78500000,
 		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
-	}, {
-		.pixclk = 80000000,
-		.pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 82000000,
 		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -213,10 +180,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 100699300,
 		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
-	}, {
-		.pixclk = 100800000,
-		.pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 102500000,
 		.pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
@@ -228,19 +192,13 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 107000000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 108000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 108108000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 118000000,
 		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
-	}, {
-		.pixclk = 118800000,
-		.pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 123000000,
 		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -261,10 +219,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 140000000,
 		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
-	}, {
-		.pixclk = 144000000,
-		.pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 148352000,
 		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
 	}, {
@@ -288,9 +243,6 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 165000000,
 		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
-	}, {
-		.pixclk = 180000000,
-		.pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 185625000,
 		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
@@ -309,25 +261,16 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 213000000,
 		.pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
-	}, {
-		.pixclk = 216000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 216216000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
-	}, {
-		.pixclk = 237600000,
-		.pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 254000000,
 		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 277500000,
 		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
-	}, {
-		.pixclk = 288000000,
-		.pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 297000000,
 		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
 	},
-- 
2.43.0



From sandor.yu at nxp.com  Mon Sep  2 22:52:59 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 3 Sep 2024 05:52:59 +0000
Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501
 DP/HDMI driver
In-Reply-To: <d9390fb4-98e2-40e7-a5d2-67d101585698@collabora.com>
References: <cover.1719903904.git.Sandor.yu@nxp.com>
 <359914108b879e995d4a39de32a33310009f0fab.1719903904.git.Sandor.yu@nxp.com>
 <d9390fb4-98e2-40e7-a5d2-67d101585698@collabora.com>
Message-ID: <PAXPR04MB9448D24C9E9CFD44C9E5521DF4932@PAXPR04MB9448.eurprd04.prod.outlook.com>

 
> 
> Le 02/07/2024 ? 14:22, Sandor Yu a ?crit :
> > Add a new DRM DisplayPort and HDMI bridge driver for Candence
> MHDP8501
> > used in i.MX8MQ SOC. MHDP8501 could support HDMI or DisplayPort
> > standards according embedded Firmware running in the uCPU.
> >
> > For iMX8MQ SOC, the DisplayPort/HDMI FW was loaded and activated by
> > SOC's ROM code. Bootload binary included respective specific firmware
> > is required.
> >
> > Driver will check display connector type and
> > then load the corresponding driver.
> >
> > Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> > Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > ---
> > v15->v16:
> > - rebase the patchset sits on top Dmitry's
> >     'make use of the HDMI connector infrastructure' patchset ([2]).
> > - Add DRM_BRIDGE_OP_HDMI flags for HDMI driver,
> > - Introduce the hdmi info frame helper functions, added
> hdmi_clear_infoframe(),
> >    hdmi_write_infoframe() and hdmi_tmds_char_rate_valid().
> > - mode_fixup() was replaced by atomic_check().
> > - Fix video mode 4Kp30 did not work on some displays that support
> >    LTE_340Mcsc_scramble.
> > - updated for tmds_char_rate added in patch #2.
> >
> > v13->v14:
> > - Rebase to next-20240219, replace get_edid function by edid_read
> >    function.
> >
> > v12->v13:
> > - Explicitly include linux/platform_device.h for cdns-mhdp8501-core.c
> > - Fix build warning
> > - Order bit bpc and color_space in descending shit.
> >
> > v11->v12:
> > - Replace DRM_INFO with dev_info or dev_warn.
> > - Replace DRM_ERROR with dev_err.
> > - Return ret when cdns_mhdp_dpcd_read failed in function
> cdns_dp_aux_transferi().
> > - Remove unused parmeter in function cdns_dp_get_msa_misc
> >    and use two separate variables for color space and bpc.
> > - Add year 2024 to copyright.
> >
> >   drivers/gpu/drm/bridge/cadence/Kconfig        |  16 +
> >   drivers/gpu/drm/bridge/cadence/Makefile       |   2 +
> >   .../drm/bridge/cadence/cdns-mhdp8501-core.c   | 330 +++++++++
> >   .../drm/bridge/cadence/cdns-mhdp8501-core.h   | 367 +++++++++
> >   .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c | 700
> ++++++++++++++++++
> >   .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   | 595
> +++++++++++++++
> >   6 files changed, 2010 insertions(+)
> >   create mode 100644
> drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
> >   create mode 100644
> drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
> >   create mode 100644
> drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> >   create mode 100644
> drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> >
> > diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig
> b/drivers/gpu/drm/bridge/cadence/Kconfig
> > index e0973339e9e3..45848e741f5f 100644
> > --- a/drivers/gpu/drm/bridge/cadence/Kconfig
> > +++ b/drivers/gpu/drm/bridge/cadence/Kconfig
> > @@ -51,3 +51,19 @@ config DRM_CDNS_MHDP8546_J721E
> >         initializes the J721E Display Port and sets up the
> >         clock and data muxes.
> >   endif
> > +
> > +config DRM_CDNS_MHDP8501
> > +     tristate "Cadence MHDP8501 DP/HDMI bridge"
> > +     select DRM_KMS_HELPER
> > +     select DRM_PANEL_BRIDGE
> > +     select DRM_DISPLAY_DP_HELPER
> > +     select DRM_DISPLAY_HELPER
> > +     select CDNS_MHDP_HELPER
> > +     select DRM_CDNS_AUDIO
> > +     depends on OF
> > +     help
> > +       Support Cadence MHDP8501 DisplayPort/HDMI bridge.
> > +       Cadence MHDP8501 support one or more protocols,
> > +       including DisplayPort and HDMI.
> > +       To use the DP and HDMI drivers, their respective
> > +       specific firmware is required.
> > diff --git a/drivers/gpu/drm/bridge/cadence/Makefile
> b/drivers/gpu/drm/bridge/cadence/Makefile
> > index 087dc074820d..02c1a9f3cf6f 100644
> > --- a/drivers/gpu/drm/bridge/cadence/Makefile
> > +++ b/drivers/gpu/drm/bridge/cadence/Makefile
> > @@ -6,3 +6,5 @@ obj-$(CONFIG_CDNS_MHDP_HELPER) +=
> cdns-mhdp-helper.o
> >   obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
> >   cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
> >   cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) +=
> cdns-mhdp8546-j721e.o
> > +obj-$(CONFIG_DRM_CDNS_MHDP8501) += cdns-mhdp8501.o
> > +cdns-mhdp8501-y := cdns-mhdp8501-core.o cdns-mhdp8501-dp.o
> cdns-mhdp8501-hdmi.o
> > diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
> b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
> > new file mode 100644
> > index 000000000000..c306db982b76
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
> > @@ -0,0 +1,330 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Cadence Display Port Interface (DP) driver
> > + *
> > + * Copyright (C) 2023, 2024 NXP Semiconductor, Inc.
> > + *
> > + */
> > +#include <drm/drm_of.h>
> > +#include <drm/drm_print.h>
> > +#include <linux/clk.h>
> > +#include <linux/irq.h>
> > +#include <linux/mutex.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/phy/phy.h>
> > +
> > +#include "cdns-mhdp8501-core.h"
> > +
> > +static int cdns_mhdp8501_read_hpd(struct cdns_mhdp8501_device
> *mhdp)
> > +{
> > +     u8 status;
> > +     int ret;
> > +
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +
> > +     ret = cdns_mhdp_mailbox_send(&mhdp->base,
> MB_MODULE_ID_GENERAL,
> > +                                  GENERAL_GET_HPD_STATE, 0,
> NULL);
> > +     if (ret)
> > +             goto err_get_hpd;
> > +
> > +     ret = cdns_mhdp_mailbox_recv_header(&mhdp->base,
> MB_MODULE_ID_GENERAL,
> > +
> GENERAL_GET_HPD_STATE,
> > +                                         sizeof(status));
> > +     if (ret)
> > +             goto err_get_hpd;
> > +
> > +     ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &status,
> sizeof(status));
> > +     if (ret)
> > +             goto err_get_hpd;
> > +
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +
> > +     return status;
> > +
> > +err_get_hpd:
> > +     dev_err(mhdp->dev, "read hpd  failed: %d\n", ret);
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +
> > +     return ret;
> > +}
> > +
> > +enum drm_connector_status cdns_mhdp8501_detect(struct
> cdns_mhdp8501_device *mhdp)
> > +{
> > +     u8 hpd = 0xf;
> > +
> > +     hpd = cdns_mhdp8501_read_hpd(mhdp);
> > +     if (hpd == 1)
> > +             return connector_status_connected;
> > +     else if (hpd == 0)
> > +             return connector_status_disconnected;
> > +
> > +     dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n", hpd);
> > +     return connector_status_unknown;
> > +}
> > +
> > +static void hotplug_work_func(struct work_struct *work)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = container_of(work,
> > +                                                  struct
> cdns_mhdp8501_device,
> > +
> hotplug_work.work);
> > +     enum drm_connector_status status =
> cdns_mhdp8501_detect(mhdp);
> > +
> > +     drm_bridge_hpd_notify(&mhdp->bridge, status);
> > +
> > +     if (status == connector_status_connected) {
> > +             /* Cable connected  */
> > +             DRM_INFO("HDMI/DP Cable Plug In\n");
> > +             enable_irq(mhdp->irq[IRQ_OUT]);
> > +     } else if (status == connector_status_disconnected) {
> > +             /* Cable Disconnected  */
> > +             DRM_INFO("HDMI/DP Cable Plug Out\n");
> > +             enable_irq(mhdp->irq[IRQ_IN]);
> > +     }
> > +}
> > +
> > +static irqreturn_t cdns_mhdp8501_irq_thread(int irq, void *data)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = data;
> > +
> > +     disable_irq_nosync(irq);
> > +
> > +     mod_delayed_work(system_wq, &mhdp->hotplug_work,
> > +                      msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
> > +
> > +     return IRQ_HANDLED;
> > +}
> > +
> > +static int cdns_mhdp8501_dt_parse(struct cdns_mhdp8501_device *mhdp,
> > +                               struct platform_device *pdev)
> > +{
> > +     struct device *dev = &pdev->dev;
> > +     struct device_node *np = dev->of_node;
> > +     struct device_node *remote;
> > +
> > +     remote = of_graph_get_remote_node(np, 1, 0);
> > +     if (!remote) {
> > +             dev_err(dev, "fail to get remote node\n");
> > +             of_node_put(remote);
> > +             return -EINVAL;
> > +     }
> > +
> > +     /* get connector type */
> > +     if (of_device_is_compatible(remote, "hdmi-connector")) {
> > +             mhdp->connector_type =
> DRM_MODE_CONNECTOR_HDMIA;
> > +
> > +     } else if (of_device_is_compatible(remote, "dp-connector")) {
> > +             mhdp->connector_type =
> DRM_MODE_CONNECTOR_DisplayPort;
> > +
> > +     } else {
> > +             dev_err(dev, "Unknown connector type\n");
> > +             of_node_put(remote);
> > +             return -EINVAL;
> > +     }
> > +
> > +     of_node_put(remote);
> > +     return true;
> > +}
> > +
> > +static void cdns_mhdp8501_add_bridge(struct cdns_mhdp8501_device
> *mhdp)
> > +{
> > +     mhdp->bridge.type = mhdp->connector_type;
> > +     mhdp->bridge.driver_private = mhdp;
> > +     mhdp->bridge.of_node = mhdp->dev->of_node;
> > +     mhdp->bridge.vendor = "NXP";
> > +     mhdp->bridge.product = "i.MX8";
> > +     mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT |
> DRM_BRIDGE_OP_EDID |
> > +                        DRM_BRIDGE_OP_HPD;
> > +
> > +     if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA) {
> > +             mhdp->bridge.funcs = &cdns_hdmi_bridge_funcs;
> > +             mhdp->bridge.ops |= DRM_BRIDGE_OP_HDMI;
> > +     } else if (mhdp->connector_type ==
> DRM_MODE_CONNECTOR_DisplayPort) {
> > +             mhdp->bridge.funcs = &cdns_dp_bridge_funcs;
> > +     } else {
> > +             dev_err(mhdp->dev, "Unsupported connector type!\n");
> > +             return;
> > +     }
> > +
> > +     drm_bridge_add(&mhdp->bridge);
> > +}
> > +
> > +static int cdns_mhdp8501_probe(struct platform_device *pdev)
> > +{
> > +     struct device *dev = &pdev->dev;
> > +     struct cdns_mhdp8501_device *mhdp;
> > +     struct resource *res;
> > +     enum phy_mode phy_mode;
> > +     u32 reg;
> > +     int ret;
> > +
> > +     mhdp = devm_kzalloc(dev, sizeof(*mhdp), GFP_KERNEL);
> > +     if (!mhdp)
> > +             return -ENOMEM;
> > +
> > +     mutex_init(&mhdp->mbox_mutex);
> > +     mhdp->dev = dev;
> > +
> > +     INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func);
> > +
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +     if (!res)
> > +             return -ENODEV;
> > +
> > +     mhdp->regs = devm_ioremap(dev, res->start, resource_size(res));
> > +     if (IS_ERR(mhdp->regs))
> > +             return PTR_ERR(mhdp->regs);
> > +
> > +     ret = cdns_mhdp8501_dt_parse(mhdp, pdev);
> > +     if (ret < 0)
> > +             return -EINVAL;
> > +
> > +     mhdp->phy = devm_of_phy_get_by_index(dev, pdev->dev.of_node,
> 0);
> > +     if (IS_ERR(mhdp->phy))
> > +             return dev_err_probe(dev, PTR_ERR(mhdp->phy), "no PHY
> configured\n");
> > +
> > +     mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
> > +     if (mhdp->irq[IRQ_IN] < 0)
> > +             return dev_err_probe(dev, mhdp->irq[IRQ_IN], "No
> plug_in irq number\n");
> > +
> > +     mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
> > +     if (mhdp->irq[IRQ_OUT] < 0)
> > +             return dev_err_probe(dev, mhdp->irq[IRQ_OUT], "No
> plug_out irq number\n");
> > +
> > +     irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN);
> > +     ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN],
> > +                                     NULL,
> cdns_mhdp8501_irq_thread,
> > +                                     IRQF_ONESHOT,
> dev_name(dev), mhdp);
> > +     if (ret < 0) {
> > +             dev_err(dev, "can't claim irq %d\n", mhdp->irq[IRQ_IN]);
> > +             return -EINVAL;
> > +     }
> > +
> > +     irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN);
> > +     ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT],
> > +                                     NULL,
> cdns_mhdp8501_irq_thread,
> > +                                     IRQF_ONESHOT,
> dev_name(dev), mhdp);
> > +     if (ret < 0) {
> > +             dev_err(dev, "can't claim irq %d\n",
> mhdp->irq[IRQ_OUT]);
> > +             return -EINVAL;
> > +     }
> > +
> > +     /* set default lane mapping */
> > +     mhdp->lane_mapping = LANE_MAPPING_NORMAL;
> > +
> > +     /* cdns_mhdp8501_dt_parse() ensures connector_type is valid */
> > +     mhdp->plat_data = of_device_get_match_data(dev);
> > +     if (mhdp->connector_type ==
> DRM_MODE_CONNECTOR_DisplayPort) {
> > +             mhdp->lane_mapping =
> mhdp->plat_data->dp_lane_mapping;
> > +             phy_mode = PHY_MODE_DP;
> > +     } else if (mhdp->connector_type ==
> DRM_MODE_CONNECTOR_HDMIA) {
> > +             mhdp->lane_mapping =
> mhdp->plat_data->hdmi_lane_mapping;
> > +             phy_mode = PHY_MODE_HDMI;
> > +     }
> 
> On imx8mq-zii-ultra board lane mapping doesn't follow your default setting.
> Please add a "lane-mapping" property in the DT to allow to customized this
> setting for each board.
> You can make it optional and keep the default value when the property is
> missing on the DT node.
> 

OK, "lane-mapping" property will be added in the next version.

Sandor

> Regards,
> Benjamin
> 
> > +
> > +     dev_set_drvdata(dev, mhdp);
> > +
> > +     /* init base struct for access mhdp mailbox */
> > +     mhdp->base.dev = mhdp->dev;
> > +     mhdp->base.regs = mhdp->regs;
> > +     mhdp->base.mbox_mutex = &mhdp->mbox_mutex;
> > +
> > +     if (mhdp->connector_type ==
> DRM_MODE_CONNECTOR_DisplayPort) {
> > +             drm_dp_aux_init(&mhdp->dp.aux);
> > +             mhdp->dp.aux.name = "mhdp8501_dp_aux";
> > +             mhdp->dp.aux.dev = dev;
> > +             mhdp->dp.aux.transfer = cdns_dp_aux_transfer;
> > +     }
> > +
> > +     /* Enable APB clock */
> > +     mhdp->apb_clk = devm_clk_get(dev, NULL);
> > +     if (IS_ERR(mhdp->apb_clk))
> > +             return dev_err_probe(dev, PTR_ERR(mhdp->apb_clk),
> > +                                  "couldn't get apb clk\n");
> > +
> > +     clk_prepare_enable(mhdp->apb_clk);
> > +
> > +     /*
> > +      * Wait for the KEEP_ALIVE "message" on the first 8 bits.
> > +      * Updated each sched "tick" (~2ms)
> > +      */
> > +     ret = readl_poll_timeout(mhdp->regs + KEEP_ALIVE, reg,
> > +                              reg & CDNS_KEEP_ALIVE_MASK, 500,
> > +                              CDNS_KEEP_ALIVE_TIMEOUT);
> > +     if (ret) {
> > +             dev_err(dev, "device didn't give any life sign: reg %d\n",
> reg);
> > +             goto clk_disable;
> > +     }
> > +
> > +     /* Mailbox protect for HDMI PHY access */
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +     ret = phy_init(mhdp->phy);
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +     if (ret) {
> > +             dev_err(dev, "Failed to initialize PHY: %d\n", ret);
> > +             goto clk_disable;
> > +     }
> > +
> > +     /* Mailbox protect for HDMI PHY access */
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +     ret = phy_set_mode(mhdp->phy, phy_mode);
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +     if (ret) {
> > +             dev_err(dev, "Failed to configure PHY: %d\n", ret);
> > +             goto clk_disable;
> > +     }
> > +
> > +     /* Enable cable hotplug detect */
> > +     if (cdns_mhdp8501_read_hpd(mhdp))
> > +             enable_irq(mhdp->irq[IRQ_OUT]);
> > +     else
> > +             enable_irq(mhdp->irq[IRQ_IN]);
> > +
> > +     cdns_mhdp8501_add_bridge(mhdp);
> > +
> > +     return 0;
> > +
> > +clk_disable:
> > +     clk_disable_unprepare(mhdp->apb_clk);
> > +
> > +     return -EINVAL;
> > +}
> > +
> > +static void cdns_mhdp8501_remove(struct platform_device *pdev)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp =
> platform_get_drvdata(pdev);
> > +
> > +     if (mhdp->connector_type ==
> DRM_MODE_CONNECTOR_DisplayPort)
> > +             cdns_dp_aux_destroy(mhdp);
> > +
> > +     drm_bridge_remove(&mhdp->bridge);
> > +     clk_disable_unprepare(mhdp->apb_clk);
> > +}
> > +
> > +static struct mhdp8501_plat_data imx8mq_mhdp_drv_data = {
> > +     .hdmi_lane_mapping = LANE_MAPPING_FLIPPED,
> > +     .dp_lane_mapping = LANE_MAPPING_IMX8MQ_DP,
> > +};
> > +
> > +static const struct of_device_id cdns_mhdp8501_dt_ids[] = {
> > +     { .compatible = "fsl,imx8mq-mhdp8501",
> > +       .data = &imx8mq_mhdp_drv_data
> > +     },
> > +     { },
> > +};
> > +MODULE_DEVICE_TABLE(of, cdns_mhdp8501_dt_ids);
> > +
> > +static struct platform_driver cdns_mhdp8501_driver = {
> > +     .probe = cdns_mhdp8501_probe,
> > +     .remove = cdns_mhdp8501_remove,
> > +     .driver = {
> > +             .name = "cdns-mhdp8501",
> > +             .of_match_table = cdns_mhdp8501_dt_ids,
> > +     },
> > +};
> > +
> > +module_platform_driver(cdns_mhdp8501_driver);
> > +
> > +MODULE_AUTHOR("Sandor Yu <sandor.yu at nxp.com>");
> > +MODULE_DESCRIPTION("Cadence MHDP8501 bridge driver");
> > +MODULE_LICENSE("GPL");
> > diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
> b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
> > new file mode 100644
> > index 000000000000..593071f36995
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
> > @@ -0,0 +1,367 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Cadence MHDP 8501 Common head file
> > + *
> > + * Copyright (C) 2019-2024 NXP Semiconductor, Inc.
> > + *
> > + */
> > +
> > +#ifndef _CDNS_MHDP8501_CORE_H_
> > +#define _CDNS_MHDP8501_CORE_H_
> > +
> > +#include <drm/bridge/cdns-mhdp-helper.h>
> > +#include <drm/drm_bridge.h>
> > +#include <drm/drm_connector.h>
> > +#include <drm/display/drm_dp_helper.h>
> > +#include <linux/bitops.h>
> > +
> > +#define ADDR_IMEM                    0x10000
> > +#define ADDR_DMEM                    0x20000
> > +
> > +/* APB CFG addr */
> > +#define APB_CTRL                     0
> > +#define XT_INT_CTRL                  0x04
> > +#define MAILBOX_FULL_ADDR            0x08
> > +#define MAILBOX_EMPTY_ADDR           0x0c
> > +#define MAILBOX0_WR_DATA             0x10
> > +#define MAILBOX0_RD_DATA             0x14
> > +#define KEEP_ALIVE                   0x18
> > +#define VER_L                                0x1c
> > +#define VER_H                                0x20
> > +#define VER_LIB_L_ADDR                       0x24
> > +#define VER_LIB_H_ADDR                       0x28
> > +#define SW_DEBUG_L                   0x2c
> > +#define SW_DEBUG_H                   0x30
> > +#define MAILBOX_INT_MASK             0x34
> > +#define MAILBOX_INT_STATUS           0x38
> > +#define SW_CLK_L                     0x3c
> > +#define SW_CLK_H                     0x40
> > +#define SW_EVENTS0                   0x44
> > +#define SW_EVENTS1                   0x48
> > +#define SW_EVENTS2                   0x4c
> > +#define SW_EVENTS3                   0x50
> > +#define XT_OCD_CTRL                  0x60
> > +#define APB_INT_MASK                 0x6c
> > +#define APB_STATUS_MASK                      0x70
> > +
> > +/* Source phy comp */
> > +#define PHY_DATA_SEL                 0x0818
> > +#define LANES_CONFIG                 0x0814
> > +
> > +/* Source CAR Addr */
> > +#define SOURCE_HDTX_CAR                      0x0900
> > +#define SOURCE_DPTX_CAR                      0x0904
> > +#define SOURCE_PHY_CAR                       0x0908
> > +#define SOURCE_CEC_CAR                       0x090c
> > +#define SOURCE_CBUS_CAR                      0x0910
> > +#define SOURCE_PKT_CAR                       0x0918
> > +#define SOURCE_AIF_CAR                       0x091c
> > +#define SOURCE_CIPHER_CAR            0x0920
> > +#define SOURCE_CRYPTO_CAR            0x0924
> > +
> > +/* clock meters addr */
> > +#define CM_CTRL                              0x0a00
> > +#define CM_I2S_CTRL                  0x0a04
> > +#define CM_SPDIF_CTRL                        0x0a08
> > +#define CM_VID_CTRL                  0x0a0c
> > +#define CM_LANE_CTRL                 0x0a10
> > +#define I2S_NM_STABLE                        0x0a14
> > +#define I2S_NCTS_STABLE                      0x0a18
> > +#define SPDIF_NM_STABLE                      0x0a1c
> > +#define SPDIF_NCTS_STABLE            0x0a20
> > +#define NMVID_MEAS_STABLE            0x0a24
> > +#define I2S_MEAS                     0x0a40
> > +#define SPDIF_MEAS                   0x0a80
> > +#define NMVID_MEAS                   0x0ac0
> > +
> > +/* source vif addr */
> > +#define BND_HSYNC2VSYNC                      0x0b00
> > +#define HSYNC2VSYNC_F1_L1            0x0b04
> > +#define HSYNC2VSYNC_STATUS           0x0b0c
> > +#define HSYNC2VSYNC_POL_CTRL         0x0b10
> > +
> > +/* MHDP TX_top_comp */
> > +#define SCHEDULER_H_SIZE             0x1000
> > +#define SCHEDULER_V_SIZE             0x1004
> > +#define HDTX_SIGNAL_FRONT_WIDTH              0x100c
> > +#define HDTX_SIGNAL_SYNC_WIDTH               0x1010
> > +#define HDTX_SIGNAL_BACK_WIDTH               0x1014
> > +#define HDTX_CONTROLLER                      0x1018
> > +#define HDTX_HPD                     0x1020
> > +#define HDTX_CLOCK_REG_0             0x1024
> > +#define HDTX_CLOCK_REG_1             0x1028
> > +
> > +/* DPTX hpd addr */
> > +#define HPD_IRQ_DET_MIN_TIMER                0x2100
> > +#define HPD_IRQ_DET_MAX_TIMER                0x2104
> > +#define HPD_UNPLGED_DET_MIN_TIMER    0x2108
> > +#define HPD_STABLE_TIMER             0x210c
> > +#define HPD_FILTER_TIMER             0x2110
> > +#define HPD_EVENT_MASK                       0x211c
> > +#define HPD_EVENT_DET                        0x2120
> > +
> > +/* DPTX framer addr */
> > +#define DP_FRAMER_GLOBAL_CONFIG              0x2200
> > +#define DP_SW_RESET                  0x2204
> > +#define DP_FRAMER_TU                 0x2208
> > +#define DP_FRAMER_PXL_REPR           0x220c
> > +#define DP_FRAMER_SP                 0x2210
> > +#define AUDIO_PACK_CONTROL           0x2214
> > +#define DP_VC_TABLE(x)                       (0x2218 + ((x) << 2))
> > +#define DP_VB_ID                     0x2258
> > +#define DP_MTPH_LVP_CONTROL          0x225c
> > +#define DP_MTPH_SYMBOL_VALUES                0x2260
> > +#define DP_MTPH_ECF_CONTROL          0x2264
> > +#define DP_MTPH_ACT_CONTROL          0x2268
> > +#define DP_MTPH_STATUS                       0x226c
> > +#define DP_INTERRUPT_SOURCE          0x2270
> > +#define DP_INTERRUPT_MASK            0x2274
> > +#define DP_FRONT_BACK_PORCH          0x2278
> > +#define DP_BYTE_COUNT                        0x227c
> > +
> > +/* DPTX stream addr */
> > +#define MSA_HORIZONTAL_0             0x2280
> > +#define MSA_HORIZONTAL_1             0x2284
> > +#define MSA_VERTICAL_0                       0x2288
> > +#define MSA_VERTICAL_1                       0x228c
> > +#define MSA_MISC                     0x2290
> > +#define STREAM_CONFIG                        0x2294
> > +#define AUDIO_PACK_STATUS            0x2298
> > +#define VIF_STATUS                   0x229c
> > +#define PCK_STUFF_STATUS_0           0x22a0
> > +#define PCK_STUFF_STATUS_1           0x22a4
> > +#define INFO_PACK_STATUS             0x22a8
> > +#define RATE_GOVERNOR_STATUS         0x22ac
> > +#define DP_HORIZONTAL                        0x22b0
> > +#define DP_VERTICAL_0                        0x22b4
> > +#define DP_VERTICAL_1                        0x22b8
> > +#define DP_BLOCK_SDP                 0x22bc
> > +
> > +/* DPTX glbl addr */
> > +#define DPTX_LANE_EN                 0x2300
> > +#define DPTX_ENHNCD                  0x2304
> > +#define DPTX_INT_MASK                        0x2308
> > +#define DPTX_INT_STATUS                      0x230c
> > +
> > +/* DP AUX Addr */
> > +#define DP_AUX_HOST_CONTROL          0x2800
> > +#define DP_AUX_INTERRUPT_SOURCE              0x2804
> > +#define DP_AUX_INTERRUPT_MASK                0x2808
> > +#define DP_AUX_SWAP_INVERSION_CONTROL        0x280c
> > +#define DP_AUX_SEND_NACK_TRANSACTION 0x2810
> > +#define DP_AUX_CLEAR_RX                      0x2814
> > +#define DP_AUX_CLEAR_TX                      0x2818
> > +#define DP_AUX_TIMER_STOP            0x281c
> > +#define DP_AUX_TIMER_CLEAR           0x2820
> > +#define DP_AUX_RESET_SW                      0x2824
> > +#define DP_AUX_DIVIDE_2M             0x2828
> > +#define DP_AUX_TX_PREACHARGE_LENGTH  0x282c
> > +#define DP_AUX_FREQUENCY_1M_MAX              0x2830
> > +#define DP_AUX_FREQUENCY_1M_MIN              0x2834
> > +#define DP_AUX_RX_PRE_MIN            0x2838
> > +#define DP_AUX_RX_PRE_MAX            0x283c
> > +#define DP_AUX_TIMER_PRESET          0x2840
> > +#define DP_AUX_NACK_FORMAT           0x2844
> > +#define DP_AUX_TX_DATA                       0x2848
> > +#define DP_AUX_RX_DATA                       0x284c
> > +#define DP_AUX_TX_STATUS             0x2850
> > +#define DP_AUX_RX_STATUS             0x2854
> > +#define DP_AUX_RX_CYCLE_COUNTER              0x2858
> > +#define DP_AUX_MAIN_STATES           0x285c
> > +#define DP_AUX_MAIN_TIMER            0x2860
> > +#define DP_AUX_AFE_OUT                       0x2864
> > +
> > +/* source pif addr */
> > +#define SOURCE_PIF_WR_ADDR           0x30800
> > +#define SOURCE_PIF_WR_REQ            0x30804
> > +#define SOURCE_PIF_RD_ADDR           0x30808
> > +#define SOURCE_PIF_RD_REQ            0x3080c
> > +#define SOURCE_PIF_DATA_WR           0x30810
> > +#define SOURCE_PIF_DATA_RD           0x30814
> > +#define SOURCE_PIF_FIFO1_FLUSH               0x30818
> > +#define SOURCE_PIF_FIFO2_FLUSH               0x3081c
> > +#define SOURCE_PIF_STATUS            0x30820
> > +#define SOURCE_PIF_INTERRUPT_SOURCE  0x30824
> > +#define SOURCE_PIF_INTERRUPT_MASK    0x30828
> > +#define SOURCE_PIF_PKT_ALLOC_REG     0x3082c
> > +#define SOURCE_PIF_PKT_ALLOC_WR_EN   0x30830
> > +#define SOURCE_PIF_SW_RESET          0x30834
> > +
> > +#define LINK_TRAINING_NOT_ACTIV              0
> > +#define LINK_TRAINING_RUN            1
> > +#define LINK_TRAINING_RESTART                2
> > +
> > +#define CONTROL_VIDEO_IDLE           0
> > +#define CONTROL_VIDEO_VALID          1
> > +
> > +#define INTERLACE_FMT_DET            BIT(12)
> > +#define VIF_BYPASS_INTERLACE         BIT(13)
> > +#define TU_CNT_RST_EN                        BIT(15)
> > +#define INTERLACE_DTCT_WIN           0x20
> > +
> > +#define DP_FRAMER_SP_INTERLACE_EN    BIT(2)
> > +#define DP_FRAMER_SP_HSP             BIT(1)
> > +#define DP_FRAMER_SP_VSP             BIT(0)
> > +
> > +/* Capability */
> > +#define AUX_HOST_INVERT                      3
> > +#define FAST_LT_SUPPORT                      1
> > +#define FAST_LT_NOT_SUPPORT          0
> > +#define LANE_MAPPING_NORMAL          0x1b
> > +#define LANE_MAPPING_FLIPPED         0xe4
> > +#define LANE_MAPPING_IMX8MQ_DP               0xc6
> > +#define ENHANCED                     1
> > +#define SCRAMBLER_EN                 BIT(4)
> > +
> > +#define FULL_LT_STARTED                      BIT(0)
> > +#define FASE_LT_STARTED                      BIT(1)
> > +#define CLK_RECOVERY_FINISHED                BIT(2)
> > +#define EQ_PHASE_FINISHED            BIT(3)
> > +#define FASE_LT_START_FINISHED               BIT(4)
> > +#define CLK_RECOVERY_FAILED          BIT(5)
> > +#define EQ_PHASE_FAILED                      BIT(6)
> > +#define FASE_LT_FAILED                       BIT(7)
> > +
> > +#define TU_SIZE                              30
> > +#define CDNS_DP_MAX_LINK_RATE                540000
> > +
> > +#define F_HDMI_ENCODING(x) (((x) & ((1 << 2) - 1)) << 16)
> > +#define F_VIF_DATA_WIDTH(x) (((x) & ((1 << 2) - 1)) << 2)
> > +#define F_HDMI_MODE(x) (((x) & ((1 << 2) - 1)) << 0)
> > +#define F_GCP_EN(x) (((x) & ((1 << 1) - 1)) << 12)
> > +#define F_DATA_EN(x) (((x) & ((1 << 1) - 1)) << 15)
> > +#define F_CLEAR_AVMUTE(x) (((x) & ((1 << 1) - 1)) << 14)
> > +#define F_HDMI2_PREAMBLE_EN(x) (((x) & ((1 << 1) - 1)) << 18)
> > +#define F_PIC_3D(x) (((x) & ((1 << 4) - 1)) << 7)
> > +#define F_BCH_EN(x) (((x) & ((1 << 1) - 1)) << 11)
> > +#define F_SOURCE_PHY_MHDP_SEL(x) (((x) & ((1 << 2) - 1)) << 3)
> > +#define F_HPD_VALID_WIDTH(x) (((x) & ((1 << 12) - 1)) << 0)
> > +#define F_HPD_GLITCH_WIDTH(x) (((x) & ((1 << 8) - 1)) << 12)
> > +#define F_HDMI2_CTRL_IL_MODE(x) (((x) & ((1 << 1) - 1)) << 19)
> > +#define F_SOURCE_PHY_LANE0_SWAP(x) (((x) & ((1 << 2) - 1)) << 0)
> > +#define F_SOURCE_PHY_LANE1_SWAP(x) (((x) & ((1 << 2) - 1)) << 2)
> > +#define F_SOURCE_PHY_LANE2_SWAP(x) (((x) & ((1 << 2) - 1)) << 4)
> > +#define F_SOURCE_PHY_LANE3_SWAP(x) (((x) & ((1 << 2) - 1)) << 6)
> > +#define F_SOURCE_PHY_COMB_BYPASS(x) (((x) & ((1 << 1) - 1)) << 21)
> > +#define F_SOURCE_PHY_20_10(x) (((x) & ((1 << 1) - 1)) << 22)
> > +#define F_PKT_ALLOC_ADDRESS(x) (((x) & ((1 << 4) - 1)) << 0)
> > +#define F_ACTIVE_IDLE_TYPE(x) (((x) & ((1 << 1) - 1)) << 17)
> > +#define F_FIFO1_FLUSH(x) (((x) & ((1 << 1) - 1)) << 0)
> > +#define F_PKT_ALLOC_WR_EN(x) (((x) & ((1 << 1) - 1)) << 0)
> > +#define F_DATA_WR(x) (x)
> > +#define F_WR_ADDR(x) (((x) & ((1 << 4) - 1)) << 0)
> > +#define F_HOST_WR(x) (((x) & ((1 << 1) - 1)) << 0)
> > +#define F_TYPE_VALID(x) (((x) & ((1 << 1) - 1)) << 16)
> > +#define F_PACKET_TYPE(x) (((x) & ((1 << 8) - 1)) << 8)
> > +
> > +/* Reference cycles when using lane clock as reference */
> > +#define LANE_REF_CYC                 0x8000
> > +
> > +/* HPD Debounce */
> > +#define HOTPLUG_DEBOUNCE_MS          200
> > +
> > +/* HPD IRQ Index */
> > +#define IRQ_IN    0
> > +#define IRQ_OUT   1
> > +#define IRQ_NUM   2
> > +
> > +/* FW check alive timeout */
> > +#define CDNS_KEEP_ALIVE_TIMEOUT              2000
> > +#define CDNS_KEEP_ALIVE_MASK         GENMASK(7, 0)
> > +
> > +enum voltage_swing_level {
> > +     VOLTAGE_LEVEL_0,
> > +     VOLTAGE_LEVEL_1,
> > +     VOLTAGE_LEVEL_2,
> > +     VOLTAGE_LEVEL_3,
> > +};
> > +
> > +enum pre_emphasis_level {
> > +     PRE_EMPHASIS_LEVEL_0,
> > +     PRE_EMPHASIS_LEVEL_1,
> > +     PRE_EMPHASIS_LEVEL_2,
> > +     PRE_EMPHASIS_LEVEL_3,
> > +};
> > +
> > +enum pattern_set {
> > +     PTS1 = BIT(0),
> > +     PTS2 = BIT(1),
> > +     PTS3 = BIT(2),
> > +     PTS4 = BIT(3),
> > +     DP_NONE = BIT(4)
> > +};
> > +
> > +enum vic_color_depth {
> > +     BCS_6 = 0x1,
> > +     BCS_8 = 0x2,
> > +     BCS_10 = 0x4,
> > +     BCS_12 = 0x8,
> > +     BCS_16 = 0x10,
> > +};
> > +
> > +enum vic_bt_type {
> > +     BT_601 = 0x0,
> > +     BT_709 = 0x1,
> > +};
> > +
> > +enum {
> > +     MODE_DVI,
> > +     MODE_HDMI_1_4,
> > +     MODE_HDMI_2_0,
> > +};
> > +
> > +struct video_info {
> > +     int bpc;
> > +     int color_fmt;
> > +};
> > +
> > +struct mhdp8501_plat_data {
> > +     int hdmi_lane_mapping;
> > +     int dp_lane_mapping;
> > +};
> > +
> > +struct cdns_mhdp8501_device {
> > +     struct cdns_mhdp_base base;
> > +
> > +     struct device *dev;
> > +     void __iomem *regs;
> > +     struct drm_connector *curr_conn;
> > +     struct drm_bridge bridge;
> > +     struct clk *apb_clk;
> > +     struct phy *phy;
> > +
> > +     struct video_info video_info;
> > +     struct drm_display_mode mode;
> > +
> > +     int irq[IRQ_NUM];
> > +     struct delayed_work hotplug_work;
> > +     int connector_type;
> > +     u32 lane_mapping;
> > +
> > +     /* protect mailbox communications with the firmware */
> > +     struct mutex mbox_mutex;
> > +
> > +     const struct mhdp8501_plat_data *plat_data;
> > +
> > +     union {
> > +             struct _dp_data {
> > +                     u32 rate;
> > +                     u8 num_lanes;
> > +                     struct drm_dp_aux aux;
> > +                     u8 dpcd[DP_RECEIVER_CAP_SIZE];
> > +             } dp;
> > +             struct _hdmi_data {
> > +                     u32 hdmi_type;
> > +                     unsigned long long char_rate;
> > +             } hdmi;
> > +     };
> > +};
> > +
> > +extern const struct drm_bridge_funcs cdns_dp_bridge_funcs;
> > +extern const struct drm_bridge_funcs cdns_hdmi_bridge_funcs;
> > +
> > +ssize_t cdns_dp_aux_transfer(struct drm_dp_aux *aux, struct
> drm_dp_aux_msg *msg);
> > +enum drm_connector_status cdns_mhdp8501_detect(struct
> cdns_mhdp8501_device *mhdp);
> > +int cdns_dp_aux_destroy(struct cdns_mhdp8501_device *mhdp);
> > +
> > +#endif
> > diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> > new file mode 100644
> > index 000000000000..d8cc31daf322
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> > @@ -0,0 +1,700 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Cadence MHDP8501 DisplayPort(DP) bridge driver
> > + *
> > + * Copyright (C) 2019-2024 NXP Semiconductor, Inc.
> > + *
> > + */
> > +#include <drm/drm_atomic_helper.h>
> > +#include <drm/drm_edid.h>
> > +#include <drm/drm_print.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/phy/phy-dp.h>
> > +
> > +#include "cdns-mhdp8501-core.h"
> > +
> > +#define LINK_TRAINING_TIMEOUT_MS     500
> > +#define LINK_TRAINING_RETRY_MS               20
> > +
> > +ssize_t cdns_dp_aux_transfer(struct drm_dp_aux *aux,
> > +                          struct drm_dp_aux_msg *msg)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = dev_get_drvdata(aux->dev);
> > +     bool native = msg->request & (DP_AUX_NATIVE_WRITE &
> DP_AUX_NATIVE_READ);
> > +     int ret;
> > +
> > +     /* Ignore address only message */
> > +     if (!msg->size || !msg->buffer) {
> > +             msg->reply = native ?
> > +                     DP_AUX_NATIVE_REPLY_ACK :
> DP_AUX_I2C_REPLY_ACK;
> > +             return msg->size;
> > +     }
> > +
> > +     if (!native) {
> > +             dev_err(mhdp->dev, "%s: only native messages
> supported\n", __func__);
> > +             return -EINVAL;
> > +     }
> > +
> > +     /* msg sanity check */
> > +     if (msg->size > DP_AUX_MAX_PAYLOAD_BYTES) {
> > +             dev_err(mhdp->dev, "%s: invalid msg: size(%zu),
> request(%x)\n",
> > +                     __func__, msg->size, (unsigned
> int)msg->request);
> > +             return -EINVAL;
> > +     }
> > +
> > +     if (msg->request == DP_AUX_NATIVE_WRITE) {
> > +             const u8 *buf = msg->buffer;
> > +             int i;
> > +
> > +             for (i = 0; i < msg->size; ++i) {
> > +                     ret = cdns_mhdp_dpcd_write(&mhdp->base,
> > +                                                msg->address +
> i, buf[i]);
> > +                     if (ret < 0) {
> > +                             dev_err(mhdp->dev, "Failed to write
> DPCD\n");
> > +                             return ret;
> > +                     }
> > +             }
> > +             msg->reply = DP_AUX_NATIVE_REPLY_ACK;
> > +             return msg->size;
> > +     }
> > +
> > +     if (msg->request == DP_AUX_NATIVE_READ) {
> > +             ret = cdns_mhdp_dpcd_read(&mhdp->base, msg->address,
> > +                                       msg->buffer, msg->size);
> > +             if (ret < 0)
> > +                     return ret;
> > +             msg->reply = DP_AUX_NATIVE_REPLY_ACK;
> > +             return msg->size;
> > +     }
> > +     return 0;
> > +}
> > +
> > +int cdns_dp_aux_destroy(struct cdns_mhdp8501_device *mhdp)
> > +{
> > +     drm_dp_aux_unregister(&mhdp->dp.aux);
> > +
> > +     return 0;
> > +}
> > +
> > +static int cdns_dp_get_msa_misc(struct video_info *video)
> > +{
> > +     u32 msa_misc;
> > +     u8 color_space = 0;
> > +     u8 bpc = 0;
> > +
> > +     switch (video->color_fmt) {
> > +     /* set YUV default color space conversion to BT601 */
> > +     case DRM_COLOR_FORMAT_YCBCR444:
> > +             color_space = 6 + BT_601 * 8;
> > +             break;
> > +     case DRM_COLOR_FORMAT_YCBCR422:
> > +             color_space = 5 + BT_601 * 8;
> > +             break;
> > +     case DRM_COLOR_FORMAT_YCBCR420:
> > +             color_space = 5;
> > +             break;
> > +     case DRM_COLOR_FORMAT_RGB444:
> > +     default:
> > +             color_space = 0;
> > +             break;
> > +     };
> > +
> > +     switch (video->bpc) {
> > +     case 6:
> > +             bpc = 0;
> > +             break;
> > +     case 10:
> > +             bpc = 2;
> > +             break;
> > +     case 12:
> > +             bpc = 3;
> > +             break;
> > +     case 16:
> > +             bpc = 4;
> > +             break;
> > +     case 8:
> > +     default:
> > +             bpc = 1;
> > +             break;
> > +     };
> > +
> > +     msa_misc = (bpc << 5) | (color_space << 1);
> > +
> > +     return msa_misc;
> > +}
> > +
> > +static int cdns_dp_config_video(struct cdns_mhdp8501_device *mhdp)
> > +{
> > +     struct video_info *video = &mhdp->video_info;
> > +     struct drm_display_mode *mode = &mhdp->mode;
> > +     bool h_sync_polarity, v_sync_polarity;
> > +     u64 symbol;
> > +     u32 val, link_rate, rem;
> > +     u8 bit_per_pix, tu_size_reg = TU_SIZE;
> > +     int ret;
> > +
> > +     bit_per_pix = (video->color_fmt ==
> DRM_COLOR_FORMAT_YCBCR422) ?
> > +                   (video->bpc * 2) : (video->bpc * 3);
> > +
> > +     link_rate = mhdp->dp.rate / 1000;
> > +
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, BND_HSYNC2VSYNC,
> VIF_BYPASS_INTERLACE);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     ret = cdns_mhdp_reg_write(&mhdp->base,
> HSYNC2VSYNC_POL_CTRL, 0);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     /*
> > +      * get a best tu_size and valid symbol:
> > +      * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32
> > +      * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes)
> > +      * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set
> > +      *    TU += 2 and repeat 2nd step.
> > +      */
> > +     do {
> > +             tu_size_reg += 2;
> > +             symbol = tu_size_reg * mode->clock * bit_per_pix;
> > +             do_div(symbol, mhdp->dp.num_lanes * link_rate * 8);
> > +             rem = do_div(symbol, 1000);
> > +             if (tu_size_reg > 64) {
> > +                     ret = -EINVAL;
> > +                     dev_err(mhdp->dev, "tu error, clk:%d, lanes:%d,
> rate:%d\n",
> > +                             mode->clock, mhdp->dp.num_lanes,
> link_rate);
> > +                     goto err_config_video;
> > +             }
> > +     } while ((symbol <= 1) || (tu_size_reg - symbol < 4) ||
> > +              (rem > 850) || (rem < 100));
> > +
> > +     val = symbol + (tu_size_reg << 8);
> > +     val |= TU_CNT_RST_EN;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_TU, val);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     /* set the FIFO Buffer size */
> > +     val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate;
> > +     val /= (mhdp->dp.num_lanes * link_rate);
> > +     val = div_u64(8 * (symbol + 1), bit_per_pix) - val;
> > +     val += 2;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, DP_VC_TABLE(15), val);
> > +
> > +     switch (video->bpc) {
> > +     case 6:
> > +             val = BCS_6;
> > +             break;
> > +     case 10:
> > +             val = BCS_10;
> > +             break;
> > +     case 12:
> > +             val = BCS_12;
> > +             break;
> > +     case 16:
> > +             val = BCS_16;
> > +             break;
> > +     case 8:
> > +     default:
> > +             val = BCS_8;
> > +             break;
> > +     };
> > +
> > +     val += video->color_fmt << 8;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_PXL_REPR,
> val);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
> > +     h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
> > +
> > +     val = h_sync_polarity ? DP_FRAMER_SP_HSP : 0;
> > +     val |= v_sync_polarity ? DP_FRAMER_SP_VSP : 0;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_SP, val);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     val = (mode->hsync_start - mode->hdisplay) << 16;
> > +     val |= mode->htotal - mode->hsync_end;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base,
> DP_FRONT_BACK_PORCH, val);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     val = mode->hdisplay * bit_per_pix / 8;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, DP_BYTE_COUNT, val);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16);
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, MSA_HORIZONTAL_0,
> val);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     val = mode->hsync_end - mode->hsync_start;
> > +     val |= (mode->hdisplay << 16) | (h_sync_polarity << 15);
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, MSA_HORIZONTAL_1,
> val);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     val = mode->vtotal;
> > +     val |= (mode->vtotal - mode->vsync_start) << 16;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, MSA_VERTICAL_0, val);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     val = mode->vsync_end - mode->vsync_start;
> > +     val |= (mode->vdisplay << 16) | (v_sync_polarity << 15);
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, MSA_VERTICAL_1, val);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     val = cdns_dp_get_msa_misc(video);
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, MSA_MISC, val);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, STREAM_CONFIG, 1);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     val = mode->hsync_end - mode->hsync_start;
> > +     val |= mode->hdisplay << 16;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, DP_HORIZONTAL, val);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     val = mode->vdisplay;
> > +     val |= (mode->vtotal - mode->vsync_start) << 16;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, DP_VERTICAL_0, val);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     val = mode->vtotal;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, DP_VERTICAL_1, val);
> > +     if (ret)
> > +             goto err_config_video;
> > +
> > +     ret = cdns_mhdp_dp_reg_write_bit(&mhdp->base, DP_VB_ID, 2, 1,
> 0);
> > +
> > +err_config_video:
> > +     if (ret)
> > +             dev_err(mhdp->dev, "config video failed: %d\n", ret);
> > +     return ret;
> > +}
> > +
> > +static void cdns_dp_pixel_clk_reset(struct cdns_mhdp8501_device *mhdp)
> > +{
> > +     u32 val;
> > +
> > +     /* reset pixel clk */
> > +     cdns_mhdp_reg_read(&mhdp->base, SOURCE_HDTX_CAR, &val);
> > +     cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR, val &
> 0xFD);
> > +     cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR, val);
> > +}
> > +
> > +static int cdns_dp_set_video_status(struct cdns_mhdp8501_device *mhdp,
> int active)
> > +{
> > +     u8 msg;
> > +     int ret;
> > +
> > +     msg = !!active;
> > +
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +
> > +     ret = cdns_mhdp_mailbox_send(&mhdp->base,
> MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO,
> > +                                  sizeof(msg), &msg);
> > +     if (ret)
> > +             dev_err(mhdp->dev, "set video status failed: %d\n", ret);
> > +
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +
> > +     return ret;
> > +}
> > +
> > +static int cdns_dp_training_start(struct cdns_mhdp8501_device *mhdp)
> > +{
> > +     unsigned long timeout;
> > +     u8 msg, event[2];
> > +     int ret;
> > +
> > +     msg = LINK_TRAINING_RUN;
> > +
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +
> > +     /* start training */
> > +     ret = cdns_mhdp_mailbox_send(&mhdp->base,
> MB_MODULE_ID_DP_TX,
> > +                                  DPTX_TRAINING_CONTROL,
> sizeof(msg), &msg);
> > +     if (ret)
> > +             goto err_training_start;
> > +
> > +     timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS);
> > +     while (time_before(jiffies, timeout)) {
> > +             msleep(LINK_TRAINING_RETRY_MS);
> > +             ret = cdns_mhdp_mailbox_send(&mhdp->base,
> MB_MODULE_ID_DP_TX,
> > +                                          DPTX_READ_EVENT, 0,
> NULL);
> > +             if (ret)
> > +                     goto err_training_start;
> > +
> > +             ret = cdns_mhdp_mailbox_recv_header(&mhdp->base,
> MB_MODULE_ID_DP_TX,
> > +
> DPTX_READ_EVENT, sizeof(event));
> > +             if (ret)
> > +                     goto err_training_start;
> > +
> > +             ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, event,
> sizeof(event));
> > +             if (ret)
> > +                     goto err_training_start;
> > +
> > +             if (event[1] & CLK_RECOVERY_FAILED) {
> > +                     dev_err(mhdp->dev, "clock recovery failed\n");
> > +             } else if (event[1] & EQ_PHASE_FINISHED) {
> > +                     mutex_unlock(&mhdp->mbox_mutex);
> > +                     return 0;
> > +             }
> > +     }
> > +
> > +     ret = -ETIMEDOUT;
> > +
> > +err_training_start:
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +
> > +     dev_err(mhdp->dev, "training failed: %d\n", ret);
> > +     return ret;
> > +}
> > +
> > +static int cdns_dp_get_training_status(struct cdns_mhdp8501_device
> *mhdp)
> > +{
> > +     u8 status[13];
> > +     int ret;
> > +
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +
> > +     ret = cdns_mhdp_mailbox_send(&mhdp->base,
> MB_MODULE_ID_DP_TX,
> > +                                  DPTX_READ_LINK_STAT, 0,
> NULL);
> > +     if (ret)
> > +             goto err_get_training_status;
> > +
> > +     ret = cdns_mhdp_mailbox_recv_header(&mhdp->base,
> MB_MODULE_ID_DP_TX,
> > +                                         DPTX_READ_LINK_STAT,
> > +                                         sizeof(status));
> > +     if (ret)
> > +             goto err_get_training_status;
> > +
> > +     ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, status,
> sizeof(status));
> > +     if (ret)
> > +             goto err_get_training_status;
> > +
> > +     mhdp->dp.rate = drm_dp_bw_code_to_link_rate(status[0]);
> > +     mhdp->dp.num_lanes = status[1];
> > +
> > +err_get_training_status:
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +
> > +     if (ret)
> > +             dev_err(mhdp->dev, "get training status failed: %d\n", ret);
> > +     return ret;
> > +}
> > +
> > +static int cdns_dp_train_link(struct cdns_mhdp8501_device *mhdp)
> > +{
> > +     int ret;
> > +
> > +     ret = cdns_dp_training_start(mhdp);
> > +     if (ret) {
> > +             dev_err(mhdp->dev, "Failed to start training %d\n", ret);
> > +             return ret;
> > +     }
> > +
> > +     ret = cdns_dp_get_training_status(mhdp);
> > +     if (ret) {
> > +             dev_err(mhdp->dev, "Failed to get training stat %d\n",
> ret);
> > +             return ret;
> > +     }
> > +
> > +     dev_dbg(mhdp->dev, "rate:0x%x, lanes:%d\n", mhdp->dp.rate,
> > +             mhdp->dp.num_lanes);
> > +     return ret;
> > +}
> > +
> > +static int cdns_dp_set_host_cap(struct cdns_mhdp8501_device *mhdp)
> > +{
> > +     u8 msg[8];
> > +     int ret;
> > +
> > +     msg[0] = drm_dp_link_rate_to_bw_code(mhdp->dp.rate);
> > +     msg[1] = mhdp->dp.num_lanes | SCRAMBLER_EN;
> > +     msg[2] = VOLTAGE_LEVEL_2;
> > +     msg[3] = PRE_EMPHASIS_LEVEL_3;
> > +     msg[4] = PTS1 | PTS2 | PTS3 | PTS4;
> > +     msg[5] = FAST_LT_NOT_SUPPORT;
> > +     msg[6] = mhdp->lane_mapping;
> > +     msg[7] = ENHANCED;
> > +
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +
> > +     ret = cdns_mhdp_mailbox_send(&mhdp->base,
> MB_MODULE_ID_DP_TX,
> > +                                  DPTX_SET_HOST_CAPABILITIES,
> > +                                  sizeof(msg), msg);
> > +
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +
> > +     if (ret)
> > +             dev_err(mhdp->dev, "set host cap failed: %d\n", ret);
> > +
> > +     return ret;
> > +}
> > +
> > +static int cdns_dp_get_edid_block(void *data, u8 *edid,
> > +                               unsigned int block, size_t length)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = data;
> > +     u8 msg[2], reg[2], i;
> > +     int ret;
> > +
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +
> > +     for (i = 0; i < 4; i++) {
> > +             msg[0] = block / 2;
> > +             msg[1] = block % 2;
> > +
> > +             ret = cdns_mhdp_mailbox_send(&mhdp->base,
> MB_MODULE_ID_DP_TX,
> > +                                          DPTX_GET_EDID,
> sizeof(msg), msg);
> > +             if (ret)
> > +                     continue;
> > +
> > +             ret = cdns_mhdp_mailbox_recv_header(&mhdp->base,
> MB_MODULE_ID_DP_TX,
> > +
> DPTX_GET_EDID,
> > +                                                 sizeof(reg) +
> length);
> > +             if (ret)
> > +                     continue;
> > +
> > +             ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg,
> sizeof(reg));
> > +             if (ret)
> > +                     continue;
> > +
> > +             ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, edid,
> length);
> > +             if (ret)
> > +                     continue;
> > +
> > +             if (reg[0] == length && reg[1] == block / 2)
> > +                     break;
> > +     }
> > +
> > +     if (ret)
> > +             dev_err(mhdp->dev, "get block[%d] edid failed: %d\n",
> block, ret);
> > +
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +     return ret;
> > +}
> > +
> > +static void cdns_dp_mode_set(struct cdns_mhdp8501_device *mhdp)
> > +{
> > +     union phy_configure_opts phy_cfg;
> > +     int ret;
> > +
> > +     cdns_dp_pixel_clk_reset(mhdp);
> > +
> > +     /* Get DP Caps  */
> > +     ret = drm_dp_dpcd_read(&mhdp->dp.aux, DP_DPCD_REV,
> mhdp->dp.dpcd,
> > +                            DP_RECEIVER_CAP_SIZE);
> > +     if (ret < 0) {
> > +             dev_err(mhdp->dev, "Failed to get caps %d\n", ret);
> > +             return;
> > +     }
> > +
> > +     mhdp->dp.rate = drm_dp_max_link_rate(mhdp->dp.dpcd);
> > +     mhdp->dp.num_lanes = drm_dp_max_lane_count(mhdp->dp.dpcd);
> > +
> > +     /* check the max link rate */
> > +     if (mhdp->dp.rate > CDNS_DP_MAX_LINK_RATE)
> > +             mhdp->dp.rate = CDNS_DP_MAX_LINK_RATE;
> > +
> > +     phy_cfg.dp.lanes = mhdp->dp.num_lanes;
> > +     phy_cfg.dp.link_rate = mhdp->dp.rate;
> > +     phy_cfg.dp.set_lanes = false;
> > +     phy_cfg.dp.set_rate = false;
> > +     phy_cfg.dp.set_voltages = true;
> > +
> > +     /* Mailbox protect for DP PHY access */
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +     ret = phy_configure(mhdp->phy, &phy_cfg);
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +     if (ret) {
> > +             dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
> > +                     __func__, ret);
> > +             return;
> > +     }
> > +
> > +     /* Video off */
> > +     ret = cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_IDLE);
> > +     if (ret) {
> > +             dev_err(mhdp->dev, "Failed to valid video %d\n", ret);
> > +             return;
> > +     }
> > +
> > +     /* Line swapping */
> > +     cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000
> | mhdp->lane_mapping);
> > +
> > +     /* Set DP host capability */
> > +     ret = cdns_dp_set_host_cap(mhdp);
> > +     if (ret) {
> > +             dev_err(mhdp->dev, "Failed to set host cap %d\n", ret);
> > +             return;
> > +     }
> > +
> > +     ret = cdns_mhdp_reg_write(&mhdp->base,
> DP_AUX_SWAP_INVERSION_CONTROL,
> > +                               AUX_HOST_INVERT);
> > +     if (ret) {
> > +             dev_err(mhdp->dev, "Failed to set host invert %d\n", ret);
> > +             return;
> > +     }
> > +
> > +     ret = cdns_dp_config_video(mhdp);
> > +     if (ret)
> > +             dev_err(mhdp->dev, "Failed to config video %d\n", ret);
> > +}
> > +
> > +static int cdns_dp_bridge_attach(struct drm_bridge *bridge,
> > +                              enum drm_bridge_attach_flags flags)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +
> > +     if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
> > +             dev_err(mhdp->dev, "do not support creating a
> drm_connector\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     mhdp->dp.aux.drm_dev = bridge->dev;
> > +
> > +     return drm_dp_aux_register(&mhdp->dp.aux);
> > +}
> > +
> > +static enum drm_mode_status
> > +cdns_dp_bridge_mode_valid(struct drm_bridge *bridge,
> > +                       const struct drm_display_info *info,
> > +                       const struct drm_display_mode *mode)
> > +{
> > +     enum drm_mode_status mode_status = MODE_OK;
> > +
> > +     /* We don't support double-clocked modes */
> > +     if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
> > +         mode->flags & DRM_MODE_FLAG_INTERLACE)
> > +             return MODE_BAD;
> > +
> > +     /* MAX support pixel clock rate 594MHz */
> > +     if (mode->clock > 594000)
> > +             return MODE_CLOCK_HIGH;
> > +
> > +     if (mode->hdisplay > 3840)
> > +             return MODE_BAD_HVALUE;
> > +
> > +     if (mode->vdisplay > 2160)
> > +             return MODE_BAD_VVALUE;
> > +
> > +     return mode_status;
> > +}
> > +
> > +static enum drm_connector_status
> > +cdns_dp_bridge_detect(struct drm_bridge *bridge)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +
> > +     return cdns_mhdp8501_detect(mhdp);
> > +}
> > +
> > +static const struct drm_edid
> > +*cdns_dp_bridge_edid_read(struct drm_bridge *bridge,
> > +                       struct drm_connector *connector)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +
> > +     return drm_edid_read_custom(connector, cdns_dp_get_edid_block,
> mhdp);
> > +}
> > +
> > +static void cdns_dp_bridge_atomic_disable(struct drm_bridge *bridge,
> > +                                       struct drm_bridge_state
> *old_state)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +
> > +     cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_IDLE);
> > +     mhdp->curr_conn = NULL;
> > +
> > +     /* Mailbox protect for DP PHY access */
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +     phy_power_off(mhdp->phy);
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +}
> > +
> > +static void cdns_dp_bridge_atomic_enable(struct drm_bridge *bridge,
> > +                                      struct drm_bridge_state
> *old_state)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +     struct drm_atomic_state *state = old_state->base.state;
> > +     struct drm_connector *connector;
> > +     struct video_info *video = &mhdp->video_info;
> > +     struct drm_crtc_state *crtc_state;
> > +     struct drm_connector_state *conn_state;
> > +     const struct drm_display_mode *mode;
> > +     int ret;
> > +
> > +     connector = drm_atomic_get_new_connector_for_encoder(state,
> > +
> bridge->encoder);
> > +     if (WARN_ON(!connector))
> > +             return;
> > +
> > +     mhdp->curr_conn = connector;
> > +
> > +     conn_state = drm_atomic_get_new_connector_state(state,
> connector);
> > +     if (WARN_ON(!conn_state))
> > +             return;
> > +
> > +     crtc_state = drm_atomic_get_new_crtc_state(state,
> conn_state->crtc);
> > +     if (WARN_ON(!crtc_state))
> > +             return;
> > +
> > +     mode = &crtc_state->adjusted_mode;
> > +
> > +     switch (connector->display_info.bpc) {
> > +     case 10:
> > +             video->bpc = 10;
> > +             break;
> > +     case 6:
> > +             video->bpc = 6;
> > +             break;
> > +     default:
> > +             video->bpc = 8;
> > +             break;
> > +     }
> > +
> > +     /* The only currently supported format */
> > +     video->color_fmt = DRM_COLOR_FORMAT_RGB444;
> > +
> > +     dev_dbg(mhdp->dev, "Mode: %dx%dp%d\n",
> > +             mode->hdisplay, mode->vdisplay, mode->clock);
> > +     memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode));
> > +
> > +     cdns_dp_mode_set(mhdp);
> > +
> > +     /* Link trainning */
> > +     ret = cdns_dp_train_link(mhdp);
> > +     if (ret) {
> > +             dev_err(mhdp->dev, "Failed link train %d\n", ret);
> > +             return;
> > +     }
> > +
> > +     ret = cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_VALID);
> > +     if (ret) {
> > +             dev_err(mhdp->dev, "Failed to valid video %d\n", ret);
> > +             return;
> > +     }
> > +}
> > +
> > +const struct drm_bridge_funcs cdns_dp_bridge_funcs = {
> > +     .attach = cdns_dp_bridge_attach,
> > +     .detect = cdns_dp_bridge_detect,
> > +     .edid_read = cdns_dp_bridge_edid_read,
> > +     .mode_valid = cdns_dp_bridge_mode_valid,
> > +     .atomic_enable = cdns_dp_bridge_atomic_enable,
> > +     .atomic_disable = cdns_dp_bridge_atomic_disable,
> > +     .atomic_duplicate_state =
> drm_atomic_helper_bridge_duplicate_state,
> > +     .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> > +     .atomic_reset = drm_atomic_helper_bridge_reset,
> > +};
> > diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> > new file mode 100644
> > index 000000000000..834ca9788a5f
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> > @@ -0,0 +1,595 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Cadence MHDP8501 HDMI bridge driver
> > + *
> > + * Copyright (C) 2019-2024 NXP Semiconductor, Inc.
> > + *
> > + */
> > +#include <drm/display/drm_hdmi_helper.h>
> > +#include <drm/display/drm_hdmi_state_helper.h>
> > +#include <drm/display/drm_scdc_helper.h>
> > +#include <drm/drm_atomic_helper.h>
> > +#include <drm/drm_edid.h>
> > +#include <drm/drm_print.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/phy/phy-hdmi.h>
> > +
> > +#include "cdns-mhdp8501-core.h"
> > +
> > +/**
> > + * cdns_hdmi_config_infoframe() - fill the HDMI infoframe
> > + * @mhdp: phandle to mhdp device.
> > + * @entry_id: The packet memory address in which the data is written.
> > + * @len: length of infoframe.
> > + * @buf: point to InfoFrame Packet.
> > + * @type: Packet Type of InfoFrame in HDMI Specification.
> > + *
> > + */
> > +static void cdns_hdmi_config_infoframe(struct cdns_mhdp8501_device
> *mhdp,
> > +                                    u8 entry_id, u8 len,
> > +                                    const u8 *buf, u8 type)
> > +{
> > +     u8 packet[32], packet_len = 32;
> > +     u32 packet32, len32;
> > +     u32 val, i;
> > +
> > +     /*
> > +      * only support 32 bytes now
> > +      * packet[0] = 0
> > +      * packet[1-3] = HB[0-2]  InfoFrame Packet Header
> > +      * packet[4-31 = PB[0-27] InfoFrame Packet Contents
> > +      */
> > +     if (len >= (packet_len - 1))
> > +             return;
> > +     packet[0] = 0;
> > +     memcpy(packet + 1, buf, len);
> > +
> > +     /* invalidate entry */
> > +     val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id);
> > +     writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG);
> > +     writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs +
> SOURCE_PIF_PKT_ALLOC_WR_EN);
> > +
> > +     /* flush fifo 1 */
> > +     writel(F_FIFO1_FLUSH(1), mhdp->regs + SOURCE_PIF_FIFO1_FLUSH);
> > +
> > +     /* write packet into memory */
> > +     len32 = packet_len / 4;
> > +     for (i = 0; i < len32; i++) {
> > +             packet32 = get_unaligned_le32(packet + 4 * i);
> > +             writel(F_DATA_WR(packet32), mhdp->regs +
> SOURCE_PIF_DATA_WR);
> > +     }
> > +
> > +     /* write entry id */
> > +     writel(F_WR_ADDR(entry_id), mhdp->regs +
> SOURCE_PIF_WR_ADDR);
> > +
> > +     /* write request */
> > +     writel(F_HOST_WR(1), mhdp->regs + SOURCE_PIF_WR_REQ);
> > +
> > +     /* update entry */
> > +     val = F_ACTIVE_IDLE_TYPE(1) | F_TYPE_VALID(1) |
> > +             F_PACKET_TYPE(type) |
> F_PKT_ALLOC_ADDRESS(entry_id);
> > +     writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG);
> > +
> > +     writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs +
> SOURCE_PIF_PKT_ALLOC_WR_EN);
> > +}
> > +
> > +static int cdns_hdmi_get_edid_block(void *data, u8 *edid,
> > +                                 u32 block, size_t length)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = data;
> > +     u8 msg[2], reg[5], i;
> > +     int ret;
> > +
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +
> > +     for (i = 0; i < 4; i++) {
> > +             msg[0] = block / 2;
> > +             msg[1] = block % 2;
> > +
> > +             ret = cdns_mhdp_mailbox_send(&mhdp->base,
> MB_MODULE_ID_HDMI_TX, HDMI_TX_EDID,
> > +                                          sizeof(msg), msg);
> > +             if (ret)
> > +                     continue;
> > +
> > +             ret = cdns_mhdp_mailbox_recv_header(&mhdp->base,
> MB_MODULE_ID_HDMI_TX,
> > +
> HDMI_TX_EDID, sizeof(reg) + length);
> > +             if (ret)
> > +                     continue;
> > +
> > +             ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg,
> sizeof(reg));
> > +             if (ret)
> > +                     continue;
> > +
> > +             ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, edid,
> length);
> > +             if (ret)
> > +                     continue;
> > +
> > +             if ((reg[3] << 8 | reg[4]) == length)
> > +                     break;
> > +     }
> > +
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +
> > +     if (ret)
> > +             dev_err(mhdp->dev, "get block[%d] edid failed: %d\n",
> block, ret);
> > +     return ret;
> > +}
> > +
> > +static int cdns_hdmi_scdc_write(struct cdns_mhdp8501_device *mhdp, u8
> addr, u8 value)
> > +{
> > +     u8 msg[5], reg[5];
> > +     int ret;
> > +
> > +     msg[0] = 0x54;
> > +     msg[1] = addr;
> > +     msg[2] = 0;
> > +     msg[3] = 1;
> > +     msg[4] = value;
> > +
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +
> > +     ret = cdns_mhdp_mailbox_send(&mhdp->base,
> MB_MODULE_ID_HDMI_TX, HDMI_TX_WRITE,
> > +                                  sizeof(msg), msg);
> > +     if (ret)
> > +             goto err_scdc_write;
> > +
> > +     ret = cdns_mhdp_mailbox_recv_header(&mhdp->base,
> MB_MODULE_ID_HDMI_TX,
> > +                                         HDMI_TX_WRITE,
> sizeof(reg));
> > +     if (ret)
> > +             goto err_scdc_write;
> > +
> > +     ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg,
> sizeof(reg));
> > +     if (ret)
> > +             goto err_scdc_write;
> > +
> > +     if (reg[0] != 0)
> > +             ret = -EINVAL;
> > +
> > +err_scdc_write:
> > +
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +
> > +     if (ret)
> > +             dev_err(mhdp->dev, "scdc write failed: %d\n", ret);
> > +     return ret;
> > +}
> > +
> > +static int cdns_hdmi_ctrl_init(struct cdns_mhdp8501_device *mhdp)
> > +{
> > +     unsigned long long char_rate = mhdp->hdmi.char_rate;
> > +     u32 protocol = mhdp->hdmi.hdmi_type;
> > +     u32 reg0, reg1, val;
> > +     int ret;
> > +
> > +     /* Set PHY to HDMI data */
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, PHY_DATA_SEL,
> F_SOURCE_PHY_MHDP_SEL(1));
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_HPD,
> > +                               F_HPD_VALID_WIDTH(4) |
> F_HPD_GLITCH_WIDTH(0));
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     /* open CARS */
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_PHY_CAR, 0xF);
> > +     if (ret < 0)
> > +             return ret;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR,
> 0xFF);
> > +     if (ret < 0)
> > +             return ret;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_PKT_CAR, 0xF);
> > +     if (ret < 0)
> > +             return ret;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_AIF_CAR, 0xF);
> > +     if (ret < 0)
> > +             return ret;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CIPHER_CAR,
> 0xF);
> > +     if (ret < 0)
> > +             return ret;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CRYPTO_CAR,
> 0xF);
> > +     if (ret < 0)
> > +             return ret;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CEC_CAR, 3);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     reg0 = 0x7c1f;
> > +     reg1 = 0x7c1f;
> > +     if (protocol == MODE_HDMI_2_0 && char_rate >= 340000000) {
> > +             reg0 = 0;
> > +             reg1 = 0xFFFFF;
> > +     }
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_0,
> reg0);
> > +     if (ret < 0)
> > +             return ret;
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_1,
> reg1);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     /* set HDMI mode and preemble mode data enable */
> > +     val = F_HDMI_MODE(protocol) | F_HDMI2_PREAMBLE_EN(1) |
> > +           F_DATA_EN(1) | F_HDMI2_CTRL_IL_MODE(1) | F_BCH_EN(1)
> |
> > +           F_PIC_3D(0XF) | F_CLEAR_AVMUTE(1);
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER,
> val);
> > +
> > +     return ret;
> > +}
> > +
> > +static int cdns_hdmi_mode_config(struct cdns_mhdp8501_device *mhdp,
> > +                              struct drm_display_mode *mode,
> > +                              struct video_info *video_info)
> > +{
> > +     u32 vsync_lines = mode->vsync_end - mode->vsync_start;
> > +     u32 eof_lines = mode->vsync_start - mode->vdisplay;
> > +     u32 sof_lines = mode->vtotal - mode->vsync_end;
> > +     u32 hblank = mode->htotal - mode->hdisplay;
> > +     u32 hactive = mode->hdisplay;
> > +     u32 vblank = mode->vtotal - mode->vdisplay;
> > +     u32 vactive = mode->vdisplay;
> > +     u32 hfront = mode->hsync_start - mode->hdisplay;
> > +     u32 hback = mode->htotal - mode->hsync_end;
> > +     u32 vfront = eof_lines;
> > +     u32 hsync = hblank - hfront - hback;
> > +     u32 vsync = vsync_lines;
> > +     u32 vback = sof_lines;
> > +     u32 v_h_polarity = ((mode->flags & DRM_MODE_FLAG_NHSYNC) ?
> 0 : 1) +
> > +                        ((mode->flags &
> DRM_MODE_FLAG_NVSYNC) ? 0 : 2);
> > +     int ret;
> > +     u32 val;
> > +
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, SCHEDULER_H_SIZE,
> (hactive << 16) + hblank);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, SCHEDULER_V_SIZE,
> (vactive << 16) + vblank);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     ret = cdns_mhdp_reg_write(&mhdp->base,
> HDTX_SIGNAL_FRONT_WIDTH, (vfront << 16) + hfront);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     ret = cdns_mhdp_reg_write(&mhdp->base,
> HDTX_SIGNAL_SYNC_WIDTH, (vsync << 16) + hsync);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     ret = cdns_mhdp_reg_write(&mhdp->base,
> HDTX_SIGNAL_BACK_WIDTH, (vback << 16) + hback);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     ret = cdns_mhdp_reg_write(&mhdp->base,
> HSYNC2VSYNC_POL_CTRL, v_h_polarity);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     /* Reset Data Enable */
> > +     cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
> > +     val &= ~F_DATA_EN(1);
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER,
> val);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     /* Set bpc */
> > +     val &= ~F_VIF_DATA_WIDTH(3);
> > +     switch (video_info->bpc) {
> > +     case 10:
> > +             val |= F_VIF_DATA_WIDTH(1);
> > +             break;
> > +     case 12:
> > +             val |= F_VIF_DATA_WIDTH(2);
> > +             break;
> > +     case 16:
> > +             val |= F_VIF_DATA_WIDTH(3);
> > +             break;
> > +     case 8:
> > +     default:
> > +             val |= F_VIF_DATA_WIDTH(0);
> > +             break;
> > +     }
> > +
> > +     /* select color encoding */
> > +     val &= ~F_HDMI_ENCODING(3);
> > +     switch (video_info->color_fmt) {
> > +     case HDMI_COLORSPACE_YUV444:
> > +             val |= F_HDMI_ENCODING(2);
> > +             break;
> > +     case HDMI_COLORSPACE_YUV422:
> > +             val |= F_HDMI_ENCODING(1);
> > +             break;
> > +     case HDMI_COLORSPACE_YUV420:
> > +             val |= F_HDMI_ENCODING(3);
> > +             break;
> > +     case HDMI_COLORSPACE_RGB:
> > +     default:
> > +             val |= F_HDMI_ENCODING(0);
> > +             break;
> > +     }
> > +
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER,
> val);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     /* set data enable */
> > +     val |= F_DATA_EN(1);
> > +     ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER,
> val);
> > +
> > +     return ret;
> > +}
> > +
> > +static int cdns_hdmi_disable_gcp(struct cdns_mhdp8501_device *mhdp)
> > +{
> > +     u32 val;
> > +
> > +     cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
> > +     val &= ~F_GCP_EN(1);
> > +
> > +     return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER,
> val);
> > +}
> > +
> > +static int cdns_hdmi_enable_gcp(struct cdns_mhdp8501_device *mhdp)
> > +{
> > +     u32 val;
> > +
> > +     cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
> > +     val |= F_GCP_EN(1);
> > +
> > +     return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER,
> val);
> > +}
> > +
> > +static void cdns_hdmi_sink_config(struct cdns_mhdp8501_device *mhdp)
> > +{
> > +     struct drm_scdc *scdc =
> &mhdp->curr_conn->display_info.hdmi.scdc;
> > +     u8 buff = 0;
> > +
> > +     /* Default work in HDMI1.4 */
> > +     mhdp->hdmi.hdmi_type = MODE_HDMI_1_4;
> > +
> > +     /* check sink support SCDC or not */
> > +     if (!scdc->supported) {
> > +             dev_info(mhdp->dev, "Sink Not Support SCDC\n");
> > +             return;
> > +     }
> > +
> > +     if (mhdp->hdmi.char_rate > 340000000) {
> > +             /*
> > +              * TMDS Character Rate above 340MHz should working in
> HDMI2.0
> > +              * Enable scrambling and TMDS_Bit_Clock_Ratio
> > +              */
> > +             buff = SCDC_TMDS_BIT_CLOCK_RATIO_BY_40 |
> SCDC_SCRAMBLING_ENABLE;
> > +             mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
> > +     } else if (scdc->scrambling.low_rates) {
> > +             /*
> > +              * Enable scrambling and HDMI2.0 when scrambling
> capability of sink
> > +              * be indicated in the HF-VSDB LTE_340Mcsc_scramble
> bit
> > +              */
> > +             buff = SCDC_SCRAMBLING_ENABLE;
> > +             mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
> > +     }
> > +
> > +     /* TMDS config */
> > +     cdns_hdmi_scdc_write(mhdp, SCDC_TMDS_CONFIG, buff);
> > +}
> > +
> > +static int cdns_hdmi_bridge_attach(struct drm_bridge *bridge,
> > +                                enum drm_bridge_attach_flags
> flags)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +
> > +     if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
> > +             dev_err(mhdp->dev, "do not support creating a
> drm_connector\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static enum drm_mode_status
> > +cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
> > +                            const struct drm_display_mode *mode,
> > +                            unsigned long long tmds_rate)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +     union phy_configure_opts phy_cfg;
> > +     int ret;
> > +
> > +     phy_cfg.hdmi.tmds_char_rate = tmds_rate;
> > +
> > +     /* Mailbox protect for HDMI PHY access */
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +     ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +     if (ret < 0)
> > +             return MODE_CLOCK_RANGE;
> > +
> > +     return MODE_OK;
> > +}
> > +
> > +static enum drm_mode_status
> > +cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
> > +                         const struct drm_display_info *info,
> > +                         const struct drm_display_mode *mode)
> > +{
> > +     unsigned long long tmds_rate;
> > +
> > +     /* We don't support double-clocked and Interlaced modes */
> > +     if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
> > +         mode->flags & DRM_MODE_FLAG_INTERLACE)
> > +             return MODE_BAD;
> > +
> > +     /* MAX support pixel clock rate 594MHz */
> > +     if (mode->clock > 594000)
> > +             return MODE_CLOCK_HIGH;
> > +
> > +     if (mode->hdisplay > 3840)
> > +             return MODE_BAD_HVALUE;
> > +
> > +     if (mode->vdisplay > 2160)
> > +             return MODE_BAD_VVALUE;
> > +
> > +     tmds_rate = mode->clock * 1000ULL;
> > +     return cdns_hdmi_tmds_char_rate_valid(bridge, mode, tmds_rate);
> > +}
> > +
> > +static enum drm_connector_status
> > +cdns_hdmi_bridge_detect(struct drm_bridge *bridge)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +
> > +     return cdns_mhdp8501_detect(mhdp);
> > +}
> > +
> > +static const struct drm_edid
> > +*cdns_hdmi_bridge_edid_read(struct drm_bridge *bridge,
> > +                         struct drm_connector *connector)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +
> > +     return drm_edid_read_custom(connector,
> cdns_hdmi_get_edid_block, mhdp);
> > +}
> > +
> > +static void cdns_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
> > +                                         struct drm_bridge_state
> *old_state)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +
> > +     mhdp->curr_conn = NULL;
> > +
> > +     /* Mailbox protect for HDMI PHY access */
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +     phy_power_off(mhdp->phy);
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +}
> > +
> > +static void cdns_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
> > +                                        struct drm_bridge_state
> *old_state)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +     struct drm_atomic_state *state = old_state->base.state;
> > +     struct drm_connector *connector;
> > +     struct video_info *video = &mhdp->video_info;
> > +     struct drm_crtc_state *crtc_state;
> > +     struct drm_connector_state *conn_state;
> > +     struct drm_display_mode *mode = &mhdp->mode;
> > +     union phy_configure_opts phy_cfg;
> > +     int ret;
> > +
> > +     connector = drm_atomic_get_new_connector_for_encoder(state,
> > +
> bridge->encoder);
> > +     if (WARN_ON(!connector))
> > +             return;
> > +
> > +     mhdp->curr_conn = connector;
> > +
> > +     conn_state = drm_atomic_get_new_connector_state(state,
> connector);
> > +     if (WARN_ON(!conn_state))
> > +             return;
> > +
> > +     crtc_state = drm_atomic_get_new_crtc_state(state,
> conn_state->crtc);
> > +     if (WARN_ON(!crtc_state))
> > +             return;
> > +
> > +     video->color_fmt = conn_state->hdmi.output_format;
> > +     video->bpc = conn_state->hdmi.output_bpc;
> > +
> > +     drm_mode_copy(&mhdp->mode, &crtc_state->adjusted_mode);
> > +
> > +     /* video mode check */
> > +     if (mode->clock == 0 || mode->hdisplay == 0 || mode->vdisplay ==
> 0)
> > +             return;
> > +
> > +     dev_dbg(mhdp->dev, "Mode: %dx%dp%d\n",
> > +             mode->hdisplay, mode->vdisplay, mode->clock);
> > +
> > +     drm_atomic_helper_connector_hdmi_update_infoframes(connector,
> state);
> > +
> > +     /* Line swapping */
> > +     cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000
> | mhdp->lane_mapping);
> > +
> > +     mhdp->hdmi.char_rate = drm_hdmi_compute_mode_clock(mode,
> > +
> mhdp->video_info.bpc,
> > +
> mhdp->video_info.color_fmt);
> > +     phy_cfg.hdmi.tmds_char_rate = mhdp->hdmi.char_rate;
> > +
> > +     /* Mailbox protect for HDMI PHY access */
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +     ret = phy_configure(mhdp->phy, &phy_cfg);
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +     if (ret) {
> > +             dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
> > +                     __func__, ret);
> > +             return;
> > +     }
> > +
> > +     cdns_hdmi_sink_config(mhdp);
> > +
> > +     ret = cdns_hdmi_ctrl_init(mhdp);
> > +     if (ret < 0) {
> > +             dev_err(mhdp->dev, "%s, ret = %d\n", __func__, ret);
> > +             return;
> > +     }
> > +
> > +     /* Config GCP */
> > +     if (mhdp->video_info.bpc == 8)
> > +             cdns_hdmi_disable_gcp(mhdp);
> > +     else
> > +             cdns_hdmi_enable_gcp(mhdp);
> > +
> > +     ret = cdns_hdmi_mode_config(mhdp, mode, &mhdp->video_info);
> > +     if (ret < 0) {
> > +             dev_err(mhdp->dev, "CDN_API_HDMITX_SetVic_blocking
> ret = %d\n", ret);
> > +             return;
> > +     }
> > +}
> > +
> > +static int cdns_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge,
> > +                                         enum
> hdmi_infoframe_type type)
> > +{
> > +     return 0;
> > +}
> > +
> > +static int cdns_hdmi_bridge_write_infoframe(struct drm_bridge *bridge,
> > +                                         enum
> hdmi_infoframe_type type,
> > +                                         const u8 *buffer, size_t
> len)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +
> > +     switch (type) {
> > +     case HDMI_INFOFRAME_TYPE_AVI:
> > +             cdns_hdmi_config_infoframe(mhdp, 0, len, buffer,
> HDMI_INFOFRAME_TYPE_AVI);
> > +             break;
> > +     case HDMI_INFOFRAME_TYPE_SPD:
> > +             cdns_hdmi_config_infoframe(mhdp, 1, len, buffer,
> HDMI_INFOFRAME_TYPE_SPD);
> > +             break;
> > +     case HDMI_INFOFRAME_TYPE_VENDOR:
> > +             cdns_hdmi_config_infoframe(mhdp, 2, len, buffer,
> HDMI_INFOFRAME_TYPE_VENDOR);
> > +             break;
> > +     default:
> > +             dev_dbg(mhdp->dev, "Unsupported infoframe type %x\n",
> type);
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int cdns_hdmi_bridge_atomic_check(struct drm_bridge *bridge,
> > +                                      struct drm_bridge_state
> *bridge_state,
> > +                                      struct drm_crtc_state
> *crtc_state,
> > +                                      struct drm_connector_state
> *conn_state)
> > +{
> > +     return
> drm_atomic_helper_connector_hdmi_check(conn_state->connector,
> conn_state->state);
> > +}
> > +
> > +const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = {
> > +     .attach = cdns_hdmi_bridge_attach,
> > +     .detect = cdns_hdmi_bridge_detect,
> > +     .edid_read = cdns_hdmi_bridge_edid_read,
> > +     .mode_valid = cdns_hdmi_bridge_mode_valid,
> > +     .atomic_enable = cdns_hdmi_bridge_atomic_enable,
> > +     .atomic_disable = cdns_hdmi_bridge_atomic_disable,
> > +     .atomic_check = cdns_hdmi_bridge_atomic_check,
> > +     .atomic_duplicate_state =
> drm_atomic_helper_bridge_duplicate_state,
> > +     .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> > +     .atomic_reset = drm_atomic_helper_bridge_reset,
> > +     .hdmi_clear_infoframe = cdns_hdmi_bridge_clear_infoframe,
> > +     .hdmi_write_infoframe = cdns_hdmi_bridge_write_infoframe,
> > +     .hdmi_tmds_char_rate_valid = cdns_hdmi_tmds_char_rate_valid,
> > +};

From xu.yang_2 at nxp.com  Tue Sep  3 23:34:07 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 4 Sep 2024 14:34:07 +0800
Subject: [PATCH v3 2/2] ARM: dts: imx7ulp: add "nxp,sim" property for
 usbphy1
In-Reply-To: <20240903075810.1196928-2-xu.yang_2@nxp.com>
References: <20240903075810.1196928-1-xu.yang_2@nxp.com>
 <20240903075810.1196928-2-xu.yang_2@nxp.com>
Message-ID: <20240904063407.qjvevd4xhvohg4cd@hippo>

Hi Shawn,

On Tue, Sep 03, 2024 at 03:58:10PM +0800, Xu Yang wrote:
> i.MX7ULP need properly set System Integration Module(SIM) module to make
> usb wakeup work well. This will add a "nxp,sim" property for usbphy1.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 
> ---
> Changes in v2:
>  - no changes
> Changes in v3:
>  - no changes
> ---
>  arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi b/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
> index ac338320ac1d..b093f2a447ae 100644
> --- a/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
> +++ b/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
> @@ -214,6 +214,7 @@ usbphy1: usb-phy at 40350000 {
>  			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
>  			clocks = <&pcc2 IMX7ULP_CLK_USB_PHY>;
>  			#phy-cells = <0>;
> +			nxp,sim = <&sim>;
>  		};

The dtschema patch #1 has been picked by Greg. You can pick up patch #2
when you see this ping. 

Thanks,
Xu Yang

>  
>  		usdhc0: mmc at 40370000 {
> -- 
> 2.34.1
> 


From gregkh at linuxfoundation.org  Wed Sep  4 00:00:45 2024
From: gregkh at linuxfoundation.org (Greg KH)
Date: Wed, 4 Sep 2024 09:00:45 +0200
Subject: [PATCH v3 2/2] ARM: dts: imx7ulp: add "nxp,sim" property for
 usbphy1
In-Reply-To: <20240904063407.qjvevd4xhvohg4cd@hippo>
References: <20240903075810.1196928-1-xu.yang_2@nxp.com>
 <20240903075810.1196928-2-xu.yang_2@nxp.com>
 <20240904063407.qjvevd4xhvohg4cd@hippo>
Message-ID: <2024090418-helpful-nearness-39ab@gregkh>

On Wed, Sep 04, 2024 at 02:34:07PM +0800, Xu Yang wrote:
> Hi Shawn,
> 
> On Tue, Sep 03, 2024 at 03:58:10PM +0800, Xu Yang wrote:
> > i.MX7ULP need properly set System Integration Module(SIM) module to make
> > usb wakeup work well. This will add a "nxp,sim" property for usbphy1.
> > 
> > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> > 
> > ---
> > Changes in v2:
> >  - no changes
> > Changes in v3:
> >  - no changes
> > ---
> >  arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi b/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
> > index ac338320ac1d..b093f2a447ae 100644
> > --- a/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
> > +++ b/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
> > @@ -214,6 +214,7 @@ usbphy1: usb-phy at 40350000 {
> >  			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
> >  			clocks = <&pcc2 IMX7ULP_CLK_USB_PHY>;
> >  			#phy-cells = <0>;
> > +			nxp,sim = <&sim>;
> >  		};
> 
> The dtschema patch #1 has been picked by Greg. You can pick up patch #2
> when you see this ping. 

Because our tools like to suck in entire patch series at once, you
should really just resend this so that Shawn doesn't accidentally take
patch 1/2 as well.

thanks,

greg k-h


From xu.yang_2 at nxp.com  Wed Sep  4 00:09:21 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 4 Sep 2024 15:09:21 +0800
Subject: [PATCH v3 2/2] ARM: dts: imx7ulp: add "nxp,sim" property for
 usbphy1
In-Reply-To: <2024090418-helpful-nearness-39ab@gregkh>
References: <20240903075810.1196928-1-xu.yang_2@nxp.com>
 <20240903075810.1196928-2-xu.yang_2@nxp.com>
 <20240904063407.qjvevd4xhvohg4cd@hippo>
 <2024090418-helpful-nearness-39ab@gregkh>
Message-ID: <20240904070921.tbtn6tjkxxj6vu5y@hippo>

On Wed, Sep 04, 2024 at 09:00:45AM +0200, Greg KH wrote:
> On Wed, Sep 04, 2024 at 02:34:07PM +0800, Xu Yang wrote:
> > Hi Shawn,
> > 
> > On Tue, Sep 03, 2024 at 03:58:10PM +0800, Xu Yang wrote:
> > > i.MX7ULP need properly set System Integration Module(SIM) module to make
> > > usb wakeup work well. This will add a "nxp,sim" property for usbphy1.
> > > 
> > > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> > > 
> > > ---
> > > Changes in v2:
> > >  - no changes
> > > Changes in v3:
> > >  - no changes
> > > ---
> > >  arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi | 1 +
> > >  1 file changed, 1 insertion(+)
> > > 
> > > diff --git a/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi b/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
> > > index ac338320ac1d..b093f2a447ae 100644
> > > --- a/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
> > > +++ b/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
> > > @@ -214,6 +214,7 @@ usbphy1: usb-phy at 40350000 {
> > >  			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
> > >  			clocks = <&pcc2 IMX7ULP_CLK_USB_PHY>;
> > >  			#phy-cells = <0>;
> > > +			nxp,sim = <&sim>;
> > >  		};
> > 
> > The dtschema patch #1 has been picked by Greg. You can pick up patch #2
> > when you see this ping. 
> 
> Because our tools like to suck in entire patch series at once, you
> should really just resend this so that Shawn doesn't accidentally take
> patch 1/2 as well.

Well, thanks for reminding me again. I'm going to do that.

Best Regards,
Xu Yang


From dominique.martinet at atmark-techno.com  Wed Sep  4 01:28:42 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Wed, 4 Sep 2024 17:28:42 +0900
Subject: [PATCH V4 3/5] phy: freescale: fsl-samsung-hdmi: Support dynamic
 integer
In-Reply-To: <20240903013113.139698-4-aford173@gmail.com>
References: <20240903013113.139698-1-aford173@gmail.com>
 <20240903013113.139698-4-aford173@gmail.com>
Message-ID: <ZtgaOlHi93b_py7T@atmark-techno.com>

Adam Ford wrote on Mon, Sep 02, 2024 at 08:30:45PM -0500:
> There is currently a look-up table for a variety of resolutions.
> Since the phy has the ability to dynamically calculate the values
> necessary to use the intger divider which should allow more
> resolutions without having to update the look-up-table.
> 
> If the lookup table cannot find an exact match, fall back to the
> dynamic calculator of the integer divider.
> 
> Previously, the value of P was hard-coded to 1, this required an
> update to the phy_pll_cfg table to add in the extra value into the
> table, so if the value of P is calculated to be something else
> by the PMS calculator, the calculated_phy_pll_cfg structure
> can be used instead without having to keep track of which method
> was used.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>

I've rechecked this series with abs() added in the later patch and this
looks fine; all modes I tried properly synced up with my monitor.
(except one but I don't see set_rate() being called for it so it's
something else)

(On a semi-unrelated note on my backport I get a "PLL failed to lock"
message for the first sync only, but everything seems to work regardless
even if there is no further set_rate(), so I'll pretend I didn't see
that... the old code just has a 20ms wait without any check so it's not
like it was any better... anyway that's unrelated to this serie)

I'm also confident enough set_rate() won't be called in parallel with
different rates for my device so I'm fine with the new global, letting
others complain if that's a problem for them.


So, feel free to add this to all 5 patches:
Test-by: Dominique Martinet <dominique.martinet at atmark-techno.com>

Just one style nitpick:

> @@ -453,29 +541,70 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
>  static long phy_clk_round_rate(struct clk_hw *hw,
>  			       unsigned long rate, unsigned long *parent_rate)
>  {
> +	u32 int_div_clk;
>  	int i;
> +	u16 m;
> +	u8 p, s;
> +
> +	/* If the clock is out of range return error instead of searching */
> +	if (rate > 297000000 || rate < 22250000)
> +		return -EINVAL;
>  
> +	/* Check the look-up table */
>  	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
>  		if (phy_pll_cfg[i].pixclk <= rate)
> -			return phy_pll_cfg[i].pixclk;
> +			break;
> +	/* If the rate is an exact match, return it now */
> +	if (rate == phy_pll_cfg[i].pixclk)
> +		return phy_pll_cfg[i].pixclk;
> +
> +	/*
> +	 * The math on the lookup table shows the PMS math yields a
> +	 * frequency 5 x pixclk.
> +	 * When we check the integer divider against the desired rate,
> +	 * multiply the rate x 5 and then divide the outcome by 5.
> +	 */
> +	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;

I still think it makes more sense to move the * 5, / 5 and comment
inside fsl_samsung_hdmi_phy_find_pms -- the other caller doesn't have
such the comment so it might look odd depending on where one started
looking.

-- 
Dominique


From quic_jingyw at quicinc.com  Wed Sep  4 01:33:41 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:41 +0800
Subject: [PATCH 00/19] Add initial support for QCS8300
Message-ID: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>

Add initial support for QCS8300 SoC and QCS8300 RIDE board.

This revision brings support for:
- CPUs with cpu idle
- interrupt-controller with PDC wakeup support
- gcc
- TLMM
- interconnect
- qup with uart
- smmu
- pmic
- ufs
- ipcc
- sram
- remoteprocs including ADSP,CDSP and GPDSP

Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
patch series organized as:
- 1-2: remoteproc binding and driver
- 3-5: ufs binding and driver
- 6-7: rpmhpd binding and driver
- 8-15: bindings for other components found on the SoC
- 16-19: changes to support the device tree

dependencies:
tlmm: https://lore.kernel.org/linux-arm-msm/20240819064933.1778204-1-quic_jingyw at quicinc.com/
gcc: https://lore.kernel.org/all/20240820-qcs8300-gcc-v1-0-d81720517a82 at quicinc.com/
interconnect: https://lore.kernel.org/linux-arm-msm/20240827151622.305-1-quic_rlaggysh at quicinc.com/

dtb check got following err:
/local/mnt/workspace/jingyi/aim500/linux/arch/arm64/boot/dts/qcom/qcs8300-ride.dtb: interconnect at 1680000: Unevaluated properties are not allowed ('reg' was unexpected)
which is cause by "reg" compatible missing in dt binding, will be fixed in interconnect patch series.

---
Jingyi Wang (11):
      dt-bindings: remoteproc: qcom,sa8775p-pas: Document QCS8300 remoteproc
      remoteproc: qcom: pas: Add QCS8300 remoteproc support
      dt-bindings: qcom,pdc: document QCS8300 Power Domain Controller
      dt-bindings: soc: qcom: add qcom,qcs8300-imem compatible
      dt-bindings: mailbox: qcom-ipcc: Document QCS8300 IPCC
      dt-bindings: mfd: qcom,tcsr: Add compatible for QCS8300
      dt-bindings: nvmem: qfprom: Add compatible for QCS8300
      dt-bindings: arm: qcom: document QCS8275/QCS8300 SoC and reference board
      arm64: defconfig: enable clock controller, interconnect and pinctrl for QCS8300
      arm64: dts: qcom: add initial support for QCS8300 DTSI
      arm64: dts: qcom: add base QCS8300 RIDE dts

Kyle Deng (1):
      dt-bindings: soc: qcom,aoss-qmp: Document the QCS8300 AOSS channel

Shazad Hussain (1):
      dt-bindings: power: rpmpd: Add QCS8300 power domains

Tingguo Cheng (1):
      pmdomain: qcom: rpmhpd: Add QCS8300 power domains

Xin Liu (3):
      dt-bindings: phy: Add QMP UFS PHY comptible for QCS8300
      dt-bindings: ufs: qcom: Document the QCS8300 UFS Controller
      phy: qcom-qmp-ufs: Add support for QCS8300

Zhenhua Huang (2):
      dt-bindings: arm-smmu: Add compatible for QCS8300 SoC
      dt-bindings: firmware: qcom,scm: document SCM on QCS8300 SoCs

 Documentation/devicetree/bindings/arm/qcom.yaml    |    8 +
 .../devicetree/bindings/firmware/qcom,scm.yaml     |    1 +
 .../bindings/interrupt-controller/qcom,pdc.yaml    |    1 +
 .../devicetree/bindings/iommu/arm,smmu.yaml        |    2 +
 .../devicetree/bindings/mailbox/qcom-ipcc.yaml     |    1 +
 .../devicetree/bindings/mfd/qcom,tcsr.yaml         |    1 +
 .../devicetree/bindings/nvmem/qcom,qfprom.yaml     |    1 +
 .../bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml    |    2 +
 .../devicetree/bindings/power/qcom,rpmpd.yaml      |    1 +
 .../bindings/remoteproc/qcom,sa8775p-pas.yaml      |    6 +
 .../bindings/soc/qcom/qcom,aoss-qmp.yaml           |    1 +
 .../devicetree/bindings/sram/qcom,imem.yaml        |    1 +
 .../devicetree/bindings/ufs/qcom,ufs.yaml          |    2 +
 arch/arm64/boot/dts/qcom/Makefile                  |    1 +
 arch/arm64/boot/dts/qcom/qcs8300-ride.dts          |  246 ++++
 arch/arm64/boot/dts/qcom/qcs8300.dtsi              | 1282 ++++++++++++++++++++
 arch/arm64/configs/defconfig                       |    3 +
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            |    3 +
 drivers/pmdomain/qcom/rpmhpd.c                     |   24 +
 drivers/remoteproc/qcom_q6v5_pas.c                 |    3 +
 include/dt-bindings/power/qcom-rpmpd.h             |   19 +
 21 files changed, 1609 insertions(+)
---
base-commit: eb8c5ca373cbb018a84eb4db25c863302c9b6314
change-id: 20240829-qcs8300_initial_dtsi-1a386eb317d3

Best regards,
-- 
Jingyi Wang <quic_jingyw at quicinc.com>



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:42 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:42 +0800
Subject: [PATCH 01/19] dt-bindings: remoteproc: qcom,sa8775p-pas: Document
 QCS8300 remoteproc
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-1-d0ea9afdc007@quicinc.com>

Document the components used to boot the ADSP, CDSP and GPDSP on the
QCS8300 SoC.

Co-developed-by: Xin Liu <quic_liuxin at quicinc.com>
Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 Documentation/devicetree/bindings/remoteproc/qcom,sa8775p-pas.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sa8775p-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sa8775p-pas.yaml
index 7fe401a06805..b788dd77e40e 100644
--- a/Documentation/devicetree/bindings/remoteproc/qcom,sa8775p-pas.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/qcom,sa8775p-pas.yaml
@@ -16,6 +16,9 @@ description:
 properties:
   compatible:
     enum:
+      - qcom,qcs8300-adsp-pas
+      - qcom,qcs8300-cdsp-pas
+      - qcom,qcs8300-gpdsp-pas
       - qcom,sa8775p-adsp-pas
       - qcom,sa8775p-cdsp0-pas
       - qcom,sa8775p-cdsp1-pas
@@ -64,6 +67,7 @@ allOf:
       properties:
         compatible:
           enum:
+            - qcom,qcs8300-adsp-pas
             - qcom,sa8775p-adsp-pas
     then:
       properties:
@@ -80,6 +84,7 @@ allOf:
       properties:
         compatible:
           enum:
+            - qcom,qcs8300-cdsp-pas
             - qcom,sa8775p-cdsp0-pas
             - qcom,sa8775p-cdsp1-pas
     then:
@@ -99,6 +104,7 @@ allOf:
       properties:
         compatible:
           enum:
+            - qcom,qcs8300-gpdsp-pas
             - qcom,sa8775p-gpdsp0-pas
             - qcom,sa8775p-gpdsp1-pas
     then:

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:43 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:43 +0800
Subject: [PATCH 02/19] remoteproc: qcom: pas: Add QCS8300 remoteproc
 support
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-2-d0ea9afdc007@quicinc.com>

Add support for PIL loading on ADSP, CDSP and GPDSP on QCS8300
platform.

Co-developed-by: Xin Liu <quic_liuxin at quicinc.com>
Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 drivers/remoteproc/qcom_q6v5_pas.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index ef82835e98a4..f92ccd4921b7 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -1416,6 +1416,9 @@ static const struct of_device_id adsp_of_match[] = {
 	{ .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
 	{ .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
 	{ .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
+	{ .compatible = "qcom,qcs8300-adsp-pas", .data = &sa8775p_adsp_resource},
+	{ .compatible = "qcom,qcs8300-cdsp-pas", .data = &sa8775p_cdsp0_resource},
+	{ .compatible = "qcom,qcs8300-gpdsp-pas", .data = &sa8775p_gpdsp0_resource},
 	{ .compatible = "qcom,sa8775p-adsp-pas", .data = &sa8775p_adsp_resource},
 	{ .compatible = "qcom,sa8775p-cdsp0-pas", .data = &sa8775p_cdsp0_resource},
 	{ .compatible = "qcom,sa8775p-cdsp1-pas", .data = &sa8775p_cdsp1_resource},

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:44 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:44 +0800
Subject: [PATCH 03/19] dt-bindings: phy: Add QMP UFS PHY comptible for
 QCS8300
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-3-d0ea9afdc007@quicinc.com>

From: Xin Liu <quic_liuxin at quicinc.com>

Document the QMP UFS PHY compatible for QCS8300 to support physical
layer functionality for USB found on the SoC.

Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
index f9cfbd0b2de6..a3540f7a8ef8 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
@@ -18,6 +18,7 @@ properties:
     enum:
       - qcom,msm8996-qmp-ufs-phy
       - qcom,msm8998-qmp-ufs-phy
+      - qcom,qcs8300-qmp-ufs-phy
       - qcom,sa8775p-qmp-ufs-phy
       - qcom,sc7180-qmp-ufs-phy
       - qcom,sc7280-qmp-ufs-phy
@@ -85,6 +86,7 @@ allOf:
           contains:
             enum:
               - qcom,msm8998-qmp-ufs-phy
+              - qcom,qcs8300-qmp-ufs-phy
               - qcom,sa8775p-qmp-ufs-phy
               - qcom,sc7180-qmp-ufs-phy
               - qcom,sc7280-qmp-ufs-phy

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:45 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:45 +0800
Subject: [PATCH 04/19] dt-bindings: ufs: qcom: Document the QCS8300 UFS
 Controller
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-4-d0ea9afdc007@quicinc.com>

From: Xin Liu <quic_liuxin at quicinc.com>

Document the Universal Flash Storage(UFS) Controller on the QCS8300
Platform.

Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 Documentation/devicetree/bindings/ufs/qcom,ufs.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml b/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml
index 25a5edeea164..cde334e3206b 100644
--- a/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml
+++ b/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml
@@ -26,6 +26,7 @@ properties:
           - qcom,msm8994-ufshc
           - qcom,msm8996-ufshc
           - qcom,msm8998-ufshc
+          - qcom,qcs8300-ufshc
           - qcom,sa8775p-ufshc
           - qcom,sc7180-ufshc
           - qcom,sc7280-ufshc
@@ -146,6 +147,7 @@ allOf:
           contains:
             enum:
               - qcom,msm8998-ufshc
+              - qcom,qcs8300-ufshc
               - qcom,sa8775p-ufshc
               - qcom,sc7280-ufshc
               - qcom,sc8180x-ufshc

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:46 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:46 +0800
Subject: [PATCH 05/19] phy: qcom-qmp-ufs: Add support for QCS8300
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-5-d0ea9afdc007@quicinc.com>

From: Xin Liu <quic_liuxin at quicinc.com>

Add QMP PHY support for QCS8300 which is compatible with SA8775P.

Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index d964bdfe8700..8bad68400736 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -2010,6 +2010,9 @@ static const struct of_device_id qmp_ufs_of_match_table[] = {
 	}, {
 		.compatible = "qcom,msm8998-qmp-ufs-phy",
 		.data = &sdm845_ufsphy_cfg,
+	}, {
+		.compatible = "qcom,qcs8300-qmp-ufs-phy",
+		.data = &sa8775p_ufsphy_cfg,
 	}, {
 		.compatible = "qcom,sa8775p-qmp-ufs-phy",
 		.data = &sa8775p_ufsphy_cfg,

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:47 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:47 +0800
Subject: [PATCH 06/19] dt-bindings: power: rpmpd: Add QCS8300 power domains
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-6-d0ea9afdc007@quicinc.com>

From: Shazad Hussain <quic_shazhuss at quicinc.com>

Add compatible and constants for the power domains exposed by the RPMH
in the Qualcomm QCS8300 platform.

Signed-off-by: Shazad Hussain <quic_shazhuss at quicinc.com>
Signed-off-by: Tingguo Cheng <quic_tingguoc at quicinc.com>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 .../devicetree/bindings/power/qcom,rpmpd.yaml         |  1 +
 include/dt-bindings/power/qcom-rpmpd.h                | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
index 929b7ef9c1bc..be1a9cb71a9b 100644
--- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
+++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
@@ -32,6 +32,7 @@ properties:
           - qcom,msm8998-rpmpd
           - qcom,qcm2290-rpmpd
           - qcom,qcs404-rpmpd
+          - qcom,qcs8300-rpmhpd
           - qcom,qdu1000-rpmhpd
           - qcom,qm215-rpmpd
           - qcom,sa8155p-rpmhpd
diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h
index 608087fb9a3d..7dd7b9ebc480 100644
--- a/include/dt-bindings/power/qcom-rpmpd.h
+++ b/include/dt-bindings/power/qcom-rpmpd.h
@@ -4,6 +4,25 @@
 #ifndef _DT_BINDINGS_POWER_QCOM_RPMPD_H
 #define _DT_BINDINGS_POWER_QCOM_RPMPD_H
 
+/* QCS8300 Power Domain Indexes */
+#define QCS8300_CX	0
+#define QCS8300_CX_AO	1
+#define QCS8300_DDR	2
+#define QCS8300_EBI	3
+#define QCS8300_GFX	4
+#define QCS8300_LCX	5
+#define QCS8300_LMX	6
+#define QCS8300_MMCX	7
+#define QCS8300_MMCX_AO	8
+#define QCS8300_MSS	9
+#define QCS8300_MX	10
+#define QCS8300_MX_AO	11
+#define QCS8300_MXC	12
+#define QCS8300_MXC_AO	13
+#define QCS8300_NSP0	14
+#define QCS8300_NSP1	15
+#define QCS8300_XO	16
+
 /* SA8775P Power Domain Indexes */
 #define SA8775P_CX	0
 #define SA8775P_CX_AO	1

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:48 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:48 +0800
Subject: [PATCH 07/19] pmdomain: qcom: rpmhpd: Add QCS8300 power domains
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-7-d0ea9afdc007@quicinc.com>

From: Tingguo Cheng <quic_tingguoc at quicinc.com>

Add support for the power-domains found on QCS8300 platform.

Co-developed-by: Shazad Hussain <quic_shazhuss at quicinc.com>
Signed-off-by: Shazad Hussain <quic_shazhuss at quicinc.com>
Signed-off-by: Tingguo Cheng <quic_tingguoc at quicinc.com>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 drivers/pmdomain/qcom/rpmhpd.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/pmdomain/qcom/rpmhpd.c b/drivers/pmdomain/qcom/rpmhpd.c
index d2cb4271a1ca..d79321b08d16 100644
--- a/drivers/pmdomain/qcom/rpmhpd.c
+++ b/drivers/pmdomain/qcom/rpmhpd.c
@@ -623,7 +623,31 @@ static const struct rpmhpd_desc x1e80100_desc = {
 	.num_pds = ARRAY_SIZE(x1e80100_rpmhpds),
 };
 
+/* QCS8300 RPMH power domains */
+static struct rpmhpd *qcs8300_rpmhpds[] = {
+	[QCS8300_CX] = &cx,
+	[QCS8300_CX_AO] = &cx_ao,
+	[QCS8300_EBI] = &ebi,
+	[QCS8300_GFX] = &gfx,
+	[QCS8300_LCX] = &lcx,
+	[QCS8300_LMX] = &lmx,
+	[QCS8300_MMCX] = &mmcx,
+	[QCS8300_MMCX_AO] = &mmcx_ao,
+	[QCS8300_MXC] = &mxc,
+	[QCS8300_MXC_AO] = &mxc_ao,
+	[QCS8300_MX] = &mx,
+	[QCS8300_MX_AO] = &mx_ao,
+	[QCS8300_NSP0] = &nsp0,
+	[QCS8300_NSP1] = &nsp1,
+};
+
+static const struct rpmhpd_desc qcs8300_desc = {
+	.rpmhpds = qcs8300_rpmhpds,
+	.num_pds = ARRAY_SIZE(qcs8300_rpmhpds),
+};
+
 static const struct of_device_id rpmhpd_match_table[] = {
+	{ .compatible = "qcom,qcs8300-rpmhpd", .data = &qcs8300_desc },
 	{ .compatible = "qcom,qdu1000-rpmhpd", .data = &qdu1000_desc },
 	{ .compatible = "qcom,sa8155p-rpmhpd", .data = &sa8155p_desc },
 	{ .compatible = "qcom,sa8540p-rpmhpd", .data = &sa8540p_desc },

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:49 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:49 +0800
Subject: [PATCH 08/19] dt-bindings: qcom,pdc: document QCS8300 Power Domain
 Controller
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-8-d0ea9afdc007@quicinc.com>

Document Power Domain Controller for QCS8300. PDC is included in QCS8300
SoC. This controller acts as an interrupt controller, enabling the
detection of interrupts when the GIC is non-operational.

Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.yaml b/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.yaml
index 985fa10abb99..acd6341e9f90 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.yaml
@@ -26,6 +26,7 @@ properties:
   compatible:
     items:
       - enum:
+          - qcom,qcs8300-pdc
           - qcom,qdu1000-pdc
           - qcom,sa8775p-pdc
           - qcom,sc7180-pdc

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:50 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:50 +0800
Subject: [PATCH 09/19] dt-bindings: arm-smmu: Add compatible for QCS8300
 SoC
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-9-d0ea9afdc007@quicinc.com>

From: Zhenhua Huang <quic_zhenhuah at quicinc.com>

QCS8300 SoC includes apps smmu that implements arm,mmu-500, which is used
to translate device-visible virtual addresses to physical addresses. Add
compatible for it.

Signed-off-by: Zhenhua Huang <quic_zhenhuah at quicinc.com>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index 280b4e49f219..a848ad2a2106 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -36,6 +36,7 @@ properties:
         items:
           - enum:
               - qcom,qcm2290-smmu-500
+              - qcom,qcs8300-smmu-500
               - qcom,qdu1000-smmu-500
               - qcom,sa8775p-smmu-500
               - qcom,sc7180-smmu-500
@@ -552,6 +553,7 @@ allOf:
               - cavium,smmu-v2
               - marvell,ap806-smmu-500
               - nvidia,smmu-500
+              - qcom,qcs8300-smmu-500
               - qcom,qdu1000-smmu-500
               - qcom,sc7180-smmu-500
               - qcom,sdm670-smmu-500

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:51 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:51 +0800
Subject: [PATCH 10/19] dt-bindings: firmware: qcom,scm: document SCM on
 QCS8300 SoCs
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-10-d0ea9afdc007@quicinc.com>

From: Zhenhua Huang <quic_zhenhuah at quicinc.com>

Document scm compatible for QCS8300 SoCs. It is an interface to
communicate to the secure firmware.

Signed-off-by: Zhenhua Huang <quic_zhenhuah at quicinc.com>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 Documentation/devicetree/bindings/firmware/qcom,scm.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
index 2cc83771d8e7..f3ab819f812f 100644
--- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
+++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
@@ -42,6 +42,7 @@ properties:
           - qcom,scm-msm8996
           - qcom,scm-msm8998
           - qcom,scm-qcm2290
+          - qcom,scm-qcs8300
           - qcom,scm-qdu1000
           - qcom,scm-sa8775p
           - qcom,scm-sc7180

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:52 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:52 +0800
Subject: [PATCH 11/19] dt-bindings: soc: qcom: add qcom,qcs8300-imem
 compatible
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-11-d0ea9afdc007@quicinc.com>

Document qcom,qcs8300-imem compatible. It has child node for debug
purpose.

Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 Documentation/devicetree/bindings/sram/qcom,imem.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/sram/qcom,imem.yaml b/Documentation/devicetree/bindings/sram/qcom,imem.yaml
index faef3d6e0a94..9b06bcd01957 100644
--- a/Documentation/devicetree/bindings/sram/qcom,imem.yaml
+++ b/Documentation/devicetree/bindings/sram/qcom,imem.yaml
@@ -21,6 +21,7 @@ properties:
           - qcom,msm8226-imem
           - qcom,msm8974-imem
           - qcom,qcs404-imem
+          - qcom,qcs8300-imem
           - qcom,qdu1000-imem
           - qcom,sa8775p-imem
           - qcom,sc7180-imem

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:53 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:53 +0800
Subject: [PATCH 12/19] dt-bindings: mailbox: qcom-ipcc: Document QCS8300
 IPCC
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-12-d0ea9afdc007@quicinc.com>

Document the Inter-Processor Communication Controller on the QCS8300
Platform, which will be used to route interrupts across various subsystems
found on the SoC.

Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml b/Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml
index 05e4e1d51713..6323c3519a8a 100644
--- a/Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml
+++ b/Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml
@@ -24,6 +24,7 @@ properties:
   compatible:
     items:
       - enum:
+          - qcom,qcs8300-ipcc
           - qcom,qdu1000-ipcc
           - qcom,sa8775p-ipcc
           - qcom,sc7280-ipcc

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:54 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:54 +0800
Subject: [PATCH 13/19] dt-bindings: mfd: qcom,tcsr: Add compatible for
 QCS8300
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-13-d0ea9afdc007@quicinc.com>

Document the qcom,qcs8300-tcsr compatible, tcsr will provide various
control and status functions for their peripherals.

Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml b/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml
index c6bd14ec5aa0..0edc7810d8ef 100644
--- a/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml
+++ b/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml
@@ -21,6 +21,7 @@ properties:
           - qcom,msm8998-tcsr
           - qcom,qcm2290-tcsr
           - qcom,qcs404-tcsr
+          - qcom,qcs8300-tcsr
           - qcom,sc7180-tcsr
           - qcom,sc7280-tcsr
           - qcom,sc8280xp-tcsr

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:55 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:55 +0800
Subject: [PATCH 14/19] dt-bindings: nvmem: qfprom: Add compatible for
 QCS8300
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-14-d0ea9afdc007@quicinc.com>

Document QFPROM compatible for QCS8300. It provides access functions for
QFPROM data to rest of the drivers via nvmem interface.

Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
index 80845c722ae4..fcd71f023808 100644
--- a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
+++ b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
@@ -32,6 +32,7 @@ properties:
           - qcom,msm8998-qfprom
           - qcom,qcm2290-qfprom
           - qcom,qcs404-qfprom
+          - qcom,qcs8300-qfprom
           - qcom,sc7180-qfprom
           - qcom,sc7280-qfprom
           - qcom,sc8280xp-qfprom

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:56 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:56 +0800
Subject: [PATCH 15/19] dt-bindings: soc: qcom,aoss-qmp: Document the
 QCS8300 AOSS channel
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-15-d0ea9afdc007@quicinc.com>

From: Kyle Deng <quic_chunkaid at quicinc.com>

Document the Always-On Subsystem side channel on the QCS8300 platform for
communication with client found on the SoC such as remoteprocs.

Signed-off-by: Kyle Deng <quic_chunkaid at quicinc.com>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml
index 7afdb60edb22..6f5c2609e82a 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml
@@ -25,6 +25,7 @@ properties:
   compatible:
     items:
       - enum:
+          - qcom,qcs8300-aoss-qmp
           - qcom,qdu1000-aoss-qmp
           - qcom,sa8775p-aoss-qmp
           - qcom,sc7180-aoss-qmp

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:57 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:57 +0800
Subject: [PATCH 16/19] dt-bindings: arm: qcom: document QCS8275/QCS8300 SoC
 and reference board
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-16-d0ea9afdc007@quicinc.com>

Document the QCS8275/QCS8300 SoC and its reference board QCS8300 RIDE.
QCS8300 is an Industrial Safe SoC, while QCS8275 is the Industrial
Non-Safe version which can share the same SoC dtsi and board DTS.

Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 Documentation/devicetree/bindings/arm/qcom.yaml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index c0529486810f..ccf9a166368f 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -42,6 +42,8 @@ description: |
         msm8996
         msm8998
         qcs404
+        qcs8275
+        qcs8300
         qcs8550
         qcm2290
         qcm6490
@@ -895,6 +897,12 @@ properties:
           - const: qcom,qcs404-evb
           - const: qcom,qcs404
 
+      - items:
+          - enum:
+              - qcom,qcs8300-ride
+          - const: qcom,qcs8275
+          - const: qcom,qcs8300
+
       - items:
           - enum:
               - qcom,sa8155p-adp

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:58 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:58 +0800
Subject: [PATCH 17/19] arm64: defconfig: enable clock controller,
 interconnect and pinctrl for QCS8300
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-17-d0ea9afdc007@quicinc.com>

Enable clock controller, interrconnect and pinctrl for QCS8300.
It needs to be built-in for UART to provide a console.

Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 arch/arm64/configs/defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 81ca46e3ab4b..a9ba6b25a0ed 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -606,6 +606,7 @@ CONFIG_PINCTRL_MSM8996=y
 CONFIG_PINCTRL_MSM8998=y
 CONFIG_PINCTRL_QCM2290=y
 CONFIG_PINCTRL_QCS404=y
+CONFIG_PINCTRL_QCS8300=y
 CONFIG_PINCTRL_QDF2XXX=y
 CONFIG_PINCTRL_QDU1000=y
 CONFIG_PINCTRL_SA8775P=y
@@ -1317,6 +1318,7 @@ CONFIG_MSM_MMCC_8998=m
 CONFIG_QCM_GCC_2290=y
 CONFIG_QCM_DISPCC_2290=m
 CONFIG_QCS_GCC_404=y
+CONFIG_QCS_GCC_8300=y
 CONFIG_QDU_GCC_1000=y
 CONFIG_SC_CAMCC_8280XP=m
 CONFIG_SC_DISPCC_7280=m
@@ -1618,6 +1620,7 @@ CONFIG_INTERCONNECT_QCOM_MSM8996=y
 CONFIG_INTERCONNECT_QCOM_OSM_L3=m
 CONFIG_INTERCONNECT_QCOM_QCM2290=y
 CONFIG_INTERCONNECT_QCOM_QCS404=m
+CONFIG_INTERCONNECT_QCOM_QCS8300=y
 CONFIG_INTERCONNECT_QCOM_QDU1000=y
 CONFIG_INTERCONNECT_QCOM_SA8775P=y
 CONFIG_INTERCONNECT_QCOM_SC7180=y

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:33:59 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:33:59 +0800
Subject: [PATCH 18/19] arm64: dts: qcom: add initial support for QCS8300
 DTSI
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-18-d0ea9afdc007@quicinc.com>

Add initial DTSI for QCS8300 SoC.

This revision brings support for:
- CPUs with cpu idle
- interrupt-controller with PDC wakeup support
- gcc
- TLMM
- interconnect
- qup with uart
- smmu
- pmic
- ufs
- ipcc
- sram
- remoteprocs including ADSP,CDSP and GPDSP

[Zhenhua: added the smmu node]
Co-developed-by: Zhenhua Huang <quic_zhenhuah at quicinc.com>
Signed-off-by: Zhenhua Huang <quic_zhenhuah at quicinc.com>
[Xin: added ufs/adsp/gpdsp nodes]
Co-developed-by: Xin Liu <quic_liuxin at quicinc.com>
Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
[Kyle: added the aoss_qmp node]
Co-developed-by: Kyle Deng <quic_chunkaid at quicinc.com>
Signed-off-by: Kyle Deng <quic_chunkaid at quicinc.com>
[Tingguo: added the pmic nodes]
Co-developed-by: Tingguo Cheng <quic_tingguoc at quicinc.com>
Signed-off-by: Tingguo Cheng <quic_tingguoc at quicinc.com>
[Raviteja: added interconnect nodes]
Co-developed-by: Raviteja Laggyshetty <quic_rlaggysh at quicinc.com>
Signed-off-by: Raviteja Laggyshetty <quic_rlaggysh at quicinc.com>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 arch/arm64/boot/dts/qcom/qcs8300.dtsi | 1282 +++++++++++++++++++++++++++++++++
 1 file changed, 1282 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcs8300.dtsi b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
new file mode 100644
index 000000000000..244fa8bf97d9
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
@@ -0,0 +1,1282 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/clock/qcom,qcs8300-gcc.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
+#include <dt-bindings/interconnect/qcom,qcs8300-rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/mailbox/qcom-ipcc.h>
+#include <dt-bindings/power/qcom,rpmhpd.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+
+/ {
+	interrupt-parent = <&intc>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	clocks {
+		sleep_clk: sleep-clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32000>;
+		};
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78c";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			next-level-cache = <&l2_0>;
+			power-domains = <&cpu_pd0>;
+			power-domain-names = "psci";
+
+			l2_0: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_0>;
+
+				l3_0: l3-cache {
+					compatible = "cache";
+					cache-level = <3>;
+					cache-unified;
+				};
+			};
+		};
+
+		cpu1: cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78c";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			next-level-cache = <&l2_1>;
+			power-domains = <&cpu_pd1>;
+			power-domain-names = "psci";
+
+			l2_1: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu2: cpu at 200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78c";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			next-level-cache = <&l2_2>;
+			power-domains = <&cpu_pd2>;
+			power-domain-names = "psci";
+
+			l2_2: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu3: cpu at 300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78c";
+			reg = <0x0 0x300>;
+			enable-method = "psci";
+			next-level-cache = <&l2_3>;
+			power-domains = <&cpu_pd3>;
+			power-domain-names = "psci";
+
+			l2_3: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu4: cpu at 10000 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x10000>;
+			enable-method = "psci";
+			next-level-cache = <&l2_4>;
+			power-domains = <&cpu_pd4>;
+			power-domain-names = "psci";
+
+			l2_4: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_1>;
+
+				l3_1: l3-cache {
+					compatible = "cache";
+					cache-level = <3>;
+					cache-unified;
+				};
+			};
+		};
+
+		cpu5: cpu at 10100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x10100>;
+			enable-method = "psci";
+			next-level-cache = <&l2_5>;
+			power-domains = <&cpu_pd5>;
+			power-domain-names = "psci";
+
+			l2_5: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_1>;
+			};
+		};
+
+		cpu6: cpu at 10200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x10200>;
+			enable-method = "psci";
+			next-level-cache = <&l2_6>;
+			power-domains = <&cpu_pd6>;
+			power-domain-names = "psci";
+
+			l2_6: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_1>;
+			};
+		};
+
+		cpu7: cpu at 10300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x10300>;
+			enable-method = "psci";
+			next-level-cache = <&l2_7>;
+			power-domains = <&cpu_pd7>;
+			power-domain-names = "psci";
+
+			l2_7: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_1>;
+			};
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+
+				core1 {
+					cpu = <&cpu1>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpu2>;
+				};
+
+				core1 {
+					cpu = <&cpu3>;
+				};
+			};
+
+			cluster2 {
+				core0 {
+					cpu = <&cpu4>;
+				};
+
+				core1 {
+					cpu = <&cpu5>;
+				};
+
+				core2 {
+					cpu = <&cpu6>;
+				};
+
+				core3 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			little_cpu_sleep_0: cpu-sleep-0-0 {
+				compatible = "arm,idle-state";
+				idle-state-name = "silver-power-collapse";
+				arm,psci-suspend-param = <0x40000003>;
+				entry-latency-us = <449>;
+				exit-latency-us = <801>;
+				min-residency-us = <1574>;
+				local-timer-stop;
+			};
+
+			little_cpu_sleep_1: cpu-sleep-0-1 {
+				compatible = "arm,idle-state";
+				idle-state-name = "silver-rail-power-collapse";
+				arm,psci-suspend-param = <0x40000004>;
+				entry-latency-us = <602>;
+				exit-latency-us = <961>;
+				min-residency-us = <4288>;
+				local-timer-stop;
+			};
+
+			big_cpu_sleep_0: cpu-sleep-1-0 {
+				compatible = "arm,idle-state";
+				idle-state-name = "gold-power-collapse";
+				arm,psci-suspend-param = <0x40000003>;
+				entry-latency-us = <549>;
+				exit-latency-us = <901>;
+				min-residency-us = <1774>;
+				local-timer-stop;
+			};
+
+			big_cpu_sleep_1: cpu-sleep-1-1 {
+				compatible = "arm,idle-state";
+				idle-state-name = "gold-rail-power-collapse";
+				arm,psci-suspend-param = <0x40000004>;
+				entry-latency-us = <702>;
+				exit-latency-us = <1061>;
+				min-residency-us = <4488>;
+				local-timer-stop;
+			};
+		};
+
+		domain-idle-states {
+			silver_cluster_sleep: cluster-sleep-0 {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x41000044>;
+				entry-latency-us = <2552>;
+				exit-latency-us = <2848>;
+				min-residency-us = <5908>;
+			};
+
+			gold_cluster_sleep: cluster-sleep-1 {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x41000044>;
+				entry-latency-us = <2752>;
+				exit-latency-us = <3048>;
+				min-residency-us = <6118>;
+			};
+
+			system_sleep: domain-sleep {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x42000144>;
+				entry-latency-us = <3263>;
+				exit-latency-us = <6562>;
+				min-residency-us = <9987>;
+			};
+		};
+	};
+
+	firmware {
+		scm: scm {
+			compatible = "qcom,scm-qcs8300", "qcom,scm";
+			qcom,dload-mode = <&tcsr 0x13000>;
+		};
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		/* We expect the bootloader to fill in the size */
+		reg = <0x0 0x80000000 0x0 0x0>;
+	};
+
+	clk_virt: interconnect-0 {
+		compatible = "qcom,qcs8300-clk-virt";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	mc_virt: interconnect-1 {
+		compatible = "qcom,qcs8300-mc-virt";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+
+		cpu_pd0: power-domain-cpu0 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd0>;
+			domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>;
+		};
+
+		cpu_pd1: power-domain-cpu1 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd0>;
+			domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>;
+		};
+
+		cpu_pd2: power-domain-cpu2 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd0>;
+			domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>;
+		};
+
+		cpu_pd3: power-domain-cpu3 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd0>;
+			domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>;
+		};
+
+		cpu_pd4: power-domain-cpu4 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd1>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+		};
+
+		cpu_pd5: power-domain-cpu5 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd1>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+		};
+
+		cpu_pd6: power-domain-cpu6 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd1>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+		};
+
+		cpu_pd7: power-domain-cpu7 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd1>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+		};
+
+		cluster_pd0: power-domain-cluster0 {
+			#power-domain-cells = <0>;
+			power-domains = <&system_pd>;
+			domain-idle-states = <&gold_cluster_sleep>;
+		};
+
+		cluster_pd1: power-domain-cluster1 {
+			#power-domain-cells = <0>;
+			power-domains = <&system_pd>;
+			domain-idle-states = <&silver_cluster_sleep>;
+		};
+
+		system_pd: power-domain-system {
+			#power-domain-cells = <0>;
+			domain-idle-states = <&system_sleep>;
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		aop_image_mem: aop-image-region at 90800000 {
+			reg = <0x0 0x90800000 0x0 0x60000>;
+			no-map;
+		};
+
+		aop_cmd_db_mem: aop-cmd-db-region at 90860000 {
+			compatible = "qcom,cmd-db";
+			reg = <0x0 0x90860000 0x0 0x20000>;
+			no-map;
+		};
+
+		smem_mem: smem at 90900000 {
+			compatible = "qcom,smem";
+			reg = <0x0 0x90900000 0x0 0x200000>;
+			no-map;
+			hwlocks = <&tcsr_mutex 3>;
+		};
+
+		lpass_machine_learning_mem: lpass-machine-learning-region at 93b00000 {
+			reg = <0x0 0x93b00000 0x0 0xf00000>;
+			no-map;
+		};
+
+		adsp_rpc_remote_heap_mem: adsp-rpc-remote-heap-region at 94a00000 {
+			reg = <0x0 0x94a00000 0x0 0x800000>;
+			no-map;
+		};
+
+		camera_mem: camera-region at 95200000 {
+			reg = <0x0 0x95200000 0x0 0x500000>;
+			no-map;
+		};
+
+		adsp_mem: adsp-region at 95c00000 {
+			no-map;
+			reg = <0x0 0x95c00000 0x0 0x1e00000>;
+		};
+
+		q6_adsp_dtb_mem: q6-adsp-dtb-region at 97a00000 {
+			reg = <0x0 0x97a00000 0x0 0x80000>;
+			no-map;
+		};
+
+		q6_gpdsp_dtb_mem: q6-gpdsp-dtb-region at 97a80000 {
+			reg = <0x0 0x97a80000 0x0 0x80000>;
+			no-map;
+		};
+
+		gpdsp_mem: gpdsp-region at 97b00000 {
+			reg = <0x0 0x97b00000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		q6_cdsp_dtb_mem: q6-cdsp-dtb-region at 99900000 {
+			reg = <0x0 0x99900000 0x0 0x80000>;
+			no-map;
+		};
+
+		cdsp_mem: cdsp-region at 99980000 {
+			reg = <0x0 0x99980000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		gpu_microcode_mem: gpu-microcode-region at 9b780000 {
+			reg = <0x0 0x9b780000 0x0 0x2000>;
+			no-map;
+		};
+
+		cvp_mem: cvp-region at 9b782000 {
+			reg = <0x0 0x9b782000 0x0 0x700000>;
+			no-map;
+		};
+
+		video_mem: video-region at 9be82000 {
+			reg = <0x0 0x9be82000 0x0 0x700000>;
+			no-map;
+		};
+	};
+
+	smp2p-adsp {
+		compatible = "qcom,smp2p";
+		interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+					     IPCC_MPROC_SIGNAL_SMP2P
+					     IRQ_TYPE_EDGE_RISING>;
+		mboxes = <&ipcc IPCC_CLIENT_LPASS
+				IPCC_MPROC_SIGNAL_SMP2P>;
+
+		qcom,smem = <443>, <429>;
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <2>;
+
+		smp2p_adsp_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_adsp_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	smp2p-cdsp {
+		compatible = "qcom,smp2p";
+		interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
+					     IPCC_MPROC_SIGNAL_SMP2P
+					     IRQ_TYPE_EDGE_RISING>;
+		mboxes = <&ipcc IPCC_CLIENT_CDSP
+				IPCC_MPROC_SIGNAL_SMP2P>;
+
+		qcom,smem = <94>, <432>;
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <5>;
+
+		smp2p_cdsp_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_cdsp_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	smp2p-gpdsp {
+		compatible = "qcom,smp2p";
+		interrupts-extended = <&ipcc IPCC_CLIENT_GPDSP0
+					     IPCC_MPROC_SIGNAL_SMP2P
+					     IRQ_TYPE_EDGE_RISING>;
+		mboxes = <&ipcc IPCC_CLIENT_GPDSP0
+				IPCC_MPROC_SIGNAL_SMP2P>;
+
+		qcom,smem = <617>, <616>;
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <17>;
+
+		smp2p_gpdsp_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_gpdsp_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	soc: soc at 0 {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges = <0 0 0 0 0x10 0>;
+
+		gcc: clock-controller at 100000 {
+			compatible = "qcom,qcs8300-gcc";
+			reg = <0x0 0x00100000 0x0 0xc7018>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+			clocks = <&rpmhcc RPMH_CXO_CLK>,
+				 <&sleep_clk>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>;
+		};
+
+		ipcc: mailbox at 408000 {
+			compatible = "qcom,qcs8300-ipcc", "qcom,ipcc";
+			reg = <0x0 0x408000 0x0 0x1000>;
+			interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			#mbox-cells = <2>;
+		};
+
+		qfprom: efuse at 784000 {
+			compatible = "qcom,qcs8300-qfprom", "qcom,qfprom";
+			reg = <0x0 0x00784000 0x0 0x1200>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+		};
+
+		qupv3_id_0: geniqup at 9c0000 {
+			compatible = "qcom,geni-se-qup";
+			reg = <0x0 0x9c0000 0x0 0x2000>;
+			ranges;
+			clocks = <&gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>,
+				 <&gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>;
+			clock-names = "m-ahb", "s-ahb";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			status = "disabled";
+
+			uart7: serial at 99c000 {
+				compatible = "qcom,geni-debug-uart";
+				reg = <0x0 0x0099c000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart7_default>;
+				interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 0
+						 &clk_virt SLAVE_QUP_CORE_0 0>,
+						<&gem_noc MASTER_APPSS_PROC 0
+						 &config_noc SLAVE_QUP_0 0>;
+				status = "disabled";
+			};
+		};
+
+		config_noc: interconnect at 14c0000 {
+			compatible = "qcom,qcs8300-config-noc";
+			reg = <0x0 0x014c0000 0x0 0x13080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		system_noc: interconnect at 1680000 {
+			compatible = "qcom,qcs8300-system-noc";
+			reg = <0x0 0x01680000 0x0 0x15080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		aggre1_noc: interconnect at 16c0000 {
+			compatible = "qcom,qcs8300-aggre1-noc";
+			reg = <0x0 0x016c0000 0x0 0x17080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		aggre2_noc: interconnect at 1700000 {
+			compatible = "qcom,qcs8300-aggre2-noc";
+			reg = <0x0 0x01700000 0x0 0x1a080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		pcie_anoc: interconnect at 1760000 {
+			compatible = "qcom,qcs8300-pcie-anoc";
+			reg = <0x0 0x01760000 0x0 0xc080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		gpdsp_anoc: interconnect at 1780000 {
+			compatible = "qcom,qcs8300-gpdsp-anoc";
+			reg = <0x0 0x01780000 0x0 0xd080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		mmss_noc: interconnect at 17a0000 {
+			compatible = "qcom,qcs8300-mmss-noc";
+			reg = <0x0 0x017a0000 0x0 0x40000>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		ufs_mem_hc: ufs at 1d84000 {
+			compatible = "qcom,qcs8300-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
+			reg = <0x0 0x01d84000 0x0 0x3000>;
+			interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+			phys = <&ufs_mem_phy>;
+			phy-names = "ufsphy";
+			lanes-per-direction = <2>;
+			#reset-cells = <1>;
+			resets = <&gcc GCC_UFS_PHY_BCR>;
+			reset-names = "rst";
+
+			power-domains = <&gcc GCC_UFS_PHY_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
+
+			iommus = <&apps_smmu 0x100 0x0>;
+			dma-coherent;
+
+			interconnects = <&aggre1_noc MASTER_UFS_MEM 0
+					 &mc_virt SLAVE_EBI1 0>,
+					<&gem_noc MASTER_APPSS_PROC 0
+					 &config_noc SLAVE_UFS_MEM_CFG 0>;
+			interconnect-names = "ufs-ddr", "cpu-ufs";
+
+			clocks = <&gcc GCC_UFS_PHY_AXI_CLK>,
+				 <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+				 <&gcc GCC_UFS_PHY_AHB_CLK>,
+				 <&gcc GCC_UFS_PHY_UNIPRO_CORE_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>,
+				 <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>,
+				 <&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>;
+			clock-names = "core_clk",
+				      "bus_aggr_clk",
+				      "iface_clk",
+				      "core_clk_unipro",
+				      "ref_clk",
+				      "tx_lane0_sync_clk",
+				      "rx_lane0_sync_clk",
+				      "rx_lane1_sync_clk";
+			freq-table-hz = <75000000 300000000>,
+					<0 0>,
+					<0 0>,
+					<75000000 300000000>,
+					<0 0>,
+					<0 0>,
+					<0 0>,
+					<0 0>;
+			status = "disabled";
+		};
+
+		ufs_mem_phy: phy at 1d87000 {
+			compatible = "qcom,qcs8300-qmp-ufs-phy";
+			reg = <0x0 0x01d87000 0x0 0xe10>;
+			/*
+			 * Yes, GCC_EDP_REF_CLKREF_EN is correct in qref. It
+			 * enables the CXO clock to eDP *and* UFS PHY.
+			 */
+			clocks = <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+				 <&gcc GCC_EDP_REF_CLKREF_EN>;
+			clock-names = "ref", "ref_aux", "qref";
+			power-domains = <&gcc GCC_UFS_PHY_GDSC>;
+
+			resets = <&ufs_mem_hc 0>;
+			reset-names = "ufsphy";
+
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		tcsr_mutex: hwlock at 1f40000 {
+			compatible = "qcom,tcsr-mutex";
+			reg = <0x0 0x01f40000 0x0 0x20000>;
+			#hwlock-cells = <1>;
+		};
+
+		tcsr: syscon at 1fc0000 {
+			compatible = "qcom,qcs8300-tcsr", "syscon";
+			reg = <0x0 0x1fc0000 0x0 0x30000>;
+		};
+
+		remoteproc_adsp: remoteproc at 3000000 {
+			compatible = "qcom,qcs8300-adsp-pas";
+			reg = <0x0 0x3000000 0x0 0x00100>;
+
+			interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog", "fatal", "ready",
+					  "handover", "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_LCX>,
+					<&rpmhpd RPMHPD_LMX>;
+			power-domain-names = "lcx", "lmx";
+
+			memory-region = <&adsp_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_adsp_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			remoteproc_adsp_glink: glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_LPASS
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "lpass";
+				qcom,remote-pid = <2>;
+			};
+		};
+
+		lpass_ag_noc: interconnect at 3c40000 {
+			compatible = "qcom,qcs8300-lpass-ag-noc";
+			reg = <0x0 0x03c40000 0x0 0x17200>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		dc_noc: interconnect at 90e0000 {
+			compatible = "qcom,qcs8300-dc-noc";
+			reg = <0x0 0x090e0000 0x0 0x5080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		gem_noc: interconnect at 9100000 {
+			compatible = "qcom,qcs8300-gem-noc";
+			reg = <0x0 0x9100000 0x0 0xf7080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		pdc: interrupt-controller at b220000 {
+			compatible = "qcom,qcs8300-pdc", "qcom,pdc";
+			reg = <0x0 0xb220000 0x0 0x30000>,
+			      <0x0 0x17c000f0 0x0 0x64>;
+			interrupt-parent = <&intc>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			qcom,pdc-ranges = <0 480 40>,
+					  <40 140 14>,
+					  <54 263 1>,
+					  <55 306 4>,
+					  <59 312 3>,
+					  <62 374 2>,
+					  <64 434 2>,
+					  <66 438 2>,
+					  <70 520 1>,
+					  <73 523 1>,
+					  <118 568 6>,
+					  <124 609 3>,
+					  <159 638 1>,
+					  <160 720 3>,
+					  <169 728 30>,
+					  <199 416 2>,
+					  <201 449 1>,
+					  <202 89 1>,
+					  <203 451 1>,
+					  <204 462 1>,
+					  <205 264 1>,
+					  <206 579 1>,
+					  <207 653 1>,
+					  <208 656 1>,
+					  <209 659 1>,
+					  <210 122 1>,
+					  <211 699 1>,
+					  <212 705 1>,
+					  <213 450 1>,
+					  <214 643 2>,
+					  <216 646 5>,
+					  <221 390 5>,
+					  <226 700 2>,
+					  <228 440 1>,
+					  <229 663 1>,
+					  <230 524 2>,
+					  <232 612 3>,
+					  <235 723 5>;
+		};
+
+		aoss_qmp: power-management at c300000 {
+			compatible = "qcom,qcs8300-aoss-qmp", "qcom,aoss-qmp";
+			reg = <0x0 0x0c300000 0x0 0x400>;
+			interrupts-extended = <&ipcc IPCC_CLIENT_AOP
+					       IPCC_MPROC_SIGNAL_GLINK_QMP
+					       IRQ_TYPE_EDGE_RISING>;
+			mboxes = <&ipcc IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_GLINK_QMP>;
+			#clock-cells = <0>;
+		};
+
+		tlmm: pinctrl at f100000 {
+			compatible = "qcom,qcs8300-tlmm";
+			reg = <0x0 0x0f100000 0x0 0x300000>;
+			interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&tlmm 0 0 133>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			wakeup-parent = <&pdc>;
+
+			qup_uart7_default: qup-uart7-state {
+				/* TX, RX */
+				pins = "gpio43", "gpio44";
+				function = "qup0_se7";
+			};
+		};
+
+		sram: sram at 146d8000 {
+			compatible = "qcom,qcs8300-imem", "syscon", "simple-mfd";
+			reg = <0x0 0x146d8000 0x0 0x1000>;
+			ranges = <0x0 0x0 0x146d8000 0x1000>;
+
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			pil-reloc at 94c {
+				compatible = "qcom,pil-reloc-info";
+				reg = <0x94c 0xc8>;
+			};
+		};
+
+		apps_smmu: iommu at 15000000 {
+			compatible = "qcom,qcs8300-smmu-500", "qcom,smmu-500", "arm,mmu-500";
+
+			reg = <0x0 0x15000000 0x0 0x100000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <2>;
+			dma-coherent;
+
+			interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI  98 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI  99 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 706 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 689 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 690 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 691 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 692 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 693 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 694 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 695 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 696 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 413 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 708 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 709 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 710 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 711 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 414 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 712 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 713 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 714 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 715 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 912 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 911 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 910 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 909 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 908 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 907 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 906 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 905 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 904 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 903 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 902 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 901 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 900 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 899 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 898 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 897 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 896 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 895 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		intc: interrupt-controller at 17a00000 {
+			compatible = "arm,gic-v3";
+			reg = <0x0 0x17a00000 0x0 0x10000>,     /* GICD */
+			      <0x0 0x17a60000 0x0 0x100000>;    /* GICR * 8 */
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			#redistributor-regions = <1>;
+			redistributor-stride = <0x0 0x20000>;
+		};
+
+		memtimer: timer at 17c20000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x17c20000 0x0 0x1000>;
+			ranges = <0x0 0x0 0x0 0x20000000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			frame at 17c21000 {
+				reg = <0x17c21000 0x1000>,
+				      <0x17c22000 0x1000>;
+				frame-number = <0>;
+				interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			};
+
+			frame at 17c23000 {
+				reg = <0x17c23000 0x1000>;
+				frame-number = <1>;
+				interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame at 17c25000 {
+				reg = <0x17c25000 0x1000>;
+				frame-number = <2>;
+				interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame at 17c27000 {
+				reg = <0x17c27000 0x1000>;
+				frame-number = <3>;
+				interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame at 17c29000 {
+				reg = <0x17c29000 0x1000>;
+				frame-number = <4>;
+				interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame at 17c2b000 {
+				reg = <0x17c2b000 0x1000>;
+				frame-number = <5>;
+				interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame at 17c2d000 {
+				reg = <0x17c2d000 0x1000>;
+				frame-number = <6>;
+				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+		};
+
+		apps_rsc: rsc at 18200000 {
+			compatible = "qcom,rpmh-rsc";
+			reg = <0x0 0x18200000 0x0 0x10000>,
+			      <0x0 0x18210000 0x0 0x10000>,
+			      <0x0 0x18220000 0x0 0x10000>;
+			reg-names = "drv-0", "drv-1", "drv-2";
+			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+
+			power-domains = <&system_pd>;
+			label = "apps_rsc";
+
+			qcom,tcs-offset = <0xd00>;
+			qcom,drv-id = <2>;
+			qcom,tcs-config = <ACTIVE_TCS 2>,
+					  <SLEEP_TCS 3>,
+					  <WAKE_TCS 3>,
+					  <CONTROL_TCS 0>;
+
+			apps_bcm_voter: bcm-voter {
+				compatible = "qcom,bcm-voter";
+			};
+
+			rpmhcc: clock-controller {
+				compatible = "qcom,sa8775p-rpmh-clk";
+				#clock-cells = <1>;
+			};
+
+			rpmhpd: power-controller {
+				compatible = "qcom,qcs8300-rpmhpd";
+				#power-domain-cells = <1>;
+				operating-points-v2 = <&rpmhpd_opp_table>;
+
+				rpmhpd_opp_table: opp-table {
+					compatible = "operating-points-v2";
+
+					rpmhpd_opp_ret: opp-0 {
+						opp-level = <RPMH_REGULATOR_LEVEL_RETENTION>;
+					};
+
+					rpmhpd_opp_min_svs: opp-1 {
+						opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
+					};
+
+					rpmhpd_opp_low_svs: opp-2 {
+						opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+					};
+
+					rpmhpd_opp_svs: opp-3 {
+						opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+					};
+
+					rpmhpd_opp_svs_l1: opp-4 {
+						opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+					};
+
+					rpmhpd_opp_nom: opp-5 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+					};
+
+					rpmhpd_opp_nom_l1: opp-6 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+					};
+
+					rpmhpd_opp_nom_l2: opp-7 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM_L2>;
+					};
+
+					rpmhpd_opp_turbo: opp-8 {
+						opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+					};
+
+					rpmhpd_opp_turbo_l1: opp-9 {
+						opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+					};
+				};
+			};
+		};
+
+		remoteproc_gpdsp: remoteproc at 20c00000 {
+			compatible = "qcom,qcs8300-gpdsp-pas";
+			reg = <0x0 0x20c00000 0x0 0x10000>;
+
+			interrupts-extended = <&intc GIC_SPI 768 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_gpdsp_in 0 0>,
+					      <&smp2p_gpdsp_in 1 0>,
+					      <&smp2p_gpdsp_in 2 0>,
+					      <&smp2p_gpdsp_in 3 0>;
+			interrupt-names = "wdog", "fatal", "ready",
+					  "handover", "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_CX>,
+					<&rpmhpd RPMHPD_MXC>;
+			power-domain-names = "cx", "mxc";
+
+			interconnects = <&gpdsp_anoc MASTER_DSP0 0 &config_noc SLAVE_CLK_CTL 0>;
+
+			memory-region = <&gpdsp_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_gpdsp_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_GPDSP0
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_GPDSP0
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "gpdsp";
+				qcom,remote-pid = <17>;
+			};
+		};
+
+		nspa_noc: interconnect at 260c0000 {
+			compatible = "qcom,qcs8300-nspa-noc";
+			reg = <0x0 0x260c0000 0x0 0x16080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		remoteproc_cdsp: remoteproc at 26300000 {
+			compatible = "qcom,qcs8300-cdsp-pas";
+			reg = <0x0 0x26300000 0x0 0x10000>;
+
+			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog", "fatal", "ready",
+					  "handover", "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_CX>,
+					<&rpmhpd RPMHPD_MXC>,
+					<&rpmhpd RPMHPD_NSP0>;
+
+			power-domain-names = "cx", "mxc", "nsp";
+
+			interconnects = <&nspa_noc MASTER_CDSP_PROC 0 &mc_virt SLAVE_EBI1 0>;
+
+			memory-region = <&cdsp_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_cdsp_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_CDSP
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "cdsp";
+				qcom,remote-pid = <5>;
+			};
+		};
+	};
+
+	arch_timer: timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 12 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+};

-- 
2.25.1



From quic_jingyw at quicinc.com  Wed Sep  4 01:34:00 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 4 Sep 2024 16:34:00 +0800
Subject: [PATCH 19/19] arm64: dts: qcom: add base QCS8300 RIDE dts
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <20240904-qcs8300_initial_dtsi-v1-19-d0ea9afdc007@quicinc.com>

Add initial support for Qualcomm QCS8300 RIDE board which enables
DSPs, UFS and booting to shell with uart console.

[Xin: added ufs/adsp/gpdsp nodes]
Co-developed-by: Xin Liu <quic_liuxin at quicinc.com>
Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
[Tingguo: added the pmic nodes]
Co-developed-by: Tingguo Cheng <quic_tingguoc at quicinc.com>
Signed-off-by: Tingguo Cheng <quic_tingguoc at quicinc.com>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 arch/arm64/boot/dts/qcom/Makefile         |   1 +
 arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 246 ++++++++++++++++++++++++++++++
 2 files changed, 247 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 197ab325c0b9..fe4c21cfbdd5 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -111,6 +111,7 @@ dtb-$(CONFIG_ARCH_QCOM)	+= qcm6490-shift-otter.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-1000.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-4000.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs8300-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs8550-aim300-aiot.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qdu1000-idp.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qrb2210-rb1.dtb
diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
new file mode 100644
index 000000000000..e204b4c57bca
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+#include "qcs8300.dtsi"
+/ {
+	model = "Qualcomm Technologies, Inc. QCS8300 Ride";
+	compatible = "qcom,qcs8300-ride", "qcom,qcs8275", "qcom,qcs8300";
+	chassis-type = "embedded";
+
+	aliases {
+		serial0 = &uart7;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	xo_board_clk: xo-board-clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <38400000>;
+	};
+};
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "a";
+
+		vreg_s4a: smps4 {
+			regulator-name = "vreg_s4a";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s9a: smps9 {
+			regulator-name = "vreg_s9a";
+			regulator-min-microvolt = <1352000>;
+			regulator-max-microvolt = <1352000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3a: ldo3 {
+			regulator-name = "vreg_l3a";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4a: ldo4 {
+			regulator-name = "vreg_l4a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5a: ldo5 {
+			regulator-name = "vreg_l5a";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6a: ldo6 {
+			regulator-name = "vreg_l6a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7a: ldo7 {
+			regulator-name = "vreg_l7a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8a: ldo8 {
+			regulator-name = "vreg_l8a";
+			regulator-min-microvolt = <2504000>;
+			regulator-max-microvolt = <2960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9a: ldo9 {
+			regulator-name = "vreg_l9a";
+			regulator-min-microvolt = <2970000>;
+			regulator-max-microvolt = <3072000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "c";
+
+		vreg_s5c: smps5 {
+			regulator-name = "vreg_s5c";
+			regulator-min-microvolt = <1104000>;
+			regulator-max-microvolt = <1104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1c: ldo1 {
+			regulator-name = "vreg_l1c";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <500000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2c: ldo2 {
+			regulator-name = "vreg_l2c";
+			regulator-min-microvolt = <900000>;
+			regulator-max-microvolt = <904000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4c: ldo4 {
+			regulator-name = "vreg_l4c";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6c: ldo6 {
+			regulator-name = "vreg_l6c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7c: ldo7 {
+			regulator-name = "vreg_l7c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8c: ldo8 {
+			regulator-name = "vreg_l8c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9c: ldo9 {
+			regulator-name = "vreg_l9c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&remoteproc_adsp {
+	firmware-name = "qcom/qcs8300/adsp.mbn";
+	status = "okay";
+};
+
+&remoteproc_cdsp {
+	firmware-name = "qcom/qcs8300/cdsp0.mbn";
+	status = "okay";
+};
+
+&remoteproc_gpdsp {
+	firmware-name = "qcom/qcs8300/gpdsp0.mbn";
+	status = "okay";
+};
+
+&rpmhcc {
+	clocks = <&xo_board_clk>;
+	clock-names = "xo";
+};
+
+&uart7 {
+	status = "okay";
+};
+
+&ufs_mem_hc {
+	reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>;
+	vcc-supply = <&vreg_l8a>;
+	vcc-max-microamp = <1100000>;
+	vccq-supply = <&vreg_l4c>;
+	vccq-max-microamp = <1200000>;
+	status = "okay";
+};
+
+&ufs_mem_phy {
+	vdda-phy-supply = <&vreg_l4a>;
+	vdda-pll-supply = <&vreg_l5a>;
+	status = "okay";
+};

-- 
2.25.1



From frieder.schrempf at kontron.de  Wed Sep  4 02:21:59 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Wed, 4 Sep 2024 11:21:59 +0200
Subject: [PATCH V5 1/5] phy: freescale: fsl-samsung-hdmi: Replace register
 defines with macro
In-Reply-To: <20240904023310.163371-2-aford173@gmail.com>
References: <20240904023310.163371-1-aford173@gmail.com>
 <20240904023310.163371-2-aford173@gmail.com>
Message-ID: <eccf0274-51c8-4afd-bf98-af7d401f4422@kontron.de>

On 04.09.24 4:32 AM, Adam Ford wrote:
> There are 47 registers defined as PHY_REG_xx were xx goes from 00 to
> 47.  Simplify this by replacing them all with a macro which is passed
> the register number to return the proper register offset.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>

Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>


From hdegoede at redhat.com  Wed Sep  4 02:26:40 2024
From: hdegoede at redhat.com (Hans de Goede)
Date: Wed, 4 Sep 2024 11:26:40 +0200
Subject: [PATCH 0/6] power: supply: Change usb_types from an array into a
 bitmask
In-Reply-To: <ez5ja55dl7w7ynq2wv4efsvvqtk4xyalf4k6agtsuhpgrtlpg3@d6ghlle4cu2q>
References: <20240831142039.28830-1-hdegoede@redhat.com>
 <ez5ja55dl7w7ynq2wv4efsvvqtk4xyalf4k6agtsuhpgrtlpg3@d6ghlle4cu2q>
Message-ID: <8febdf39-ea1a-4e03-afc8-bd6e0c3b8624@redhat.com>

Hi,

On 9/4/24 12:04 AM, Sebastian Reichel wrote:
> Hi,
> 
> On Sat, Aug 31, 2024 at 04:20:33PM GMT, Hans de Goede wrote:
>> When support for the "charge_behaviour" property was added the list of
>> available values was made a bitmask in power_supply_desc.
>>
>> "usb_types" is very similar in that:
>> 1. It is an enum
>> 2. The list of available values is stored in power_supply_desc
>> 3. When shown it shows all available values, with the active one surrounded
>>    by square brackets.
>>
>> But "usb_types" uses an array with valid enum values instead of a bitmask.
>> This uses more memory then the bitmap approach and it makes it impossible
>> to have a shared generic show() function for properties which show
>> available values, with the active one surrounded by square brackets.
>>
>> This patch-set moves "usb_types" over to a bitmask in power_supply_desc
>> to indicate the available values.
>>
>> Patches 1 - 3:
>>
>> It turns out that the ucs1002-power driver contained a surprise in that
>> it supports writing to "usb_type" even though the ABI doc says it is
>> read-only. Since we cannot break shipped userspace API, the ship has sailed
>> on this one. The first patch documents that writing "usb_type" is allowed,
>> but only for power-supply devices which provide USB power rather then
>> consume it.
>>
>> Enum properties accept writing the FOO_TEXT[] string values, passing
>> the enum value matching the FOO_TEXT entry to set_property(), the second
>> patch adjusts ucs1002_set_usb_type() to directly accept enum values.
>>
>> The rt9467 driver was another driver which allowed writing to "usb_type"
>> but there the use made no sense, so it is simply dropped.
>>
>> Patches 4 - 6:
>>
>> These patches implement the actual moving of usb_types to a bitmask.
>>
>> Patch 6 is a bit of a bigbang patch moving all drivers over in one go,
>> touching a couple of drivers outside drivers/power/supply: 1 in
>> drivers/extcon/ 1 in drivers/phy/ and 5 in drivers/usb/typec/ since
>> the changes outside of drivers/power/supply are small I've chosen to
>> make all the changes in one go rather then have some sort of
>> intermediate state where both ways are supported.
>>
>> For merging this I believe it would be best for an immutable branch / tag
>> to be created on the linux-power-supply tree and then send a pull-request
>> to the extcon, phy and usb-typec maintainers to merge the tag.
>>
>> extcon, phy and typec maintainers can you please give your Acked-by for
>> patch 6/6 for merging these changes through the linux-power-supply tree?
>>
>> This set is based on top of the latest linux-power-supply/for-next.
> 
> As we are quite close before the merge window I just took it with
> just the Ack from Greg. The changes in PHY and Extcon are quite
> small.

Great, thank you.

Regards,

Hans




> I did prepare an immutable branch in case it is needed by
> any of the other involved trees:
> 
> The following changes since commit 8400291e289ee6b2bf9779ff1c83a291501f017b:
> 
>   Linux 6.11-rc1 (2024-07-28 14:19:55 -0700)
> 
> are available in the Git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git tags/ib-psy-usb-types-signed
> 
> for you to fetch changes up to 364ea7ccaef917a3068236a19a4b31a0623b561a:
> 
>   power: supply: Change usb_types from an array into a bitmask (2024-09-03 23:20:28 +0200)
> 
> ----------------------------------------------------------------
> Immutable branch for usb_types change for v6.12
> 
> Changing usb_types type from array to bitmap in the power_supply_desc
> struct requires updating power-supply drivers living in different
> subsystem, so it is handled via an immutable branch.
> 
> ----------------------------------------------------------------
> Hans de Goede (6):
>       power: supply: "usb_type" property may be written to
>       power: supply: ucs1002: Adjust ucs1002_set_usb_type() to accept string values
>       power: supply: rt9467-charger: Remove "usb_type" property write support
>       power: supply: sysfs: Add power_supply_show_enum_with_available() helper
>       power: supply: sysfs: Move power_supply_show_enum_with_available() up
>       power: supply: Change usb_types from an array into a bitmask
> 
>  Documentation/ABI/testing/sysfs-class-power     |  7 ++-
>  drivers/extcon/extcon-intel-cht-wc.c            | 15 ++----
>  drivers/phy/ti/phy-tusb1210.c                   | 11 ++---
>  drivers/power/supply/axp20x_usb_power.c         | 13 ++---
>  drivers/power/supply/bq256xx_charger.c          | 15 ++----
>  drivers/power/supply/cros_usbpd-charger.c       | 22 +++------
>  drivers/power/supply/lenovo_yoga_c630_battery.c |  7 +--
>  drivers/power/supply/mp2629_charger.c           | 15 ++----
>  drivers/power/supply/mt6360_charger.c           | 13 ++---
>  drivers/power/supply/mt6370-charger.c           | 13 ++---
>  drivers/power/supply/power_supply_core.c        |  4 --
>  drivers/power/supply/power_supply_sysfs.c       | 66 ++++++++-----------------
>  drivers/power/supply/qcom_battmgr.c             | 37 +++++++-------
>  drivers/power/supply/qcom_pmi8998_charger.c     | 13 ++---
>  drivers/power/supply/rk817_charger.c            |  9 +---
>  drivers/power/supply/rn5t618_power.c            | 13 ++---
>  drivers/power/supply/rt9467-charger.c           | 16 ++----
>  drivers/power/supply/rt9471.c                   | 15 ++----
>  drivers/power/supply/ucs1002_power.c            | 26 +++++-----
>  drivers/usb/typec/anx7411.c                     | 11 ++---
>  drivers/usb/typec/rt1719.c                      | 11 ++---
>  drivers/usb/typec/tcpm/tcpm.c                   | 11 ++---
>  drivers/usb/typec/tipd/core.c                   |  9 +---
>  drivers/usb/typec/ucsi/psy.c                    | 11 ++---
>  include/linux/power_supply.h                    |  3 +-
>  25 files changed, 132 insertions(+), 254 deletions(-)
> 
> -- Sebastian



From frieder.schrempf at kontron.de  Wed Sep  4 02:30:34 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Wed, 4 Sep 2024 11:30:34 +0200
Subject: [PATCH V5 2/5] phy: freescale: fsl-samsung-hdmi: Simplify
 REG21_PMS_S_MASK lookup
In-Reply-To: <20240904023310.163371-3-aford173@gmail.com>
References: <20240904023310.163371-1-aford173@gmail.com>
 <20240904023310.163371-3-aford173@gmail.com>
Message-ID: <3d1a6153-61c8-46a1-afaa-ec4e79069174@kontron.de>

On 04.09.24 4:32 AM, Adam Ford wrote:
> The value of 'S' is writen to two places, PHY_REG3[7:4] and
> PHY_REG21[3:0].  There is a lookup table which contains
> the value of PHY_REG3.  Rather than using a switch statement
> based on the pixel clock to search for the value of 'S' again,
> just shift the contents of PHY_REG3[7:4] >> 4 and place the value
> in PHY_REG21[3:0].  Doing this can eliminate an entire function.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>

Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>


From krzk at kernel.org  Wed Sep  4 02:34:41 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Sep 2024 11:34:41 +0200
Subject: [PATCH 00/19] Add initial support for QCS8300
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <fcfaeed3-8544-4e98-9f95-f43346dc83e8@kernel.org>

On 04/09/2024 10:33, Jingyi Wang wrote:
> Add initial support for QCS8300 SoC and QCS8300 RIDE board.
> 
> This revision brings support for:
> - CPUs with cpu idle
> - interrupt-controller with PDC wakeup support
> - gcc
> - TLMM
> - interconnect
> - qup with uart
> - smmu
> - pmic
> - ufs
> - ipcc
> - sram
> - remoteprocs including ADSP,CDSP and GPDSP
> 
> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
> ---
> patch series organized as:
> - 1-2: remoteproc binding and driver
> - 3-5: ufs binding and driver
> - 6-7: rpmhpd binding and driver
> - 8-15: bindings for other components found on the SoC

Limit your CC list. I found like 8 unnecessary addresses for already
huge Cc list. Or organize your patches per subsystem, as we usually expect.

> - 16-19: changes to support the device tree
> 
> dependencies:
> tlmm: https://lore.kernel.org/linux-arm-msm/20240819064933.1778204-1-quic_jingyw at quicinc.com/
> gcc: https://lore.kernel.org/all/20240820-qcs8300-gcc-v1-0-d81720517a82 at quicinc.com/
> interconnect: https://lore.kernel.org/linux-arm-msm/20240827151622.305-1-quic_rlaggysh at quicinc.com/

Why? UFS cannot depend on pinctrl for example.

This blocks testing and merging.

Please organize properly (so decouple) your patches, so that there is no
fake dependency.

Best regards,
Krzysztof



From krzk at kernel.org  Wed Sep  4 02:36:08 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Sep 2024 11:36:08 +0200
Subject: [PATCH 02/19] remoteproc: qcom: pas: Add QCS8300 remoteproc
 support
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-2-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
 <20240904-qcs8300_initial_dtsi-v1-2-d0ea9afdc007@quicinc.com>
Message-ID: <ecd95f82-ea98-4279-ad01-dc73d361180a@kernel.org>

On 04/09/2024 10:33, Jingyi Wang wrote:
> Add support for PIL loading on ADSP, CDSP and GPDSP on QCS8300
> platform.
> 
> Co-developed-by: Xin Liu <quic_liuxin at quicinc.com>
> Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
> ---
>  drivers/remoteproc/qcom_q6v5_pas.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> index ef82835e98a4..f92ccd4921b7 100644
> --- a/drivers/remoteproc/qcom_q6v5_pas.c
> +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> @@ -1416,6 +1416,9 @@ static const struct of_device_id adsp_of_match[] = {
>  	{ .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
>  	{ .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
>  	{ .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
> +	{ .compatible = "qcom,qcs8300-adsp-pas", .data = &sa8775p_adsp_resource},
> +	{ .compatible = "qcom,qcs8300-cdsp-pas", .data = &sa8775p_cdsp0_resource},
> +	{ .compatible = "qcom,qcs8300-gpdsp-pas", .data = &sa8775p_gpdsp0_resource},

What's the point of this? You have entire commit msg to explain such
weird duplication. Otherwise sorry, don't duplicate unnecessarily.
Devices are compatible, aren't they?

Best regards,
Krzysztof



From krzk at kernel.org  Wed Sep  4 02:36:37 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Sep 2024 11:36:37 +0200
Subject: [PATCH 05/19] phy: qcom-qmp-ufs: Add support for QCS8300
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-5-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
 <20240904-qcs8300_initial_dtsi-v1-5-d0ea9afdc007@quicinc.com>
Message-ID: <8e5e611c-bce6-478f-b63c-e532b95cbe5c@kernel.org>

On 04/09/2024 10:33, Jingyi Wang wrote:
> From: Xin Liu <quic_liuxin at quicinc.com>
> 
> Add QMP PHY support for QCS8300 which is compatible with SA8775P.
> 
> Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> index d964bdfe8700..8bad68400736 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> @@ -2010,6 +2010,9 @@ static const struct of_device_id qmp_ufs_of_match_table[] = {
>  	}, {
>  		.compatible = "qcom,msm8998-qmp-ufs-phy",
>  		.data = &sdm845_ufsphy_cfg,
> +	}, {
> +		.compatible = "qcom,qcs8300-qmp-ufs-phy",
> +		.data = &sa8775p_ufsphy_cfg,

Is compatible? Then this is redundant. Drop.

Best regards,
Krzysztof



From krzk at kernel.org  Wed Sep  4 02:38:08 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Sep 2024 11:38:08 +0200
Subject: [PATCH 16/19] dt-bindings: arm: qcom: document QCS8275/QCS8300
 SoC and reference board
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-16-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
 <20240904-qcs8300_initial_dtsi-v1-16-d0ea9afdc007@quicinc.com>
Message-ID: <0627fd69-f7d8-48ae-bbba-3a2d9bbaa5b1@kernel.org>

On 04/09/2024 10:33, Jingyi Wang wrote:
> Document the QCS8275/QCS8300 SoC and its reference board QCS8300 RIDE.
> QCS8300 is an Industrial Safe SoC, while QCS8275 is the Industrial
> Non-Safe version which can share the same SoC dtsi and board DTS.
> 
> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
> ---
>  Documentation/devicetree/bindings/arm/qcom.yaml | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
> index c0529486810f..ccf9a166368f 100644
> --- a/Documentation/devicetree/bindings/arm/qcom.yaml
> +++ b/Documentation/devicetree/bindings/arm/qcom.yaml
> @@ -42,6 +42,8 @@ description: |
>          msm8996
>          msm8998
>          qcs404
> +        qcs8275
> +        qcs8300
>          qcs8550
>          qcm2290
>          qcm6490
> @@ -895,6 +897,12 @@ properties:
>            - const: qcom,qcs404-evb
>            - const: qcom,qcs404
>  
> +      - items:
> +          - enum:
> +              - qcom,qcs8300-ride
> +          - const: qcom,qcs8275

So the qcs8300 ride comes with non-safe SoC?

Best regards,
Krzysztof



From krzk at kernel.org  Wed Sep  4 02:39:13 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Sep 2024 11:39:13 +0200
Subject: [PATCH 17/19] arm64: defconfig: enable clock controller,
 interconnect and pinctrl for QCS8300
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-17-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
 <20240904-qcs8300_initial_dtsi-v1-17-d0ea9afdc007@quicinc.com>
Message-ID: <851566fe-4802-41c7-bb35-d6d1e9cf9bdf@kernel.org>

On 04/09/2024 10:33, Jingyi Wang wrote:
> Enable clock controller, interrconnect and pinctrl for QCS8300.

NXP QCS8300? What is QCS8300? Which products use it? That's a defconfig
for entire kernel, not your Qualcomm one.

> It needs to be built-in for UART to provide a console.
> 
> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
> ---
>  arch/arm64/configs/defconfig | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 81ca46e3ab4b..a9ba6b25a0ed 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -606,6 +606,7 @@ CONFIG_PINCTRL_MSM8996=y
>  CONFIG_PINCTRL_MSM8998=y
>  CONFIG_PINCTRL_QCM2290=y
>  CONFIG_PINCTRL_QCS404=y
> +CONFIG_PINCTRL_QCS8300=y
>  CONFIG_PINCTRL_QDF2XXX=y
>  CONFIG_PINCTRL_QDU1000=y
>  CONFIG_PINCTRL_SA8775P=y
> @@ -1317,6 +1318,7 @@ CONFIG_MSM_MMCC_8998=m
>  CONFIG_QCM_GCC_2290=y
>  CONFIG_QCM_DISPCC_2290=m
>  CONFIG_QCS_GCC_404=y
> +CONFIG_QCS_GCC_8300=y
>  CONFIG_QDU_GCC_1000=y
>  CONFIG_SC_CAMCC_8280XP=m
>  CONFIG_SC_DISPCC_7280=m
> @@ -1618,6 +1620,7 @@ CONFIG_INTERCONNECT_QCOM_MSM8996=y
>  CONFIG_INTERCONNECT_QCOM_OSM_L3=m
>  CONFIG_INTERCONNECT_QCOM_QCM2290=y
>  CONFIG_INTERCONNECT_QCOM_QCS404=m
> +CONFIG_INTERCONNECT_QCOM_QCS8300=y

Why this cannot be a module?



Best regards,
Krzysztof



From krzk at kernel.org  Wed Sep  4 02:41:56 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Sep 2024 11:41:56 +0200
Subject: [PATCH 18/19] arm64: dts: qcom: add initial support for QCS8300
 DTSI
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-18-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
 <20240904-qcs8300_initial_dtsi-v1-18-d0ea9afdc007@quicinc.com>
Message-ID: <be8b573c-db4e-4eec-a9a6-3cd83d04156d@kernel.org>

On 04/09/2024 10:33, Jingyi Wang wrote:
> Add initial DTSI for QCS8300 SoC.
> 
> This revision brings support for:
> - CPUs with cpu idle
> - interrupt-controller with PDC wakeup support
> - gcc
> - TLMM
> - interconnect
> - qup with uart
> - smmu
> - pmic
> - ufs
> - ipcc
> - sram
> - remoteprocs including ADSP,CDSP and GPDSP
> 
> [Zhenhua: added the smmu node]
> Co-developed-by: Zhenhua Huang <quic_zhenhuah at quicinc.com>
> Signed-off-by: Zhenhua Huang <quic_zhenhuah at quicinc.com>
> [Xin: added ufs/adsp/gpdsp nodes]
> Co-developed-by: Xin Liu <quic_liuxin at quicinc.com>
> Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
> [Kyle: added the aoss_qmp node]
> Co-developed-by: Kyle Deng <quic_chunkaid at quicinc.com>
> Signed-off-by: Kyle Deng <quic_chunkaid at quicinc.com>
> [Tingguo: added the pmic nodes]
> Co-developed-by: Tingguo Cheng <quic_tingguoc at quicinc.com>
> Signed-off-by: Tingguo Cheng <quic_tingguoc at quicinc.com>
> [Raviteja: added interconnect nodes]
> Co-developed-by: Raviteja Laggyshetty <quic_rlaggysh at quicinc.com>
> Signed-off-by: Raviteja Laggyshetty <quic_rlaggysh at quicinc.com>
> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
> ---
>  arch/arm64/boot/dts/qcom/qcs8300.dtsi | 1282 +++++++++++++++++++++++++++++++++
>  1 file changed, 1282 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/qcs8300.dtsi b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
> new file mode 100644
> index 000000000000..244fa8bf97d9
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
> @@ -0,0 +1,1282 @@
> +// SPDX-License-Identifier: BSD-3-Clause
> +/*
> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#include <dt-bindings/clock/qcom,qcs8300-gcc.h>
> +#include <dt-bindings/clock/qcom,rpmh.h>
> +#include <dt-bindings/interconnect/qcom,icc.h>
> +#include <dt-bindings/interconnect/qcom,qcs8300-rpmh.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/mailbox/qcom-ipcc.h>
> +#include <dt-bindings/power/qcom,rpmhpd.h>
> +#include <dt-bindings/power/qcom-rpmpd.h>
> +#include <dt-bindings/soc/qcom,rpmh-rsc.h>
> +
> +/ {
> +	interrupt-parent = <&intc>;
> +	#address-cells = <2>;
> +	#size-cells = <2>;
> +
> +	clocks {
> +		sleep_clk: sleep-clk {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <32000>;

Are you sure that sleep clock is physically part of the SoC?

> +		};
> +	};
> +
> +	cpus {
> +		#address-cells = <2>;
> +		#size-cells = <0>;
> +

...

> +
> +	soc: soc at 0 {
> +		compatible = "simple-bus";
> +
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges = <0 0 0 0 0x10 0>;

ranges follow compatible, so it is the second property.



Best regards,
Krzysztof



From krzk at kernel.org  Wed Sep  4 03:19:19 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Sep 2024 12:19:19 +0200
Subject: [PATCH 00/19] Add initial support for QCS8300
In-Reply-To: <fcfaeed3-8544-4e98-9f95-f43346dc83e8@kernel.org>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
 <fcfaeed3-8544-4e98-9f95-f43346dc83e8@kernel.org>
Message-ID: <3535a897-8708-463d-b931-fa344a967f18@kernel.org>

On 04/09/2024 11:34, Krzysztof Kozlowski wrote:
> On 04/09/2024 10:33, Jingyi Wang wrote:
>> Add initial support for QCS8300 SoC and QCS8300 RIDE board.
>>
>> This revision brings support for:
>> - CPUs with cpu idle
>> - interrupt-controller with PDC wakeup support
>> - gcc
>> - TLMM
>> - interconnect
>> - qup with uart
>> - smmu
>> - pmic
>> - ufs
>> - ipcc
>> - sram
>> - remoteprocs including ADSP,CDSP and GPDSP
>>
>> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
>> ---
>> patch series organized as:
>> - 1-2: remoteproc binding and driver
>> - 3-5: ufs binding and driver
>> - 6-7: rpmhpd binding and driver
>> - 8-15: bindings for other components found on the SoC
> 
> Limit your CC list. I found like 8 unnecessary addresses for already
> huge Cc list. Or organize your patches per subsystem, as we usually expect.
> 
>> - 16-19: changes to support the device tree
>>
>> dependencies:
>> tlmm: https://lore.kernel.org/linux-arm-msm/20240819064933.1778204-1-quic_jingyw at quicinc.com/
>> gcc: https://lore.kernel.org/all/20240820-qcs8300-gcc-v1-0-d81720517a82 at quicinc.com/
>> interconnect: https://lore.kernel.org/linux-arm-msm/20240827151622.305-1-quic_rlaggysh at quicinc.com/
> 
> Why? UFS cannot depend on pinctrl for example.
> 
> This blocks testing and merging.
> 
> Please organize properly (so decouple) your patches, so that there is no
> fake dependency.

Let me also add here one more thought. That's like fourth or fifth
QCS/SA patchset last two weeks from Qualcomm and they repeat the same
mistakes. Not correctly organized, huge cc list, same problems with
bindings or drivers.

I am giving much more comments to fix than review/ack tags.

I am not going to review this. I will also slow down with reviewing
other Qualcomm patches. Why? Because you post simultaneously, apparently
you do not learn from other review, so I have to keep repeating the same.

I am overwhelmed with this, so please expect two week review time from me.

Best regards,
Krzysztof



From aford173 at gmail.com  Wed Sep  4 03:37:00 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed, 4 Sep 2024 05:37:00 -0500
Subject: [PATCH V4 3/5] phy: freescale: fsl-samsung-hdmi: Support dynamic integer
In-Reply-To: <ZtgaOlHi93b_py7T@atmark-techno.com>
References: <20240903013113.139698-1-aford173@gmail.com> <20240903013113.139698-4-aford173@gmail.com>
 <ZtgaOlHi93b_py7T@atmark-techno.com>
Message-ID: <CAHCN7xJs1AefLJ1=0FfOs=A2B-gE5sC_VSVS6aGVhnSPOKDuxg@mail.gmail.com>

On Wed, Sep 4, 2024 at 3:28?AM Dominique Martinet
<dominique.martinet at atmark-techno.com> wrote:
>
> Adam Ford wrote on Mon, Sep 02, 2024 at 08:30:45PM -0500:
> > There is currently a look-up table for a variety of resolutions.
> > Since the phy has the ability to dynamically calculate the values
> > necessary to use the intger divider which should allow more
> > resolutions without having to update the look-up-table.
> >
> > If the lookup table cannot find an exact match, fall back to the
> > dynamic calculator of the integer divider.
> >
> > Previously, the value of P was hard-coded to 1, this required an
> > update to the phy_pll_cfg table to add in the extra value into the
> > table, so if the value of P is calculated to be something else
> > by the PMS calculator, the calculated_phy_pll_cfg structure
> > can be used instead without having to keep track of which method
> > was used.
> >
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
>
> I've rechecked this series with abs() added in the later patch and this

Oh shoot, I totally missed your request for the abs patch.
Sorry about that.  Do you want me to do a V6?

adam

> looks fine; all modes I tried properly synced up with my monitor.
> (except one but I don't see set_rate() being called for it so it's
> something else)
>
> (On a semi-unrelated note on my backport I get a "PLL failed to lock"
> message for the first sync only, but everything seems to work regardless
> even if there is no further set_rate(), so I'll pretend I didn't see
> that... the old code just has a 20ms wait without any check so it's not
> like it was any better... anyway that's unrelated to this serie)
>
> I'm also confident enough set_rate() won't be called in parallel with
> different rates for my device so I'm fine with the new global, letting
> others complain if that's a problem for them.
>
>
> So, feel free to add this to all 5 patches:
> Test-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
>
> Just one style nitpick:
>
> > @@ -453,29 +541,70 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
> >  static long phy_clk_round_rate(struct clk_hw *hw,
> >                              unsigned long rate, unsigned long *parent_rate)
> >  {
> > +     u32 int_div_clk;
> >       int i;
> > +     u16 m;
> > +     u8 p, s;
> > +
> > +     /* If the clock is out of range return error instead of searching */
> > +     if (rate > 297000000 || rate < 22250000)
> > +             return -EINVAL;
> >
> > +     /* Check the look-up table */
> >       for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> >               if (phy_pll_cfg[i].pixclk <= rate)
> > -                     return phy_pll_cfg[i].pixclk;
> > +                     break;
> > +     /* If the rate is an exact match, return it now */
> > +     if (rate == phy_pll_cfg[i].pixclk)
> > +             return phy_pll_cfg[i].pixclk;
> > +
> > +     /*
> > +      * The math on the lookup table shows the PMS math yields a
> > +      * frequency 5 x pixclk.
> > +      * When we check the integer divider against the desired rate,
> > +      * multiply the rate x 5 and then divide the outcome by 5.
> > +      */
> > +     int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
>
> I still think it makes more sense to move the * 5, / 5 and comment
> inside fsl_samsung_hdmi_phy_find_pms -- the other caller doesn't have
> such the comment so it might look odd depending on where one started
> looking.
>
> --
> Dominique


From dmitry.baryshkov at linaro.org  Wed Sep  4 03:55:34 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 4 Sep 2024 13:55:34 +0300
Subject: [PATCH 03/19] dt-bindings: phy: Add QMP UFS PHY comptible for
 QCS8300
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-3-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
 <20240904-qcs8300_initial_dtsi-v1-3-d0ea9afdc007@quicinc.com>
Message-ID: <e7qsuk3xoqgywubrkejoy3dztae2comlfn3mu6t226mvfvpfof@mlnj5s2xcsjf>

On Wed, Sep 04, 2024 at 04:33:44PM GMT, Jingyi Wang wrote:
> From: Xin Liu <quic_liuxin at quicinc.com>
> 
> Document the QMP UFS PHY compatible for QCS8300 to support physical
> layer functionality for USB found on the SoC.

So this is talking about USB, but the patch changes UFS. Please adjust.

> 
> Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
> ---
>  Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
> index f9cfbd0b2de6..a3540f7a8ef8 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
> @@ -18,6 +18,7 @@ properties:
>      enum:
>        - qcom,msm8996-qmp-ufs-phy
>        - qcom,msm8998-qmp-ufs-phy
> +      - qcom,qcs8300-qmp-ufs-phy
>        - qcom,sa8775p-qmp-ufs-phy
>        - qcom,sc7180-qmp-ufs-phy
>        - qcom,sc7280-qmp-ufs-phy
> @@ -85,6 +86,7 @@ allOf:
>            contains:
>              enum:
>                - qcom,msm8998-qmp-ufs-phy
> +              - qcom,qcs8300-qmp-ufs-phy
>                - qcom,sa8775p-qmp-ufs-phy
>                - qcom,sc7180-qmp-ufs-phy
>                - qcom,sc7280-qmp-ufs-phy
> 
> -- 
> 2.25.1
> 

-- 
With best wishes
Dmitry


From lkp at intel.com  Wed Sep  4 04:50:09 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 4 Sep 2024 19:50:09 +0800
Subject: [PATCH v5 2/5] phy: stm32: Add support for STM32MP25 COMBOPHY.
In-Reply-To: <20240903121303.2953150-3-christian.bruel@foss.st.com>
References: <20240903121303.2953150-3-christian.bruel@foss.st.com>
Message-ID: <202409041913.v0xzfcJ2-lkp@intel.com>

Hi Christian,

kernel test robot noticed the following build warnings:

[auto build test WARNING on atorgue-stm32/stm32-next]
[also build test WARNING on robh/for-next linus/master v6.11-rc6 next-20240904]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Christian-Bruel/dt-bindings-phy-Add-STM32MP25-COMBOPHY-bindings/20240903-201737
base:   https://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32.git stm32-next
patch link:    https://lore.kernel.org/r/20240903121303.2953150-3-christian.bruel%40foss.st.com
patch subject: [PATCH v5 2/5] phy: stm32: Add support for STM32MP25 COMBOPHY.
config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20240904/202409041913.v0xzfcJ2-lkp at intel.com/config)
compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240904/202409041913.v0xzfcJ2-lkp at 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 at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409041913.v0xzfcJ2-lkp at intel.com/

All warnings (new ones prefixed by >>):

>> drivers/phy/st/phy-stm32-combophy.c:524:10: warning: variable 'ret' is uninitialized when used here [-Wuninitialized]
     524 |                 return ret;
         |                        ^~~
   drivers/phy/st/phy-stm32-combophy.c:509:9: note: initialize the variable 'ret' to silence this warning
     509 |         int ret, irq;
         |                ^
         |                 = 0
   1 warning generated.


vim +/ret +524 drivers/phy/st/phy-stm32-combophy.c

   503	
   504	static int stm32_combophy_probe(struct platform_device *pdev)
   505	{
   506		struct stm32_combophy *combophy;
   507		struct device *dev = &pdev->dev;
   508		struct phy_provider *phy_provider;
   509		int ret, irq;
   510	
   511		combophy = devm_kzalloc(dev, sizeof(*combophy), GFP_KERNEL);
   512		if (!combophy)
   513			return -ENOMEM;
   514	
   515		combophy->dev = dev;
   516	
   517		dev_set_drvdata(dev, combophy);
   518	
   519		combophy->base = devm_platform_ioremap_resource(pdev, 0);
   520		if (IS_ERR(combophy->base))
   521			return PTR_ERR(combophy->base);
   522	
   523		if (stm32_combophy_get_clocks(combophy))
 > 524			return ret;
   525	
   526		combophy->phy_reset = devm_reset_control_get(dev, "phy");
   527		if (IS_ERR(combophy->phy_reset))
   528			return dev_err_probe(dev, PTR_ERR(combophy->phy_reset),
   529					     "Failed to get PHY reset\n");
   530	
   531		combophy->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg");
   532		if (IS_ERR(combophy->regmap))
   533			return dev_err_probe(dev, PTR_ERR(combophy->regmap),
   534					     "No syscfg specified\n");
   535	
   536		combophy->phy = devm_phy_create(dev, NULL, &stm32_combophy_phy_data);
   537		if (IS_ERR(combophy->phy))
   538			return dev_err_probe(dev, PTR_ERR(combophy->phy),
   539					     "failed to create PCIe/USB3 ComboPHY\n");
   540	
   541		if (device_property_read_bool(dev, "wakeup-source")) {
   542			irq = platform_get_irq(pdev, 0);
   543			if (irq < 0)
   544				return dev_err_probe(dev, irq, "failed to get IRQ\n");
   545			combophy->irq_wakeup = irq;
   546	
   547			ret = devm_request_threaded_irq(dev, combophy->irq_wakeup, NULL,
   548							stm32_combophy_irq_wakeup_handler, IRQF_ONESHOT,
   549							NULL, NULL);
   550			if (ret)
   551				return dev_err_probe(dev, ret, "unable to request wake IRQ %d\n",
   552							 combophy->irq_wakeup);
   553		}
   554	
   555		ret = devm_pm_runtime_enable(dev);
   556		if (ret)
   557			return dev_err_probe(dev, ret, "Failed to enable pm runtime\n");
   558	
   559		phy_set_drvdata(combophy->phy, combophy);
   560	
   561		phy_provider = devm_of_phy_provider_register(dev, stm32_combophy_xlate);
   562	
   563		return PTR_ERR_OR_ZERO(phy_provider);
   564	}
   565	

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


From frieder.schrempf at kontron.de  Wed Sep  4 06:35:35 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Wed, 4 Sep 2024 15:35:35 +0200
Subject: [PATCH V5 3/5] phy: freescale: fsl-samsung-hdmi: Support dynamic
 integer
In-Reply-To: <20240904023310.163371-4-aford173@gmail.com>
References: <20240904023310.163371-1-aford173@gmail.com>
 <20240904023310.163371-4-aford173@gmail.com>
Message-ID: <c882eed1-9f36-4382-89fe-f56dd457a45f@kontron.de>

On 04.09.24 4:32 AM, Adam Ford wrote:
> There is currently a look-up table for a variety of resolutions.
> Since the phy has the ability to dynamically calculate the values
> necessary to use the intger divider which should allow more

                       ^ integer

> resolutions without having to update the look-up-table.
> 
> If the lookup table cannot find an exact match, fall back to the
> dynamic calculator of the integer divider.

Nitpick: You have thre different versions of how to spell "lookup table"
in the paragraphs above. Maybe you can decide on one... ;)

> 
> Previously, the value of P was hard-coded to 1, this required an
> update to the phy_pll_cfg table to add in the extra value into the
> table, so if the value of P is calculated to be something else
> by the PMS calculator, the calculated_phy_pll_cfg structure
> can be used instead without having to keep track of which method
> was used.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>

The comments I have are only nitpicks and the patch seems to work fine
for me. So feel free to add:

Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>

> ---
> V5:  No Change
> V4:  No Change
> V3:  Change size of pll_div_regs to include PHY_REG01 (P)
>      Create calculated_phy_pll_cfg to containe the values
>      Eliminate the PMS calculation from fsl_samsung_hdmi_phy_configure
>      Make the LUT primary and fall back to integer calculator in
>      phy_clk_round_rate.
>      Check the range right away to ensure it's reaonsable rather than
>      trying to find a clock only to learn it's outside the range.
>      Overall added notes and comments where stuff may not be intuitive.
> 
> V2:  Update phy_clk_round_rate and phy_clk_set_rate to both support
>      the integer clock PMS calculator.
> ---
>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 341 +++++++++++++------
>  1 file changed, 235 insertions(+), 106 deletions(-)
> 
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> index 4f6874226f9a..8f2c0082aa12 100644
> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -16,6 +16,8 @@
>  
>  #define PHY_REG(reg)		(reg * 4)
>  
> +#define REG01_PMS_P_MASK	GENMASK(3, 0)
> +#define REG03_PMS_S_MASK	GENMASK(7, 4)
>  #define REG12_CK_DIV_MASK	GENMASK(5, 4)
>  
>  #define REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
> @@ -38,281 +40,296 @@
>  #define REG34_PLL_LOCK		BIT(6)
>  #define REG34_PHY_CLK_READY	BIT(5)
>  
> -#define PHY_PLL_DIV_REGS_NUM 6
> +#ifndef MHZ
> +#define MHZ	(1000UL * 1000UL)
> +#endif
> +
> +#define PHY_PLL_DIV_REGS_NUM 7
>  
>  struct phy_config {
>  	u32	pixclk;
>  	u8	pll_div_regs[PHY_PLL_DIV_REGS_NUM];
>  };
>  
> +/*
> + * The calculated_phy_pll_cfg only handles integer divider for PMS only,

Nitpick: Remove duplicate 'only'

> + * meaning the last four entries will be fixed, but the first three will
> + * be calculated by the PMS calculator

Nitpick: Period at the end of the sentence

> + */
> +static struct phy_config calculated_phy_pll_cfg = {
> +	.pixclk = 0,
> +	.pll_div_regs = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
> +};
> +
> +/* The lookup table contains values for which the fractional divder is used */

Nitpick: It seems this comment would rather belong into patch 5/5.

>  static const struct phy_config phy_pll_cfg[] = {
>  	{
>  		.pixclk = 22250000,
> -		.pll_div_regs = { 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 23750000,
> -		.pll_div_regs = { 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 24000000,
> -		.pll_div_regs = { 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 24024000,
> -		.pll_div_regs = { 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 25175000,
> -		.pll_div_regs = { 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 25200000,
> -		.pll_div_regs = { 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 26750000,
> -		.pll_div_regs = { 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 27000000,
> -		.pll_div_regs = { 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 27027000,
> -		.pll_div_regs = { 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 29500000,
> -		.pll_div_regs = { 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 30750000,
> -		.pll_div_regs = { 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
>  	}, {
>  		.pixclk = 30888000,
> -		.pll_div_regs = { 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
>  	}, {
>  		.pixclk = 33750000,
> -		.pll_div_regs = { 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 35000000,
> -		.pll_div_regs = { 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 36000000,
> -		.pll_div_regs = { 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 36036000,
> -		.pll_div_regs = { 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 40000000,
> -		.pll_div_regs = { 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 43200000,
> -		.pll_div_regs = { 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 43243200,
> -		.pll_div_regs = { 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 44500000,
> -		.pll_div_regs = { 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
> +		.pll_div_regs = { 0xd1, 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
>  	}, {
>  		.pixclk = 47000000,
> -		.pll_div_regs = { 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 47500000,
> -		.pll_div_regs = { 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 50349650,
> -		.pll_div_regs = { 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 50400000,
> -		.pll_div_regs = { 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 53250000,
> -		.pll_div_regs = { 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
> +		.pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
>  	}, {
>  		.pixclk = 53500000,
> -		.pll_div_regs = { 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 54000000,
> -		.pll_div_regs = { 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 54054000,
> -		.pll_div_regs = { 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 59000000,
> -		.pll_div_regs = { 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 59340659,
> -		.pll_div_regs = { 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
> +		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
>  	}, {
>  		.pixclk = 59400000,
> -		.pll_div_regs = { 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 61500000,
> -		.pll_div_regs = { 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
>  	}, {
>  		.pixclk = 63500000,
> -		.pll_div_regs = { 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 67500000,
> -		.pll_div_regs = { 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 70000000,
> -		.pll_div_regs = { 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 72000000,
> -		.pll_div_regs = { 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 72072000,
> -		.pll_div_regs = { 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 74176000,
> -		.pll_div_regs = { 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
> +		.pll_div_regs = { 0xd1, 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
>  	}, {
>  		.pixclk = 74250000,
> -		.pll_div_regs = { 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
> +		.pll_div_regs = { 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
>  	}, {
>  		.pixclk = 78500000,
> -		.pll_div_regs = { 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 80000000,
> -		.pll_div_regs = { 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 82000000,
> -		.pll_div_regs = { 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
>  	}, {
>  		.pixclk = 82500000,
> -		.pll_div_regs = { 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
> +		.pll_div_regs = { 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
>  	}, {
>  		.pixclk = 89000000,
> -		.pll_div_regs = { 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 90000000,
> -		.pll_div_regs = { 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 94000000,
> -		.pll_div_regs = { 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 95000000,
> -		.pll_div_regs = { 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 98901099,
> -		.pll_div_regs = { 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
> +		.pll_div_regs = { 0xd1, 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
>  	}, {
>  		.pixclk = 99000000,
> -		.pll_div_regs = { 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
> +		.pll_div_regs = { 0xd1, 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
>  	}, {
>  		.pixclk = 100699300,
> -		.pll_div_regs = { 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 100800000,
> -		.pll_div_regs = { 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 102500000,
> -		.pll_div_regs = { 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
> +		.pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
>  	}, {
>  		.pixclk = 104750000,
> -		.pll_div_regs = { 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
> +		.pll_div_regs = { 0xd1, 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
>  	}, {
>  		.pixclk = 106500000,
> -		.pll_div_regs = { 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
> +		.pll_div_regs = { 0xd1, 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
>  	}, {
>  		.pixclk = 107000000,
> -		.pll_div_regs = { 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 108000000,
> -		.pll_div_regs = { 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 108108000,
> -		.pll_div_regs = { 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 118000000,
> -		.pll_div_regs = { 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 118800000,
> -		.pll_div_regs = { 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 123000000,
> -		.pll_div_regs = { 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
>  	}, {
>  		.pixclk = 127000000,
> -		.pll_div_regs = { 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 135000000,
> -		.pll_div_regs = { 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 135580000,
> -		.pll_div_regs = { 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
> +		.pll_div_regs = { 0xd1, 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
>  	}, {
>  		.pixclk = 137520000,
> -		.pll_div_regs = { 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
> +		.pll_div_regs = { 0xd1, 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
>  	}, {
>  		.pixclk = 138750000,
> -		.pll_div_regs = { 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
> +		.pll_div_regs = { 0xd1, 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
>  	}, {
>  		.pixclk = 140000000,
> -		.pll_div_regs = { 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 144000000,
> -		.pll_div_regs = { 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 148352000,
> -		.pll_div_regs = { 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
>  	}, {
>  		.pixclk = 148500000,
> -		.pll_div_regs = { 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
>  	}, {
>  		.pixclk = 154000000,
> -		.pll_div_regs = { 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
>  	}, {
>  		.pixclk = 157000000,
> -		.pll_div_regs = { 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 160000000,
> -		.pll_div_regs = { 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 162000000,
> -		.pll_div_regs = { 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
> +		.pll_div_regs = { 0xd1, 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
>  	}, {
>  		.pixclk = 164000000,
> -		.pll_div_regs = { 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
> +		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
>  	}, {
>  		.pixclk = 165000000,
> -		.pll_div_regs = { 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
> +		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
>  	}, {
>  		.pixclk = 180000000,
> -		.pll_div_regs = { 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 185625000,
> -		.pll_div_regs = { 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 188000000,
> -		.pll_div_regs = { 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 198000000,
> -		.pll_div_regs = { 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
> +		.pll_div_regs = { 0xd1, 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
>  	}, {
>  		.pixclk = 205000000,
> -		.pll_div_regs = { 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
> +		.pll_div_regs = { 0xd1, 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
>  	}, {
>  		.pixclk = 209500000,
> -		.pll_div_regs = { 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
> +		.pll_div_regs = { 0xd1, 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
>  	}, {
>  		.pixclk = 213000000,
> -		.pll_div_regs = { 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
> +		.pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
>  	}, {
>  		.pixclk = 216000000,
> -		.pll_div_regs = { 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 216216000,
> -		.pll_div_regs = { 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 237600000,
> -		.pll_div_regs = { 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 254000000,
> -		.pll_div_regs = { 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 277500000,
> -		.pll_div_regs = { 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
> +		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
>  	}, {
>  		.pixclk = 288000000,
> -		.pll_div_regs = { 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 297000000,
> -		.pll_div_regs = { 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
>  	},
>  };
>  
> @@ -322,7 +339,8 @@ struct reg_settings {
>  };
>  
>  static const struct reg_settings common_phy_cfg[] = {
> -	{ PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
> +	{ PHY_REG(0), 0x00 },
> +	/* PHY_REG(1-7) pix clk specific */
>  	{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
>  	{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
>  	/* REG12 pixclk specific */
> @@ -415,6 +433,76 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
>  	       phy->regs + PHY_REG(14));
>  }
>  
> +static unsigned long fsl_samsung_hdmi_phy_find_pms(unsigned long fout, u8 *p, u16 *m, u8 *s)
> +{
> +	unsigned long best_freq = 0;
> +	u32 min_delta = 0xffffffff;
> +	u8 _p, best_p;
> +	u16 _m, best_m;
> +	u8 _s, best_s;
> +
> +	/* The ref manual states the values of 'P' range from 1 to 11 */
> +	for (_p = 1; _p <= 11; ++_p) {
> +		for (_s = 1; _s <= 16; ++_s) {
> +			u64 tmp;
> +			u32 delta;
> +
> +			/* s must be one or even */
> +			if (_s > 1 && (_s & 0x01) == 1)
> +				_s++;
> +
> +			/* _s cannot be 14 per the TRM */
> +			if (_s == 14)
> +				continue;
> +
> +			/*
> +			 * TODO: Ref Manual doesn't state the range of _m
> +			 * so this should be further refined if possible.
> +			 * This range was set based on the original values
> +			 * in the look-up table
> +			 */

There is the strange note "Div by -Div by 255" in the RM. I think it's
supposed to define the range, but is missing the number for the lower
bound. The upper bound is probably 255!?

But we might also leave it like it is here and extend it later after
further testing.

> +			tmp = (u64)fout * (_p * _s);
> +			do_div(tmp, 24 * MHZ);
> +			_m = tmp;
> +			if (_m < 0x30 || _m > 0x7b)
> +				continue;
> +
> +			/*
> +			 * Rev 2 of the Ref Manual states the
> +			 * VCO can range between 750MHz and
> +			 * 3GHz.  The VCO is assumed to be _m x
> +			 * the reference frequency of 24MHz divided
> +			 * by the prescaler, _p

Maybe better: "The VSO is assumed to be (M * f_ref) / P"

> +			 */
> +			tmp = (u64)_m * 24 * MHZ;
> +			do_div(tmp, _p);
> +			if (tmp < 750 * MHZ ||
> +			    tmp > 3000 * MHZ)
> +				continue;
> +
> +			tmp = (u64)_m * 24 * MHZ;
> +			do_div(tmp, _p * _s);

tmp already contains (_m * f_ref) / _p, so we sould be able to reuse
that value here and simply do do_div(tmp, _s) without recalculating tmp, no?

> +
> +			delta = abs(fout - tmp);
> +			if (delta < min_delta) {
> +				best_p = _p;
> +				best_s = _s;
> +				best_m = _m;
> +				min_delta = delta;
> +				best_freq = tmp;
> +			}
> +		}
> +	}
> +
> +	if (best_freq) {
> +		*p = best_p;
> +		*m = best_m;
> +		*s = best_s;
> +	}
> +
> +	return best_freq;
> +}
> +
>  static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
>  					  const struct phy_config *cfg)
>  {
> @@ -428,13 +516,13 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
>  	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
>  		writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
>  
> -	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
> +	/* set individual PLL registers PHY_REG1 ... PHY_REG7 */
>  	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
> -		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
> +		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(1) + i * 4);
>  
> -	/* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
> +	/* High nibble of PHY_REG3 and low nibble of PHY_REG21 both contain 'S' */
>  	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
> -	       cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
> +	       cfg->pll_div_regs[2] >> 4), phy->regs + PHY_REG(21));
>  
>  	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
>  
> @@ -462,29 +550,70 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
>  static long phy_clk_round_rate(struct clk_hw *hw,
>  			       unsigned long rate, unsigned long *parent_rate)
>  {
> +	u32 int_div_clk;
>  	int i;
> +	u16 m;
> +	u8 p, s;
> +
> +	/* If the clock is out of range return error instead of searching */
> +	if (rate > 297000000 || rate < 22250000)
> +		return -EINVAL;
>  
> +	/* Check the look-up table */
>  	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
>  		if (phy_pll_cfg[i].pixclk <= rate)
> -			return phy_pll_cfg[i].pixclk;
> +			break;
> +	/* If the rate is an exact match, return it now */
> +	if (rate == phy_pll_cfg[i].pixclk)
> +		return phy_pll_cfg[i].pixclk;
> +
> +	/*
> +	 * The math on the lookup table shows the PMS math yields a
> +	 * frequency 5 x pixclk.
> +	 * When we check the integer divider against the desired rate,
> +	 * multiply the rate x 5 and then divide the outcome by 5.
> +	 */
> +	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
>  
> -	return -EINVAL;
> +	/* If the rate is an exact match, return it now */
> +	if (int_div_clk == rate)
> +		return int_div_clk;
> +
> +	/* Fall back to the closest value in the LUT */
> +	return phy_pll_cfg[i].pixclk;
>  }
>  
>  static int phy_clk_set_rate(struct clk_hw *hw,
>  			    unsigned long rate, unsigned long parent_rate)
>  {
>  	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
> +	u32 int_div_clk;
>  	int i;
> -
> -	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> -		if (phy_pll_cfg[i].pixclk <= rate)
> -			break;
> -
> -	if (i < 0)
> -		return -EINVAL;
> -
> -	phy->cur_cfg = &phy_pll_cfg[i];
> +	u16 m;
> +	u8 p, s;
> +
> +	/* If the integer divider works, just use it */
> +	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
> +	if (int_div_clk == rate) {
> +		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using integer divider\n");
> +		calculated_phy_pll_cfg.pixclk = int_div_clk;
> +		calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
> +		calculated_phy_pll_cfg.pll_div_regs[1] = m;
> +		calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
> +		/* pll_div_regs 3-6 are fixed and pre-defined already */
> +		phy->cur_cfg  = &calculated_phy_pll_cfg;
> +	} else {
> +		/* Otherwise, search the LUT */
> +		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");> +		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> +			if (phy_pll_cfg[i].pixclk <= rate)
> +				break;
> +
> +		if (i < 0)
> +			return -EINVAL;
> +
> +		phy->cur_cfg = &phy_pll_cfg[i];
> +	}
>  
>  	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
>  }


From robh at kernel.org  Wed Sep  4 06:36:47 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 04 Sep 2024 08:36:47 -0500
Subject: [PATCH 00/19] Add initial support for QCS8300
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
Message-ID: <172545686260.2410635.12324465724634886770.robh@kernel.org>


On Wed, 04 Sep 2024 16:33:41 +0800, Jingyi Wang wrote:
> Add initial support for QCS8300 SoC and QCS8300 RIDE board.
> 
> This revision brings support for:
> - CPUs with cpu idle
> - interrupt-controller with PDC wakeup support
> - gcc
> - TLMM
> - interconnect
> - qup with uart
> - smmu
> - pmic
> - ufs
> - ipcc
> - sram
> - remoteprocs including ADSP,CDSP and GPDSP
> 
> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
> ---
> patch series organized as:
> - 1-2: remoteproc binding and driver
> - 3-5: ufs binding and driver
> - 6-7: rpmhpd binding and driver
> - 8-15: bindings for other components found on the SoC
> - 16-19: changes to support the device tree
> 
> dependencies:
> tlmm: https://lore.kernel.org/linux-arm-msm/20240819064933.1778204-1-quic_jingyw at quicinc.com/
> gcc: https://lore.kernel.org/all/20240820-qcs8300-gcc-v1-0-d81720517a82 at quicinc.com/
> interconnect: https://lore.kernel.org/linux-arm-msm/20240827151622.305-1-quic_rlaggysh at quicinc.com/
> 
> dtb check got following err:
> /local/mnt/workspace/jingyi/aim500/linux/arch/arm64/boot/dts/qcom/qcs8300-ride.dtb: interconnect at 1680000: Unevaluated properties are not allowed ('reg' was unexpected)
> which is cause by "reg" compatible missing in dt binding, will be fixed in interconnect patch series.
> 
> ---
> Jingyi Wang (11):
>       dt-bindings: remoteproc: qcom,sa8775p-pas: Document QCS8300 remoteproc
>       remoteproc: qcom: pas: Add QCS8300 remoteproc support
>       dt-bindings: qcom,pdc: document QCS8300 Power Domain Controller
>       dt-bindings: soc: qcom: add qcom,qcs8300-imem compatible
>       dt-bindings: mailbox: qcom-ipcc: Document QCS8300 IPCC
>       dt-bindings: mfd: qcom,tcsr: Add compatible for QCS8300
>       dt-bindings: nvmem: qfprom: Add compatible for QCS8300
>       dt-bindings: arm: qcom: document QCS8275/QCS8300 SoC and reference board
>       arm64: defconfig: enable clock controller, interconnect and pinctrl for QCS8300
>       arm64: dts: qcom: add initial support for QCS8300 DTSI
>       arm64: dts: qcom: add base QCS8300 RIDE dts
> 
> Kyle Deng (1):
>       dt-bindings: soc: qcom,aoss-qmp: Document the QCS8300 AOSS channel
> 
> Shazad Hussain (1):
>       dt-bindings: power: rpmpd: Add QCS8300 power domains
> 
> Tingguo Cheng (1):
>       pmdomain: qcom: rpmhpd: Add QCS8300 power domains
> 
> Xin Liu (3):
>       dt-bindings: phy: Add QMP UFS PHY comptible for QCS8300
>       dt-bindings: ufs: qcom: Document the QCS8300 UFS Controller
>       phy: qcom-qmp-ufs: Add support for QCS8300
> 
> Zhenhua Huang (2):
>       dt-bindings: arm-smmu: Add compatible for QCS8300 SoC
>       dt-bindings: firmware: qcom,scm: document SCM on QCS8300 SoCs
> 
>  Documentation/devicetree/bindings/arm/qcom.yaml    |    8 +
>  .../devicetree/bindings/firmware/qcom,scm.yaml     |    1 +
>  .../bindings/interrupt-controller/qcom,pdc.yaml    |    1 +
>  .../devicetree/bindings/iommu/arm,smmu.yaml        |    2 +
>  .../devicetree/bindings/mailbox/qcom-ipcc.yaml     |    1 +
>  .../devicetree/bindings/mfd/qcom,tcsr.yaml         |    1 +
>  .../devicetree/bindings/nvmem/qcom,qfprom.yaml     |    1 +
>  .../bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml    |    2 +
>  .../devicetree/bindings/power/qcom,rpmpd.yaml      |    1 +
>  .../bindings/remoteproc/qcom,sa8775p-pas.yaml      |    6 +
>  .../bindings/soc/qcom/qcom,aoss-qmp.yaml           |    1 +
>  .../devicetree/bindings/sram/qcom,imem.yaml        |    1 +
>  .../devicetree/bindings/ufs/qcom,ufs.yaml          |    2 +
>  arch/arm64/boot/dts/qcom/Makefile                  |    1 +
>  arch/arm64/boot/dts/qcom/qcs8300-ride.dts          |  246 ++++
>  arch/arm64/boot/dts/qcom/qcs8300.dtsi              | 1282 ++++++++++++++++++++
>  arch/arm64/configs/defconfig                       |    3 +
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            |    3 +
>  drivers/pmdomain/qcom/rpmhpd.c                     |   24 +
>  drivers/remoteproc/qcom_q6v5_pas.c                 |    3 +
>  include/dt-bindings/power/qcom-rpmpd.h             |   19 +
>  21 files changed, 1609 insertions(+)
> ---
> base-commit: eb8c5ca373cbb018a84eb4db25c863302c9b6314
> change-id: 20240829-qcs8300_initial_dtsi-1a386eb317d3
> 
> Best regards,
> --
> Jingyi Wang <quic_jingyw at quicinc.com>
> 
> 
> 


My bot found new DTB warnings on the .dts files added or changed in this
series.

Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.

If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:

  pip3 install dtschema --upgrade


New warnings running 'make CHECK_DTBS=y qcom/qcs8300-ride.dtb' for 20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007 at quicinc.com:

In file included from arch/arm64/boot/dts/qcom/qcs8300-ride.dts:11:
arch/arm64/boot/dts/qcom/qcs8300.dtsi:6:10: fatal error: dt-bindings/clock/qcom,qcs8300-gcc.h: No such file or directory
    6 | #include <dt-bindings/clock/qcom,qcs8300-gcc.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[3]: *** [scripts/Makefile.lib:434: arch/arm64/boot/dts/qcom/qcs8300-ride.dtb] Error 1
make[2]: *** [scripts/Makefile.build:490: arch/arm64/boot/dts/qcom] Error 2
make[2]: Target 'arch/arm64/boot/dts/qcom/qcs8300-ride.dtb' not remade because of errors.
make[1]: *** [/home/rob/proj/linux-dt-testing/Makefile:1390: qcom/qcs8300-ride.dtb] Error 2
make: *** [Makefile:224: __sub-make] Error 2
make: Target 'qcom/qcs8300-ride.dtb' not remade because of errors.







From frieder.schrempf at kontron.de  Wed Sep  4 06:40:33 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Wed, 4 Sep 2024 15:40:33 +0200
Subject: [PATCH V5 4/5] phy: freescale: fsl-samsung-hdmi: Use closest
 divider
In-Reply-To: <20240904023310.163371-5-aford173@gmail.com>
References: <20240904023310.163371-1-aford173@gmail.com>
 <20240904023310.163371-5-aford173@gmail.com>
Message-ID: <0a860fc7-14df-40c6-a92a-868568ae7a24@kontron.de>

On 04.09.24 4:32 AM, Adam Ford wrote:
> Currently, if the clock values cannot be set to the exact rate,
> the round_rate and set_rate functions use the closest value found in
> the look-up-table.  In preparation of removing values from the LUT
> that can be calculated evenly with the integer calculator, it's
> necessary to ensure to check both the look-up-table and the integer
> divider clock values to get the closest values to the requested
> value.  It does this by measuring the difference between the
> requested clock value and the closest value in both integer divider
> calucator and the fractional clock look-up-table.
> 
> Which ever has the smallest difference between them is returned as
> the cloesest rate.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Signed-off-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
> ---
> V5:  No Change
> V4:  New to series
> ---
>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 40 +++++++++++++++-----
>  1 file changed, 31 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> index 8f2c0082aa12..56b08e684179 100644
> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -550,7 +550,7 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
>  static long phy_clk_round_rate(struct clk_hw *hw,
>  			       unsigned long rate, unsigned long *parent_rate)
>  {
> -	u32 int_div_clk;
> +	u32 int_div_clk, delta_int, delta_frac;
>  	int i;
>  	u16 m;
>  	u8 p, s;
> @@ -563,6 +563,7 @@ static long phy_clk_round_rate(struct clk_hw *hw,
>  	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
>  		if (phy_pll_cfg[i].pixclk <= rate)
>  			break;
> +
>  	/* If the rate is an exact match, return it now */
>  	if (rate == phy_pll_cfg[i].pixclk)
>  		return phy_pll_cfg[i].pixclk;
> @@ -579,15 +580,21 @@ static long phy_clk_round_rate(struct clk_hw *hw,
>  	if (int_div_clk == rate)
>  		return int_div_clk;
>  
> -	/* Fall back to the closest value in the LUT */
> -	return phy_pll_cfg[i].pixclk;
> +	/* Calculate the differences and use the closest one */
> +	delta_frac = (rate - phy_pll_cfg[i].pixclk);
> +	delta_int = (rate - int_div_clk);
> +
> +	if (delta_int < delta_frac)
> +		return int_div_clk;
> +	else
> +		return phy_pll_cfg[i].pixclk;
>  }
>  
>  static int phy_clk_set_rate(struct clk_hw *hw,
>  			    unsigned long rate, unsigned long parent_rate)
>  {
>  	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
> -	u32 int_div_clk;
> +	u32 int_div_clk, delta_int, delta_frac;
>  	int i;
>  	u16 m;
>  	u8 p, s;
> @@ -602,19 +609,34 @@ static int phy_clk_set_rate(struct clk_hw *hw,
>  		calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
>  		/* pll_div_regs 3-6 are fixed and pre-defined already */
>  		phy->cur_cfg  = &calculated_phy_pll_cfg;

                             ^ unneeded whitespace (comment belongs to
patch 3/5)

> +		goto done;
>  	} else {
>  		/* Otherwise, search the LUT */
> -		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
> -		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> -			if (phy_pll_cfg[i].pixclk <= rate)
> +		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--) {
> +			if (phy_pll_cfg[i].pixclk == rate) {
> +				dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
> +				phy->cur_cfg = &phy_pll_cfg[i];
> +				goto done;
> +			}
> +
> +			if (phy_pll_cfg[i].pixclk < rate)
>  				break;
> +		}
>  
>  		if (i < 0)
>  			return -EINVAL;
> -
> -		phy->cur_cfg = &phy_pll_cfg[i];
>  	}
>  
> +	/* Calculate the differences for each clock against the requested value */
> +	delta_frac = (rate - phy_pll_cfg[i].pixclk);
> +	delta_int = (rate - int_div_clk);
> +
> +	/* Use the value closest to the desired */
> +	if (delta_int < delta_frac)
> +		phy->cur_cfg  = &calculated_phy_pll_cfg;

                             ^ unneeded whitespace

Are you sure that this is correct? The calculated_phy_pll_cfg is only
set above if there is an exact match for the integer divider. I don't
think it contains the data you expect here, or am I missing something?

> +	else
> +		phy->cur_cfg = &phy_pll_cfg[i];
> +done:
>  	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
>  }
>  


From frieder.schrempf at kontron.de  Wed Sep  4 06:44:27 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Wed, 4 Sep 2024 15:44:27 +0200
Subject: [PATCH V5 5/5] phy: freescale: fsl-samsung-hdmi: Remove
 unnecessary LUT entries
In-Reply-To: <20240904023310.163371-6-aford173@gmail.com>
References: <20240904023310.163371-1-aford173@gmail.com>
 <20240904023310.163371-6-aford173@gmail.com>
Message-ID: <727803d7-2b0a-449b-97bc-b18fe2378a38@kontron.de>

On 04.09.24 4:32 AM, Adam Ford wrote:
> The lookup table contains entries which use the integer divider
> instead of just the fractional divider.  Since the set and round

                                          ^ unneeded whitespace

> functions check both the integer divider values and the LUT values,
> it's no longer necessary to keep the integer divder values in the,

                                               ^ divider        ^ table?
> as they are able to by dynamically calcuated.

          ^ can be calculated dynamically.

> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>

With commit message fixed:

Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>


From aford173 at gmail.com  Wed Sep  4 06:52:52 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed, 4 Sep 2024 08:52:52 -0500
Subject: [PATCH V5 3/5] phy: freescale: fsl-samsung-hdmi: Support dynamic integer
In-Reply-To: <c882eed1-9f36-4382-89fe-f56dd457a45f@kontron.de>
References: <20240904023310.163371-1-aford173@gmail.com> <20240904023310.163371-4-aford173@gmail.com>
 <c882eed1-9f36-4382-89fe-f56dd457a45f@kontron.de>
Message-ID: <CAHCN7xL4WikbY+k+QdBS64-Kt2oHTQU1i_G44PGJDZZKkRaymw@mail.gmail.com>

On Wed, Sep 4, 2024 at 8:35?AM Frieder Schrempf
<frieder.schrempf at kontron.de> wrote:
>
> On 04.09.24 4:32 AM, Adam Ford wrote:
> > There is currently a look-up table for a variety of resolutions.
> > Since the phy has the ability to dynamically calculate the values
> > necessary to use the intger divider which should allow more
>
>                        ^ integer
>
> > resolutions without having to update the look-up-table.
> >
> > If the lookup table cannot find an exact match, fall back to the
> > dynamic calculator of the integer divider.
>
> Nitpick: You have thre different versions of how to spell "lookup table"
> in the paragraphs above. Maybe you can decide on one... ;)
>
> >
> > Previously, the value of P was hard-coded to 1, this required an
> > update to the phy_pll_cfg table to add in the extra value into the
> > table, so if the value of P is calculated to be something else
> > by the PMS calculator, the calculated_phy_pll_cfg structure
> > can be used instead without having to keep track of which method
> > was used.
> >
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
>
> The comments I have are only nitpicks and the patch seems to work fine
> for me. So feel free to add:
>
> Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
> Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
>
> > ---
> > V5:  No Change
> > V4:  No Change
> > V3:  Change size of pll_div_regs to include PHY_REG01 (P)
> >      Create calculated_phy_pll_cfg to containe the values
> >      Eliminate the PMS calculation from fsl_samsung_hdmi_phy_configure
> >      Make the LUT primary and fall back to integer calculator in
> >      phy_clk_round_rate.
> >      Check the range right away to ensure it's reaonsable rather than
> >      trying to find a clock only to learn it's outside the range.
> >      Overall added notes and comments where stuff may not be intuitive.
> >
> > V2:  Update phy_clk_round_rate and phy_clk_set_rate to both support
> >      the integer clock PMS calculator.
> > ---
> >  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 341 +++++++++++++------
> >  1 file changed, 235 insertions(+), 106 deletions(-)
> >
> > diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > index 4f6874226f9a..8f2c0082aa12 100644
> > --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > @@ -16,6 +16,8 @@
> >
> >  #define PHY_REG(reg)         (reg * 4)
> >
> > +#define REG01_PMS_P_MASK     GENMASK(3, 0)
> > +#define REG03_PMS_S_MASK     GENMASK(7, 4)
> >  #define REG12_CK_DIV_MASK    GENMASK(5, 4)
> >
> >  #define REG13_TG_CODE_LOW_MASK       GENMASK(7, 0)
> > @@ -38,281 +40,296 @@
> >  #define REG34_PLL_LOCK               BIT(6)
> >  #define REG34_PHY_CLK_READY  BIT(5)
> >
> > -#define PHY_PLL_DIV_REGS_NUM 6
> > +#ifndef MHZ
> > +#define MHZ  (1000UL * 1000UL)
> > +#endif
> > +
> > +#define PHY_PLL_DIV_REGS_NUM 7
> >
> >  struct phy_config {
> >       u32     pixclk;
> >       u8      pll_div_regs[PHY_PLL_DIV_REGS_NUM];
> >  };
> >
> > +/*
> > + * The calculated_phy_pll_cfg only handles integer divider for PMS only,
>
> Nitpick: Remove duplicate 'only'
>
> > + * meaning the last four entries will be fixed, but the first three will
> > + * be calculated by the PMS calculator
>
> Nitpick: Period at the end of the sentence


Good catch.  I ran these through checkpatch, but I need to tell myself
not do work on this stuff at night when I am tired.
Sorry about that.  My grammar isn't normally this bad.  :-)

adam
>
> > + */
> > +static struct phy_config calculated_phy_pll_cfg = {
> > +     .pixclk = 0,
> > +     .pll_div_regs = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
> > +};
> > +
> > +/* The lookup table contains values for which the fractional divder is used */
>
> Nitpick: It seems this comment would rather belong into patch 5/5.

I put it here because I wanted to distinguish between the table below
and the variable above which are both of the same structure type to
explain why we needed both.
>
> >  static const struct phy_config phy_pll_cfg[] = {
> >       {
> >               .pixclk = 22250000,
> > -             .pll_div_regs = { 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 23750000,
> > -             .pll_div_regs = { 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 24000000,
> > -             .pll_div_regs = { 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 24024000,
> > -             .pll_div_regs = { 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 25175000,
> > -             .pll_div_regs = { 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 25200000,
> > -             .pll_div_regs = { 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 26750000,
> > -             .pll_div_regs = { 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 27000000,
> > -             .pll_div_regs = { 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 27027000,
> > -             .pll_div_regs = { 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 29500000,
> > -             .pll_div_regs = { 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 30750000,
> > -             .pll_div_regs = { 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
> > +             .pll_div_regs = { 0xd1, 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
> >       }, {
> >               .pixclk = 30888000,
> > -             .pll_div_regs = { 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
> > +             .pll_div_regs = { 0xd1, 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
> >       }, {
> >               .pixclk = 33750000,
> > -             .pll_div_regs = { 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 35000000,
> > -             .pll_div_regs = { 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 36000000,
> > -             .pll_div_regs = { 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 36036000,
> > -             .pll_div_regs = { 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 40000000,
> > -             .pll_div_regs = { 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 43200000,
> > -             .pll_div_regs = { 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 43243200,
> > -             .pll_div_regs = { 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 44500000,
> > -             .pll_div_regs = { 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
> > +             .pll_div_regs = { 0xd1, 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
> >       }, {
> >               .pixclk = 47000000,
> > -             .pll_div_regs = { 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 47500000,
> > -             .pll_div_regs = { 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 50349650,
> > -             .pll_div_regs = { 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 50400000,
> > -             .pll_div_regs = { 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 53250000,
> > -             .pll_div_regs = { 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
> > +             .pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
> >       }, {
> >               .pixclk = 53500000,
> > -             .pll_div_regs = { 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 54000000,
> > -             .pll_div_regs = { 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 54054000,
> > -             .pll_div_regs = { 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 59000000,
> > -             .pll_div_regs = { 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 59340659,
> > -             .pll_div_regs = { 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
> > +             .pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
> >       }, {
> >               .pixclk = 59400000,
> > -             .pll_div_regs = { 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 61500000,
> > -             .pll_div_regs = { 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
> > +             .pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
> >       }, {
> >               .pixclk = 63500000,
> > -             .pll_div_regs = { 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 67500000,
> > -             .pll_div_regs = { 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 70000000,
> > -             .pll_div_regs = { 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 72000000,
> > -             .pll_div_regs = { 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 72072000,
> > -             .pll_div_regs = { 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 74176000,
> > -             .pll_div_regs = { 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
> > +             .pll_div_regs = { 0xd1, 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
> >       }, {
> >               .pixclk = 74250000,
> > -             .pll_div_regs = { 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
> > +             .pll_div_regs = { 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
> >       }, {
> >               .pixclk = 78500000,
> > -             .pll_div_regs = { 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 80000000,
> > -             .pll_div_regs = { 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 82000000,
> > -             .pll_div_regs = { 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
> > +             .pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
> >       }, {
> >               .pixclk = 82500000,
> > -             .pll_div_regs = { 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
> > +             .pll_div_regs = { 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
> >       }, {
> >               .pixclk = 89000000,
> > -             .pll_div_regs = { 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 90000000,
> > -             .pll_div_regs = { 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 94000000,
> > -             .pll_div_regs = { 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 95000000,
> > -             .pll_div_regs = { 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 98901099,
> > -             .pll_div_regs = { 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
> > +             .pll_div_regs = { 0xd1, 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
> >       }, {
> >               .pixclk = 99000000,
> > -             .pll_div_regs = { 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
> > +             .pll_div_regs = { 0xd1, 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
> >       }, {
> >               .pixclk = 100699300,
> > -             .pll_div_regs = { 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 100800000,
> > -             .pll_div_regs = { 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 102500000,
> > -             .pll_div_regs = { 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
> > +             .pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
> >       }, {
> >               .pixclk = 104750000,
> > -             .pll_div_regs = { 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
> > +             .pll_div_regs = { 0xd1, 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
> >       }, {
> >               .pixclk = 106500000,
> > -             .pll_div_regs = { 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
> > +             .pll_div_regs = { 0xd1, 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
> >       }, {
> >               .pixclk = 107000000,
> > -             .pll_div_regs = { 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 108000000,
> > -             .pll_div_regs = { 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 108108000,
> > -             .pll_div_regs = { 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 118000000,
> > -             .pll_div_regs = { 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 118800000,
> > -             .pll_div_regs = { 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 123000000,
> > -             .pll_div_regs = { 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
> > +             .pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
> >       }, {
> >               .pixclk = 127000000,
> > -             .pll_div_regs = { 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 135000000,
> > -             .pll_div_regs = { 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 135580000,
> > -             .pll_div_regs = { 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
> > +             .pll_div_regs = { 0xd1, 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
> >       }, {
> >               .pixclk = 137520000,
> > -             .pll_div_regs = { 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
> > +             .pll_div_regs = { 0xd1, 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
> >       }, {
> >               .pixclk = 138750000,
> > -             .pll_div_regs = { 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
> > +             .pll_div_regs = { 0xd1, 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
> >       }, {
> >               .pixclk = 140000000,
> > -             .pll_div_regs = { 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 144000000,
> > -             .pll_div_regs = { 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 148352000,
> > -             .pll_div_regs = { 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
> > +             .pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
> >       }, {
> >               .pixclk = 148500000,
> > -             .pll_div_regs = { 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
> > +             .pll_div_regs = { 0xd1, 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
> >       }, {
> >               .pixclk = 154000000,
> > -             .pll_div_regs = { 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
> >       }, {
> >               .pixclk = 157000000,
> > -             .pll_div_regs = { 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 160000000,
> > -             .pll_div_regs = { 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 162000000,
> > -             .pll_div_regs = { 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
> > +             .pll_div_regs = { 0xd1, 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
> >       }, {
> >               .pixclk = 164000000,
> > -             .pll_div_regs = { 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
> > +             .pll_div_regs = { 0xd1, 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
> >       }, {
> >               .pixclk = 165000000,
> > -             .pll_div_regs = { 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
> > +             .pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
> >       }, {
> >               .pixclk = 180000000,
> > -             .pll_div_regs = { 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 185625000,
> > -             .pll_div_regs = { 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 188000000,
> > -             .pll_div_regs = { 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 198000000,
> > -             .pll_div_regs = { 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
> > +             .pll_div_regs = { 0xd1, 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
> >       }, {
> >               .pixclk = 205000000,
> > -             .pll_div_regs = { 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
> > +             .pll_div_regs = { 0xd1, 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
> >       }, {
> >               .pixclk = 209500000,
> > -             .pll_div_regs = { 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
> > +             .pll_div_regs = { 0xd1, 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
> >       }, {
> >               .pixclk = 213000000,
> > -             .pll_div_regs = { 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
> > +             .pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
> >       }, {
> >               .pixclk = 216000000,
> > -             .pll_div_regs = { 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 216216000,
> > -             .pll_div_regs = { 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 237600000,
> > -             .pll_div_regs = { 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 254000000,
> > -             .pll_div_regs = { 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
> > +             .pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
> >       }, {
> >               .pixclk = 277500000,
> > -             .pll_div_regs = { 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
> > +             .pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
> >       }, {
> >               .pixclk = 288000000,
> > -             .pll_div_regs = { 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
> > +             .pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
> >       }, {
> >               .pixclk = 297000000,
> > -             .pll_div_regs = { 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
> > +             .pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
> >       },
> >  };
> >
> > @@ -322,7 +339,8 @@ struct reg_settings {
> >  };
> >
> >  static const struct reg_settings common_phy_cfg[] = {
> > -     { PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
> > +     { PHY_REG(0), 0x00 },
> > +     /* PHY_REG(1-7) pix clk specific */
> >       { PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
> >       { PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
> >       /* REG12 pixclk specific */
> > @@ -415,6 +433,76 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
> >              phy->regs + PHY_REG(14));
> >  }
> >
> > +static unsigned long fsl_samsung_hdmi_phy_find_pms(unsigned long fout, u8 *p, u16 *m, u8 *s)
> > +{
> > +     unsigned long best_freq = 0;
> > +     u32 min_delta = 0xffffffff;
> > +     u8 _p, best_p;
> > +     u16 _m, best_m;
> > +     u8 _s, best_s;
> > +
> > +     /* The ref manual states the values of 'P' range from 1 to 11 */
> > +     for (_p = 1; _p <= 11; ++_p) {
> > +             for (_s = 1; _s <= 16; ++_s) {
> > +                     u64 tmp;
> > +                     u32 delta;
> > +
> > +                     /* s must be one or even */
> > +                     if (_s > 1 && (_s & 0x01) == 1)
> > +                             _s++;
> > +
> > +                     /* _s cannot be 14 per the TRM */
> > +                     if (_s == 14)
> > +                             continue;
> > +
> > +                     /*
> > +                      * TODO: Ref Manual doesn't state the range of _m
> > +                      * so this should be further refined if possible.
> > +                      * This range was set based on the original values
> > +                      * in the look-up table
> > +                      */
>
> There is the strange note "Div by -Div by 255" in the RM. I think it's
> supposed to define the range, but is missing the number for the lower
> bound. The upper bound is probably 255!?
>
> But we might also leave it like it is here and extend it later after
> further testing.

I was confused by that too.  I am not sure how a negative division
would work in this context.

>
> > +                     tmp = (u64)fout * (_p * _s);
> > +                     do_div(tmp, 24 * MHZ);
> > +                     _m = tmp;
> > +                     if (_m < 0x30 || _m > 0x7b)
> > +                             continue;
> > +
> > +                     /*
> > +                      * Rev 2 of the Ref Manual states the
> > +                      * VCO can range between 750MHz and
> > +                      * 3GHz.  The VCO is assumed to be _m x
> > +                      * the reference frequency of 24MHz divided
> > +                      * by the prescaler, _p
>
> Maybe better: "The VSO is assumed to be (M * f_ref) / P"

I can reword this for better readability.

>
> > +                      */
> > +                     tmp = (u64)_m * 24 * MHZ;
> > +                     do_div(tmp, _p);
> > +                     if (tmp < 750 * MHZ ||
> > +                         tmp > 3000 * MHZ)
> > +                             continue;
> > +
> > +                     tmp = (u64)_m * 24 * MHZ;
> > +                     do_div(tmp, _p * _s);
>
> tmp already contains (_m * f_ref) / _p, so we sould be able to reuse
> that value here and simply do do_div(tmp, _s) without recalculating tmp, no?
>
> > +
> > +                     delta = abs(fout - tmp);
> > +                     if (delta < min_delta) {
> > +                             best_p = _p;
> > +                             best_s = _s;
> > +                             best_m = _m;
> > +                             min_delta = delta;
> > +                             best_freq = tmp;
> > +                     }
> > +             }
> > +     }
> > +
> > +     if (best_freq) {
> > +             *p = best_p;
> > +             *m = best_m;
> > +             *s = best_s;
> > +     }
> > +
> > +     return best_freq;
> > +}
> > +
> >  static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
> >                                         const struct phy_config *cfg)
> >  {
> > @@ -428,13 +516,13 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
> >       for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
> >               writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
> >
> > -     /* set individual PLL registers PHY_REG2 ... PHY_REG7 */
> > +     /* set individual PLL registers PHY_REG1 ... PHY_REG7 */
> >       for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
> > -             writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
> > +             writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(1) + i * 4);
> >
> > -     /* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
> > +     /* High nibble of PHY_REG3 and low nibble of PHY_REG21 both contain 'S' */
> >       writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
> > -            cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
> > +            cfg->pll_div_regs[2] >> 4), phy->regs + PHY_REG(21));
> >
> >       fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
> >
> > @@ -462,29 +550,70 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
> >  static long phy_clk_round_rate(struct clk_hw *hw,
> >                              unsigned long rate, unsigned long *parent_rate)
> >  {
> > +     u32 int_div_clk;
> >       int i;
> > +     u16 m;
> > +     u8 p, s;
> > +
> > +     /* If the clock is out of range return error instead of searching */
> > +     if (rate > 297000000 || rate < 22250000)
> > +             return -EINVAL;
> >
> > +     /* Check the look-up table */
> >       for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> >               if (phy_pll_cfg[i].pixclk <= rate)
> > -                     return phy_pll_cfg[i].pixclk;
> > +                     break;
> > +     /* If the rate is an exact match, return it now */
> > +     if (rate == phy_pll_cfg[i].pixclk)
> > +             return phy_pll_cfg[i].pixclk;
> > +
> > +     /*
> > +      * The math on the lookup table shows the PMS math yields a
> > +      * frequency 5 x pixclk.
> > +      * When we check the integer divider against the desired rate,
> > +      * multiply the rate x 5 and then divide the outcome by 5.
> > +      */
> > +     int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
> >
> > -     return -EINVAL;
> > +     /* If the rate is an exact match, return it now */
> > +     if (int_div_clk == rate)
> > +             return int_div_clk;
> > +
> > +     /* Fall back to the closest value in the LUT */
> > +     return phy_pll_cfg[i].pixclk;
> >  }
> >
> >  static int phy_clk_set_rate(struct clk_hw *hw,
> >                           unsigned long rate, unsigned long parent_rate)
> >  {
> >       struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
> > +     u32 int_div_clk;
> >       int i;
> > -
> > -     for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> > -             if (phy_pll_cfg[i].pixclk <= rate)
> > -                     break;
> > -
> > -     if (i < 0)
> > -             return -EINVAL;
> > -
> > -     phy->cur_cfg = &phy_pll_cfg[i];
> > +     u16 m;
> > +     u8 p, s;
> > +
> > +     /* If the integer divider works, just use it */
> > +     int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
> > +     if (int_div_clk == rate) {
> > +             dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using integer divider\n");
> > +             calculated_phy_pll_cfg.pixclk = int_div_clk;
> > +             calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
> > +             calculated_phy_pll_cfg.pll_div_regs[1] = m;
> > +             calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
> > +             /* pll_div_regs 3-6 are fixed and pre-defined already */
> > +             phy->cur_cfg  = &calculated_phy_pll_cfg;
> > +     } else {
> > +             /* Otherwise, search the LUT */
> > +             dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");> +               for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> > +                     if (phy_pll_cfg[i].pixclk <= rate)
> > +                             break;
> > +
> > +             if (i < 0)
> > +                     return -EINVAL;
> > +
> > +             phy->cur_cfg = &phy_pll_cfg[i];
> > +     }
> >
> >       return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
> >  }


From frieder.schrempf at kontron.de  Wed Sep  4 06:54:39 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Wed, 4 Sep 2024 15:54:39 +0200
Subject: [PATCH V5 4/5] phy: freescale: fsl-samsung-hdmi: Use closest
 divider
In-Reply-To: <0a860fc7-14df-40c6-a92a-868568ae7a24@kontron.de>
References: <20240904023310.163371-1-aford173@gmail.com>
 <20240904023310.163371-5-aford173@gmail.com>
 <0a860fc7-14df-40c6-a92a-868568ae7a24@kontron.de>
Message-ID: <92f51c96-9386-43e4-bd19-422dcd8462b9@kontron.de>

On 04.09.24 3:40 PM, Frieder Schrempf wrote:
> On 04.09.24 4:32 AM, Adam Ford wrote:
>> Currently, if the clock values cannot be set to the exact rate,
>> the round_rate and set_rate functions use the closest value found in
>> the look-up-table.  In preparation of removing values from the LUT
>> that can be calculated evenly with the integer calculator, it's
>> necessary to ensure to check both the look-up-table and the integer
>> divider clock values to get the closest values to the requested
>> value.  It does this by measuring the difference between the
>> requested clock value and the closest value in both integer divider
>> calucator and the fractional clock look-up-table.
>>
>> Which ever has the smallest difference between them is returned as
>> the cloesest rate.
>>
>> Signed-off-by: Adam Ford <aford173 at gmail.com>
>> Signed-off-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
>> ---
>> V5:  No Change
>> V4:  New to series
>> ---
>>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 40 +++++++++++++++-----
>>  1 file changed, 31 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
>> index 8f2c0082aa12..56b08e684179 100644
>> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
>> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
>> @@ -550,7 +550,7 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
>>  static long phy_clk_round_rate(struct clk_hw *hw,
>>  			       unsigned long rate, unsigned long *parent_rate)
>>  {
>> -	u32 int_div_clk;
>> +	u32 int_div_clk, delta_int, delta_frac;
>>  	int i;
>>  	u16 m;
>>  	u8 p, s;
>> @@ -563,6 +563,7 @@ static long phy_clk_round_rate(struct clk_hw *hw,
>>  	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
>>  		if (phy_pll_cfg[i].pixclk <= rate)
>>  			break;
>> +
>>  	/* If the rate is an exact match, return it now */
>>  	if (rate == phy_pll_cfg[i].pixclk)
>>  		return phy_pll_cfg[i].pixclk;
>> @@ -579,15 +580,21 @@ static long phy_clk_round_rate(struct clk_hw *hw,
>>  	if (int_div_clk == rate)
>>  		return int_div_clk;
>>  
>> -	/* Fall back to the closest value in the LUT */
>> -	return phy_pll_cfg[i].pixclk;
>> +	/* Calculate the differences and use the closest one */
>> +	delta_frac = (rate - phy_pll_cfg[i].pixclk);
>> +	delta_int = (rate - int_div_clk);
>> +
>> +	if (delta_int < delta_frac)
>> +		return int_div_clk;
>> +	else
>> +		return phy_pll_cfg[i].pixclk;

I would also prefer to use a helper for calculating the closest rate.
Something like:

static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate,
						 u32 int_div_clk,
						 u32 frac_div_clk)
{
	if ((rate - int_div_clk) < (rate - frac_div_clk))
		return int_div_clk;
	
	return frac_div_clk;
}

This can be used above:

return fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk,
phy_pll_cfg[i].pixclk);

And also below in phy_clk_set_rate():

if (fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk,
phy_pll_cfg[i].pixclk) == int_div_clk)
		phy->cur_cfg = &calculated_phy_pll_cfg;
	else
		phy->cur_cfg = &phy_pll_cfg[i];


>>  }
>>  
>>  static int phy_clk_set_rate(struct clk_hw *hw,
>>  			    unsigned long rate, unsigned long parent_rate)
>>  {
>>  	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
>> -	u32 int_div_clk;
>> +	u32 int_div_clk, delta_int, delta_frac;
>>  	int i;
>>  	u16 m;
>>  	u8 p, s;
>> @@ -602,19 +609,34 @@ static int phy_clk_set_rate(struct clk_hw *hw,
>>  		calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
>>  		/* pll_div_regs 3-6 are fixed and pre-defined already */
>>  		phy->cur_cfg  = &calculated_phy_pll_cfg;
> 
>                              ^ unneeded whitespace (comment belongs to
> patch 3/5)
> 
>> +		goto done;
>>  	} else {
>>  		/* Otherwise, search the LUT */
>> -		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
>> -		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
>> -			if (phy_pll_cfg[i].pixclk <= rate)
>> +		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--) {
>> +			if (phy_pll_cfg[i].pixclk == rate) {
>> +				dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
>> +				phy->cur_cfg = &phy_pll_cfg[i];
>> +				goto done;
>> +			}
>> +
>> +			if (phy_pll_cfg[i].pixclk < rate)
>>  				break;
>> +		}
>>  
>>  		if (i < 0)
>>  			return -EINVAL;
>> -
>> -		phy->cur_cfg = &phy_pll_cfg[i];
>>  	}
>>  
>> +	/* Calculate the differences for each clock against the requested value */
>> +	delta_frac = (rate - phy_pll_cfg[i].pixclk);
>> +	delta_int = (rate - int_div_clk);
>> +
>> +	/* Use the value closest to the desired */
>> +	if (delta_int < delta_frac)
>> +		phy->cur_cfg  = &calculated_phy_pll_cfg;
> 
>                              ^ unneeded whitespace
> 
> Are you sure that this is correct? The calculated_phy_pll_cfg is only
> set above if there is an exact match for the integer divider. I don't
> think it contains the data you expect here, or am I missing something?
> 
>> +	else
>> +		phy->cur_cfg = &phy_pll_cfg[i];
>> +done:
>>  	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
>>  }
>>  


From aford173 at gmail.com  Wed Sep  4 06:58:50 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed, 4 Sep 2024 08:58:50 -0500
Subject: [PATCH V5 5/5] phy: freescale: fsl-samsung-hdmi: Remove
 unnecessary LUT entries
In-Reply-To: <727803d7-2b0a-449b-97bc-b18fe2378a38@kontron.de>
References: <20240904023310.163371-1-aford173@gmail.com> <20240904023310.163371-6-aford173@gmail.com>
 <727803d7-2b0a-449b-97bc-b18fe2378a38@kontron.de>
Message-ID: <CAHCN7xL1rgnD_Amebnf+Mx4RrSkGM4+0LxbPSYqwVWT0VHAc0w@mail.gmail.com>

On Wed, Sep 4, 2024 at 8:44?AM Frieder Schrempf
<frieder.schrempf at kontron.de> wrote:
>
> On 04.09.24 4:32 AM, Adam Ford wrote:
> > The lookup table contains entries which use the integer divider
> > instead of just the fractional divider.  Since the set and round
>
>                                           ^ unneeded whitespace
>
> > functions check both the integer divider values and the LUT values,
> > it's no longer necessary to keep the integer divder values in the,
>
>                                                ^ divider        ^ table?
> > as they are able to by dynamically calcuated.
>
>           ^ can be calculated dynamically.
>

Wow, I must have been really tired when I wrote this.  I promise that
I wasn't drinking.  :-)

I will fix and proof-read my comments in the V6.  :-)


adam
> >
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
>
> With commit message fixed:
>
> Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
> Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>


From frieder.schrempf at kontron.de  Wed Sep  4 07:00:08 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Wed, 4 Sep 2024 16:00:08 +0200
Subject: [PATCH V5 3/5] phy: freescale: fsl-samsung-hdmi: Support dynamic
 integer
In-Reply-To: <CAHCN7xL4WikbY+k+QdBS64-Kt2oHTQU1i_G44PGJDZZKkRaymw@mail.gmail.com>
References: <20240904023310.163371-1-aford173@gmail.com>
 <20240904023310.163371-4-aford173@gmail.com>
 <c882eed1-9f36-4382-89fe-f56dd457a45f@kontron.de>
 <CAHCN7xL4WikbY+k+QdBS64-Kt2oHTQU1i_G44PGJDZZKkRaymw@mail.gmail.com>
Message-ID: <739a8732-532c-4ffc-b3ef-d01793c70d4b@kontron.de>

On 04.09.24 3:52 PM, Adam Ford wrote:
> On Wed, Sep 4, 2024 at 8:35?AM Frieder Schrempf
> <frieder.schrempf at kontron.de> wrote:
>>
>> On 04.09.24 4:32 AM, Adam Ford wrote:
>>> There is currently a look-up table for a variety of resolutions.
>>> Since the phy has the ability to dynamically calculate the values
>>> necessary to use the intger divider which should allow more
>>
>>                        ^ integer
>>
>>> resolutions without having to update the look-up-table.
>>>
>>> If the lookup table cannot find an exact match, fall back to the
>>> dynamic calculator of the integer divider.
>>
>> Nitpick: You have thre different versions of how to spell "lookup table"
>> in the paragraphs above. Maybe you can decide on one... ;)
>>
>>>
>>> Previously, the value of P was hard-coded to 1, this required an
>>> update to the phy_pll_cfg table to add in the extra value into the
>>> table, so if the value of P is calculated to be something else
>>> by the PMS calculator, the calculated_phy_pll_cfg structure
>>> can be used instead without having to keep track of which method
>>> was used.
>>>
>>> Signed-off-by: Adam Ford <aford173 at gmail.com>
>>
>> The comments I have are only nitpicks and the patch seems to work fine
>> for me. So feel free to add:
>>
>> Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
>> Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
>>
>>> ---
>>> V5:  No Change
>>> V4:  No Change
>>> V3:  Change size of pll_div_regs to include PHY_REG01 (P)
>>>      Create calculated_phy_pll_cfg to containe the values
>>>      Eliminate the PMS calculation from fsl_samsung_hdmi_phy_configure
>>>      Make the LUT primary and fall back to integer calculator in
>>>      phy_clk_round_rate.
>>>      Check the range right away to ensure it's reaonsable rather than
>>>      trying to find a clock only to learn it's outside the range.
>>>      Overall added notes and comments where stuff may not be intuitive.
>>>
>>> V2:  Update phy_clk_round_rate and phy_clk_set_rate to both support
>>>      the integer clock PMS calculator.
>>> ---
>>>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 341 +++++++++++++------
>>>  1 file changed, 235 insertions(+), 106 deletions(-)
>>>
>>> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
>>> index 4f6874226f9a..8f2c0082aa12 100644
>>> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
>>> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
>>> @@ -16,6 +16,8 @@
>>>
>>>  #define PHY_REG(reg)         (reg * 4)
>>>
>>> +#define REG01_PMS_P_MASK     GENMASK(3, 0)
>>> +#define REG03_PMS_S_MASK     GENMASK(7, 4)
>>>  #define REG12_CK_DIV_MASK    GENMASK(5, 4)
>>>
>>>  #define REG13_TG_CODE_LOW_MASK       GENMASK(7, 0)
>>> @@ -38,281 +40,296 @@
>>>  #define REG34_PLL_LOCK               BIT(6)
>>>  #define REG34_PHY_CLK_READY  BIT(5)
>>>
>>> -#define PHY_PLL_DIV_REGS_NUM 6
>>> +#ifndef MHZ
>>> +#define MHZ  (1000UL * 1000UL)
>>> +#endif
>>> +
>>> +#define PHY_PLL_DIV_REGS_NUM 7
>>>
>>>  struct phy_config {
>>>       u32     pixclk;
>>>       u8      pll_div_regs[PHY_PLL_DIV_REGS_NUM];
>>>  };
>>>
>>> +/*
>>> + * The calculated_phy_pll_cfg only handles integer divider for PMS only,
>>
>> Nitpick: Remove duplicate 'only'
>>
>>> + * meaning the last four entries will be fixed, but the first three will
>>> + * be calculated by the PMS calculator
>>
>> Nitpick: Period at the end of the sentence
> 
> 
> Good catch.  I ran these through checkpatch, but I need to tell myself
> not do work on this stuff at night when I am tired.
> Sorry about that.  My grammar isn't normally this bad.  :-)

I know. I already assumed that you were tired as the commit messages get
worse towards the end of the series ;)

> 
> adam
>>
>>> + */
>>> +static struct phy_config calculated_phy_pll_cfg = {
>>> +     .pixclk = 0,
>>> +     .pll_div_regs = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
>>> +};
>>> +
>>> +/* The lookup table contains values for which the fractional divder is used */
>>
>> Nitpick: It seems this comment would rather belong into patch 5/5.
> 
> I put it here because I wanted to distinguish between the table below
> and the variable above which are both of the same structure type to
> explain why we needed both.

Ok, fine.

>>
>>>  static const struct phy_config phy_pll_cfg[] = {
>>>       {
>>>               .pixclk = 22250000,
>>> -             .pll_div_regs = { 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 23750000,
>>> -             .pll_div_regs = { 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 24000000,
>>> -             .pll_div_regs = { 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 24024000,
>>> -             .pll_div_regs = { 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 25175000,
>>> -             .pll_div_regs = { 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 25200000,
>>> -             .pll_div_regs = { 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 26750000,
>>> -             .pll_div_regs = { 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 27000000,
>>> -             .pll_div_regs = { 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 27027000,
>>> -             .pll_div_regs = { 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 29500000,
>>> -             .pll_div_regs = { 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 30750000,
>>> -             .pll_div_regs = { 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
>>> +             .pll_div_regs = { 0xd1, 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
>>>       }, {
>>>               .pixclk = 30888000,
>>> -             .pll_div_regs = { 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
>>> +             .pll_div_regs = { 0xd1, 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
>>>       }, {
>>>               .pixclk = 33750000,
>>> -             .pll_div_regs = { 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 35000000,
>>> -             .pll_div_regs = { 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 36000000,
>>> -             .pll_div_regs = { 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 36036000,
>>> -             .pll_div_regs = { 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 40000000,
>>> -             .pll_div_regs = { 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 43200000,
>>> -             .pll_div_regs = { 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 43243200,
>>> -             .pll_div_regs = { 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 44500000,
>>> -             .pll_div_regs = { 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
>>> +             .pll_div_regs = { 0xd1, 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
>>>       }, {
>>>               .pixclk = 47000000,
>>> -             .pll_div_regs = { 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 47500000,
>>> -             .pll_div_regs = { 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 50349650,
>>> -             .pll_div_regs = { 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 50400000,
>>> -             .pll_div_regs = { 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 53250000,
>>> -             .pll_div_regs = { 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
>>> +             .pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
>>>       }, {
>>>               .pixclk = 53500000,
>>> -             .pll_div_regs = { 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 54000000,
>>> -             .pll_div_regs = { 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 54054000,
>>> -             .pll_div_regs = { 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 59000000,
>>> -             .pll_div_regs = { 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 59340659,
>>> -             .pll_div_regs = { 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
>>> +             .pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
>>>       }, {
>>>               .pixclk = 59400000,
>>> -             .pll_div_regs = { 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 61500000,
>>> -             .pll_div_regs = { 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
>>> +             .pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
>>>       }, {
>>>               .pixclk = 63500000,
>>> -             .pll_div_regs = { 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 67500000,
>>> -             .pll_div_regs = { 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 70000000,
>>> -             .pll_div_regs = { 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 72000000,
>>> -             .pll_div_regs = { 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 72072000,
>>> -             .pll_div_regs = { 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 74176000,
>>> -             .pll_div_regs = { 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
>>> +             .pll_div_regs = { 0xd1, 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
>>>       }, {
>>>               .pixclk = 74250000,
>>> -             .pll_div_regs = { 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
>>> +             .pll_div_regs = { 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
>>>       }, {
>>>               .pixclk = 78500000,
>>> -             .pll_div_regs = { 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 80000000,
>>> -             .pll_div_regs = { 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 82000000,
>>> -             .pll_div_regs = { 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
>>> +             .pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
>>>       }, {
>>>               .pixclk = 82500000,
>>> -             .pll_div_regs = { 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
>>> +             .pll_div_regs = { 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
>>>       }, {
>>>               .pixclk = 89000000,
>>> -             .pll_div_regs = { 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 90000000,
>>> -             .pll_div_regs = { 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 94000000,
>>> -             .pll_div_regs = { 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 95000000,
>>> -             .pll_div_regs = { 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 98901099,
>>> -             .pll_div_regs = { 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
>>> +             .pll_div_regs = { 0xd1, 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
>>>       }, {
>>>               .pixclk = 99000000,
>>> -             .pll_div_regs = { 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
>>> +             .pll_div_regs = { 0xd1, 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
>>>       }, {
>>>               .pixclk = 100699300,
>>> -             .pll_div_regs = { 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 100800000,
>>> -             .pll_div_regs = { 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 102500000,
>>> -             .pll_div_regs = { 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
>>> +             .pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
>>>       }, {
>>>               .pixclk = 104750000,
>>> -             .pll_div_regs = { 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
>>> +             .pll_div_regs = { 0xd1, 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
>>>       }, {
>>>               .pixclk = 106500000,
>>> -             .pll_div_regs = { 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
>>> +             .pll_div_regs = { 0xd1, 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
>>>       }, {
>>>               .pixclk = 107000000,
>>> -             .pll_div_regs = { 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 108000000,
>>> -             .pll_div_regs = { 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 108108000,
>>> -             .pll_div_regs = { 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 118000000,
>>> -             .pll_div_regs = { 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 118800000,
>>> -             .pll_div_regs = { 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 123000000,
>>> -             .pll_div_regs = { 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
>>> +             .pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
>>>       }, {
>>>               .pixclk = 127000000,
>>> -             .pll_div_regs = { 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 135000000,
>>> -             .pll_div_regs = { 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 135580000,
>>> -             .pll_div_regs = { 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
>>> +             .pll_div_regs = { 0xd1, 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
>>>       }, {
>>>               .pixclk = 137520000,
>>> -             .pll_div_regs = { 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
>>> +             .pll_div_regs = { 0xd1, 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
>>>       }, {
>>>               .pixclk = 138750000,
>>> -             .pll_div_regs = { 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
>>> +             .pll_div_regs = { 0xd1, 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
>>>       }, {
>>>               .pixclk = 140000000,
>>> -             .pll_div_regs = { 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 144000000,
>>> -             .pll_div_regs = { 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 148352000,
>>> -             .pll_div_regs = { 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
>>> +             .pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
>>>       }, {
>>>               .pixclk = 148500000,
>>> -             .pll_div_regs = { 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
>>> +             .pll_div_regs = { 0xd1, 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
>>>       }, {
>>>               .pixclk = 154000000,
>>> -             .pll_div_regs = { 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
>>>       }, {
>>>               .pixclk = 157000000,
>>> -             .pll_div_regs = { 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 160000000,
>>> -             .pll_div_regs = { 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 162000000,
>>> -             .pll_div_regs = { 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
>>> +             .pll_div_regs = { 0xd1, 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
>>>       }, {
>>>               .pixclk = 164000000,
>>> -             .pll_div_regs = { 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
>>> +             .pll_div_regs = { 0xd1, 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
>>>       }, {
>>>               .pixclk = 165000000,
>>> -             .pll_div_regs = { 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
>>> +             .pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
>>>       }, {
>>>               .pixclk = 180000000,
>>> -             .pll_div_regs = { 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 185625000,
>>> -             .pll_div_regs = { 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 188000000,
>>> -             .pll_div_regs = { 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 198000000,
>>> -             .pll_div_regs = { 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
>>> +             .pll_div_regs = { 0xd1, 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
>>>       }, {
>>>               .pixclk = 205000000,
>>> -             .pll_div_regs = { 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
>>> +             .pll_div_regs = { 0xd1, 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
>>>       }, {
>>>               .pixclk = 209500000,
>>> -             .pll_div_regs = { 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
>>> +             .pll_div_regs = { 0xd1, 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
>>>       }, {
>>>               .pixclk = 213000000,
>>> -             .pll_div_regs = { 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
>>> +             .pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
>>>       }, {
>>>               .pixclk = 216000000,
>>> -             .pll_div_regs = { 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 216216000,
>>> -             .pll_div_regs = { 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 237600000,
>>> -             .pll_div_regs = { 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 254000000,
>>> -             .pll_div_regs = { 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
>>> +             .pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
>>>       }, {
>>>               .pixclk = 277500000,
>>> -             .pll_div_regs = { 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
>>> +             .pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
>>>       }, {
>>>               .pixclk = 288000000,
>>> -             .pll_div_regs = { 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
>>> +             .pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
>>>       }, {
>>>               .pixclk = 297000000,
>>> -             .pll_div_regs = { 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
>>> +             .pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
>>>       },
>>>  };
>>>
>>> @@ -322,7 +339,8 @@ struct reg_settings {
>>>  };
>>>
>>>  static const struct reg_settings common_phy_cfg[] = {
>>> -     { PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
>>> +     { PHY_REG(0), 0x00 },
>>> +     /* PHY_REG(1-7) pix clk specific */
>>>       { PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
>>>       { PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
>>>       /* REG12 pixclk specific */
>>> @@ -415,6 +433,76 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
>>>              phy->regs + PHY_REG(14));
>>>  }
>>>
>>> +static unsigned long fsl_samsung_hdmi_phy_find_pms(unsigned long fout, u8 *p, u16 *m, u8 *s)
>>> +{
>>> +     unsigned long best_freq = 0;
>>> +     u32 min_delta = 0xffffffff;
>>> +     u8 _p, best_p;
>>> +     u16 _m, best_m;
>>> +     u8 _s, best_s;
>>> +
>>> +     /* The ref manual states the values of 'P' range from 1 to 11 */
>>> +     for (_p = 1; _p <= 11; ++_p) {
>>> +             for (_s = 1; _s <= 16; ++_s) {
>>> +                     u64 tmp;
>>> +                     u32 delta;
>>> +
>>> +                     /* s must be one or even */
>>> +                     if (_s > 1 && (_s & 0x01) == 1)
>>> +                             _s++;
>>> +
>>> +                     /* _s cannot be 14 per the TRM */
>>> +                     if (_s == 14)
>>> +                             continue;
>>> +
>>> +                     /*
>>> +                      * TODO: Ref Manual doesn't state the range of _m
>>> +                      * so this should be further refined if possible.
>>> +                      * This range was set based on the original values
>>> +                      * in the look-up table
>>> +                      */
>>
>> There is the strange note "Div by -Div by 255" in the RM. I think it's
>> supposed to define the range, but is missing the number for the lower
>> bound. The upper bound is probably 255!?
>>
>> But we might also leave it like it is here and extend it later after
>> further testing.
> 
> I was confused by that too.  I am not sure how a negative division
> would work in this context.

I assume that's a dash not a minus, meaning "from ... to 255", only that
it misses the first value.

> 
>>
>>> +                     tmp = (u64)fout * (_p * _s);
>>> +                     do_div(tmp, 24 * MHZ);
>>> +                     _m = tmp;
>>> +                     if (_m < 0x30 || _m > 0x7b)
>>> +                             continue;
>>> +
>>> +                     /*
>>> +                      * Rev 2 of the Ref Manual states the
>>> +                      * VCO can range between 750MHz and
>>> +                      * 3GHz.  The VCO is assumed to be _m x
>>> +                      * the reference frequency of 24MHz divided
>>> +                      * by the prescaler, _p
>>
>> Maybe better: "The VSO is assumed to be (M * f_ref) / P"
> 
> I can reword this for better readability.

Ok.

> 
>>
>>> +                      */
>>> +                     tmp = (u64)_m * 24 * MHZ;
>>> +                     do_div(tmp, _p);
>>> +                     if (tmp < 750 * MHZ ||
>>> +                         tmp > 3000 * MHZ)
>>> +                             continue;
>>> +
>>> +                     tmp = (u64)_m * 24 * MHZ;
>>> +                     do_div(tmp, _p * _s);
>>
>> tmp already contains (_m * f_ref) / _p, so we sould be able to reuse
>> that value here and simply do do_div(tmp, _s) without recalculating tmp, no?

Any reply to this comment? Can this be optimized?

>>
>>> +
>>> +                     delta = abs(fout - tmp);
>>> +                     if (delta < min_delta) {
>>> +                             best_p = _p;
>>> +                             best_s = _s;
>>> +                             best_m = _m;
>>> +                             min_delta = delta;
>>> +                             best_freq = tmp;
>>> +                     }
>>> +             }
>>> +     }
>>> +
>>> +     if (best_freq) {
>>> +             *p = best_p;
>>> +             *m = best_m;
>>> +             *s = best_s;
>>> +     }
>>> +
>>> +     return best_freq;
>>> +}
>>> +
>>>  static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
>>>                                         const struct phy_config *cfg)
>>>  {
>>> @@ -428,13 +516,13 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
>>>       for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
>>>               writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
>>>
>>> -     /* set individual PLL registers PHY_REG2 ... PHY_REG7 */
>>> +     /* set individual PLL registers PHY_REG1 ... PHY_REG7 */
>>>       for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
>>> -             writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
>>> +             writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(1) + i * 4);
>>>
>>> -     /* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
>>> +     /* High nibble of PHY_REG3 and low nibble of PHY_REG21 both contain 'S' */
>>>       writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
>>> -            cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
>>> +            cfg->pll_div_regs[2] >> 4), phy->regs + PHY_REG(21));
>>>
>>>       fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
>>>
>>> @@ -462,29 +550,70 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
>>>  static long phy_clk_round_rate(struct clk_hw *hw,
>>>                              unsigned long rate, unsigned long *parent_rate)
>>>  {
>>> +     u32 int_div_clk;
>>>       int i;
>>> +     u16 m;
>>> +     u8 p, s;
>>> +
>>> +     /* If the clock is out of range return error instead of searching */
>>> +     if (rate > 297000000 || rate < 22250000)
>>> +             return -EINVAL;
>>>
>>> +     /* Check the look-up table */
>>>       for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
>>>               if (phy_pll_cfg[i].pixclk <= rate)
>>> -                     return phy_pll_cfg[i].pixclk;
>>> +                     break;
>>> +     /* If the rate is an exact match, return it now */
>>> +     if (rate == phy_pll_cfg[i].pixclk)
>>> +             return phy_pll_cfg[i].pixclk;
>>> +
>>> +     /*
>>> +      * The math on the lookup table shows the PMS math yields a
>>> +      * frequency 5 x pixclk.
>>> +      * When we check the integer divider against the desired rate,
>>> +      * multiply the rate x 5 and then divide the outcome by 5.
>>> +      */
>>> +     int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
>>>
>>> -     return -EINVAL;
>>> +     /* If the rate is an exact match, return it now */
>>> +     if (int_div_clk == rate)
>>> +             return int_div_clk;
>>> +
>>> +     /* Fall back to the closest value in the LUT */
>>> +     return phy_pll_cfg[i].pixclk;
>>>  }
>>>
>>>  static int phy_clk_set_rate(struct clk_hw *hw,
>>>                           unsigned long rate, unsigned long parent_rate)
>>>  {
>>>       struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
>>> +     u32 int_div_clk;
>>>       int i;
>>> -
>>> -     for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
>>> -             if (phy_pll_cfg[i].pixclk <= rate)
>>> -                     break;
>>> -
>>> -     if (i < 0)
>>> -             return -EINVAL;
>>> -
>>> -     phy->cur_cfg = &phy_pll_cfg[i];
>>> +     u16 m;
>>> +     u8 p, s;
>>> +
>>> +     /* If the integer divider works, just use it */
>>> +     int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
>>> +     if (int_div_clk == rate) {
>>> +             dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using integer divider\n");
>>> +             calculated_phy_pll_cfg.pixclk = int_div_clk;
>>> +             calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
>>> +             calculated_phy_pll_cfg.pll_div_regs[1] = m;
>>> +             calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
>>> +             /* pll_div_regs 3-6 are fixed and pre-defined already */
>>> +             phy->cur_cfg  = &calculated_phy_pll_cfg;
>>> +     } else {
>>> +             /* Otherwise, search the LUT */
>>> +             dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");> +               for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
>>> +                     if (phy_pll_cfg[i].pixclk <= rate)
>>> +                             break;
>>> +
>>> +             if (i < 0)
>>> +                     return -EINVAL;
>>> +
>>> +             phy->cur_cfg = &phy_pll_cfg[i];
>>> +     }
>>>
>>>       return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
>>>  }


From aford173 at gmail.com  Wed Sep  4 07:05:25 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed, 4 Sep 2024 09:05:25 -0500
Subject: [PATCH V5 3/5] phy: freescale: fsl-samsung-hdmi: Support dynamic integer
In-Reply-To: <739a8732-532c-4ffc-b3ef-d01793c70d4b@kontron.de>
References: <20240904023310.163371-1-aford173@gmail.com> <20240904023310.163371-4-aford173@gmail.com>
 <c882eed1-9f36-4382-89fe-f56dd457a45f@kontron.de> <CAHCN7xL4WikbY+k+QdBS64-Kt2oHTQU1i_G44PGJDZZKkRaymw@mail.gmail.com>
 <739a8732-532c-4ffc-b3ef-d01793c70d4b@kontron.de>
Message-ID: <CAHCN7xK+JTE=Xdf3m+xyiJ5sjvN0QrZ-VpNnwrD_3XM+LPMHNg@mail.gmail.com>

On Wed, Sep 4, 2024 at 9:00?AM Frieder Schrempf
<frieder.schrempf at kontron.de> wrote:
>
> On 04.09.24 3:52 PM, Adam Ford wrote:
> > On Wed, Sep 4, 2024 at 8:35?AM Frieder Schrempf
> > <frieder.schrempf at kontron.de> wrote:
> >>
> >> On 04.09.24 4:32 AM, Adam Ford wrote:
> >>> There is currently a look-up table for a variety of resolutions.
> >>> Since the phy has the ability to dynamically calculate the values
> >>> necessary to use the intger divider which should allow more
> >>
> >>                        ^ integer
> >>
> >>> resolutions without having to update the look-up-table.
> >>>
> >>> If the lookup table cannot find an exact match, fall back to the
> >>> dynamic calculator of the integer divider.
> >>
> >> Nitpick: You have thre different versions of how to spell "lookup table"
> >> in the paragraphs above. Maybe you can decide on one... ;)
> >>
> >>>
> >>> Previously, the value of P was hard-coded to 1, this required an
> >>> update to the phy_pll_cfg table to add in the extra value into the
> >>> table, so if the value of P is calculated to be something else
> >>> by the PMS calculator, the calculated_phy_pll_cfg structure
> >>> can be used instead without having to keep track of which method
> >>> was used.
> >>>
> >>> Signed-off-by: Adam Ford <aford173 at gmail.com>
> >>
> >> The comments I have are only nitpicks and the patch seems to work fine
> >> for me. So feel free to add:
> >>
> >> Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
> >> Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
> >>
> >>> ---
> >>> V5:  No Change
> >>> V4:  No Change
> >>> V3:  Change size of pll_div_regs to include PHY_REG01 (P)
> >>>      Create calculated_phy_pll_cfg to containe the values
> >>>      Eliminate the PMS calculation from fsl_samsung_hdmi_phy_configure
> >>>      Make the LUT primary and fall back to integer calculator in
> >>>      phy_clk_round_rate.
> >>>      Check the range right away to ensure it's reaonsable rather than
> >>>      trying to find a clock only to learn it's outside the range.
> >>>      Overall added notes and comments where stuff may not be intuitive.
> >>>
> >>> V2:  Update phy_clk_round_rate and phy_clk_set_rate to both support
> >>>      the integer clock PMS calculator.
> >>> ---
> >>>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 341 +++++++++++++------
> >>>  1 file changed, 235 insertions(+), 106 deletions(-)
> >>>
> >>> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> >>> index 4f6874226f9a..8f2c0082aa12 100644
> >>> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> >>> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> >>> @@ -16,6 +16,8 @@
> >>>
> >>>  #define PHY_REG(reg)         (reg * 4)
> >>>
> >>> +#define REG01_PMS_P_MASK     GENMASK(3, 0)
> >>> +#define REG03_PMS_S_MASK     GENMASK(7, 4)
> >>>  #define REG12_CK_DIV_MASK    GENMASK(5, 4)
> >>>
> >>>  #define REG13_TG_CODE_LOW_MASK       GENMASK(7, 0)
> >>> @@ -38,281 +40,296 @@
> >>>  #define REG34_PLL_LOCK               BIT(6)
> >>>  #define REG34_PHY_CLK_READY  BIT(5)
> >>>
> >>> -#define PHY_PLL_DIV_REGS_NUM 6
> >>> +#ifndef MHZ
> >>> +#define MHZ  (1000UL * 1000UL)
> >>> +#endif
> >>> +
> >>> +#define PHY_PLL_DIV_REGS_NUM 7
> >>>
> >>>  struct phy_config {
> >>>       u32     pixclk;
> >>>       u8      pll_div_regs[PHY_PLL_DIV_REGS_NUM];
> >>>  };
> >>>
> >>> +/*
> >>> + * The calculated_phy_pll_cfg only handles integer divider for PMS only,
> >>
> >> Nitpick: Remove duplicate 'only'
> >>
> >>> + * meaning the last four entries will be fixed, but the first three will
> >>> + * be calculated by the PMS calculator
> >>
> >> Nitpick: Period at the end of the sentence
> >
> >
> > Good catch.  I ran these through checkpatch, but I need to tell myself
> > not do work on this stuff at night when I am tired.
> > Sorry about that.  My grammar isn't normally this bad.  :-)
>
> I know. I already assumed that you were tired as the commit messages get
> worse towards the end of the series ;)

I do this stuff as a hobby at night after my day-job is done, so my
brain is somewhat shot.  Most of the actual work that I do for this is
done on weekends in the morning when I am fresh, but I do the cleanup
at night.  I should probably reevaluate that decision.  :-)

Thanks for the understanding.  :-)


>
> >
> > adam
> >>
> >>> + */
> >>> +static struct phy_config calculated_phy_pll_cfg = {
> >>> +     .pixclk = 0,
> >>> +     .pll_div_regs = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
> >>> +};
> >>> +
> >>> +/* The lookup table contains values for which the fractional divder is used */
> >>
> >> Nitpick: It seems this comment would rather belong into patch 5/5.
> >
> > I put it here because I wanted to distinguish between the table below
> > and the variable above which are both of the same structure type to
> > explain why we needed both.
>
> Ok, fine.
>
> >>
> >>>  static const struct phy_config phy_pll_cfg[] = {
> >>>       {
> >>>               .pixclk = 22250000,
> >>> -             .pll_div_regs = { 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 23750000,
> >>> -             .pll_div_regs = { 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 24000000,
> >>> -             .pll_div_regs = { 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 24024000,
> >>> -             .pll_div_regs = { 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 25175000,
> >>> -             .pll_div_regs = { 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 25200000,
> >>> -             .pll_div_regs = { 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 26750000,
> >>> -             .pll_div_regs = { 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 27000000,
> >>> -             .pll_div_regs = { 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 27027000,
> >>> -             .pll_div_regs = { 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 29500000,
> >>> -             .pll_div_regs = { 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 30750000,
> >>> -             .pll_div_regs = { 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
> >>> +             .pll_div_regs = { 0xd1, 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
> >>>       }, {
> >>>               .pixclk = 30888000,
> >>> -             .pll_div_regs = { 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
> >>> +             .pll_div_regs = { 0xd1, 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
> >>>       }, {
> >>>               .pixclk = 33750000,
> >>> -             .pll_div_regs = { 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 35000000,
> >>> -             .pll_div_regs = { 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 36000000,
> >>> -             .pll_div_regs = { 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 36036000,
> >>> -             .pll_div_regs = { 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 40000000,
> >>> -             .pll_div_regs = { 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 43200000,
> >>> -             .pll_div_regs = { 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 43243200,
> >>> -             .pll_div_regs = { 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 44500000,
> >>> -             .pll_div_regs = { 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
> >>> +             .pll_div_regs = { 0xd1, 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
> >>>       }, {
> >>>               .pixclk = 47000000,
> >>> -             .pll_div_regs = { 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 47500000,
> >>> -             .pll_div_regs = { 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 50349650,
> >>> -             .pll_div_regs = { 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 50400000,
> >>> -             .pll_div_regs = { 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 53250000,
> >>> -             .pll_div_regs = { 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
> >>> +             .pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
> >>>       }, {
> >>>               .pixclk = 53500000,
> >>> -             .pll_div_regs = { 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 54000000,
> >>> -             .pll_div_regs = { 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 54054000,
> >>> -             .pll_div_regs = { 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 59000000,
> >>> -             .pll_div_regs = { 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 59340659,
> >>> -             .pll_div_regs = { 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
> >>> +             .pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
> >>>       }, {
> >>>               .pixclk = 59400000,
> >>> -             .pll_div_regs = { 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 61500000,
> >>> -             .pll_div_regs = { 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
> >>> +             .pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
> >>>       }, {
> >>>               .pixclk = 63500000,
> >>> -             .pll_div_regs = { 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 67500000,
> >>> -             .pll_div_regs = { 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 70000000,
> >>> -             .pll_div_regs = { 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 72000000,
> >>> -             .pll_div_regs = { 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 72072000,
> >>> -             .pll_div_regs = { 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 74176000,
> >>> -             .pll_div_regs = { 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
> >>> +             .pll_div_regs = { 0xd1, 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
> >>>       }, {
> >>>               .pixclk = 74250000,
> >>> -             .pll_div_regs = { 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
> >>> +             .pll_div_regs = { 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
> >>>       }, {
> >>>               .pixclk = 78500000,
> >>> -             .pll_div_regs = { 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 80000000,
> >>> -             .pll_div_regs = { 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 82000000,
> >>> -             .pll_div_regs = { 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
> >>> +             .pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
> >>>       }, {
> >>>               .pixclk = 82500000,
> >>> -             .pll_div_regs = { 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
> >>> +             .pll_div_regs = { 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
> >>>       }, {
> >>>               .pixclk = 89000000,
> >>> -             .pll_div_regs = { 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 90000000,
> >>> -             .pll_div_regs = { 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 94000000,
> >>> -             .pll_div_regs = { 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 95000000,
> >>> -             .pll_div_regs = { 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 98901099,
> >>> -             .pll_div_regs = { 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
> >>> +             .pll_div_regs = { 0xd1, 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
> >>>       }, {
> >>>               .pixclk = 99000000,
> >>> -             .pll_div_regs = { 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
> >>> +             .pll_div_regs = { 0xd1, 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
> >>>       }, {
> >>>               .pixclk = 100699300,
> >>> -             .pll_div_regs = { 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 100800000,
> >>> -             .pll_div_regs = { 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 102500000,
> >>> -             .pll_div_regs = { 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
> >>> +             .pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
> >>>       }, {
> >>>               .pixclk = 104750000,
> >>> -             .pll_div_regs = { 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
> >>> +             .pll_div_regs = { 0xd1, 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
> >>>       }, {
> >>>               .pixclk = 106500000,
> >>> -             .pll_div_regs = { 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
> >>> +             .pll_div_regs = { 0xd1, 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
> >>>       }, {
> >>>               .pixclk = 107000000,
> >>> -             .pll_div_regs = { 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 108000000,
> >>> -             .pll_div_regs = { 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 108108000,
> >>> -             .pll_div_regs = { 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 118000000,
> >>> -             .pll_div_regs = { 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 118800000,
> >>> -             .pll_div_regs = { 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 123000000,
> >>> -             .pll_div_regs = { 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
> >>> +             .pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
> >>>       }, {
> >>>               .pixclk = 127000000,
> >>> -             .pll_div_regs = { 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 135000000,
> >>> -             .pll_div_regs = { 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 135580000,
> >>> -             .pll_div_regs = { 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
> >>> +             .pll_div_regs = { 0xd1, 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
> >>>       }, {
> >>>               .pixclk = 137520000,
> >>> -             .pll_div_regs = { 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
> >>> +             .pll_div_regs = { 0xd1, 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
> >>>       }, {
> >>>               .pixclk = 138750000,
> >>> -             .pll_div_regs = { 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
> >>> +             .pll_div_regs = { 0xd1, 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
> >>>       }, {
> >>>               .pixclk = 140000000,
> >>> -             .pll_div_regs = { 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 144000000,
> >>> -             .pll_div_regs = { 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 148352000,
> >>> -             .pll_div_regs = { 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
> >>> +             .pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
> >>>       }, {
> >>>               .pixclk = 148500000,
> >>> -             .pll_div_regs = { 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
> >>> +             .pll_div_regs = { 0xd1, 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
> >>>       }, {
> >>>               .pixclk = 154000000,
> >>> -             .pll_div_regs = { 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
> >>>       }, {
> >>>               .pixclk = 157000000,
> >>> -             .pll_div_regs = { 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 160000000,
> >>> -             .pll_div_regs = { 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 162000000,
> >>> -             .pll_div_regs = { 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
> >>> +             .pll_div_regs = { 0xd1, 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
> >>>       }, {
> >>>               .pixclk = 164000000,
> >>> -             .pll_div_regs = { 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
> >>> +             .pll_div_regs = { 0xd1, 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
> >>>       }, {
> >>>               .pixclk = 165000000,
> >>> -             .pll_div_regs = { 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
> >>> +             .pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
> >>>       }, {
> >>>               .pixclk = 180000000,
> >>> -             .pll_div_regs = { 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 185625000,
> >>> -             .pll_div_regs = { 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 188000000,
> >>> -             .pll_div_regs = { 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 198000000,
> >>> -             .pll_div_regs = { 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
> >>> +             .pll_div_regs = { 0xd1, 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
> >>>       }, {
> >>>               .pixclk = 205000000,
> >>> -             .pll_div_regs = { 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
> >>> +             .pll_div_regs = { 0xd1, 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
> >>>       }, {
> >>>               .pixclk = 209500000,
> >>> -             .pll_div_regs = { 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
> >>> +             .pll_div_regs = { 0xd1, 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
> >>>       }, {
> >>>               .pixclk = 213000000,
> >>> -             .pll_div_regs = { 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
> >>> +             .pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
> >>>       }, {
> >>>               .pixclk = 216000000,
> >>> -             .pll_div_regs = { 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 216216000,
> >>> -             .pll_div_regs = { 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 237600000,
> >>> -             .pll_div_regs = { 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 254000000,
> >>> -             .pll_div_regs = { 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
> >>> +             .pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
> >>>       }, {
> >>>               .pixclk = 277500000,
> >>> -             .pll_div_regs = { 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
> >>> +             .pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
> >>>       }, {
> >>>               .pixclk = 288000000,
> >>> -             .pll_div_regs = { 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
> >>> +             .pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
> >>>       }, {
> >>>               .pixclk = 297000000,
> >>> -             .pll_div_regs = { 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
> >>> +             .pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
> >>>       },
> >>>  };
> >>>
> >>> @@ -322,7 +339,8 @@ struct reg_settings {
> >>>  };
> >>>
> >>>  static const struct reg_settings common_phy_cfg[] = {
> >>> -     { PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
> >>> +     { PHY_REG(0), 0x00 },
> >>> +     /* PHY_REG(1-7) pix clk specific */
> >>>       { PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
> >>>       { PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
> >>>       /* REG12 pixclk specific */
> >>> @@ -415,6 +433,76 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
> >>>              phy->regs + PHY_REG(14));
> >>>  }
> >>>
> >>> +static unsigned long fsl_samsung_hdmi_phy_find_pms(unsigned long fout, u8 *p, u16 *m, u8 *s)
> >>> +{
> >>> +     unsigned long best_freq = 0;
> >>> +     u32 min_delta = 0xffffffff;
> >>> +     u8 _p, best_p;
> >>> +     u16 _m, best_m;
> >>> +     u8 _s, best_s;
> >>> +
> >>> +     /* The ref manual states the values of 'P' range from 1 to 11 */
> >>> +     for (_p = 1; _p <= 11; ++_p) {
> >>> +             for (_s = 1; _s <= 16; ++_s) {
> >>> +                     u64 tmp;
> >>> +                     u32 delta;
> >>> +
> >>> +                     /* s must be one or even */
> >>> +                     if (_s > 1 && (_s & 0x01) == 1)
> >>> +                             _s++;
> >>> +
> >>> +                     /* _s cannot be 14 per the TRM */
> >>> +                     if (_s == 14)
> >>> +                             continue;
> >>> +
> >>> +                     /*
> >>> +                      * TODO: Ref Manual doesn't state the range of _m
> >>> +                      * so this should be further refined if possible.
> >>> +                      * This range was set based on the original values
> >>> +                      * in the look-up table
> >>> +                      */
> >>
> >> There is the strange note "Div by -Div by 255" in the RM. I think it's
> >> supposed to define the range, but is missing the number for the lower
> >> bound. The upper bound is probably 255!?
> >>
> >> But we might also leave it like it is here and extend it later after
> >> further testing.
> >
> > I was confused by that too.  I am not sure how a negative division
> > would work in this context.
>
> I assume that's a dash not a minus, meaning "from ... to 255", only that
> it misses the first value.
>
> >
> >>
> >>> +                     tmp = (u64)fout * (_p * _s);
> >>> +                     do_div(tmp, 24 * MHZ);
> >>> +                     _m = tmp;
> >>> +                     if (_m < 0x30 || _m > 0x7b)
> >>> +                             continue;
> >>> +
> >>> +                     /*
> >>> +                      * Rev 2 of the Ref Manual states the
> >>> +                      * VCO can range between 750MHz and
> >>> +                      * 3GHz.  The VCO is assumed to be _m x
> >>> +                      * the reference frequency of 24MHz divided
> >>> +                      * by the prescaler, _p
> >>
> >> Maybe better: "The VSO is assumed to be (M * f_ref) / P"
> >
> > I can reword this for better readability.
>
> Ok.
>
> >
> >>
> >>> +                      */
> >>> +                     tmp = (u64)_m * 24 * MHZ;
> >>> +                     do_div(tmp, _p);
> >>> +                     if (tmp < 750 * MHZ ||
> >>> +                         tmp > 3000 * MHZ)
> >>> +                             continue;
> >>> +
> >>> +                     tmp = (u64)_m * 24 * MHZ;
> >>> +                     do_div(tmp, _p * _s);
> >>
> >> tmp already contains (_m * f_ref) / _p, so we sould be able to reuse
> >> that value here and simply do do_div(tmp, _s) without recalculating tmp, no?
>
> Any reply to this comment? Can this be optimized?

I was going to investigate it before agreeing to do it. On the
surface, it makes sense.

adam
>
> >>
> >>> +
> >>> +                     delta = abs(fout - tmp);
> >>> +                     if (delta < min_delta) {
> >>> +                             best_p = _p;
> >>> +                             best_s = _s;
> >>> +                             best_m = _m;
> >>> +                             min_delta = delta;
> >>> +                             best_freq = tmp;
> >>> +                     }
> >>> +             }
> >>> +     }
> >>> +
> >>> +     if (best_freq) {
> >>> +             *p = best_p;
> >>> +             *m = best_m;
> >>> +             *s = best_s;
> >>> +     }
> >>> +
> >>> +     return best_freq;
> >>> +}
> >>> +
> >>>  static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
> >>>                                         const struct phy_config *cfg)
> >>>  {
> >>> @@ -428,13 +516,13 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
> >>>       for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
> >>>               writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
> >>>
> >>> -     /* set individual PLL registers PHY_REG2 ... PHY_REG7 */
> >>> +     /* set individual PLL registers PHY_REG1 ... PHY_REG7 */
> >>>       for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
> >>> -             writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
> >>> +             writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(1) + i * 4);
> >>>
> >>> -     /* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
> >>> +     /* High nibble of PHY_REG3 and low nibble of PHY_REG21 both contain 'S' */
> >>>       writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
> >>> -            cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
> >>> +            cfg->pll_div_regs[2] >> 4), phy->regs + PHY_REG(21));
> >>>
> >>>       fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
> >>>
> >>> @@ -462,29 +550,70 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
> >>>  static long phy_clk_round_rate(struct clk_hw *hw,
> >>>                              unsigned long rate, unsigned long *parent_rate)
> >>>  {
> >>> +     u32 int_div_clk;
> >>>       int i;
> >>> +     u16 m;
> >>> +     u8 p, s;
> >>> +
> >>> +     /* If the clock is out of range return error instead of searching */
> >>> +     if (rate > 297000000 || rate < 22250000)
> >>> +             return -EINVAL;
> >>>
> >>> +     /* Check the look-up table */
> >>>       for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> >>>               if (phy_pll_cfg[i].pixclk <= rate)
> >>> -                     return phy_pll_cfg[i].pixclk;
> >>> +                     break;
> >>> +     /* If the rate is an exact match, return it now */
> >>> +     if (rate == phy_pll_cfg[i].pixclk)
> >>> +             return phy_pll_cfg[i].pixclk;
> >>> +
> >>> +     /*
> >>> +      * The math on the lookup table shows the PMS math yields a
> >>> +      * frequency 5 x pixclk.
> >>> +      * When we check the integer divider against the desired rate,
> >>> +      * multiply the rate x 5 and then divide the outcome by 5.
> >>> +      */
> >>> +     int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
> >>>
> >>> -     return -EINVAL;
> >>> +     /* If the rate is an exact match, return it now */
> >>> +     if (int_div_clk == rate)
> >>> +             return int_div_clk;
> >>> +
> >>> +     /* Fall back to the closest value in the LUT */
> >>> +     return phy_pll_cfg[i].pixclk;
> >>>  }
> >>>
> >>>  static int phy_clk_set_rate(struct clk_hw *hw,
> >>>                           unsigned long rate, unsigned long parent_rate)
> >>>  {
> >>>       struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
> >>> +     u32 int_div_clk;
> >>>       int i;
> >>> -
> >>> -     for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> >>> -             if (phy_pll_cfg[i].pixclk <= rate)
> >>> -                     break;
> >>> -
> >>> -     if (i < 0)
> >>> -             return -EINVAL;
> >>> -
> >>> -     phy->cur_cfg = &phy_pll_cfg[i];
> >>> +     u16 m;
> >>> +     u8 p, s;
> >>> +
> >>> +     /* If the integer divider works, just use it */
> >>> +     int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
> >>> +     if (int_div_clk == rate) {
> >>> +             dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using integer divider\n");
> >>> +             calculated_phy_pll_cfg.pixclk = int_div_clk;
> >>> +             calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
> >>> +             calculated_phy_pll_cfg.pll_div_regs[1] = m;
> >>> +             calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
> >>> +             /* pll_div_regs 3-6 are fixed and pre-defined already */
> >>> +             phy->cur_cfg  = &calculated_phy_pll_cfg;
> >>> +     } else {
> >>> +             /* Otherwise, search the LUT */
> >>> +             dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");> +               for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> >>> +                     if (phy_pll_cfg[i].pixclk <= rate)
> >>> +                             break;
> >>> +
> >>> +             if (i < 0)
> >>> +                     return -EINVAL;
> >>> +
> >>> +             phy->cur_cfg = &phy_pll_cfg[i];
> >>> +     }
> >>>
> >>>       return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
> >>>  }


From frieder.schrempf at kontron.de  Wed Sep  4 07:09:39 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Wed, 4 Sep 2024 16:09:39 +0200
Subject: [PATCH V5 3/5] phy: freescale: fsl-samsung-hdmi: Support dynamic
 integer
In-Reply-To: <CAHCN7xK+JTE=Xdf3m+xyiJ5sjvN0QrZ-VpNnwrD_3XM+LPMHNg@mail.gmail.com>
References: <20240904023310.163371-1-aford173@gmail.com>
 <20240904023310.163371-4-aford173@gmail.com>
 <c882eed1-9f36-4382-89fe-f56dd457a45f@kontron.de>
 <CAHCN7xL4WikbY+k+QdBS64-Kt2oHTQU1i_G44PGJDZZKkRaymw@mail.gmail.com>
 <739a8732-532c-4ffc-b3ef-d01793c70d4b@kontron.de>
 <CAHCN7xK+JTE=Xdf3m+xyiJ5sjvN0QrZ-VpNnwrD_3XM+LPMHNg@mail.gmail.com>
Message-ID: <a40d8846-6a6b-4da0-b7d0-dbea1fa76c63@kontron.de>

On 04.09.24 4:05 PM, Adam Ford wrote:
> On Wed, Sep 4, 2024 at 9:00?AM Frieder Schrempf
> <frieder.schrempf at kontron.de> wrote:
>>
>> On 04.09.24 3:52 PM, Adam Ford wrote:
>>> On Wed, Sep 4, 2024 at 8:35?AM Frieder Schrempf
>>> <frieder.schrempf at kontron.de> wrote:
>>>>
>>>> On 04.09.24 4:32 AM, Adam Ford wrote:
>>>>> There is currently a look-up table for a variety of resolutions.
>>>>> Since the phy has the ability to dynamically calculate the values
>>>>> necessary to use the intger divider which should allow more
>>>>
>>>>                        ^ integer
>>>>
>>>>> resolutions without having to update the look-up-table.
>>>>>
>>>>> If the lookup table cannot find an exact match, fall back to the
>>>>> dynamic calculator of the integer divider.
>>>>
>>>> Nitpick: You have thre different versions of how to spell "lookup table"
>>>> in the paragraphs above. Maybe you can decide on one... ;)
>>>>
>>>>>
>>>>> Previously, the value of P was hard-coded to 1, this required an
>>>>> update to the phy_pll_cfg table to add in the extra value into the
>>>>> table, so if the value of P is calculated to be something else
>>>>> by the PMS calculator, the calculated_phy_pll_cfg structure
>>>>> can be used instead without having to keep track of which method
>>>>> was used.
>>>>>
>>>>> Signed-off-by: Adam Ford <aford173 at gmail.com>
>>>>
>>>> The comments I have are only nitpicks and the patch seems to work fine
>>>> for me. So feel free to add:
>>>>
>>>> Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
>>>> Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
>>>>
>>>>> ---
>>>>> V5:  No Change
>>>>> V4:  No Change
>>>>> V3:  Change size of pll_div_regs to include PHY_REG01 (P)
>>>>>      Create calculated_phy_pll_cfg to containe the values
>>>>>      Eliminate the PMS calculation from fsl_samsung_hdmi_phy_configure
>>>>>      Make the LUT primary and fall back to integer calculator in
>>>>>      phy_clk_round_rate.
>>>>>      Check the range right away to ensure it's reaonsable rather than
>>>>>      trying to find a clock only to learn it's outside the range.
>>>>>      Overall added notes and comments where stuff may not be intuitive.
>>>>>
>>>>> V2:  Update phy_clk_round_rate and phy_clk_set_rate to both support
>>>>>      the integer clock PMS calculator.
>>>>> ---
>>>>>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 341 +++++++++++++------
>>>>>  1 file changed, 235 insertions(+), 106 deletions(-)
>>>>>
>>>>> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
>>>>> index 4f6874226f9a..8f2c0082aa12 100644
>>>>> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
>>>>> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
>>>>> @@ -16,6 +16,8 @@
>>>>>
>>>>>  #define PHY_REG(reg)         (reg * 4)
>>>>>
>>>>> +#define REG01_PMS_P_MASK     GENMASK(3, 0)
>>>>> +#define REG03_PMS_S_MASK     GENMASK(7, 4)
>>>>>  #define REG12_CK_DIV_MASK    GENMASK(5, 4)
>>>>>
>>>>>  #define REG13_TG_CODE_LOW_MASK       GENMASK(7, 0)
>>>>> @@ -38,281 +40,296 @@
>>>>>  #define REG34_PLL_LOCK               BIT(6)
>>>>>  #define REG34_PHY_CLK_READY  BIT(5)
>>>>>
>>>>> -#define PHY_PLL_DIV_REGS_NUM 6
>>>>> +#ifndef MHZ
>>>>> +#define MHZ  (1000UL * 1000UL)
>>>>> +#endif
>>>>> +
>>>>> +#define PHY_PLL_DIV_REGS_NUM 7
>>>>>
>>>>>  struct phy_config {
>>>>>       u32     pixclk;
>>>>>       u8      pll_div_regs[PHY_PLL_DIV_REGS_NUM];
>>>>>  };
>>>>>
>>>>> +/*
>>>>> + * The calculated_phy_pll_cfg only handles integer divider for PMS only,
>>>>
>>>> Nitpick: Remove duplicate 'only'
>>>>
>>>>> + * meaning the last four entries will be fixed, but the first three will
>>>>> + * be calculated by the PMS calculator
>>>>
>>>> Nitpick: Period at the end of the sentence
>>>
>>>
>>> Good catch.  I ran these through checkpatch, but I need to tell myself
>>> not do work on this stuff at night when I am tired.
>>> Sorry about that.  My grammar isn't normally this bad.  :-)
>>
>> I know. I already assumed that you were tired as the commit messages get
>> worse towards the end of the series ;)
> 
> I do this stuff as a hobby at night after my day-job is done, so my
> brain is somewhat shot.  Most of the actual work that I do for this is
> done on weekends in the morning when I am fresh, but I do the cleanup
> at night.  I should probably reevaluate that decision.  :-)
> 
> Thanks for the understanding.  :-)

No worries. You are doing great work. You have my full understanding for
any of such flaws. :)

[...]
>>>>> +                      */
>>>>> +                     tmp = (u64)_m * 24 * MHZ;
>>>>> +                     do_div(tmp, _p);
>>>>> +                     if (tmp < 750 * MHZ ||
>>>>> +                         tmp > 3000 * MHZ)
>>>>> +                             continue;
>>>>> +
>>>>> +                     tmp = (u64)_m * 24 * MHZ;
>>>>> +                     do_div(tmp, _p * _s);
>>>>
>>>> tmp already contains (_m * f_ref) / _p, so we sould be able to reuse
>>>> that value here and simply do do_div(tmp, _s) without recalculating tmp, no?
>>
>> Any reply to this comment? Can this be optimized?
> 
> I was going to investigate it before agreeing to do it. On the
> surface, it makes sense.

Great, I just thought you may have missed it. Thanks!

[...]


From aford173 at gmail.com  Wed Sep  4 07:14:08 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed, 4 Sep 2024 09:14:08 -0500
Subject: [PATCH V5 4/5] phy: freescale: fsl-samsung-hdmi: Use closest divider
In-Reply-To: <92f51c96-9386-43e4-bd19-422dcd8462b9@kontron.de>
References: <20240904023310.163371-1-aford173@gmail.com> <20240904023310.163371-5-aford173@gmail.com>
 <0a860fc7-14df-40c6-a92a-868568ae7a24@kontron.de> <92f51c96-9386-43e4-bd19-422dcd8462b9@kontron.de>
Message-ID: <CAHCN7xJn4K5VDpnvH2oqEuiLo08p4gvsQCrobDVOvh4JHspazg@mail.gmail.com>

On Wed, Sep 4, 2024 at 8:54?AM Frieder Schrempf
<frieder.schrempf at kontron.de> wrote:
>
> On 04.09.24 3:40 PM, Frieder Schrempf wrote:
> > On 04.09.24 4:32 AM, Adam Ford wrote:
> >> Currently, if the clock values cannot be set to the exact rate,
> >> the round_rate and set_rate functions use the closest value found in
> >> the look-up-table.  In preparation of removing values from the LUT
> >> that can be calculated evenly with the integer calculator, it's
> >> necessary to ensure to check both the look-up-table and the integer
> >> divider clock values to get the closest values to the requested
> >> value.  It does this by measuring the difference between the
> >> requested clock value and the closest value in both integer divider
> >> calucator and the fractional clock look-up-table.
> >>
> >> Which ever has the smallest difference between them is returned as
> >> the cloesest rate.
> >>
> >> Signed-off-by: Adam Ford <aford173 at gmail.com>
> >> Signed-off-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
> >> ---
> >> V5:  No Change
> >> V4:  New to series
> >> ---
> >>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 40 +++++++++++++++-----
> >>  1 file changed, 31 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> >> index 8f2c0082aa12..56b08e684179 100644
> >> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> >> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> >> @@ -550,7 +550,7 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
> >>  static long phy_clk_round_rate(struct clk_hw *hw,
> >>                             unsigned long rate, unsigned long *parent_rate)
> >>  {
> >> -    u32 int_div_clk;
> >> +    u32 int_div_clk, delta_int, delta_frac;
> >>      int i;
> >>      u16 m;
> >>      u8 p, s;
> >> @@ -563,6 +563,7 @@ static long phy_clk_round_rate(struct clk_hw *hw,
> >>      for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> >>              if (phy_pll_cfg[i].pixclk <= rate)
> >>                      break;
> >> +
> >>      /* If the rate is an exact match, return it now */
> >>      if (rate == phy_pll_cfg[i].pixclk)
> >>              return phy_pll_cfg[i].pixclk;
> >> @@ -579,15 +580,21 @@ static long phy_clk_round_rate(struct clk_hw *hw,
> >>      if (int_div_clk == rate)
> >>              return int_div_clk;
> >>
> >> -    /* Fall back to the closest value in the LUT */
> >> -    return phy_pll_cfg[i].pixclk;
> >> +    /* Calculate the differences and use the closest one */
> >> +    delta_frac = (rate - phy_pll_cfg[i].pixclk);
> >> +    delta_int = (rate - int_div_clk);
> >> +
> >> +    if (delta_int < delta_frac)
> >> +            return int_div_clk;
> >> +    else
> >> +            return phy_pll_cfg[i].pixclk;
>
> I would also prefer to use a helper for calculating the closest rate.
> Something like:
>
> static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate,
>                                                  u32 int_div_clk,
>                                                  u32 frac_div_clk)
> {
>         if ((rate - int_div_clk) < (rate - frac_div_clk))
>                 return int_div_clk;
>
>         return frac_div_clk;
> }

I like this idea.  As Dominique noted, the int_div_clk might be
greater than rate, so I'll add abs() here when I simplify this.
>
> This can be used above:
>
> return fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk,
> phy_pll_cfg[i].pixclk);
>
> And also below in phy_clk_set_rate():
>
> if (fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk,
> phy_pll_cfg[i].pixclk) == int_div_clk)
>                 phy->cur_cfg = &calculated_phy_pll_cfg;
>         else
>                 phy->cur_cfg = &phy_pll_cfg[i];
>

I like this too.

adam
>
> >>  }
> >>
> >>  static int phy_clk_set_rate(struct clk_hw *hw,
> >>                          unsigned long rate, unsigned long parent_rate)
> >>  {
> >>      struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
> >> -    u32 int_div_clk;
> >> +    u32 int_div_clk, delta_int, delta_frac;
> >>      int i;
> >>      u16 m;
> >>      u8 p, s;
> >> @@ -602,19 +609,34 @@ static int phy_clk_set_rate(struct clk_hw *hw,
> >>              calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
> >>              /* pll_div_regs 3-6 are fixed and pre-defined already */
> >>              phy->cur_cfg  = &calculated_phy_pll_cfg;
> >
> >                              ^ unneeded whitespace (comment belongs to
> > patch 3/5)
> >
> >> +            goto done;
> >>      } else {
> >>              /* Otherwise, search the LUT */
> >> -            dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
> >> -            for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> >> -                    if (phy_pll_cfg[i].pixclk <= rate)
> >> +            for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--) {
> >> +                    if (phy_pll_cfg[i].pixclk == rate) {
> >> +                            dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
> >> +                            phy->cur_cfg = &phy_pll_cfg[i];
> >> +                            goto done;
> >> +                    }
> >> +
> >> +                    if (phy_pll_cfg[i].pixclk < rate)
> >>                              break;
> >> +            }
> >>
> >>              if (i < 0)
> >>                      return -EINVAL;
> >> -
> >> -            phy->cur_cfg = &phy_pll_cfg[i];
> >>      }
> >>
> >> +    /* Calculate the differences for each clock against the requested value */
> >> +    delta_frac = (rate - phy_pll_cfg[i].pixclk);
> >> +    delta_int = (rate - int_div_clk);
> >> +
> >> +    /* Use the value closest to the desired */
> >> +    if (delta_int < delta_frac)
> >> +            phy->cur_cfg  = &calculated_phy_pll_cfg;
> >
> >                              ^ unneeded whitespace
> >
> > Are you sure that this is correct? The calculated_phy_pll_cfg is only
> > set above if there is an exact match for the integer divider. I don't
> > think it contains the data you expect here, or am I missing something?
> >
> >> +    else
> >> +            phy->cur_cfg = &phy_pll_cfg[i];
> >> +done:
> >>      return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
> >>  }
> >>


From quic_srichara at quicinc.com  Wed Sep  4 10:20:17 2024
From: quic_srichara at quicinc.com (Sricharan Ramabadhran)
Date: Wed, 4 Sep 2024 22:50:17 +0530
Subject: [PATCH V3 1/6] dt-bindings: phy: qcom,uniphy-pcie: Document PCIe
 uniphy
In-Reply-To: <e2qgpvfccpo2sd4mbrynxruvt5attqmtd5oik26of7tv7u4lq6@kvb63sglwa5b>
References: <20240830081132.4016860-1-quic_srichara@quicinc.com>
 <20240830081132.4016860-2-quic_srichara@quicinc.com>
 <e2qgpvfccpo2sd4mbrynxruvt5attqmtd5oik26of7tv7u4lq6@kvb63sglwa5b>
Message-ID: <de17d37f-ed0c-4e73-91d5-fc902573212a@quicinc.com>



On 8/30/2024 1:53 PM, Krzysztof Kozlowski wrote:
> On Fri, Aug 30, 2024 at 01:41:27PM +0530, Sricharan R wrote:
>> From: Nitheesh Sekar <quic_nsekar at quicinc.com>
>>
>> Document the Qualcomm UNIPHY PCIe 28LP present in IPQ5018.
>>
>> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>> Signed-off-by: Nitheesh Sekar <quic_nsekar at quicinc.com>
>> Signed-off-by: Sricharan Ramabadhran <quic_srichara at quicinc.com>
>> ---
>>   [v3] Added reviewed-by tags
>>
>>   .../phy/qcom,ipq5018-uniphy-pcie.yaml         | 70 +++++++++++++++++++
>>   1 file changed, 70 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/phy/qcom,ipq5018-uniphy-pcie.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom,ipq5018-uniphy-pcie.yaml b/Documentation/devicetree/bindings/phy/qcom,ipq5018-uniphy-pcie.yaml
>> new file mode 100644
>> index 000000000000..c04dd179eb8b
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/phy/qcom,ipq5018-uniphy-pcie.yaml
>> @@ -0,0 +1,70 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/phy/qcom,ipq5018-uniphy-pcie.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Qualcomm UNIPHY PCIe 28LP PHY controller for genx1, genx2
>> +
>> +maintainers:
>> +  - Nitheesh Sekar <quic_nsekar at quicinc.com>
>> +  - Sricharan Ramabadhran <quic_srichara at quicinc.com>
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - qcom,ipq5018-uniphy-pcie-gen2x1
>> +      - qcom,ipq5018-uniphy-pcie-gen2x2
> 
> ... and now I wonder why there are two compatibles. Isn't the phy the
> same? We talk about the same hardware?
  We have 2 different physical phys. One with single lane and another
  with dual lane. Its same IP, but for 2 lanes, 2 sets of the phy
  specific registers needs to configured. So differentiating that here.

Regards,
  Sricharan





From quic_srichara at quicinc.com  Wed Sep  4 10:21:30 2024
From: quic_srichara at quicinc.com (Sricharan Ramabadhran)
Date: Wed, 4 Sep 2024 22:51:30 +0530
Subject: [PATCH V2 4/6] PCI: qcom: Add support for IPQ5018
In-Reply-To: <20240830083852.cwjc6skgypva6u6u@thinkpad>
References: <20240827045757.1101194-1-quic_srichara@quicinc.com>
 <20240827045757.1101194-5-quic_srichara@quicinc.com>
 <20240830083852.cwjc6skgypva6u6u@thinkpad>
Message-ID: <ea8ccb1e-2344-4c35-8a95-7b3f1fe23e08@quicinc.com>



On 8/30/2024 2:08 PM, Manivannan Sadhasivam wrote:
> On Tue, Aug 27, 2024 at 10:27:55AM +0530, Sricharan R wrote:
>> Introduce a new compatible and re-use 2_9_0 ops.
>>
> 
> While adding a new SoC, please add more info about the controller. Like the
> hardware revision (internal/synopsys), max number of lanes supported, max link
> speed, is it a derivative etc...
> 
  ok sure, will add.

Regards,
  Sricharan



From quic_srichara at quicinc.com  Wed Sep  4 10:47:19 2024
From: quic_srichara at quicinc.com (Sricharan Ramabadhran)
Date: Wed, 4 Sep 2024 23:17:19 +0530
Subject: [PATCH V2 5/6] arm64: dts: qcom: ipq5018: Add PCIe related nodes
In-Reply-To: <20240830085901.oeiuuijlvq2ydho2@thinkpad>
References: <20240827045757.1101194-1-quic_srichara@quicinc.com>
 <20240827045757.1101194-6-quic_srichara@quicinc.com>
 <20240830085901.oeiuuijlvq2ydho2@thinkpad>
Message-ID: <c5c1f0bf-2f69-44ae-b54b-d69d002e3199@quicinc.com>



On 8/30/2024 2:29 PM, Manivannan Sadhasivam wrote:
> On Tue, Aug 27, 2024 at 10:27:56AM +0530, Sricharan R wrote:
>> From: Nitheesh Sekar <quic_nsekar at quicinc.com>
>>
>> Add phy and controller nodes for a 2-lane Gen2 and
>> 1-lane Gen2 PCIe buses.
>>
>> Signed-off-by: Nitheesh Sekar <quic_nsekar at quicinc.com>
>> Signed-off-by: Sricharan R <quic_srichara at quicinc.com>
>> ---
>>   [v2] Removed relocatable flags,  removed assigned-clock-rates,
>>        fixed rest of the cosmetic comments.
>>
>>   arch/arm64/boot/dts/qcom/ipq5018.dtsi | 168 +++++++++++++++++++++++++-
>>   1 file changed, 166 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/ipq5018.dtsi b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
>> index 7e6e2c121979..dd5d6b7ff094 100644
>> --- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
>> @@ -9,6 +9,7 @@
>>   #include <dt-bindings/interrupt-controller/arm-gic.h>
>>   #include <dt-bindings/clock/qcom,gcc-ipq5018.h>
>>   #include <dt-bindings/reset/qcom,gcc-ipq5018.h>
>> +#include <dt-bindings/gpio/gpio.h>
>>   
>>   / {
>>   	interrupt-parent = <&intc>;
>> @@ -143,7 +144,33 @@ usbphy0: phy at 5b000 {
>>   			resets = <&gcc GCC_QUSB2_0_PHY_BCR>;
>>   
>>   			#phy-cells = <0>;
>> +		};
>> +
>> +		pcie_x1phy: phy at 7e000{
>> +			compatible = "qcom,ipq5018-uniphy-pcie-gen2x1";
>> +			reg = <0x0007e000 0x800>;
>> +			#phy-cells = <0>;
>> +			#clock-cells = <0>;
>> +			clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
>> +			clock-names = "pipe";
>> +			assigned-clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
>> +			resets = <&gcc GCC_PCIE1_PHY_BCR>,
>> +				 <&gcc GCC_PCIE1PHY_PHY_BCR>;
>> +			reset-names = "phy", "common";
>> +			status = "disabled";
>> +		};
>>   
>> +		pcie_x2phy: phy at 86000{
>> +			compatible = "qcom,ipq5018-uniphy-pcie-gen2x2";
>> +			reg = <0x00086000 0x1000>;
>> +			#phy-cells = <0>;
>> +			#clock-cells = <0>;
>> +			clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
>> +			clock-names = "pipe";
>> +			assigned-clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
>> +			resets = <&gcc GCC_PCIE0_PHY_BCR>,
>> +				 <&gcc GCC_PCIE0PHY_PHY_BCR>;
>> +			reset-names = "phy", "common";
>>   			status = "disabled";
>>   		};
>>   
>> @@ -170,8 +197,8 @@ gcc: clock-controller at 1800000 {
>>   			reg = <0x01800000 0x80000>;
>>   			clocks = <&xo_board_clk>,
>>   				 <&sleep_clk>,
>> -				 <0>,
>> -				 <0>,
>> +				 <&pcie_x2phy>,
>> +				 <&pcie_x1phy>,
>>   				 <0>,
>>   				 <0>,
>>   				 <0>,
>> @@ -387,6 +414,143 @@ frame at b128000 {
>>   				status = "disabled";
>>   			};
>>   		};
>> +
>> +		pcie0: pci at 80000000 {
> 
> pcie@
> 
  ok

>> +			compatible = "qcom,pcie-ipq5018";
>> +			reg =  <0x80000000 0xf1d>,
>> +			       <0x80000f20 0xa8>,
>> +			       <0x80001000 0x1000>,
>> +			       <0x00078000 0x3000>,
>> +			       <0x80100000 0x1000>;
> 
> Are you sure that the config space is only 4K?
> 
  ok, let me double check.

>> +			reg-names = "dbi", "elbi", "atu", "parf", "config";
>> +			device_type = "pci";
>> +			linux,pci-domain = <0>;
>> +			bus-range = <0x00 0xff>;
>> +			num-lanes = <1>;
>> +			max-link-speed = <2>;
>> +			#address-cells = <3>;
>> +			#size-cells = <2>;
>> +
>> +			phys = <&pcie_x1phy>;
>> +			phy-names ="pciephy";
>> +
>> +			ranges = <0x01000000 0 0x80200000 0x80200000 0 0x00100000
> 
> Please check the value of this field in other SoCs.

  ok, if its about the child address encoding for IO region, will fix.

> 
>> +				  0x02000000 0 0x80300000 0x80300000 0 0x10000000>;
>> +
>> +			#interrupt-cells = <1>;
>> +			interrupt-map-mask = <0 0 0 0x7>;
>> +			interrupt-map = <0 0 0 1 &intc 0 0 142 IRQ_TYPE_LEVEL_HIGH>,
>> +					<0 0 0 2 &intc 0 0 143 IRQ_TYPE_LEVEL_HIGH>,
>> +					<0 0 0 3 &intc 0 0 144 IRQ_TYPE_LEVEL_HIGH>,
>> +					<0 0 0 4 &intc 0 0 145 IRQ_TYPE_LEVEL_HIGH>;
>> +
>> +			interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
>> +			interrupt-names = "global_irq";
> 
> I'm pretty sure that this SoC has SPI based MSI interrupts. So they should be
> described even though ITS is supported.

  ok

> 
>> +
>> +			clocks = <&gcc GCC_SYS_NOC_PCIE1_AXI_CLK>,
>> +				 <&gcc GCC_PCIE1_AXI_M_CLK>,
>> +				 <&gcc GCC_PCIE1_AXI_S_CLK>,
>> +				 <&gcc GCC_PCIE1_AHB_CLK>,
>> +				 <&gcc GCC_PCIE1_AUX_CLK>,
>> +				 <&gcc GCC_PCIE1_AXI_S_BRIDGE_CLK>;
>> +
>> +			clock-names = "iface",
>> +				      "axi_m",
>> +				      "axi_s",
>> +				      "ahb",
>> +				      "aux",
>> +				      "axi_bridge";
>> +
>> +			resets = <&gcc GCC_PCIE1_PIPE_ARES>,
>> +				 <&gcc GCC_PCIE1_SLEEP_ARES>,
>> +				 <&gcc GCC_PCIE1_CORE_STICKY_ARES>,
>> +				 <&gcc GCC_PCIE1_AXI_MASTER_ARES>,
>> +				 <&gcc GCC_PCIE1_AXI_SLAVE_ARES>,
>> +				 <&gcc GCC_PCIE1_AHB_ARES>,
>> +				 <&gcc GCC_PCIE1_AXI_MASTER_STICKY_ARES>,
>> +				 <&gcc GCC_PCIE1_AXI_SLAVE_STICKY_ARES>;
>> +
>> +			reset-names = "pipe",
>> +				      "sleep",
>> +				      "sticky",
>> +				      "axi_m",
>> +				      "axi_s",
>> +				      "ahb",
>> +				      "axi_m_sticky",
>> +				      "axi_s_sticky";
>> +
>> +			msi-map = <0x0 &v2m0 0x0 0xff8>;
>> +			status = "disabled";
> 
> Please add the rootport node also as like other SoCs.
> 
  ok

> Above comments applies to below PCIe node.
>
  ok

Regards,
  Sricharan



From krzk at kernel.org  Wed Sep  4 11:16:19 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Sep 2024 20:16:19 +0200
Subject: [PATCH V3 1/6] dt-bindings: phy: qcom,uniphy-pcie: Document PCIe
 uniphy
In-Reply-To: <de17d37f-ed0c-4e73-91d5-fc902573212a@quicinc.com>
References: <20240830081132.4016860-1-quic_srichara@quicinc.com>
 <20240830081132.4016860-2-quic_srichara@quicinc.com>
 <e2qgpvfccpo2sd4mbrynxruvt5attqmtd5oik26of7tv7u4lq6@kvb63sglwa5b>
 <de17d37f-ed0c-4e73-91d5-fc902573212a@quicinc.com>
Message-ID: <ec59c6d0-0ef9-482f-8aa6-42d36c3420e5@kernel.org>

On 04/09/2024 19:20, Sricharan Ramabadhran wrote:
> 
> 
> On 8/30/2024 1:53 PM, Krzysztof Kozlowski wrote:
>> On Fri, Aug 30, 2024 at 01:41:27PM +0530, Sricharan R wrote:
>>> From: Nitheesh Sekar <quic_nsekar at quicinc.com>
>>>
>>> Document the Qualcomm UNIPHY PCIe 28LP present in IPQ5018.
>>>
>>> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>>> Signed-off-by: Nitheesh Sekar <quic_nsekar at quicinc.com>
>>> Signed-off-by: Sricharan Ramabadhran <quic_srichara at quicinc.com>
>>> ---
>>>   [v3] Added reviewed-by tags
>>>
>>>   .../phy/qcom,ipq5018-uniphy-pcie.yaml         | 70 +++++++++++++++++++
>>>   1 file changed, 70 insertions(+)
>>>   create mode 100644 Documentation/devicetree/bindings/phy/qcom,ipq5018-uniphy-pcie.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/phy/qcom,ipq5018-uniphy-pcie.yaml b/Documentation/devicetree/bindings/phy/qcom,ipq5018-uniphy-pcie.yaml
>>> new file mode 100644
>>> index 000000000000..c04dd179eb8b
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/phy/qcom,ipq5018-uniphy-pcie.yaml
>>> @@ -0,0 +1,70 @@
>>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/phy/qcom,ipq5018-uniphy-pcie.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: Qualcomm UNIPHY PCIe 28LP PHY controller for genx1, genx2
>>> +
>>> +maintainers:
>>> +  - Nitheesh Sekar <quic_nsekar at quicinc.com>
>>> +  - Sricharan Ramabadhran <quic_srichara at quicinc.com>
>>> +
>>> +properties:
>>> +  compatible:
>>> +    enum:
>>> +      - qcom,ipq5018-uniphy-pcie-gen2x1
>>> +      - qcom,ipq5018-uniphy-pcie-gen2x2
>>
>> ... and now I wonder why there are two compatibles. Isn't the phy the
>> same? We talk about the same hardware?
>   We have 2 different physical phys. One with single lane and another
>   with dual lane. Its same IP, but for 2 lanes, 2 sets of the phy
>   specific registers needs to configured. So differentiating that here.

What you described, suggests using phy mode or num-lanes in PCI
controller, not separate compatible. It's the same IP.

Best regards,
Krzysztof



From aford173 at gmail.com  Wed Sep  4 16:30:28 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed,  4 Sep 2024 18:30:28 -0500
Subject: [PATCH V6 0/5] phy: freescale: fsl-samsung-hdmi: Expand phy clock options
Message-ID: <20240904233100.114611-1-aford173@gmail.com>

Currently, there is a look-up-table to describe all the clock options the HDMI PHY
can use.  Some of these entries in the LUT are using a fractional divider which does
not have a well documented algorithm for determinging values, but the the integer
divider can use an algorithm to calculate the integer divder values dynamically
beyond those listed in the LUT and also duplicates some of the entries.

The first two patches do not do anything functionally other than simplify
some of the register accesses and de-duplicates some of the register look-ups.

The third patch adds support for the integer divider and uses it whenever the
clock request is an exact match.  Otherwise, it will use the LUT as before.
The rouding is still based on the LUT if the integer clock isn't an exact match.

The forth patch updates thes set_rate and round_rate functions to use either
the fractional clock LUT or the the integer divder mechanism to determine
which ever clock rate might be closest match.

The last patch removes the integer divider entries from the LUT since by then
it'll be comparing both the integer divider calculator and the closest value
in the LUT.

In my testing with a AOC 4K monitor, I was able to add 4 entries in my modetest
table.  I do not have an HDMI analyzer, so I just used my monitor to determine
if this series worked.

V6: Fix some whitespace
    Fix issues with calculating the closest divider
    
V5: Updates patch 1 of 5 for whitespace and comment updates
      Patches 1 and 2 add RB tags
      No functional changes from V4
      
Adam Ford (5):
  phy: freescale: fsl-samsung-hdmi: Replace register defines with macro
  phy: freescale: fsl-samsung-hdmi: Simplify REG21_PMS_S_MASK lookup
  phy: freescale: fsl-samsung-hdmi: Support dynamic integer
  phy: freescale: fsl-samsung-hdmi: Use closest divider
  phy: freescale: fsl-samsung-hdmi: Remove unnecessary LUT entries

 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 570 ++++++++++---------
 1 file changed, 292 insertions(+), 278 deletions(-)

-- 
2.43.0



From aford173 at gmail.com  Wed Sep  4 16:30:29 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed,  4 Sep 2024 18:30:29 -0500
Subject: [PATCH V6 1/5] phy: freescale: fsl-samsung-hdmi: Replace register defines with macro
In-Reply-To: <20240904233100.114611-1-aford173@gmail.com>
References: <20240904233100.114611-1-aford173@gmail.com>
Message-ID: <20240904233100.114611-2-aford173@gmail.com>

There are 47 registers defined as PHY_REG_xx were xx goes from 00 to
47.  Simplify this by replacing them all with a macro which is passed
the register number to return the proper register offset.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
V6:  No Change

V5:  Restore comment about REG33.
     Add spacing between the REG entries to easier readability
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 133 ++++++-------------
 1 file changed, 43 insertions(+), 90 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 9048cdc760c2..acea7008aefc 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -14,76 +14,29 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 
-#define PHY_REG_00		0x00
-#define PHY_REG_01		0x04
-#define PHY_REG_02		0x08
-#define PHY_REG_08		0x20
-#define PHY_REG_09		0x24
-#define PHY_REG_10		0x28
-#define PHY_REG_11		0x2c
-
-#define PHY_REG_12		0x30
-#define  REG12_CK_DIV_MASK	GENMASK(5, 4)
-
-#define PHY_REG_13		0x34
-#define  REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
-
-#define PHY_REG_14		0x38
-#define  REG14_TOL_MASK		GENMASK(7, 4)
-#define  REG14_RP_CODE_MASK	GENMASK(3, 1)
-#define  REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
-
-#define PHY_REG_15		0x3c
-#define PHY_REG_16		0x40
-#define PHY_REG_17		0x44
-#define PHY_REG_18		0x48
-#define PHY_REG_19		0x4c
-#define PHY_REG_20		0x50
-
-#define PHY_REG_21		0x54
-#define  REG21_SEL_TX_CK_INV	BIT(7)
-#define  REG21_PMS_S_MASK	GENMASK(3, 0)
-
-#define PHY_REG_22		0x58
-#define PHY_REG_23		0x5c
-#define PHY_REG_24		0x60
-#define PHY_REG_25		0x64
-#define PHY_REG_26		0x68
-#define PHY_REG_27		0x6c
-#define PHY_REG_28		0x70
-#define PHY_REG_29		0x74
-#define PHY_REG_30		0x78
-#define PHY_REG_31		0x7c
-#define PHY_REG_32		0x80
+#define PHY_REG(reg)		(reg * 4)
 
+#define REG12_CK_DIV_MASK	GENMASK(5, 4)
+
+#define REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
+
+#define REG14_TOL_MASK		GENMASK(7, 4)
+#define REG14_RP_CODE_MASK	GENMASK(3, 1)
+#define REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
+
+#define REG21_SEL_TX_CK_INV	BIT(7)
+#define REG21_PMS_S_MASK	GENMASK(3, 0)
 /*
  * REG33 does not match the ref manual. According to Sandor Yu from NXP,
  * "There is a doc issue on the i.MX8MP latest RM"
  * REG33 is being used per guidance from Sandor
  */
+#define REG33_MODE_SET_DONE	BIT(7)
+#define REG33_FIX_DA		BIT(1)
 
-#define PHY_REG_33		0x84
-#define  REG33_MODE_SET_DONE	BIT(7)
-#define  REG33_FIX_DA		BIT(1)
-
-#define PHY_REG_34		0x88
-#define  REG34_PHY_READY	BIT(7)
-#define  REG34_PLL_LOCK		BIT(6)
-#define  REG34_PHY_CLK_READY	BIT(5)
-
-#define PHY_REG_35		0x8c
-#define PHY_REG_36		0x90
-#define PHY_REG_37		0x94
-#define PHY_REG_38		0x98
-#define PHY_REG_39		0x9c
-#define PHY_REG_40		0xa0
-#define PHY_REG_41		0xa4
-#define PHY_REG_42		0xa8
-#define PHY_REG_43		0xac
-#define PHY_REG_44		0xb0
-#define PHY_REG_45		0xb4
-#define PHY_REG_46		0xb8
-#define PHY_REG_47		0xbc
+#define REG34_PHY_READY	BIT(7)
+#define REG34_PLL_LOCK		BIT(6)
+#define REG34_PHY_CLK_READY	BIT(5)
 
 #define PHY_PLL_DIV_REGS_NUM 6
 
@@ -369,29 +322,29 @@ struct reg_settings {
 };
 
 static const struct reg_settings common_phy_cfg[] = {
-	{ PHY_REG_00, 0x00 }, { PHY_REG_01, 0xd1 },
-	{ PHY_REG_08, 0x4f }, { PHY_REG_09, 0x30 },
-	{ PHY_REG_10, 0x33 }, { PHY_REG_11, 0x65 },
+	{ PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
+	{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
+	{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
 	/* REG12 pixclk specific */
 	/* REG13 pixclk specific */
 	/* REG14 pixclk specific */
-	{ PHY_REG_15, 0x80 }, { PHY_REG_16, 0x6c },
-	{ PHY_REG_17, 0xf2 }, { PHY_REG_18, 0x67 },
-	{ PHY_REG_19, 0x00 }, { PHY_REG_20, 0x10 },
+	{ PHY_REG(15), 0x80 }, { PHY_REG(16), 0x6c },
+	{ PHY_REG(17), 0xf2 }, { PHY_REG(18), 0x67 },
+	{ PHY_REG(19), 0x00 }, { PHY_REG(20), 0x10 },
 	/* REG21 pixclk specific */
-	{ PHY_REG_22, 0x30 }, { PHY_REG_23, 0x32 },
-	{ PHY_REG_24, 0x60 }, { PHY_REG_25, 0x8f },
-	{ PHY_REG_26, 0x00 }, { PHY_REG_27, 0x00 },
-	{ PHY_REG_28, 0x08 }, { PHY_REG_29, 0x00 },
-	{ PHY_REG_30, 0x00 }, { PHY_REG_31, 0x00 },
-	{ PHY_REG_32, 0x00 }, { PHY_REG_33, 0x80 },
-	{ PHY_REG_34, 0x00 }, { PHY_REG_35, 0x00 },
-	{ PHY_REG_36, 0x00 }, { PHY_REG_37, 0x00 },
-	{ PHY_REG_38, 0x00 }, { PHY_REG_39, 0x00 },
-	{ PHY_REG_40, 0x00 }, { PHY_REG_41, 0xe0 },
-	{ PHY_REG_42, 0x83 }, { PHY_REG_43, 0x0f },
-	{ PHY_REG_44, 0x3E }, { PHY_REG_45, 0xf8 },
-	{ PHY_REG_46, 0x00 }, { PHY_REG_47, 0x00 }
+	{ PHY_REG(22), 0x30 }, { PHY_REG(23), 0x32 },
+	{ PHY_REG(24), 0x60 }, { PHY_REG(25), 0x8f },
+	{ PHY_REG(26), 0x00 }, { PHY_REG(27), 0x00 },
+	{ PHY_REG(28), 0x08 }, { PHY_REG(29), 0x00 },
+	{ PHY_REG(30), 0x00 }, { PHY_REG(31), 0x00 },
+	{ PHY_REG(32), 0x00 }, { PHY_REG(33), 0x80 },
+	{ PHY_REG(34), 0x00 }, { PHY_REG(35), 0x00 },
+	{ PHY_REG(36), 0x00 }, { PHY_REG(37), 0x00 },
+	{ PHY_REG(38), 0x00 }, { PHY_REG(39), 0x00 },
+	{ PHY_REG(40), 0x00 }, { PHY_REG(41), 0xe0 },
+	{ PHY_REG(42), 0x83 }, { PHY_REG(43), 0x0f },
+	{ PHY_REG(44), 0x3E }, { PHY_REG(45), 0xf8 },
+	{ PHY_REG(46), 0x00 }, { PHY_REG(47), 0x00 }
 };
 
 struct fsl_samsung_hdmi_phy {
@@ -442,7 +395,7 @@ fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
 	}
 
 	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
-	       phy->regs + PHY_REG_21);
+	       phy->regs + PHY_REG(21));
 }
 
 static void
@@ -469,7 +422,7 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 		break;
 	}
 
-	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG_12);
+	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG(12));
 
 	/*
 	 * Calculation for the frequency lock detector target code (fld_tg_code)
@@ -489,11 +442,11 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 
 	/* FLD_TOL and FLD_RP_CODE taken from downstream driver */
 	writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),
-	       phy->regs + PHY_REG_13);
+	       phy->regs + PHY_REG(13));
 	writeb(FIELD_PREP(REG14_TOL_MASK, 2) |
 	       FIELD_PREP(REG14_RP_CODE_MASK, 2) |
 	       FIELD_PREP(REG14_TG_CODE_HIGH_MASK, fld_tg_code >> 8),
-	       phy->regs + PHY_REG_14);
+	       phy->regs + PHY_REG(14));
 }
 
 static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
@@ -503,7 +456,7 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	u8 val;
 
 	/* HDMI PHY init */
-	writeb(REG33_FIX_DA, phy->regs + PHY_REG_33);
+	writeb(REG33_FIX_DA, phy->regs + PHY_REG(33));
 
 	/* common PHY registers */
 	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
@@ -511,14 +464,14 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 
 	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
-		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG_02 + i * 4);
+		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
 
 	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
-	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG_33);
+	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));
 
-	ret = readb_poll_timeout(phy->regs + PHY_REG_34, val,
+	ret = readb_poll_timeout(phy->regs + PHY_REG(34), val,
 				 val & REG34_PLL_LOCK, 50, 20000);
 	if (ret)
 		dev_err(phy->dev, "PLL failed to lock\n");
-- 
2.43.0



From aford173 at gmail.com  Wed Sep  4 16:30:30 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed,  4 Sep 2024 18:30:30 -0500
Subject: [PATCH V6 2/5] phy: freescale: fsl-samsung-hdmi: Simplify REG21_PMS_S_MASK lookup
In-Reply-To: <20240904233100.114611-1-aford173@gmail.com>
References: <20240904233100.114611-1-aford173@gmail.com>
Message-ID: <20240904233100.114611-3-aford173@gmail.com>

The value of 'S' is writen to two places, PHY_REG3[7:4] and
PHY_REG21[3:0].  There is a lookup table which contains
the value of PHY_REG3.  Rather than using a switch statement
based on the pixel clock to search for the value of 'S' again,
just shift the contents of PHY_REG3[7:4] >> 4 and place the value
in PHY_REG21[3:0].  Doing this can eliminate an entire function.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
V6:  No Change
V5:  No Change
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 39 ++------------------
 1 file changed, 4 insertions(+), 35 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index acea7008aefc..4f6874226f9a 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -364,40 +364,6 @@ to_fsl_samsung_hdmi_phy(struct clk_hw *hw)
 	return container_of(hw, struct fsl_samsung_hdmi_phy, hw);
 }
 
-static void
-fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
-				      const struct phy_config *cfg)
-{
-	u8 div = 0x1;
-
-	switch (cfg->pixclk) {
-	case  22250000 ...  33750000:
-		div = 0xf;
-		break;
-	case  35000000 ...  40000000:
-		div = 0xb;
-		break;
-	case  43200000 ...  47500000:
-		div = 0x9;
-		break;
-	case  50349650 ...  63500000:
-		div = 0x7;
-		break;
-	case  67500000 ...  90000000:
-		div = 0x5;
-		break;
-	case  94000000 ... 148500000:
-		div = 0x3;
-		break;
-	case 154000000 ... 297000000:
-		div = 0x1;
-		break;
-	}
-
-	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
-	       phy->regs + PHY_REG(21));
-}
-
 static void
 fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 					    const struct phy_config *cfg)
@@ -466,7 +432,10 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
 		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
 
-	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
+	/* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
+	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
+	       cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
+
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
 	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));
-- 
2.43.0



From aford173 at gmail.com  Wed Sep  4 16:30:31 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed,  4 Sep 2024 18:30:31 -0500
Subject: [PATCH V6 3/5] phy: freescale: fsl-samsung-hdmi: Support dynamic integer
In-Reply-To: <20240904233100.114611-1-aford173@gmail.com>
References: <20240904233100.114611-1-aford173@gmail.com>
Message-ID: <20240904233100.114611-4-aford173@gmail.com>

There is currently a look-up table for a variety of resolutions.
Since the phy has the ability to dynamically calculate the values
necessary to use the intger divider which should allow more
resolutions without having to update the look-up-table.

If the lookup table cannot find an exact match, fall back to the
dynamic calculator of the integer divider.

Previously, the value of P was hard-coded to 1, this required an
update to the phy_pll_cfg table to add in the extra value into the
table, so if the value of P is calculated to be something else
by the PMS calculator, the calculated_phy_pll_cfg structure
can be used instead without having to keep track of which method
was used.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
V6:  Fix comment typos and remove an unnecesary extra calculation
     by using the cached value.
V5:  No Change
V4:  No Change
V3:  Change size of pll_div_regs to include PHY_REG01 (P)
     Create calculated_phy_pll_cfg to containe the values
     Eliminate the PMS calculation from fsl_samsung_hdmi_phy_configure
     Make the LUT primary and fall back to integer calculator in
     phy_clk_round_rate.
     Check the range right away to ensure it's reaonsable rather than
     trying to find a clock only to learn it's outside the range.
     Overall added notes and comments where stuff may not be intuitive.

V2:  Update phy_clk_round_rate and phy_clk_set_rate to both support
     the integer clock PMS calculator.
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 341 +++++++++++++------
 1 file changed, 235 insertions(+), 106 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 4f6874226f9a..4b13e386e5ba 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -16,6 +16,8 @@
 
 #define PHY_REG(reg)		(reg * 4)
 
+#define REG01_PMS_P_MASK	GENMASK(3, 0)
+#define REG03_PMS_S_MASK	GENMASK(7, 4)
 #define REG12_CK_DIV_MASK	GENMASK(5, 4)
 
 #define REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
@@ -38,281 +40,296 @@
 #define REG34_PLL_LOCK		BIT(6)
 #define REG34_PHY_CLK_READY	BIT(5)
 
-#define PHY_PLL_DIV_REGS_NUM 6
+#ifndef MHZ
+#define MHZ	(1000UL * 1000UL)
+#endif
+
+#define PHY_PLL_DIV_REGS_NUM 7
 
 struct phy_config {
 	u32	pixclk;
 	u8	pll_div_regs[PHY_PLL_DIV_REGS_NUM];
 };
 
+/*
+ * The calculated_phy_pll_cfg only handles integer divider for PMS,
+ * meaning the last four entries will be fixed, but the first three will
+ * be calculated by the PMS calculator.
+ */
+static struct phy_config calculated_phy_pll_cfg = {
+	.pixclk = 0,
+	.pll_div_regs = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
+};
+
+/* The lookup table contains values for which the fractional divder is used */
 static const struct phy_config phy_pll_cfg[] = {
 	{
 		.pixclk = 22250000,
-		.pll_div_regs = { 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 23750000,
-		.pll_div_regs = { 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
 	}, {
 		.pixclk = 24000000,
-		.pll_div_regs = { 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 24024000,
-		.pll_div_regs = { 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
 	}, {
 		.pixclk = 25175000,
-		.pll_div_regs = { 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
 	}, {
 		.pixclk = 25200000,
-		.pll_div_regs = { 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 26750000,
-		.pll_div_regs = { 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 27000000,
-		.pll_div_regs = { 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 27027000,
-		.pll_div_regs = { 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 29500000,
-		.pll_div_regs = { 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 30750000,
-		.pll_div_regs = { 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 30888000,
-		.pll_div_regs = { 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
 	}, {
 		.pixclk = 33750000,
-		.pll_div_regs = { 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 35000000,
-		.pll_div_regs = { 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 36000000,
-		.pll_div_regs = { 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 36036000,
-		.pll_div_regs = { 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 40000000,
-		.pll_div_regs = { 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43200000,
-		.pll_div_regs = { 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43243200,
-		.pll_div_regs = { 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 44500000,
-		.pll_div_regs = { 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
 	}, {
 		.pixclk = 47000000,
-		.pll_div_regs = { 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
 	}, {
 		.pixclk = 47500000,
-		.pll_div_regs = { 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
 	}, {
 		.pixclk = 50349650,
-		.pll_div_regs = { 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
 	}, {
 		.pixclk = 50400000,
-		.pll_div_regs = { 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 53250000,
-		.pll_div_regs = { 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 53500000,
-		.pll_div_regs = { 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 54000000,
-		.pll_div_regs = { 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 54054000,
-		.pll_div_regs = { 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 59000000,
-		.pll_div_regs = { 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 59340659,
-		.pll_div_regs = { 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
 	}, {
 		.pixclk = 59400000,
-		.pll_div_regs = { 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 61500000,
-		.pll_div_regs = { 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 63500000,
-		.pll_div_regs = { 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 67500000,
-		.pll_div_regs = { 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
 	}, {
 		.pixclk = 70000000,
-		.pll_div_regs = { 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 72000000,
-		.pll_div_regs = { 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 72072000,
-		.pll_div_regs = { 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 74176000,
-		.pll_div_regs = { 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
 	}, {
 		.pixclk = 74250000,
-		.pll_div_regs = { 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
 	}, {
 		.pixclk = 78500000,
-		.pll_div_regs = { 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 80000000,
-		.pll_div_regs = { 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 82000000,
-		.pll_div_regs = { 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 82500000,
-		.pll_div_regs = { 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
 	}, {
 		.pixclk = 89000000,
-		.pll_div_regs = { 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
 	}, {
 		.pixclk = 90000000,
-		.pll_div_regs = { 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 94000000,
-		.pll_div_regs = { 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
 	}, {
 		.pixclk = 95000000,
-		.pll_div_regs = { 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
 	}, {
 		.pixclk = 98901099,
-		.pll_div_regs = { 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
 	}, {
 		.pixclk = 99000000,
-		.pll_div_regs = { 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
 	}, {
 		.pixclk = 100699300,
-		.pll_div_regs = { 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
 	}, {
 		.pixclk = 100800000,
-		.pll_div_regs = { 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 102500000,
-		.pll_div_regs = { 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
 		.pixclk = 104750000,
-		.pll_div_regs = { 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
 	}, {
 		.pixclk = 106500000,
-		.pll_div_regs = { 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 107000000,
-		.pll_div_regs = { 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 108000000,
-		.pll_div_regs = { 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 108108000,
-		.pll_div_regs = { 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 118000000,
-		.pll_div_regs = { 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 118800000,
-		.pll_div_regs = { 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 123000000,
-		.pll_div_regs = { 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 127000000,
-		.pll_div_regs = { 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 135000000,
-		.pll_div_regs = { 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 135580000,
-		.pll_div_regs = { 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
+		.pll_div_regs = { 0xd1, 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
 	}, {
 		.pixclk = 137520000,
-		.pll_div_regs = { 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
+		.pll_div_regs = { 0xd1, 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
 	}, {
 		.pixclk = 138750000,
-		.pll_div_regs = { 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
+		.pll_div_regs = { 0xd1, 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
 	}, {
 		.pixclk = 140000000,
-		.pll_div_regs = { 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
 	}, {
 		.pixclk = 144000000,
-		.pll_div_regs = { 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 148352000,
-		.pll_div_regs = { 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
 	}, {
 		.pixclk = 148500000,
-		.pll_div_regs = { 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
 	}, {
 		.pixclk = 154000000,
-		.pll_div_regs = { 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
+		.pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
 	}, {
 		.pixclk = 157000000,
-		.pll_div_regs = { 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
 	}, {
 		.pixclk = 160000000,
-		.pll_div_regs = { 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
 	}, {
 		.pixclk = 162000000,
-		.pll_div_regs = { 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
+		.pll_div_regs = { 0xd1, 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
 	}, {
 		.pixclk = 164000000,
-		.pll_div_regs = { 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
 	}, {
 		.pixclk = 165000000,
-		.pll_div_regs = { 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
 	}, {
 		.pixclk = 180000000,
-		.pll_div_regs = { 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 185625000,
-		.pll_div_regs = { 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
 	}, {
 		.pixclk = 188000000,
-		.pll_div_regs = { 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
 	}, {
 		.pixclk = 198000000,
-		.pll_div_regs = { 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
 	}, {
 		.pixclk = 205000000,
-		.pll_div_regs = { 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
 		.pixclk = 209500000,
-		.pll_div_regs = { 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
 	}, {
 		.pixclk = 213000000,
-		.pll_div_regs = { 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 216000000,
-		.pll_div_regs = { 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 216216000,
-		.pll_div_regs = { 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 237600000,
-		.pll_div_regs = { 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 254000000,
-		.pll_div_regs = { 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 277500000,
-		.pll_div_regs = { 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
+		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
 	}, {
 		.pixclk = 288000000,
-		.pll_div_regs = { 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 297000000,
-		.pll_div_regs = { 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
 	},
 };
 
@@ -322,7 +339,8 @@ struct reg_settings {
 };
 
 static const struct reg_settings common_phy_cfg[] = {
-	{ PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
+	{ PHY_REG(0), 0x00 },
+	/* PHY_REG(1-7) pix clk specific */
 	{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
 	{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
 	/* REG12 pixclk specific */
@@ -415,6 +433,76 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 	       phy->regs + PHY_REG(14));
 }
 
+static unsigned long fsl_samsung_hdmi_phy_find_pms(unsigned long fout, u8 *p, u16 *m, u8 *s)
+{
+	unsigned long best_freq = 0;
+	u32 min_delta = 0xffffffff;
+	u8 _p, best_p;
+	u16 _m, best_m;
+	u8 _s, best_s;
+
+	/* The ref manual states the values of 'P' range from 1 to 11 */
+	for (_p = 1; _p <= 11; ++_p) {
+		for (_s = 1; _s <= 16; ++_s) {
+			u64 tmp;
+			u32 delta;
+
+			/* s must be one or even */
+			if (_s > 1 && (_s & 0x01) == 1)
+				_s++;
+
+			/* _s cannot be 14 per the TRM */
+			if (_s == 14)
+				continue;
+
+			/*
+			 * TODO: Ref Manual doesn't state the range of _m
+			 * so this should be further refined if possible.
+			 * This range was set based on the original values
+			 * in the lookup table
+			 */
+			tmp = (u64)fout * (_p * _s);
+			do_div(tmp, 24 * MHZ);
+			_m = tmp;
+			if (_m < 0x30 || _m > 0x7b)
+				continue;
+
+			/*
+			 * Rev 2 of the Ref Manual states the
+			 * VCO can range between 750MHz and
+			 * 3GHz.  The VCO is assumed to be
+			 * is assumed to be (M * f_ref) / P,
+			 * where f_ref is 24MHz.
+			 */
+			tmp = (u64)_m * 24 * MHZ;
+			do_div(tmp, _p);
+			if (tmp < 750 * MHZ ||
+			    tmp > 3000 * MHZ)
+				continue;
+
+			/* Final frequency after post-divider */
+			do_div(tmp, _s);
+
+			delta = abs(fout - tmp);
+			if (delta < min_delta) {
+				best_p = _p;
+				best_s = _s;
+				best_m = _m;
+				min_delta = delta;
+				best_freq = tmp;
+			}
+		}
+	}
+
+	if (best_freq) {
+		*p = best_p;
+		*m = best_m;
+		*s = best_s;
+	}
+
+	return best_freq;
+}
+
 static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 					  const struct phy_config *cfg)
 {
@@ -428,13 +516,13 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
 		writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
 
-	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
+	/* set individual PLL registers PHY_REG1 ... PHY_REG7 */
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
-		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
+		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(1) + i * 4);
 
-	/* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
+	/* High nibble of PHY_REG3 and low nibble of PHY_REG21 both contain 'S' */
 	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
-	       cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
+	       cfg->pll_div_regs[2] >> 4), phy->regs + PHY_REG(21));
 
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
@@ -462,29 +550,70 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
 static long phy_clk_round_rate(struct clk_hw *hw,
 			       unsigned long rate, unsigned long *parent_rate)
 {
+	u32 int_div_clk;
 	int i;
+	u16 m;
+	u8 p, s;
+
+	/* If the clock is out of range return error instead of searching */
+	if (rate > 297000000 || rate < 22250000)
+		return -EINVAL;
 
+	/* Check the lookup table */
 	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
 		if (phy_pll_cfg[i].pixclk <= rate)
-			return phy_pll_cfg[i].pixclk;
+			break;
+	/* If the rate is an exact match, return it now */
+	if (rate == phy_pll_cfg[i].pixclk)
+		return phy_pll_cfg[i].pixclk;
+
+	/*
+	 * The math on the lookup table shows the PMS math yields a
+	 * frequency 5 x pixclk.
+	 * When we check the integer divider against the desired rate,
+	 * multiply the rate x 5 and then divide the outcome by 5.
+	 */
+	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
 
-	return -EINVAL;
+	/* If the rate is an exact match, return it now */
+	if (int_div_clk == rate)
+		return int_div_clk;
+
+	/* Fall back to the closest value in the LUT */
+	return phy_pll_cfg[i].pixclk;
 }
 
 static int phy_clk_set_rate(struct clk_hw *hw,
 			    unsigned long rate, unsigned long parent_rate)
 {
 	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
+	u32 int_div_clk;
 	int i;
-
-	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
-		if (phy_pll_cfg[i].pixclk <= rate)
-			break;
-
-	if (i < 0)
-		return -EINVAL;
-
-	phy->cur_cfg = &phy_pll_cfg[i];
+	u16 m;
+	u8 p, s;
+
+	/* If the integer divider works, just use it */
+	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
+	if (int_div_clk == rate) {
+		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using integer divider\n");
+		calculated_phy_pll_cfg.pixclk = int_div_clk;
+		calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
+		calculated_phy_pll_cfg.pll_div_regs[1] = m;
+		calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
+		/* pll_div_regs 3-6 are fixed and pre-defined already */
+		phy->cur_cfg  = &calculated_phy_pll_cfg;
+	} else {
+		/* Otherwise, search the LUT */
+		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
+		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
+			if (phy_pll_cfg[i].pixclk <= rate)
+				break;
+
+		if (i < 0)
+			return -EINVAL;
+
+		phy->cur_cfg = &phy_pll_cfg[i];
+	}
 
 	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
 }
-- 
2.43.0



From aford173 at gmail.com  Wed Sep  4 16:30:32 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed,  4 Sep 2024 18:30:32 -0500
Subject: [PATCH V6 4/5] phy: freescale: fsl-samsung-hdmi: Use closest divider
In-Reply-To: <20240904233100.114611-1-aford173@gmail.com>
References: <20240904233100.114611-1-aford173@gmail.com>
Message-ID: <20240904233100.114611-5-aford173@gmail.com>

Currently, if the clock values cannot be set to the exact rate,
the round_rate and set_rate functions use the closest value found in
the look-up-table.  In preparation of removing values from the LUT
that can be calculated evenly with the integer calculator, it's
necessary to ensure to check both the look-up-table and the integer
divider clock values to get the closest values to the requested
value.  It does this by measuring the difference between the
requested clock value and the closest value in both integer divider
calucator and the fractional clock look-up-table.

Which ever has the smallest difference between them is returned as
the cloesest rate.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Signed-off-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
---
V6:  Simplify the calculation of the closest rate and fix
     a situation where the integer divider values may not be properly
     setup before they are used.
     Fixup some comments
V5:  No Change
V4:  New to series
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 46 ++++++++++++++------
 1 file changed, 33 insertions(+), 13 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 4b13e386e5ba..9a21dbbf1a82 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -547,6 +547,16 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
 	return phy->cur_cfg->pixclk;
 }
 
+static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate,
+						 u32 int_div_clk, u32 frac_div_clk)
+{
+	/* The int_div_clk may be greater than rate, so cast it and use ABS */
+	if (abs((long)rate - (long)int_div_clk) < (rate - frac_div_clk))
+		return int_div_clk;
+
+	return frac_div_clk;
+}
+
 static long phy_clk_round_rate(struct clk_hw *hw,
 			       unsigned long rate, unsigned long *parent_rate)
 {
@@ -563,6 +573,7 @@ static long phy_clk_round_rate(struct clk_hw *hw,
 	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
 		if (phy_pll_cfg[i].pixclk <= rate)
 			break;
+
 	/* If the rate is an exact match, return it now */
 	if (rate == phy_pll_cfg[i].pixclk)
 		return phy_pll_cfg[i].pixclk;
@@ -579,8 +590,7 @@ static long phy_clk_round_rate(struct clk_hw *hw,
 	if (int_div_clk == rate)
 		return int_div_clk;
 
-	/* Fall back to the closest value in the LUT */
-	return phy_pll_cfg[i].pixclk;
+	return fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk, phy_pll_cfg[i].pixclk);
 }
 
 static int phy_clk_set_rate(struct clk_hw *hw,
@@ -594,27 +604,37 @@ static int phy_clk_set_rate(struct clk_hw *hw,
 
 	/* If the integer divider works, just use it */
 	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
+	calculated_phy_pll_cfg.pixclk = int_div_clk;
+	calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
+	calculated_phy_pll_cfg.pll_div_regs[1] = m;
+	calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
+	phy->cur_cfg = &calculated_phy_pll_cfg;
 	if (int_div_clk == rate) {
 		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using integer divider\n");
-		calculated_phy_pll_cfg.pixclk = int_div_clk;
-		calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
-		calculated_phy_pll_cfg.pll_div_regs[1] = m;
-		calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
-		/* pll_div_regs 3-6 are fixed and pre-defined already */
-		phy->cur_cfg  = &calculated_phy_pll_cfg;
+		goto done;
 	} else {
 		/* Otherwise, search the LUT */
-		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
-		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
-			if (phy_pll_cfg[i].pixclk <= rate)
+		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--) {
+			if (phy_pll_cfg[i].pixclk == rate) {
+				dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
+				phy->cur_cfg = &phy_pll_cfg[i];
+				goto done;
+			}
+
+			if (phy_pll_cfg[i].pixclk < rate)
 				break;
+		}
 
 		if (i < 0)
 			return -EINVAL;
-
-		phy->cur_cfg = &phy_pll_cfg[i];
 	}
 
+	if (fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk,
+						  phy_pll_cfg[i].pixclk) == int_div_clk)
+		phy->cur_cfg = &calculated_phy_pll_cfg;
+	else
+		phy->cur_cfg = &phy_pll_cfg[i];
+done:
 	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
 }
 
-- 
2.43.0



From aford173 at gmail.com  Wed Sep  4 16:30:33 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed,  4 Sep 2024 18:30:33 -0500
Subject: [PATCH V6 5/5] phy: freescale: fsl-samsung-hdmi: Remove unnecessary LUT entries
In-Reply-To: <20240904233100.114611-1-aford173@gmail.com>
References: <20240904233100.114611-1-aford173@gmail.com>
Message-ID: <20240904233100.114611-6-aford173@gmail.com>

The lookup table contains entries which use the integer divider
instead of just the fractional divider. Since the set and round
functions check both the integer divider values and the LUT values,
it's no longer necessary to keep the integer divider values in the
lookup table, as can be dynamically calcuated.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
V6: Fix typos in commit message
V5: No Change
V4:  New to series
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 83 +++-----------------
 1 file changed, 13 insertions(+), 70 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 9a21dbbf1a82..1203143bad7a 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -69,25 +69,16 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 23750000,
 		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
-	}, {
-		.pixclk = 24000000,
-		.pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 24024000,
 		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
 	}, {
 		.pixclk = 25175000,
 		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
-	}, {
-		.pixclk = 25200000,
-		.pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 26750000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 27000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 27027000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -105,18 +96,9 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 35000000,
 		.pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 36000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 36036000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
-	}, {
-		.pixclk = 40000000,
-		.pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
-		.pixclk = 43200000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43243200,
 		.pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
@@ -132,19 +114,13 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 50349650,
 		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
-	}, {
-		.pixclk = 50400000,
-		.pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 53250000,
 		.pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 53500000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 54000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 54054000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -153,10 +129,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 59340659,
 		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
-	}, {
-		.pixclk = 59400000,
-		.pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 61500000,
 		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -168,10 +141,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 70000000,
 		.pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 72000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 72072000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -183,10 +153,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 78500000,
 		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
-	}, {
-		.pixclk = 80000000,
-		.pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 82000000,
 		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -213,10 +180,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 100699300,
 		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
-	}, {
-		.pixclk = 100800000,
-		.pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 102500000,
 		.pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
@@ -228,19 +192,13 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 107000000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 108000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 108108000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 118000000,
 		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
-	}, {
-		.pixclk = 118800000,
-		.pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 123000000,
 		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -261,10 +219,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 140000000,
 		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
-	}, {
-		.pixclk = 144000000,
-		.pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 148352000,
 		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
 	}, {
@@ -288,9 +243,6 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 165000000,
 		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
-	}, {
-		.pixclk = 180000000,
-		.pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 185625000,
 		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
@@ -309,25 +261,16 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 213000000,
 		.pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
-	}, {
-		.pixclk = 216000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 216216000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
-	}, {
-		.pixclk = 237600000,
-		.pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 254000000,
 		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 277500000,
 		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
-	}, {
-		.pixclk = 288000000,
-		.pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 297000000,
 		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
 	},
-- 
2.43.0



From dmitry.baryshkov at linaro.org  Wed Sep  4 20:33:36 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu,  5 Sep 2024 06:33:36 +0300
Subject: [PATCH v7 0/6] HDMI TX support in msm8998
In-Reply-To: <20240724-hdmi-tx-v7-0-e44a20553464@freebox.fr>
References: <20240724-hdmi-tx-v7-0-e44a20553464@freebox.fr>
Message-ID: <172550712143.3299484.1580127137460046609.b4-ty@linaro.org>


On Wed, 24 Jul 2024 17:01:33 +0200, Marc Gonzalez wrote:
> DT bits required for HDMI TX support in qcom APQ8098 (MSM8998 cousin)
> 

Applied, thanks!

[1/6] dt-bindings: phy: add qcom,hdmi-phy-8998
      https://gitlab.freedesktop.org/lumag/msm/-/commit/8886def25eef
[2/6] dt-bindings: display/msm: hdmi: add qcom,hdmi-tx-8998
      https://gitlab.freedesktop.org/lumag/msm/-/commit/656810411b1d
[3/6] drm/msm/hdmi: add "qcom,hdmi-tx-8998" compatible
      https://gitlab.freedesktop.org/lumag/msm/-/commit/a61eb17f40e8
[4/6] drm/msm: add msm8998 hdmi phy/pll support
      https://gitlab.freedesktop.org/lumag/msm/-/commit/caedbf17c48d

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov at linaro.org>


From frieder.schrempf at kontron.de  Thu Sep  5 00:30:44 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Thu, 5 Sep 2024 09:30:44 +0200
Subject: [PATCH V6 4/5] phy: freescale: fsl-samsung-hdmi: Use closest
 divider
In-Reply-To: <20240904233100.114611-5-aford173@gmail.com>
References: <20240904233100.114611-1-aford173@gmail.com>
 <20240904233100.114611-5-aford173@gmail.com>
Message-ID: <d99018f8-09a6-49eb-a054-e8605cb169ce@kontron.de>

On 05.09.24 1:30 AM, Adam Ford wrote:
> Currently, if the clock values cannot be set to the exact rate,
> the round_rate and set_rate functions use the closest value found in
> the look-up-table.  In preparation of removing values from the LUT
> that can be calculated evenly with the integer calculator, it's
> necessary to ensure to check both the look-up-table and the integer
> divider clock values to get the closest values to the requested
> value.  It does this by measuring the difference between the
> requested clock value and the closest value in both integer divider
> calucator and the fractional clock look-up-table.
> 
> Which ever has the smallest difference between them is returned as
> the cloesest rate.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Signed-off-by: Dominique Martinet <dominique.martinet at atmark-techno.com>

Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>


From frieder.schrempf at kontron.de  Thu Sep  5 00:49:29 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Thu, 5 Sep 2024 09:49:29 +0200
Subject: [PATCH V6 0/5] phy: freescale: fsl-samsung-hdmi: Expand phy clock
 options
In-Reply-To: <20240904233100.114611-1-aford173@gmail.com>
References: <20240904233100.114611-1-aford173@gmail.com>
Message-ID: <0f9c3794-6bb4-41fa-8bc6-c00ecaf506a1@kontron.de>

On 05.09.24 1:30 AM, Adam Ford wrote:
> Currently, there is a look-up-table to describe all the clock options the HDMI PHY
> can use.  Some of these entries in the LUT are using a fractional divider which does
> not have a well documented algorithm for determinging values, but the the integer
> divider can use an algorithm to calculate the integer divder values dynamically
> beyond those listed in the LUT and also duplicates some of the entries.
> 
> The first two patches do not do anything functionally other than simplify
> some of the register accesses and de-duplicates some of the register look-ups.
> 
> The third patch adds support for the integer divider and uses it whenever the
> clock request is an exact match.  Otherwise, it will use the LUT as before.
> The rouding is still based on the LUT if the integer clock isn't an exact match.
> 
> The forth patch updates thes set_rate and round_rate functions to use either
> the fractional clock LUT or the the integer divder mechanism to determine
> which ever clock rate might be closest match.
> 
> The last patch removes the integer divider entries from the LUT since by then
> it'll be comparing both the integer divider calculator and the closest value
> in the LUT.
> 
> In my testing with a AOC 4K monitor, I was able to add 4 entries in my modetest
> table.  I do not have an HDMI analyzer, so I just used my monitor to determine
> if this series worked.

So I tested this series and it works fine. With Dominique's patch to
allow for 0.5% deviation for the clock, all the 24 modes of my monitor
and 30 out of 42 modes of my HDMI grabber are working now.

I still have some issues with LCDIF underrun errors on modeswitch with
v6.11-rc6 but these are unrelated to this series.

Thanks Adam and Dominique for the great work!


From dsimic at manjaro.org  Thu Sep  5 01:28:21 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Thu,  5 Sep 2024 10:28:21 +0200
Subject: [PATCH v3 0/3] Improve error handling in Rockchip Inno USB 2.0 PHY driver
Message-ID: <cover.1725524802.git.dsimic@manjaro.org>

This is a small series that improves error handling in the probe path
of the Rockchip Innosilicon USB 2.0 PHY driver, by returning the actual
error code in one place and by using dev_err_probe() properly in multiple
places.  It also performs a bunch of small, rather trivial code cleanups,
to make the code neater and a bit easier to read.

Changes in v3:
  - Collected Reviewed-by tags from Heiko for patches 1/3 and 2/3
  - Brought back one empty line as a separator of dissimilar operations
    in patch 1/3, as suggested by Heiko [2]
  - Dropped one backward conversion of dev_err_probe() to dev_err() in
    patch 3/3, as suggested by Heiko, [3] and adjusted the summary and
    description of patch 3/3 accordingly

Changes in v2:
  - Expanded into a small series, after a suggestion from Heiko [1] to
    use dev_err_probe(), because it all happens in the probe path

Link to v2: https://lore.kernel.org/linux-phy/cover.1724225528.git.dsimic at manjaro.org/T/#u
Link to v1: https://lore.kernel.org/linux-phy/5fa7796d71e2f46344e972bc98a54539f55b6109.1723551599.git.dsimic at manjaro.org/T/#u

[1] https://lore.kernel.org/linux-phy/4927264.xgNZFEDtJV at diego/
[2] https://lore.kernel.org/linux-phy/5307900.6fTUFtlzNn at diego/
[3] https://lore.kernel.org/linux-phy/6073817.31tnzDBltd at diego/

Dragan Simic (3):
  phy: phy-rockchip-inno-usb2: Perform trivial code cleanups
  phy: phy-rockchip-inno-usb2: Handle failed extcon allocation better
  phy: phy-rockchip-inno-usb2: Use dev_err_probe() in the probe path

 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 56 +++++++------------
 1 file changed, 21 insertions(+), 35 deletions(-)



From dsimic at manjaro.org  Thu Sep  5 01:28:22 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Thu,  5 Sep 2024 10:28:22 +0200
Subject: [PATCH v3 1/3] phy: phy-rockchip-inno-usb2: Perform trivial code cleanups
In-Reply-To: <cover.1725524802.git.dsimic@manjaro.org>
References: <cover.1725524802.git.dsimic@manjaro.org>
Message-ID: <adce7309f6fd9e1191c53bab552a8531d1a71216.1725524802.git.dsimic@manjaro.org>

Perform a few trivial code cleanups, e.g. to obey the reverse Christmas tree
rule, to avoid use of "{ ... }" code blocks where they aren't really needed,
or to avoid line wrapping by using the 100-column width better.

No intended functional changes are introduced by these code cleanups.

Reviewed-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Dragan Simic <dsimic at manjaro.org>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 26 +++++++------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 4f71373ae6e1..03b772200fed 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -418,9 +418,9 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
 
 static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
 {
-	int ret;
 	struct device_node *node = rphy->dev->of_node;
 	struct extcon_dev *edev;
+	int ret;
 
 	if (of_property_read_bool(node, "extcon")) {
 		edev = extcon_get_edev_by_phandle(rphy->dev, 0);
@@ -1327,21 +1327,19 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 	struct rockchip_usb2phy *rphy;
 	const struct rockchip_usb2phy_cfg *phy_cfgs;
 	unsigned int reg;
-	int index, ret;
+	int index = 0, ret;
 
 	rphy = devm_kzalloc(dev, sizeof(*rphy), GFP_KERNEL);
 	if (!rphy)
 		return -ENOMEM;
 
 	if (!dev->parent || !dev->parent->of_node) {
 		rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf");
 		if (IS_ERR(rphy->grf)) {
 			dev_err(dev, "failed to locate usbgrf\n");
 			return PTR_ERR(rphy->grf);
 		}
-	}
-
-	else {
+	} else {
 		rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
 		if (IS_ERR(rphy->grf))
 			return PTR_ERR(rphy->grf);
@@ -1358,16 +1356,14 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 	}
 
 	if (of_property_read_u32_index(np, "reg", 0, &reg)) {
-		dev_err(dev, "the reg property is not assigned in %pOFn node\n",
-			np);
+		dev_err(dev, "the reg property is not assigned in %pOFn node\n", np);
 		return -EINVAL;
 	}
 
 	/* support address_cells=2 */
 	if (of_property_count_u32_elems(np, "reg") > 2 && reg == 0) {
 		if (of_property_read_u32_index(np, "reg", 1, &reg)) {
-			dev_err(dev, "the reg property is not assigned in %pOFn node\n",
-				np);
+			dev_err(dev, "the reg property is not assigned in %pOFn node\n", np);
 			return -EINVAL;
 		}
 	}
@@ -1386,8 +1382,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	/* find out a proper config which can be matched with dt. */
-	index = 0;
+	/* find a proper config that can be matched with the DT */
 	do {
 		if (phy_cfgs[index].reg == reg) {
 			rphy->phy_cfg = &phy_cfgs[index];
@@ -1407,10 +1402,9 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 		return PTR_ERR(rphy->phy_reset);
 
 	rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk");
-	if (IS_ERR(rphy->clk)) {
+	if (IS_ERR(rphy->clk))
 		return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk),
 				     "failed to get phyclk\n");
-	}
 
 	ret = rockchip_usb2phy_clk480m_register(rphy);
 	if (ret) {
@@ -1446,13 +1440,11 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 
 		/* initialize otg/host port separately */
 		if (of_node_name_eq(child_np, "host-port")) {
-			ret = rockchip_usb2phy_host_port_init(rphy, rport,
-							      child_np);
+			ret = rockchip_usb2phy_host_port_init(rphy, rport, child_np);
 			if (ret)
 				goto put_child;
 		} else {
-			ret = rockchip_usb2phy_otg_port_init(rphy, rport,
-							     child_np);
+			ret = rockchip_usb2phy_otg_port_init(rphy, rport, child_np);
 			if (ret)
 				goto put_child;
 		}


From dsimic at manjaro.org  Thu Sep  5 01:28:23 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Thu,  5 Sep 2024 10:28:23 +0200
Subject: [PATCH v3 2/3] phy: phy-rockchip-inno-usb2: Handle failed extcon allocation better
In-Reply-To: <cover.1725524802.git.dsimic@manjaro.org>
References: <cover.1725524802.git.dsimic@manjaro.org>
Message-ID: <cc4995aa3e569be6bc23ca126b41fba82d50eeee.1725524802.git.dsimic@manjaro.org>

Return the actual error code upon failure to allocate extcon device, instead
of hardcoding -ENOMEM.  Use dev_err_probe() to also log appropriate messages,
which is fine because the containing function is used in the probe path.

Helped-by: Heiko Stubner <heiko at sntech.de>
Reviewed-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Dragan Simic <dsimic at manjaro.org>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 03b772200fed..cf6b67dd9f10 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -435,7 +435,8 @@ static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
 						rockchip_usb2phy_extcon_cable);
 
 		if (IS_ERR(edev))
-			return -ENOMEM;
+			return dev_err_probe(rphy->dev, PTR_ERR(edev),
+					     "failed to allocate extcon device\n");
 
 		ret = devm_extcon_dev_register(rphy->dev, edev);
 		if (ret) {


From dsimic at manjaro.org  Thu Sep  5 01:28:24 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Thu,  5 Sep 2024 10:28:24 +0200
Subject: [PATCH v3 3/3] phy: phy-rockchip-inno-usb2: Use dev_err_probe() in the probe path
In-Reply-To: <cover.1725524802.git.dsimic@manjaro.org>
References: <cover.1725524802.git.dsimic@manjaro.org>
Message-ID: <d4ccd9fc278fb46ea868406bf77811ee507f0e4e.1725524803.git.dsimic@manjaro.org>

Improve error handling in the probe path by using function dev_err_probe()
instead of function dev_err(), where appropriate.

Signed-off-by: Dragan Simic <dsimic at manjaro.org>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 27 +++++++------------
 1 file changed, 10 insertions(+), 17 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index cf6b67dd9f10..6e5214862b8a 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -424,25 +424,22 @@ static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
 
 	if (of_property_read_bool(node, "extcon")) {
 		edev = extcon_get_edev_by_phandle(rphy->dev, 0);
-		if (IS_ERR(edev)) {
-			if (PTR_ERR(edev) != -EPROBE_DEFER)
-				dev_err(rphy->dev, "Invalid or missing extcon\n");
-			return PTR_ERR(edev);
-		}
+		if (IS_ERR(edev))
+			return dev_err_probe(rphy->dev, PTR_ERR(edev),
+					     "invalid or missing extcon\n");
 	} else {
 		/* Initialize extcon device */
 		edev = devm_extcon_dev_allocate(rphy->dev,
 						rockchip_usb2phy_extcon_cable);
 
 		if (IS_ERR(edev))
 			return dev_err_probe(rphy->dev, PTR_ERR(edev),
 					     "failed to allocate extcon device\n");
 
 		ret = devm_extcon_dev_register(rphy->dev, edev);
-		if (ret) {
-			dev_err(rphy->dev, "failed to register extcon device\n");
-			return ret;
-		}
+		if (ret)
+			return dev_err_probe(rphy->dev, ret,
+					     "failed to register extcon device\n");
 	}
 
 	rphy->edev = edev;
@@ -1408,10 +1405,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 				     "failed to get phyclk\n");
 
 	ret = rockchip_usb2phy_clk480m_register(rphy);
-	if (ret) {
-		dev_err(dev, "failed to register 480m output clock\n");
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to register 480m output clock\n");
 
 	if (rphy->phy_cfg->phy_tuning) {
 		ret = rphy->phy_cfg->phy_tuning(rphy);
@@ -1431,8 +1426,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 
 		phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops);
 		if (IS_ERR(phy)) {
-			dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
-			ret = PTR_ERR(phy);
+			ret = dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
 			goto put_child;
 		}
 
@@ -1467,8 +1461,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 						"rockchip_usb2phy",
 						rphy);
 		if (ret) {
-			dev_err(rphy->dev,
-				"failed to request usb2phy irq handle\n");
+			dev_err_probe(rphy->dev, ret, "failed to request usb2phy irq handle\n");
 			goto put_child;
 		}
 	}


From heiko at sntech.de  Thu Sep  5 02:16:08 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 05 Sep 2024 11:16:08 +0200
Subject: [PATCH v3 3/3] phy: phy-rockchip-inno-usb2: Use dev_err_probe() in the
 probe path
In-Reply-To: <d4ccd9fc278fb46ea868406bf77811ee507f0e4e.1725524803.git.dsimic@manjaro.org>
References: <cover.1725524802.git.dsimic@manjaro.org>
 <d4ccd9fc278fb46ea868406bf77811ee507f0e4e.1725524803.git.dsimic@manjaro.org>
Message-ID: <3681742.qqrk5fENW1@diego>

Am Donnerstag, 5. September 2024, 10:28:24 CEST schrieb Dragan Simic:
> Improve error handling in the probe path by using function dev_err_probe()
> instead of function dev_err(), where appropriate.
> 
> Signed-off-by: Dragan Simic <dsimic at manjaro.org>

Reviewed-by: Heiko Stuebner <heiko at sntech.de>




From konradybcio at kernel.org  Thu Sep  5 04:30:49 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Thu, 5 Sep 2024 13:30:49 +0200
Subject: [PATCH 06/19] dt-bindings: power: rpmpd: Add QCS8300 power
 domains
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-6-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
 <20240904-qcs8300_initial_dtsi-v1-6-d0ea9afdc007@quicinc.com>
Message-ID: <d5e338fe-bd38-49f7-b69f-fc27f9f87495@kernel.org>

On 4.09.2024 10:33 AM, Jingyi Wang wrote:
> From: Shazad Hussain <quic_shazhuss at quicinc.com>
> 
> Add compatible and constants for the power domains exposed by the RPMH
> in the Qualcomm QCS8300 platform.
> 
> Signed-off-by: Shazad Hussain <quic_shazhuss at quicinc.com>
> Signed-off-by: Tingguo Cheng <quic_tingguoc at quicinc.com>
> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
> ---
>  .../devicetree/bindings/power/qcom,rpmpd.yaml         |  1 +
>  include/dt-bindings/power/qcom-rpmpd.h                | 19 +++++++++++++++++++
>  2 files changed, 20 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
> index 929b7ef9c1bc..be1a9cb71a9b 100644
> --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
> +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
> @@ -32,6 +32,7 @@ properties:
>            - qcom,msm8998-rpmpd
>            - qcom,qcm2290-rpmpd
>            - qcom,qcs404-rpmpd
> +          - qcom,qcs8300-rpmhpd
>            - qcom,qdu1000-rpmhpd
>            - qcom,qm215-rpmpd
>            - qcom,sa8155p-rpmhpd
> diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h
> index 608087fb9a3d..7dd7b9ebc480 100644
> --- a/include/dt-bindings/power/qcom-rpmpd.h
> +++ b/include/dt-bindings/power/qcom-rpmpd.h
> @@ -4,6 +4,25 @@
>  #ifndef _DT_BINDINGS_POWER_QCOM_RPMPD_H
>  #define _DT_BINDINGS_POWER_QCOM_RPMPD_H
>  
> +/* QCS8300 Power Domain Indexes */
> +#define QCS8300_CX	0
> +#define QCS8300_CX_AO	1
> +#define QCS8300_DDR	2
> +#define QCS8300_EBI	3
> +#define QCS8300_GFX	4
> +#define QCS8300_LCX	5
> +#define QCS8300_LMX	6
> +#define QCS8300_MMCX	7
> +#define QCS8300_MMCX_AO	8
> +#define QCS8300_MSS	9
> +#define QCS8300_MX	10
> +#define QCS8300_MX_AO	11
> +#define QCS8300_MXC	12
> +#define QCS8300_MXC_AO	13
> +#define QCS8300_NSP0	14
> +#define QCS8300_NSP1	15
> +#define QCS8300_XO	16

Some time ago we moved RPM*h*pd to common defines.. we should
definitely do the same here. Please reuse the RPMPD_xxx definitions
from [1] and credit Rohit in the commit message, as he did some
processing on that to make sure they're ordered based on usage

Konrad

[1] https://lore.kernel.org/all/1688647793-20950-2-git-send-email-quic_rohiagar at quicinc.com/


From konradybcio at kernel.org  Thu Sep  5 04:31:56 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Thu, 5 Sep 2024 13:31:56 +0200
Subject: [PATCH 06/19] dt-bindings: power: rpmpd: Add QCS8300 power
 domains
In-Reply-To: <d5e338fe-bd38-49f7-b69f-fc27f9f87495@kernel.org>
References: <20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007@quicinc.com>
 <20240904-qcs8300_initial_dtsi-v1-6-d0ea9afdc007@quicinc.com>
 <d5e338fe-bd38-49f7-b69f-fc27f9f87495@kernel.org>
Message-ID: <8ad6d902-8d19-49a5-b12d-d0d8b0b17cb6@kernel.org>

On 5.09.2024 1:30 PM, Konrad Dybcio wrote:
> On 4.09.2024 10:33 AM, Jingyi Wang wrote:
>> From: Shazad Hussain <quic_shazhuss at quicinc.com>
>>
>> Add compatible and constants for the power domains exposed by the RPMH
>> in the Qualcomm QCS8300 platform.
>>
>> Signed-off-by: Shazad Hussain <quic_shazhuss at quicinc.com>
>> Signed-off-by: Tingguo Cheng <quic_tingguoc at quicinc.com>
>> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
>> ---
>>  .../devicetree/bindings/power/qcom,rpmpd.yaml         |  1 +
>>  include/dt-bindings/power/qcom-rpmpd.h                | 19 +++++++++++++++++++
>>  2 files changed, 20 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
>> index 929b7ef9c1bc..be1a9cb71a9b 100644
>> --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
>> +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
>> @@ -32,6 +32,7 @@ properties:
>>            - qcom,msm8998-rpmpd
>>            - qcom,qcm2290-rpmpd
>>            - qcom,qcs404-rpmpd
>> +          - qcom,qcs8300-rpmhpd
>>            - qcom,qdu1000-rpmhpd
>>            - qcom,qm215-rpmpd
>>            - qcom,sa8155p-rpmhpd
>> diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h
>> index 608087fb9a3d..7dd7b9ebc480 100644
>> --- a/include/dt-bindings/power/qcom-rpmpd.h
>> +++ b/include/dt-bindings/power/qcom-rpmpd.h
>> @@ -4,6 +4,25 @@
>>  #ifndef _DT_BINDINGS_POWER_QCOM_RPMPD_H
>>  #define _DT_BINDINGS_POWER_QCOM_RPMPD_H
>>  
>> +/* QCS8300 Power Domain Indexes */
>> +#define QCS8300_CX	0
>> +#define QCS8300_CX_AO	1
>> +#define QCS8300_DDR	2
>> +#define QCS8300_EBI	3
>> +#define QCS8300_GFX	4
>> +#define QCS8300_LCX	5
>> +#define QCS8300_LMX	6
>> +#define QCS8300_MMCX	7
>> +#define QCS8300_MMCX_AO	8
>> +#define QCS8300_MSS	9
>> +#define QCS8300_MX	10
>> +#define QCS8300_MX_AO	11
>> +#define QCS8300_MXC	12
>> +#define QCS8300_MXC_AO	13
>> +#define QCS8300_NSP0	14
>> +#define QCS8300_NSP1	15
>> +#define QCS8300_XO	16
> 
> Some time ago we moved RPM*h*pd to common defines.. we should
> definitely do the same here. Please reuse the RPMPD_xxx definitions
> from [1] and credit Rohit in the commit message, as he did some
> processing on that to make sure they're ordered based on usage

Oh no, this is actually rpmhpd... drop this patch and use RPMHPD_x
from include/dt-bindings/power/qcom,rpmhpd.h

Konrad


From aford173 at gmail.com  Thu Sep  5 05:35:42 2024
From: aford173 at gmail.com (Adam Ford)
Date: Thu, 5 Sep 2024 07:35:42 -0500
Subject: [PATCH V6 0/5] phy: freescale: fsl-samsung-hdmi: Expand phy clock options
In-Reply-To: <0f9c3794-6bb4-41fa-8bc6-c00ecaf506a1@kontron.de>
References: <20240904233100.114611-1-aford173@gmail.com> <0f9c3794-6bb4-41fa-8bc6-c00ecaf506a1@kontron.de>
Message-ID: <CAHCN7xK_chbt3t2YkHRLmu+5wNg7KpDuJ0esLAMOav-2w5E4Uw@mail.gmail.com>

On Thu, Sep 5, 2024 at 2:49?AM Frieder Schrempf
<frieder.schrempf at kontron.de> wrote:
>
> On 05.09.24 1:30 AM, Adam Ford wrote:
> > Currently, there is a look-up-table to describe all the clock options the HDMI PHY
> > can use.  Some of these entries in the LUT are using a fractional divider which does
> > not have a well documented algorithm for determinging values, but the the integer
> > divider can use an algorithm to calculate the integer divder values dynamically
> > beyond those listed in the LUT and also duplicates some of the entries.
> >
> > The first two patches do not do anything functionally other than simplify
> > some of the register accesses and de-duplicates some of the register look-ups.
> >
> > The third patch adds support for the integer divider and uses it whenever the
> > clock request is an exact match.  Otherwise, it will use the LUT as before.
> > The rouding is still based on the LUT if the integer clock isn't an exact match.
> >
> > The forth patch updates thes set_rate and round_rate functions to use either
> > the fractional clock LUT or the the integer divder mechanism to determine
> > which ever clock rate might be closest match.
> >
> > The last patch removes the integer divider entries from the LUT since by then
> > it'll be comparing both the integer divider calculator and the closest value
> > in the LUT.
> >
> > In my testing with a AOC 4K monitor, I was able to add 4 entries in my modetest
> > table.  I do not have an HDMI analyzer, so I just used my monitor to determine
> > if this series worked.
>
> So I tested this series and it works fine. With Dominique's patch to
> allow for 0.5% deviation for the clock, all the 24 modes of my monitor
> and 30 out of 42 modes of my HDMI grabber are working now.
>
> I still have some issues with LCDIF underrun errors on modeswitch with
> v6.11-rc6 but these are unrelated to this series.

I was comparing the LCDIF driver from the NXP downstream and the
mainline, and I noticed the panic threshold values are different in
the NXP downstream for the LCDIF3 which generates the video for the
HDMI.

The downstream threshold states the default low value is 1/3 and the
default high value is 2/3
It appears the mainline matches these values [1].
However, there is an option to override the defaults and change the
values to 1/2 and 3/4.  I don't really understand what these values
do, but it might be worth some investigation to see if playing with
these values helps or not.  The notes in both versions state the panic
isn't designed to trigger an interrupt, but to get the Noc and QoS
modules to handle it.

Either way, it's unrelated to this patch, but my monitor doesn't
always sync values from the LUT, but sometimes it does, but I can't
tell if we have an underflow or not.

adam

[1] - https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/gpu/drm/mxsfb/lcdif_kms.c?h=next-20240905#n350

>
> Thanks Adam and Dominique for the great work!

I enjoy puzzles.  Reading through the tables and looking for patterns
was fun.  I did spend some time trying to understand the fractional
divider stuff, but I didn't make much progress.

adam


From frieder.schrempf at kontron.de  Thu Sep  5 05:43:51 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Thu, 5 Sep 2024 14:43:51 +0200
Subject: [PATCH V6 0/5] phy: freescale: fsl-samsung-hdmi: Expand phy clock
 options
In-Reply-To: <CAHCN7xK_chbt3t2YkHRLmu+5wNg7KpDuJ0esLAMOav-2w5E4Uw@mail.gmail.com>
References: <20240904233100.114611-1-aford173@gmail.com>
 <0f9c3794-6bb4-41fa-8bc6-c00ecaf506a1@kontron.de>
 <CAHCN7xK_chbt3t2YkHRLmu+5wNg7KpDuJ0esLAMOav-2w5E4Uw@mail.gmail.com>
Message-ID: <3ccfb490-4924-47d9-ada3-22af95de8714@kontron.de>

On 05.09.24 2:35 PM, Adam Ford wrote:
> On Thu, Sep 5, 2024 at 2:49?AM Frieder Schrempf
> <frieder.schrempf at kontron.de> wrote:
>>
>> On 05.09.24 1:30 AM, Adam Ford wrote:
>>> Currently, there is a look-up-table to describe all the clock options the HDMI PHY
>>> can use.  Some of these entries in the LUT are using a fractional divider which does
>>> not have a well documented algorithm for determinging values, but the the integer
>>> divider can use an algorithm to calculate the integer divder values dynamically
>>> beyond those listed in the LUT and also duplicates some of the entries.
>>>
>>> The first two patches do not do anything functionally other than simplify
>>> some of the register accesses and de-duplicates some of the register look-ups.
>>>
>>> The third patch adds support for the integer divider and uses it whenever the
>>> clock request is an exact match.  Otherwise, it will use the LUT as before.
>>> The rouding is still based on the LUT if the integer clock isn't an exact match.
>>>
>>> The forth patch updates thes set_rate and round_rate functions to use either
>>> the fractional clock LUT or the the integer divder mechanism to determine
>>> which ever clock rate might be closest match.
>>>
>>> The last patch removes the integer divider entries from the LUT since by then
>>> it'll be comparing both the integer divider calculator and the closest value
>>> in the LUT.
>>>
>>> In my testing with a AOC 4K monitor, I was able to add 4 entries in my modetest
>>> table.  I do not have an HDMI analyzer, so I just used my monitor to determine
>>> if this series worked.
>>
>> So I tested this series and it works fine. With Dominique's patch to
>> allow for 0.5% deviation for the clock, all the 24 modes of my monitor
>> and 30 out of 42 modes of my HDMI grabber are working now.
>>
>> I still have some issues with LCDIF underrun errors on modeswitch with
>> v6.11-rc6 but these are unrelated to this series.
> 
> I was comparing the LCDIF driver from the NXP downstream and the
> mainline, and I noticed the panic threshold values are different in
> the NXP downstream for the LCDIF3 which generates the video for the
> HDMI.
> 
> The downstream threshold states the default low value is 1/3 and the
> default high value is 2/3
> It appears the mainline matches these values [1].
> However, there is an option to override the defaults and change the
> values to 1/2 and 3/4.  I don't really understand what these values
> do, but it might be worth some investigation to see if playing with
> these values helps or not.  The notes in both versions state the panic
> isn't designed to trigger an interrupt, but to get the Noc and QoS
> modules to handle it.

I will try that. Although I doubt that it is related to the thresholds.
This should be relevant in cases where bus priorities play some role
(high load, conflicts with other peripherals, etc.).

In my case the target is basically idle and other peripherals are not
used. Also it happens only when switching modes or turning on/off.

> 
> Either way, it's unrelated to this patch, but my monitor doesn't
> always sync values from the LUT, but sometimes it does, but I can't
> tell if we have an underflow or not.

You can check by reading register 0x32fc6024 and see if the second bit
(UNDERRUN) is set.

> 
> adam
> 
> [1] - https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/gpu/drm/mxsfb/lcdif_kms.c?h=next-20240905#n350
> 
>>
>> Thanks Adam and Dominique for the great work!
> 
> I enjoy puzzles.  Reading through the tables and looking for patterns
> was fun.  I did spend some time trying to understand the fractional
> divider stuff, but I didn't make much progress.

I tried myself and I made some further progress today. But I'm not quite
there, yet. The goal would be to be able to calculate some more table
entries. Let's see.


From konradybcio at kernel.org  Thu Sep  5 06:47:35 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Thu, 5 Sep 2024 15:47:35 +0200
Subject: [PATCH V3 3/6] phy: qcom: Introduce PCIe UNIPHY 28LP driver
In-Reply-To: <20240830081132.4016860-4-quic_srichara@quicinc.com>
References: <20240830081132.4016860-1-quic_srichara@quicinc.com>
 <20240830081132.4016860-4-quic_srichara@quicinc.com>
Message-ID: <bf114807-c56c-4209-ab26-9e90ac00cedf@kernel.org>

On 30.08.2024 10:11 AM, Sricharan R wrote:
> From: Nitheesh Sekar <quic_nsekar at quicinc.com>
> 
> Add Qualcomm PCIe UNIPHY 28LP driver support present
> in Qualcomm IPQ5018 SoC and the phy init sequence.
> 
> Signed-off-by: Nitheesh Sekar <quic_nsekar at quicinc.com>
> Signed-off-by: Sricharan Ramabadhran <quic_srichara at quicinc.com>
> ---

[...]

> +static const struct qcom_uniphy_pcie_data ipq5018_2x1_data = {
> +	.lanes		= 1,
> +	.lane_offset	= 0x800,
> +	.phy_type	= PHY_TYPE_PCIE_GEN2,
> +	.init_seq	= ipq5018_regs,
> +	.init_seq_num	= ARRAY_SIZE(ipq5018_regs),
> +};
> +
> +static const struct qcom_uniphy_pcie_data ipq5018_2x2_data = {
> +	.lanes		= 2,
> +	.lane_offset	= 0x800,
> +	.phy_type	= PHY_TYPE_PCIE_GEN2,
> +	.init_seq	= ipq5018_regs,
> +	.init_seq_num	= ARRAY_SIZE(ipq5018_regs),
> +};

As krzk suggested, the difference is just num-lanes

[...]

> +static int qcom_uniphy_pcie_power_off(struct phy *x)
> +{
> +	struct qcom_uniphy_pcie *phy = phy_get_drvdata(x);
> +	
> +	reset_control_assert(phy->resets);

Is the reset line supposed to be kept asserted?

[...]

> +MODULE_LICENSE("Dual BSD/GPL");

Was that intended?

Konrad


From mgonzalez at freebox.fr  Thu Sep  5 09:14:15 2024
From: mgonzalez at freebox.fr (Marc Gonzalez)
Date: Thu, 5 Sep 2024 18:14:15 +0200
Subject: [PATCH v7 0/6] HDMI TX support in msm8998
In-Reply-To: <172550712143.3299484.1580127137460046609.b4-ty@linaro.org>
References: <20240724-hdmi-tx-v7-0-e44a20553464@freebox.fr>
 <172550712143.3299484.1580127137460046609.b4-ty@linaro.org>
Message-ID: <747218ab-86a1-4308-b34a-98064ccdac30@freebox.fr>

On 05/09/2024 05:33, Dmitry Baryshkov wrote:

> On Wed, 24 Jul 2024 17:01:33 +0200, Marc Gonzalez wrote:
>
>> DT bits required for HDMI TX support in qcom APQ8098 (MSM8998 cousin)
> 
> Applied, thanks!
> 
> [1/6] dt-bindings: phy: add qcom,hdmi-phy-8998
>       https://gitlab.freedesktop.org/lumag/msm/-/commit/8886def25eef
> [2/6] dt-bindings: display/msm: hdmi: add qcom,hdmi-tx-8998
>       https://gitlab.freedesktop.org/lumag/msm/-/commit/656810411b1d
> [3/6] drm/msm/hdmi: add "qcom,hdmi-tx-8998" compatible
>       https://gitlab.freedesktop.org/lumag/msm/-/commit/a61eb17f40e8
> [4/6] drm/msm: add msm8998 hdmi phy/pll support
>       https://gitlab.freedesktop.org/lumag/msm/-/commit/caedbf17c48d

Hello Bjorn,

Now that the binding & driver parts have been merged,
(Thanks, Dmitry! And thanks to all reviewers)
am I right to assume that you are supposed to pick up
patches 5 & 6 for the msm8998 DTSI?
(Hopefully in time for 6.12-rc1)

Regards



From dominique.martinet at atmark-techno.com  Thu Sep  5 17:26:36 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Fri, 6 Sep 2024 09:26:36 +0900
Subject: [PATCH V6 4/5] phy: freescale: fsl-samsung-hdmi: Use closest
 divider
In-Reply-To: <20240904233100.114611-5-aford173@gmail.com>
References: <20240904233100.114611-1-aford173@gmail.com>
 <20240904233100.114611-5-aford173@gmail.com>
Message-ID: <ZtpMPCHBnEgtkBWp@atmark-techno.com>


(sorry I meant to send this yesterday but I'm being forced to adjust my
mail pipeline with work and gmail and it didn't go out -- trying
again. Sorry if it actually did go through. Hopefully I didn't misfire
anything else yesterday...)

Adam Ford wrote on Wed, Sep 04, 2024 at 06:30:32PM -0500:
> Currently, if the clock values cannot be set to the exact rate,
> the round_rate and set_rate functions use the closest value found in
> the look-up-table.  In preparation of removing values from the LUT
> that can be calculated evenly with the integer calculator, it's
> necessary to ensure to check both the look-up-table and the integer
> divider clock values to get the closest values to the requested
> value.  It does this by measuring the difference between the
> requested clock value and the closest value in both integer divider
> calucator and the fractional clock look-up-table.
> 
> Which ever has the smallest difference between them is returned as
> the cloesest rate.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Signed-off-by: Dominique Martinet <dominique.martinet at atmark-techno.com>

b4 (or whatever you're using) probably picked that up from the patch I
included in my reply to this patch, this sob should go away.



> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> index 4b13e386e5ba..9a21dbbf1a82 100644
> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -547,6 +547,16 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
>  	return phy->cur_cfg->pixclk;
>  }
>  
> +static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate,
> +						 u32 int_div_clk, u32 frac_div_clk)
> +{
> +	/* The int_div_clk may be greater than rate, so cast it and use ABS */
> +	if (abs((long)rate - (long)int_div_clk) < (rate - frac_div_clk))

I still think `rate - frac_div_clk` might not always hold in the future
(because there is no intrinsic reason we'd pick the smaller end in case
of inexact match and a future improvement might change this to the
closest value as well), so I'll argue again for having both use abs(),
but at least there's only one place to update if that changes in the
future now so hopefully whoever does this will notice...

> +		return int_div_clk;
> +
> +	return frac_div_clk;
> +}
> +
>  static long phy_clk_round_rate(struct clk_hw *hw,
>  			       unsigned long rate, unsigned long *parent_rate)
>  {
> @@ -563,6 +573,7 @@ static long phy_clk_round_rate(struct clk_hw *hw,
>  	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
>  		if (phy_pll_cfg[i].pixclk <= rate)
>  			break;
> +

(unrelated)

>  	/* If the rate is an exact match, return it now */
>  	if (rate == phy_pll_cfg[i].pixclk)
>  		return phy_pll_cfg[i].pixclk;
> @@ -579,8 +590,7 @@ static long phy_clk_round_rate(struct clk_hw *hw,
>  	if (int_div_clk == rate)
>  		return int_div_clk;
>  
> -	/* Fall back to the closest value in the LUT */
> -	return phy_pll_cfg[i].pixclk;
> +	return fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk, phy_pll_cfg[i].pixclk);
>  }
>  
>  static int phy_clk_set_rate(struct clk_hw *hw,
> @@ -594,27 +604,37 @@ static int phy_clk_set_rate(struct clk_hw *hw,
>  
>  	/* If the integer divider works, just use it */

I found this comment a bit confusing given the current flow as of this
patch. Might make more sense immediately before the if?


>  	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
> +	calculated_phy_pll_cfg.pixclk = int_div_clk;
> +	calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
> +	calculated_phy_pll_cfg.pll_div_regs[1] = m;
> +	calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
> +	phy->cur_cfg = &calculated_phy_pll_cfg;
>  	if (int_div_clk == rate) {
>  		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using integer divider\n");
> -		calculated_phy_pll_cfg.pixclk = int_div_clk;
> -		calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
> -		calculated_phy_pll_cfg.pll_div_regs[1] = m;
> -		calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
> -		/* pll_div_regs 3-6 are fixed and pre-defined already */

nitpick: might want to keep the above comment?

> -		phy->cur_cfg  = &calculated_phy_pll_cfg;
> +		goto done;
>  	} else {
>  		/* Otherwise, search the LUT */
> -		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
> -		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> -			if (phy_pll_cfg[i].pixclk <= rate)
> +		for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--) {
> +			if (phy_pll_cfg[i].pixclk == rate) {
> +				dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");

nitpick: might make sense to print what was picked in case of inexact
match as well, but these are dbg warning so probably fine either way.


overall I find the flow of this function hard to read; it's a bit ugly
flow-wise but jumping in the clock comparison 'if' might help trim this?
(and if we're going out of our way to factor out the diff, maybe the lut
lookup could be as well)

But I'm probably just being overcritical here, it's fine as is if you
pefer your version, just writing down this as an illustration of what I
meant with the above sentence as I'm not sure I was clear -- I'll be
just as happy to consider this series done so we can do more interesting
things :P

{
    u32 int_div_clk, frac_div_clk;
    int i;
    u16 m;
    u8 p, s;
    
    // (I haven't given up on that *5 to move inside this function...)
    int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
    if (int_div_clk == rate)
        goto use_int_clk;

    frac_div_clk = fsl_samsung_hdmi_phy_find_lut(rate, &i);
    // (not convinced that check actually brings much, but it's not like
    // it hurts either)
    if (frac_div_clk == rate)
        goto use_frac_clk;
    
    if (fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk,
                                              frac_div_clk) == int_div_clk) {
use_int_clk:
        dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using integer divider\n");
        calculated_phy_pll_cfg.pixclk = int_div_clk;
        calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
        calculated_phy_pll_cfg.pll_div_regs[1] = m;
        calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
        /* pll_div_regs 3-6 are fixed and pre-defined already */
        phy->cur_cfg  = &calculated_phy_pll_cfg;
    } else {
use_frac_clk:
        dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
        phy->cur_cfg = &phy_pll_cfg[i];
    }
    return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
}

-- 
Dominique


From aford173 at gmail.com  Thu Sep  5 17:57:36 2024
From: aford173 at gmail.com (Adam Ford)
Date: Thu, 5 Sep 2024 19:57:36 -0500
Subject: [PATCH V6 4/5] phy: freescale: fsl-samsung-hdmi: Use closest divider
In-Reply-To: <ZtpMPCHBnEgtkBWp@atmark-techno.com>
References: <20240904233100.114611-1-aford173@gmail.com> <20240904233100.114611-5-aford173@gmail.com>
 <ZtpMPCHBnEgtkBWp@atmark-techno.com>
Message-ID: <CAHCN7xLo1RgkUPTdTpCtKjnT7w=gPDCfe_ZEbKj0joVvLG02Dw@mail.gmail.com>

On Thu, Sep 5, 2024 at 7:26?PM Dominique Martinet
<dominique.martinet at atmark-techno.com> wrote:
>
>
> (sorry I meant to send this yesterday but I'm being forced to adjust my
> mail pipeline with work and gmail and it didn't go out -- trying
> again. Sorry if it actually did go through. Hopefully I didn't misfire
> anything else yesterday...)
>
> Adam Ford wrote on Wed, Sep 04, 2024 at 06:30:32PM -0500:
> > Currently, if the clock values cannot be set to the exact rate,
> > the round_rate and set_rate functions use the closest value found in
> > the look-up-table.  In preparation of removing values from the LUT
> > that can be calculated evenly with the integer calculator, it's
> > necessary to ensure to check both the look-up-table and the integer
> > divider clock values to get the closest values to the requested
> > value.  It does this by measuring the difference between the
> > requested clock value and the closest value in both integer divider
> > calucator and the fractional clock look-up-table.
> >
> > Which ever has the smallest difference between them is returned as
> > the cloesest rate.
> >
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
> > Signed-off-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
>
> b4 (or whatever you're using) probably picked that up from the patch I
> included in my reply to this patch, this sob should go away.
>
For each iteration, I grabbed the patches from patchwork which
contained any s-o-b messages, if present.  I didn't add anything
manually.
>
>
> > diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > index 4b13e386e5ba..9a21dbbf1a82 100644
> > --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > @@ -547,6 +547,16 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
> >       return phy->cur_cfg->pixclk;
> >  }
> >
> > +static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate,
> > +                                              u32 int_div_clk, u32 frac_div_clk)
> > +{
> > +     /* The int_div_clk may be greater than rate, so cast it and use ABS */
> > +     if (abs((long)rate - (long)int_div_clk) < (rate - frac_div_clk))
>
> I still think `rate - frac_div_clk` might not always hold in the future
> (because there is no intrinsic reason we'd pick the smaller end in case
> of inexact match and a future improvement might change this to the
> closest value as well), so I'll argue again for having both use abs(),
> but at least there's only one place to update if that changes in the
> future now so hopefully whoever does this will notice...

I can add the ABS on the fractional divider.  I left it out on purpose
since the LUT table always return a value equal or less, so the extra
ABS seemed like busy work.  However, I can see the argument for being
consistent.

>
> > +             return int_div_clk;
> > +
> > +     return frac_div_clk;
> > +}
> > +
> >  static long phy_clk_round_rate(struct clk_hw *hw,
> >                              unsigned long rate, unsigned long *parent_rate)
> >  {
> > @@ -563,6 +573,7 @@ static long phy_clk_round_rate(struct clk_hw *hw,
> >       for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> >               if (phy_pll_cfg[i].pixclk <= rate)
> >                       break;
> > +
>
> (unrelated)

I don't understand what you're asking here.

>
> >       /* If the rate is an exact match, return it now */
> >       if (rate == phy_pll_cfg[i].pixclk)
> >               return phy_pll_cfg[i].pixclk;
> > @@ -579,8 +590,7 @@ static long phy_clk_round_rate(struct clk_hw *hw,
> >       if (int_div_clk == rate)
> >               return int_div_clk;
> >
> > -     /* Fall back to the closest value in the LUT */
> > -     return phy_pll_cfg[i].pixclk;
> > +     return fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk, phy_pll_cfg[i].pixclk);
> >  }
> >
> >  static int phy_clk_set_rate(struct clk_hw *hw,
> > @@ -594,27 +604,37 @@ static int phy_clk_set_rate(struct clk_hw *hw,
> >
> >       /* If the integer divider works, just use it */
>
> I found this comment a bit confusing given the current flow as of this
> patch. Might make more sense immediately before the if?
>

This code evolved with each iteration, but I didn't necessarily
reorganize the comments.  I can rearrange them.
>
> >       int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
> > +     calculated_phy_pll_cfg.pixclk = int_div_clk;
> > +     calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
> > +     calculated_phy_pll_cfg.pll_div_regs[1] = m;
> > +     calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
> > +     phy->cur_cfg = &calculated_phy_pll_cfg;
> >       if (int_div_clk == rate) {
> >               dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using integer divider\n");
> > -             calculated_phy_pll_cfg.pixclk = int_div_clk;
> > -             calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
> > -             calculated_phy_pll_cfg.pll_div_regs[1] = m;
> > -             calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
> > -             /* pll_div_regs 3-6 are fixed and pre-defined already */
>
> nitpick: might want to keep the above comment?

ok.
>
> > -             phy->cur_cfg  = &calculated_phy_pll_cfg;
> > +             goto done;
> >       } else {
> >               /* Otherwise, search the LUT */
> > -             dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
> > -             for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> > -                     if (phy_pll_cfg[i].pixclk <= rate)
> > +             for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--) {
> > +                     if (phy_pll_cfg[i].pixclk == rate) {
> > +                             dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
>
> nitpick: might make sense to print what was picked in case of inexact
> match as well, but these are dbg warning so probably fine either way.

I can add the actual values returned.

>
>
> overall I find the flow of this function hard to read; it's a bit ugly
> flow-wise but jumping in the clock comparison 'if' might help trim this?
> (and if we're going out of our way to factor out the diff, maybe the lut
> lookup could be as well)
>
> But I'm probably just being overcritical here, it's fine as is if you
> pefer your version, just writing down this as an illustration of what I
> meant with the above sentence as I'm not sure I was clear -- I'll be
> just as happy to consider this series done so we can do more interesting
> things :P

Now I am a bit more confused, because above I got the impression you
were withdrawing your s-o-b, but now it sounds like you want to move
it forward.

It sounded like Frieder was making some progress on understanding a
little more about the fractional divider.

>
> {
>     u32 int_div_clk, frac_div_clk;
>     int i;
>     u16 m;
>     u8 p, s;
>
>     // (I haven't given up on that *5 to move inside this function...)

I wanted to keep the PMS calculator returning the real clock value
since the calculations are based on equation in the ref manual, Fpll =
Fref * M / (P*S)
This way, the calling function can determine if it needs to be
multiplied by 5.  I haven't fully determined how the fractional
calculator determines what frequency it wants for a target frequency,
and using the values for P, M and S from the fractional divider
doesn't seem to always yield 5x like they did for the table entries
using the integer divider.

I am hoping someone from NXP can elaborate, or give us some clues on
how to get better fractional divider values.

>     int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
>     if (int_div_clk == rate)
>         goto use_int_clk;
>
>     frac_div_clk = fsl_samsung_hdmi_phy_find_lut(rate, &i);
>     // (not convinced that check actually brings much, but it's not like
>     // it hurts either)
>     if (frac_div_clk == rate)
>         goto use_frac_clk;
>
>     if (fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk,
>                                               frac_div_clk) == int_div_clk) {
> use_int_clk:
>         dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using integer divider\n");
>         calculated_phy_pll_cfg.pixclk = int_div_clk;
>         calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
>         calculated_phy_pll_cfg.pll_div_regs[1] = m;
>         calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
>         /* pll_div_regs 3-6 are fixed and pre-defined already */
>         phy->cur_cfg  = &calculated_phy_pll_cfg;
>     } else {
> use_frac_clk:
>         dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
>         phy->cur_cfg = &phy_pll_cfg[i];
>     }
>     return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
> }
>
> --
> Dominique


From dominique.martinet at atmark-techno.com  Thu Sep  5 18:54:39 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Fri, 6 Sep 2024 10:54:39 +0900
Subject: [PATCH V6 4/5] phy: freescale: fsl-samsung-hdmi: Use closest
 divider
In-Reply-To: <CAHCN7xLo1RgkUPTdTpCtKjnT7w=gPDCfe_ZEbKj0joVvLG02Dw@mail.gmail.com>
References: <20240904233100.114611-1-aford173@gmail.com>
 <20240904233100.114611-5-aford173@gmail.com>
 <ZtpMPCHBnEgtkBWp@atmark-techno.com>
 <CAHCN7xLo1RgkUPTdTpCtKjnT7w=gPDCfe_ZEbKj0joVvLG02Dw@mail.gmail.com>
Message-ID: <Ztpg3_iE2Dbqb4VT@atmark-techno.com>

Adam Ford wrote on Thu, Sep 05, 2024 at 07:57:36PM -0500:
> > > Signed-off-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
> >
> > b4 (or whatever you're using) probably picked that up from the patch I
> > included in my reply to this patch, this sob should go away.
> >
> For each iteration, I grabbed the patches from patchwork which
> contained any s-o-b messages, if present.  I didn't add anything
> manually.

Yes, I'm just saying the tool got confused - I replied to an earlier
iteration of this patch with a quote of the 0.5% tolerance patch I
properly sent afterwards here:
https://lore.kernel.org/all/ZtaawD3vb8gmnVmO at atmark-techno.com/

And it picked the sob from the patch, that I hadn't intended to be added
as a review -- from my understanding a sob is something you'd add if you
pick the patch through your tree (e.g. I add sob for patches I apply
through the 9p tree I maintain), but not something to give on reviews.
I'll reply to individual patches with reviewed-by/tested-by once this
thread has settled down; I don't have more comments than what I sent
just now, so I think this is almost ready.


> > > +static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate,
> > > +                                              u32 int_div_clk, u32 frac_div_clk)
> > > +{
> > > +     /* The int_div_clk may be greater than rate, so cast it and use ABS */
> > > +     if (abs((long)rate - (long)int_div_clk) < (rate - frac_div_clk))
> >
> > I still think `rate - frac_div_clk` might not always hold in the future
> > (because there is no intrinsic reason we'd pick the smaller end in case
> > of inexact match and a future improvement might change this to the
> > closest value as well), so I'll argue again for having both use abs(),
> > but at least there's only one place to update if that changes in the
> > future now so hopefully whoever does this will notice...
> 
> I can add the ABS on the fractional divider.  I left it out on purpose
> since the LUT table always return a value equal or less, so the extra
> ABS seemed like busy work.  However, I can see the argument for being
> consistent.

Yeah, I agree it's not needed right now; I won't insist on this, just
saying I prefer consistency/future-proofing here.

> > > +             return int_div_clk;
> > > +
> > > +     return frac_div_clk;
> > > +}
> > > +
> > >  static long phy_clk_round_rate(struct clk_hw *hw,
> > >                              unsigned long rate, unsigned long *parent_rate)
> > >  {
> > > @@ -563,6 +573,7 @@ static long phy_clk_round_rate(struct clk_hw *hw,
> > >       for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> > >               if (phy_pll_cfg[i].pixclk <= rate)
> > >                       break;
> > > +
> >
> > (unrelated)
> 
> I don't understand what you're asking here.

This chunk is just adding a blank line that's not related to the rest of
the patch; it's fine, just pointed it out if it wasn't intended.
(these are usually leftovers from tests or something like that)

> > > -             phy->cur_cfg  = &calculated_phy_pll_cfg;
> > > +             goto done;
> > >       } else {
> > >               /* Otherwise, search the LUT */
> > > -             dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
> > > -             for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> > > -                     if (phy_pll_cfg[i].pixclk <= rate)
> > > +             for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--) {
> > > +                     if (phy_pll_cfg[i].pixclk == rate) {
> > > +                             dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
> >
> > nitpick: might make sense to print what was picked in case of inexact
> > match as well, but these are dbg warning so probably fine either way.
> 
> I can add the actual values returned.

Note my argument here wasn't about having the values on this line, it's
that the inexact case (when comparing with
fsl_samsung_hdmi_phy_get_closest_rate) doesn't print either line

(having the values can't hurt for dbg though, I think it could be useful
if you rework this)

> > overall I find the flow of this function hard to read; it's a bit ugly
> > flow-wise but jumping in the clock comparison 'if' might help trim this?
> > (and if we're going out of our way to factor out the diff, maybe the lut
> > lookup could be as well)
> >
> > But I'm probably just being overcritical here, it's fine as is if you
> > pefer your version, just writing down this as an illustration of what I
> > meant with the above sentence as I'm not sure I was clear -- I'll be
> > just as happy to consider this series done so we can do more interesting
> > things :P
> 
> Now I am a bit more confused, because above I got the impression you
> were withdrawing your s-o-b, but now it sounds like you want to move
> it forward.

I don't have any strong opinion here: I generally dislike nitpicking
about form, and value the progress you've done more than fixing the flow
of this function (e.g. this function already is good/progress from what
we have right now, we don't need perfect)

withdrawing my s-o-b doesn't meant I disagree with the patch, I just
hadn't willingly given it. If you don't mind reworking the patch a bit
I'll retest the new version, otherwise I'm fine approving this as is.

> It sounded like Frieder was making some progress on understanding a
> little more about the fractional divider.

That's awesome!
I think we can/want to get this merged first, and we can improve
with fractional divider calculations in a later iteration to get rid of
the LUT altogether; it'll be easier for other users of the chip to go a
step at a time as well if they notice a breakage.

> >     // (I haven't given up on that *5 to move inside this function...)
> 
> I wanted to keep the PMS calculator returning the real clock value
> since the calculations are based on equation in the ref manual, Fpll =
> Fref * M / (P*S)
> This way, the calling function can determine if it needs to be
> multiplied by 5.  I haven't fully determined how the fractional
> calculator determines what frequency it wants for a target frequency,
> and using the values for P, M and S from the fractional divider
> doesn't seem to always yield 5x like they did for the table entries
> using the integer divider.

The way I see it is that 5x is an artifact of the PMS calculation:
the caller doesn't want '5x rate', it wants 'rate', and actually setting
the p/m/s values provided by the function gets us 'rate', so it feels
like that's not the caller should have to worry about.. When we add
fractional divider support then it'll be the calculator's job to
determine if/when it needs that 5x.

But if I understand what you're saying, fsl_samsung_hdmi_phy_find_pms()
is not a pms specific to the NXP chip, but something more general to any
integer divisor that is better kept more generic if it weren't for the
few references to our hardware (e.g. limits on m)?

If so then I guess I can understand your position, I wouldn't go as far
as saying it warrants another level of indirection so I guess it's fine
as is.

(In a similar line of thought, had I implemented this I would have had
the function not return generic p/m/s but return the pll registers
directly -- it took me a moment to check why we were setting regs[2] to
`s-1` and confirming we had s>1...)



Anyway, once again I don't feel like I am in any position to be preachy
about all of this, so I'm fine with this patch as is - please take of it
what you agree with/want to rework and we can leave the rest here as far
as I'm concerned.
-- 
Dominique


From sandor.yu at nxp.com  Thu Sep  5 19:50:08 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Fri, 6 Sep 2024 02:50:08 +0000
Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501
 DP/HDMI driver
In-Reply-To: <20240903-gay-capable-hound-3cbef2@houat>
References: <cover.1719903904.git.Sandor.yu@nxp.com>
 <359914108b879e995d4a39de32a33310009f0fab.1719903904.git.Sandor.yu@nxp.com>
 <20240702-quartz-salamander-of-culture-eec264@houat>
 <PAXPR04MB94480AB0490BBF00D2BA17BBF4932@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <20240903-gay-capable-hound-3cbef2@houat>
Message-ID: <PAXPR04MB9448EF507CB5C18A43239A80F49E2@PAXPR04MB9448.eurprd04.prod.outlook.com>



> 
> On Tue, Sep 03, 2024 at 06:07:25AM GMT, Sandor Yu wrote:
> > Hi Maxime,
> >
> > Thanks for your comments,
> >
> > > -----Original Message-----
> > > From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On Behalf
> > > Of Maxime Ripard
> > > Sent: 2024?7?2? 21:25
> > > To: Sandor Yu <sandor.yu at nxp.com>
> > > Cc: dmitry.baryshkov at linaro.org; andrzej.hajda at intel.com;
> > > neil.armstrong at linaro.org; Laurent Pinchart
> > > <laurent.pinchart at ideasonboard.com>; jonas at kwiboo.se;
> > > jernej.skrabec at gmail.com; airlied at gmail.com; daniel at ffwll.ch;
> > > robh+dt at kernel.org; krzysztof.kozlowski+dt at linaro.org;
> > > shawnguo at kernel.org; s.hauer at pengutronix.de; festevam at gmail.com;
> > > vkoul at kernel.org; dri-devel at lists.freedesktop.org;
> > > devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > > linux-kernel at vger.kernel.org; linux-phy at lists.infradead.org;
> > > kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>; Oliver
> > > Brown <oliver.brown at nxp.com>; alexander.stein at ew.tq-group.com;
> > > sam at ravnborg.org
> > > Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add
> > > MHDP8501 DP/HDMI driver
> > >
> > > Hi,
> > >
> > > There's still the scrambler issue we discussed on v15, but I have
> > > some more comments.
> > >
> > > On Tue, Jul 02, 2024 at 08:22:36PM GMT, Sandor Yu wrote:
> > > > +enum drm_connector_status cdns_mhdp8501_detect(struct
> > > > +cdns_mhdp8501_device *mhdp) {
> > > > +	u8 hpd = 0xf;
> > > > +
> > > > +	hpd = cdns_mhdp8501_read_hpd(mhdp);
> > > > +	if (hpd == 1)
> > > > +		return connector_status_connected;
> > > > +	else if (hpd == 0)
> > > > +		return connector_status_disconnected;
> > > > +
> > > > +	dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n", hpd);
> > > > +	return connector_status_unknown; }
> > > > +
> > > > +static void hotplug_work_func(struct work_struct *work) {
> > > > +	struct cdns_mhdp8501_device *mhdp = container_of(work,
> > > > +						     struct cdns_mhdp8501_device,
> > > > +						     hotplug_work.work);
> > > > +	enum drm_connector_status status =
> cdns_mhdp8501_detect(mhdp);
> > > > +
> > > > +	drm_bridge_hpd_notify(&mhdp->bridge, status);
> > > > +
> > > > +	if (status == connector_status_connected) {
> > > > +		/* Cable connected  */
> > > > +		DRM_INFO("HDMI/DP Cable Plug In\n");
> > > > +		enable_irq(mhdp->irq[IRQ_OUT]);
> > > > +	} else if (status == connector_status_disconnected) {
> > > > +		/* Cable Disconnected  */
> > > > +		DRM_INFO("HDMI/DP Cable Plug Out\n");
> > > > +		enable_irq(mhdp->irq[IRQ_IN]);
> > > > +	}
> > > > +}
> > >
> > > You shouldn't play with the interrupt being enabled here: hotplug
> > > interrupts should always enabled.
> > >
> > > If you can't for some reason, the reason should be documented in your
> driver.
> >
> > iMX8MQ have two HPD interrupters, one for plugout and the other for
> > plugin, because they could not be masked, so we have to enable one and
> disable the other.
> > I will add more comments here.
> 
> Right, but why do you need to enable and disable them? Do you get spurious
> interrupts?

They don't have status registers and cannot be masked. If they are not disabled, 
they will continuously generate interrupts. Therefore, I have to disable one and enable the other.

> 
> > >
> > > > +	/* Mailbox protect for HDMI PHY access */
> > > > +	mutex_lock(&mhdp->mbox_mutex);
> > > > +	ret = phy_init(mhdp->phy);
> > > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > > +	if (ret) {
> > > > +		dev_err(dev, "Failed to initialize PHY: %d\n", ret);
> > > > +		goto clk_disable;
> > > > +	}
> > > > +
> > > > +	/* Mailbox protect for HDMI PHY access */
> > > > +	mutex_lock(&mhdp->mbox_mutex);
> > > > +	ret = phy_set_mode(mhdp->phy, phy_mode);
> > > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > > +	if (ret) {
> > > > +		dev_err(dev, "Failed to configure PHY: %d\n", ret);
> > > > +		goto clk_disable;
> > > > +	}
> > >
> > > Why do you need a shared mutex between the phy and HDMI controller?
> >
> > Both PHY and HDMI controller could access to the HDMI firmware by
> > mailbox, So add mutex to avoid race condition.
> 
> That should be handled at either the phy or mailbox level, not in your hdmi
> driver.
> 
In both HDMI driver and PHY driver, every mailbox access had protected by its owns mutex. 
However, this mutex can only protect each mailbox access within their respective drivers, 
and it cannot provide protection for access between the HDMI and PHY drivers.

The PHY driver only provides two API functions, and these functions are only called in the HDMI driver. 
Therefore, when accessing these functions, we use a mutex to protect them. 
This ensures that mailbox access is protected across different PHY and HDMI drivers.

> > >
> > > > +static enum drm_mode_status
> > > > +cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
> > > > +			       const struct drm_display_mode *mode,
> > > > +			       unsigned long long tmds_rate) {
> > > > +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > > > +	union phy_configure_opts phy_cfg;
> > > > +	int ret;
> > > > +
> > > > +	phy_cfg.hdmi.tmds_char_rate = tmds_rate;
> > > > +
> > > > +	/* Mailbox protect for HDMI PHY access */
> > > > +	mutex_lock(&mhdp->mbox_mutex);
> > > > +	ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
> > > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > > +	if (ret < 0)
> > > > +		return MODE_CLOCK_RANGE;
> > > > +
> > > > +	return MODE_OK;
> > > > +}
> > > > +
> > > > +static enum drm_mode_status
> > > > +cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
> > > > +			    const struct drm_display_info *info,
> > > > +			    const struct drm_display_mode *mode) {
> > > > +	unsigned long long tmds_rate;
> > > > +
> > > > +	/* We don't support double-clocked and Interlaced modes */
> > > > +	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
> > > > +	    mode->flags & DRM_MODE_FLAG_INTERLACE)
> > > > +		return MODE_BAD;
> > > > +
> > > > +	/* MAX support pixel clock rate 594MHz */
> > > > +	if (mode->clock > 594000)
> > > > +		return MODE_CLOCK_HIGH;
> > >
> > > This needs to be in the tmds_char_rate_valid function
> > This clock rate check is covered by function tmds_char_rate_valid() It
> > could be removed if keep function tmds_char_rate_valid() be called by
> mode_valid.
> 
> Yeah, it's not something you should have to duplicate.
> 
> > >
> > > > +	if (mode->hdisplay > 3840)
> > > > +		return MODE_BAD_HVALUE;
> > > > +
> > > > +	if (mode->vdisplay > 2160)
> > > > +		return MODE_BAD_VVALUE;
> > > > +
> > > > +	tmds_rate = mode->clock * 1000ULL;
> > > > +	return cdns_hdmi_tmds_char_rate_valid(bridge, mode, tmds_rate);
> > >
> > > It will already be called by the core so this is redundant.
> >
> > mode_valid function is use to filter the mode list in
> > drm_helper_probe_single_connector_modes(),
> > if function cdns_hdmi_tmds_char_rate_valid() is not called, unsupported
> modes will in mode list.
> 
> It's probably something we should deal with in the core somehow. I'm not
> entirely sure how to reconcile drm_bridge_connector and the hdmi
> framework there, but we should at the very least provide a mode_valid
> helper for bridges.
> 
I agree with that. In fact, I'm a bit confused about the current mode_valid and tmds_char_rate_valid functions.
Ideally, we should find a way to make tmds_char_rate_valid also work for filtering out the mode list, rather than just during atomic_check.

> > >
> > > > +static void cdns_hdmi_bridge_atomic_enable(struct drm_bridge
> *bridge,
> > > > +					   struct drm_bridge_state *old_state) {
> > > > +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > > > +	struct drm_atomic_state *state = old_state->base.state;
> > > > +	struct drm_connector *connector;
> > > > +	struct video_info *video = &mhdp->video_info;
> > > > +	struct drm_crtc_state *crtc_state;
> > > > +	struct drm_connector_state *conn_state;
> > > > +	struct drm_display_mode *mode = &mhdp->mode;
> > > > +	union phy_configure_opts phy_cfg;
> > > > +	int ret;
> > > > +
> > > > +	connector = drm_atomic_get_new_connector_for_encoder(state,
> > > > +							     bridge->encoder);
> > > > +	if (WARN_ON(!connector))
> > > > +		return;
> > > > +
> > > > +	mhdp->curr_conn = connector;
> > > > +
> > > > +	conn_state = drm_atomic_get_new_connector_state(state,
> connector);
> > > > +	if (WARN_ON(!conn_state))
> > > > +		return;
> > > > +
> > > > +	crtc_state = drm_atomic_get_new_crtc_state(state,
> conn_state->crtc);
> > > > +	if (WARN_ON(!crtc_state))
> > > > +		return;
> > > > +
> > > > +	video->color_fmt = conn_state->hdmi.output_format;
> > > > +	video->bpc = conn_state->hdmi.output_bpc;
> > > > +
> > > > +	drm_mode_copy(&mhdp->mode, &crtc_state->adjusted_mode);
> > >
> > > Why do you need a copy of all these fields? You should pass the
> > > connector / bridge state around and not copy these fields.
> > >
> > OK, mode will be removed, and it will replace by drm_connector_state.
> >
> > > > +	/* video mode check */
> > > > +	if (mode->clock == 0 || mode->hdisplay == 0 || mode->vdisplay ==
> 0)
> > > > +		return;
> > >
> > > This should be checked in atomic_check, but I'm pretty sure it's
> redundant.
> > OK, It will be removed.
> > >
> > > > +	dev_dbg(mhdp->dev, "Mode: %dx%dp%d\n",
> > > > +		mode->hdisplay, mode->vdisplay, mode->clock);
> > > > +
> > > > +
> 	drm_atomic_helper_connector_hdmi_update_infoframes(connector,
> > > > +state);
> > > > +
> > > > +	/* Line swapping */
> > > > +	cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000
> |
> > > > +mhdp->lane_mapping);
> > > > +
> > > > +	mhdp->hdmi.char_rate = drm_hdmi_compute_mode_clock(mode,
> > > > +							   mhdp->video_info.bpc,
> > > > +							   mhdp->video_info.color_fmt);
> > >
> > > The TMDS char rate is already available in the connector_state so
> > > there no need to recompute it.
> > >
> > > > +	phy_cfg.hdmi.tmds_char_rate = mhdp->hdmi.char_rate;
> > >
> > > And you shouldn't store a copy either.
> > OK, variable char_rate will be removed and will use the
> > drm_connector_state-> hdmi.tmds_char_rate
> >
> > >
> > > > +	/* Mailbox protect for HDMI PHY access */
> > > > +	mutex_lock(&mhdp->mbox_mutex);
> > > > +	ret = phy_configure(mhdp->phy, &phy_cfg);
> > > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > > +	if (ret) {
> > > > +		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
> > > > +			__func__, ret);
> > > > +		return;
> > > > +	}
> > > > +
> > > > +	cdns_hdmi_sink_config(mhdp);
> > > > +
> > > > +	ret = cdns_hdmi_ctrl_init(mhdp);
> > > > +	if (ret < 0) {
> > > > +		dev_err(mhdp->dev, "%s, ret = %d\n", __func__, ret);
> > > > +		return;
> > > > +	}
> > > > +
> > > > +	/* Config GCP */
> > > > +	if (mhdp->video_info.bpc == 8)
> > > > +		cdns_hdmi_disable_gcp(mhdp);
> > > > +	else
> > > > +		cdns_hdmi_enable_gcp(mhdp);
> > > > +
> > > > +	ret = cdns_hdmi_mode_config(mhdp, mode, &mhdp->video_info);
> > > > +	if (ret < 0) {
> > > > +		dev_err(mhdp->dev, "CDN_API_HDMITX_SetVic_blocking ret
> > > = %d\n", ret);
> > > > +		return;
> > > > +	}
> > > > +}
> > > > +
> > > > +static int cdns_hdmi_bridge_clear_infoframe(struct drm_bridge
> *bridge,
> > > > +					    enum hdmi_infoframe_type type) {
> > > > +	return 0;
> > > > +}
> > >
> > > Either implement it or don't, but an empty function is dead code.
> > Must have function hdmi_clear_infoframe when set
> DRM_BRIDGE_OP_HDMI
> > flag in &drm_bridge->ops, otherwise the drm_bridge_connector_init() will
> fail.
> > https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tr
> > ee/drivers/gpu/drm/drm_bridge_connector.c?h=next-20240902#n419
> 
> That's a strong hint that you should implement it, not workaround it :)

OK, I will add it.

Sandor

> 
> Maxime

From quic_songxue at quicinc.com  Fri Sep  6 01:40:18 2024
From: quic_songxue at quicinc.com (Song Xue)
Date: Fri, 6 Sep 2024 16:40:18 +0800
Subject: [PATCH v2 2/2] phy: add NXP PTN3222 eUSB2 to USB2 redriver
In-Reply-To: <CAA8EJpoTb_-HtBPv2=FecHvtHYQD4ipqfq3C98ky=qXEXB=_6Q@mail.gmail.com>
References: <20240830-nxp-ptn3222-v2-0-4c6d8535cf6c@linaro.org>
 <20240830-nxp-ptn3222-v2-2-4c6d8535cf6c@linaro.org>
 <6fcaa893-70a4-44f4-afc0-853799e30774@quicinc.com>
 <CAA8EJpoTb_-HtBPv2=FecHvtHYQD4ipqfq3C98ky=qXEXB=_6Q@mail.gmail.com>
Message-ID: <237865a2-61fb-4d05-a57d-261710aad821@quicinc.com>



On 8/31/2024 7:45 AM, Dmitry Baryshkov wrote:
> On Sat, 31 Aug 2024 at 02:13, Song Xue <quic_songxue at quicinc.com> wrote:
>> On 8/30/2024 4:20 PM, Dmitry Baryshkov wrote:
>>> The NXP PTN3222 is the single-port eUSB2 to USB2 redriver that performs
>>> translation between eUSB2 and USB2 signalling schemes. It supports all
>>> three data rates: Low Speed, Full Speed and High Speed.
>>>
>>> The reset state enables autonegotiation of the PHY role and of the data
>>> rate, so no additional programming is required.
>>>
>>> Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
>>> Tested-by: Konrad Dybcio <konradybcio at kernel.org>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>>> ---
>>>    drivers/phy/Kconfig           |  11 ++++
>>>    drivers/phy/Makefile          |   1 +
>>>    drivers/phy/phy-nxp-ptn3222.c | 123 ++++++++++++++++++++++++++++++++++++++++++
>>>    3 files changed, 135 insertions(+)
> 
> [trimmed]
> 
>>> +
>>> +MODULE_DESCRIPTION("NXP PTN3222 eUSB2 Redriver driver");
>>> +MODULE_LICENSE("GPL");
>>>
>> The I2C driver just realizes the function on reset and PWR. What about
>> other I2C driver function like I2C interface operations,
> 
> I don't quite understand what you mean by this. Could you please clarify?
> 
>>   auto-suspend,
> 
> I think you mean pm_runtime here. It's a valid case, but granted that
> it should stay enabled when USB controller is enabled, the gain should
> be pretty limited. I'll consider a followup patch implementing
> pm_runtime for the sake of being able to disable I2C host if DWC3
> controller disables the PHY.
> 
>> remote wakeup,
> 
> Not supported by design. PTN3222 doesn't have IRQ pins to report
> events to the host.
> 
>> memory maps etc.
> 
> huh?
> 
>>   Who will enable these? I think it is not
>> incomplete I2C driver, if on someday, ptn3222 is used as I2C device.
> 
> Well, I'm using it as an I2C device.
> 
Sorry for the delayed response.
The functions I listed, such as auto-suspend and wake-up, are just 
examples. My main point is that a basic I2C driver should include 
fundamental functions like setting up the I2C bus, configuring the 
clock, and setting the SDA (data line) and SCL (clock line). A basic I2C 
driver shouldn?t be limited to enabling the power supply and reset pin, 
as these features can be handled by other drivers as well.
If you implement these fundamental functions, I think it will be sufficient.

Regards,
Song Xue




From dmitry.baryshkov at linaro.org  Fri Sep  6 02:28:25 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 6 Sep 2024 12:28:25 +0300
Subject: [PATCH v2 2/2] phy: add NXP PTN3222 eUSB2 to USB2 redriver
In-Reply-To: <237865a2-61fb-4d05-a57d-261710aad821@quicinc.com>
References: <20240830-nxp-ptn3222-v2-0-4c6d8535cf6c@linaro.org>
 <20240830-nxp-ptn3222-v2-2-4c6d8535cf6c@linaro.org> <6fcaa893-70a4-44f4-afc0-853799e30774@quicinc.com>
 <CAA8EJpoTb_-HtBPv2=FecHvtHYQD4ipqfq3C98ky=qXEXB=_6Q@mail.gmail.com> <237865a2-61fb-4d05-a57d-261710aad821@quicinc.com>
Message-ID: <CAA8EJpqa3_ZaC7xo+pWBovKEvJ5utxR7nS1vSRnyskw7GZf-wQ@mail.gmail.com>

On Fri, 6 Sept 2024 at 11:40, Song Xue <quic_songxue at quicinc.com> wrote:
>
>
>
> On 8/31/2024 7:45 AM, Dmitry Baryshkov wrote:
> > On Sat, 31 Aug 2024 at 02:13, Song Xue <quic_songxue at quicinc.com> wrote:
> >> On 8/30/2024 4:20 PM, Dmitry Baryshkov wrote:
> >>> The NXP PTN3222 is the single-port eUSB2 to USB2 redriver that performs
> >>> translation between eUSB2 and USB2 signalling schemes. It supports all
> >>> three data rates: Low Speed, Full Speed and High Speed.
> >>>
> >>> The reset state enables autonegotiation of the PHY role and of the data
> >>> rate, so no additional programming is required.
> >>>
> >>> Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
> >>> Tested-by: Konrad Dybcio <konradybcio at kernel.org>
> >>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> >>> ---
> >>>    drivers/phy/Kconfig           |  11 ++++
> >>>    drivers/phy/Makefile          |   1 +
> >>>    drivers/phy/phy-nxp-ptn3222.c | 123 ++++++++++++++++++++++++++++++++++++++++++
> >>>    3 files changed, 135 insertions(+)
> >
> > [trimmed]
> >
> >>> +
> >>> +MODULE_DESCRIPTION("NXP PTN3222 eUSB2 Redriver driver");
> >>> +MODULE_LICENSE("GPL");
> >>>
> >> The I2C driver just realizes the function on reset and PWR. What about
> >> other I2C driver function like I2C interface operations,
> >
> > I don't quite understand what you mean by this. Could you please clarify?
> >
> >>   auto-suspend,
> >
> > I think you mean pm_runtime here. It's a valid case, but granted that
> > it should stay enabled when USB controller is enabled, the gain should
> > be pretty limited. I'll consider a followup patch implementing
> > pm_runtime for the sake of being able to disable I2C host if DWC3
> > controller disables the PHY.
> >
> >> remote wakeup,
> >
> > Not supported by design. PTN3222 doesn't have IRQ pins to report
> > events to the host.
> >
> >> memory maps etc.
> >
> > huh?
> >
> >>   Who will enable these? I think it is not
> >> incomplete I2C driver, if on someday, ptn3222 is used as I2C device.
> >
> > Well, I'm using it as an I2C device.
> >
> Sorry for the delayed response.
> The functions I listed, such as auto-suspend and wake-up, are just
> examples. My main point is that a basic I2C driver should include
> fundamental functions like setting up the I2C bus, configuring the
> clock, and setting the SDA (data line) and SCL (clock line). A basic I2C
> driver shouldn?t be limited to enabling the power supply and reset pin,
> as these features can be handled by other drivers as well.
> If you implement these fundamental functions, I think it will be sufficient.

I think you have mixed two things. You are describing an I2C bus
device, which PTN3222 isn't. I2C clients do not have to setup
anything. SDA/SCL and clock frequency are handled by the I2C bus
drivers and by the I2C framework.

-- 
With best wishes
Dmitry


From daniel.machon at microchip.com  Fri Sep  6 05:52:37 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 6 Sep 2024 14:52:37 +0200
Subject: [PATCH 0/9] phy: sparx5-serdes: add support for lan969x serdes
 driver
Message-ID: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>

The lan969x switch chip (upstreaming efforts beginning soon) has ten 10G
SERDES'es which share the same features and data rates as the Sparx5 10G
SERDES'es. Lets take advantage of this and reuse the existing SERDES
driver for lan969x.

In order to do this, we add a new indirection layer to the register
macros, that takes register differences into account. Additionally, we
add driver match data for other differences that we need to handle.
These other differences are handled by a combination of constants (eg.
the number of SERDES'es), ops and if's

Patch #1 adds support for match data.

Patch #2 adds a struct to handle constants and adds a constant for the
number of SERDES'es.

Patch #3 adds a constant for the number of CMU's

Patch #4 adds a struct for ops and adds a function for setting SERDES
type.

Patch #5 adds a function for getting the number of CMU's.

Patch #6 adds register macro indirection layer.

Patch #7 adds SERDES target types (eg. Sparx5, lan969x) to be used for
branching out based on the target.

Patch #8 adds support for lan969x in the Sparx5 dt-bindings.

Patch #9 introduces the new lan969x SERDES driver.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
Daniel Machon (9):
      phy: sparx5-serdes: add support for private match data
      phy: sparx5-serdes: add constants to match data
      phy: sparx5-serdes: add constant for the number of CMU's
      phy: sparx5-serdes: add ops to match data
      phy: sparx5-serdes: add function for getting the CMU index
      phy: sparx5-serdes: add indirection layer to register macros
      phy: sparx5-serdes: add support for branching on chip type
      dt-bindings: phy: sparx5: document lan969x in sparx5 dt-bindings
      phy: lan969x-serdes: add support for lan969x serdes driver

 .../bindings/phy/microchip,sparx5-serdes.yaml      |  18 +-
 drivers/phy/microchip/sparx5_serdes.c              | 195 +++++-
 drivers/phy/microchip/sparx5_serdes.h              |  44 +-
 drivers/phy/microchip/sparx5_serdes_regs.h         | 746 ++++++++++++++-------
 4 files changed, 706 insertions(+), 297 deletions(-)
---
base-commit: 221f9cce949ac8042f65b71ed1fde13b99073256
change-id: 20240822-sparx5-lan969x-serdes-driver-8389dbdd9a89

Best regards,
-- 
Daniel Machon <daniel.machon at microchip.com>



From daniel.machon at microchip.com  Fri Sep  6 05:52:38 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 6 Sep 2024 14:52:38 +0200
Subject: [PATCH 1/9] phy: sparx5-serdes: add support for private match data
In-Reply-To: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
References: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
Message-ID: <20240906-sparx5-lan969x-serdes-driver-v1-1-8d630614c58a@microchip.com>

In order to reuse the existing Sparx5 SERDES driver for lan969x, we add
support for private match data, with initial fields for the iomap and
imap_size.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c | 16 +++++++++++++---
 drivers/phy/microchip/sparx5_serdes.h |  6 ++++++
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index 7cb85029fab3..5427e8627a78 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -2507,6 +2507,11 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] =  {
 	{ TARGET_SD_LANE_25G + 7, 0x5c8000 }, /* 0x610dd0000: sd_lane_25g_32 */
 };
 
+static const struct sparx5_serdes_match_data sparx5_desc = {
+	.iomap = sparx5_serdes_iomap,
+	.iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
+};
+
 /* Client lookup function, uses serdes index */
 static struct phy *sparx5_serdes_xlate(struct device *dev,
 				     const struct of_phandle_args *args)
@@ -2555,6 +2560,10 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, priv);
 	priv->dev = &pdev->dev;
 
+	priv->data = device_get_match_data(priv->dev);
+	if (!priv->data)
+		return -EINVAL;
+
 	/* Get coreclock */
 	clk = devm_clk_get(priv->dev, NULL);
 	if (IS_ERR(clk)) {
@@ -2579,8 +2588,9 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 			iores->name);
 		return -ENOMEM;
 	}
-	for (idx = 0; idx < ARRAY_SIZE(sparx5_serdes_iomap); idx++) {
-		struct sparx5_serdes_io_resource *iomap = &sparx5_serdes_iomap[idx];
+	for (idx = 0; idx < priv->data->iomap_size; idx++) {
+		const struct sparx5_serdes_io_resource *iomap =
+			&priv->data->iomap[idx];
 
 		priv->regs[iomap->id] = iomem + iomap->offset;
 	}
@@ -2599,7 +2609,7 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id sparx5_serdes_match[] = {
-	{ .compatible = "microchip,sparx5-serdes" },
+	{ .compatible = "microchip,sparx5-serdes", .data = &sparx5_desc },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, sparx5_serdes_match);
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index 13f94a29225a..128f8c53172f 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -26,11 +26,17 @@ enum sparx5_serdes_mode {
 	SPX5_SD_MODE_SFI,
 };
 
+struct sparx5_serdes_match_data {
+	const struct sparx5_serdes_io_resource *iomap;
+	int iomap_size;
+};
+
 struct sparx5_serdes_private {
 	struct device *dev;
 	void __iomem *regs[NUM_TARGETS];
 	struct phy *phys[SPX5_SERDES_MAX];
 	unsigned long coreclock;
+	const struct sparx5_serdes_match_data *data;
 };
 
 struct sparx5_serdes_macro {

-- 
2.34.1



From daniel.machon at microchip.com  Fri Sep  6 05:52:39 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 6 Sep 2024 14:52:39 +0200
Subject: [PATCH 2/9] phy: sparx5-serdes: add constants to match data
In-Reply-To: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
References: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
Message-ID: <20240906-sparx5-lan969x-serdes-driver-v1-2-8d630614c58a@microchip.com>

We need to handle a few different constants that differ for Sparx5 and
lan969x. Add a new struct: sparx5_serdes_consts for this purpose. We
populate it with an initial field for the number of SERDES'es: sd_max.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c | 7 +++++--
 drivers/phy/microchip/sparx5_serdes.h | 5 +++++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index 5427e8627a78..c3ed028fc74e 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -2510,6 +2510,9 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] =  {
 static const struct sparx5_serdes_match_data sparx5_desc = {
 	.iomap = sparx5_serdes_iomap,
 	.iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
+	.consts = {
+		.sd_max       = 33,
+	},
 };
 
 /* Client lookup function, uses serdes index */
@@ -2526,7 +2529,7 @@ static struct phy *sparx5_serdes_xlate(struct device *dev,
 	sidx = args->args[0];
 
 	/* Check validity: ERR_PTR(-ENODEV) if not valid */
-	for (idx = 0; idx < SPX5_SERDES_MAX; idx++) {
+	for (idx = 0; idx < priv->data->consts.sd_max; idx++) {
 		struct sparx5_serdes_macro *macro =
 			phy_get_drvdata(priv->phys[idx]);
 
@@ -2594,7 +2597,7 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 
 		priv->regs[iomap->id] = iomem + iomap->offset;
 	}
-	for (idx = 0; idx < SPX5_SERDES_MAX; idx++) {
+	for (idx = 0; idx < priv->data->consts.sd_max; idx++) {
 		err = sparx5_phy_create(priv, idx, &priv->phys[idx]);
 		if (err)
 			return err;
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index 128f8c53172f..8c27cfde4938 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -26,7 +26,12 @@ enum sparx5_serdes_mode {
 	SPX5_SD_MODE_SFI,
 };
 
+struct sparx5_serdes_consts {
+	int sd_max;
+};
+
 struct sparx5_serdes_match_data {
+	const struct sparx5_serdes_consts consts;
 	const struct sparx5_serdes_io_resource *iomap;
 	int iomap_size;
 };

-- 
2.34.1



From daniel.machon at microchip.com  Fri Sep  6 05:52:41 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 6 Sep 2024 14:52:41 +0200
Subject: [PATCH 4/9] phy: sparx5-serdes: add ops to match data
In-Reply-To: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
References: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
Message-ID: <20240906-sparx5-lan969x-serdes-driver-v1-4-8d630614c58a@microchip.com>

We need to handle code differently in a few places. Add a struct:
sparx5_serdes_ops for this purpose, and populate it a with function to
set the SERDES type.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c | 29 +++++++++++++++++++----------
 drivers/phy/microchip/sparx5_serdes.h | 27 ++++++++++++++++-----------
 2 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index 9c91545dd8e1..b1376a142b14 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -2373,6 +2373,20 @@ static const struct phy_ops sparx5_serdes_ops = {
 	.owner		= THIS_MODULE,
 };
 
+static void sparx5_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
+{
+	if (sidx < SPX5_SERDES_10G_START) {
+		macro->serdestype = SPX5_SDT_6G;
+		macro->stpidx = macro->sidx;
+	} else if (sidx < SPX5_SERDES_25G_START) {
+		macro->serdestype = SPX5_SDT_10G;
+		macro->stpidx = macro->sidx - SPX5_SERDES_10G_START;
+	} else {
+		macro->serdestype = SPX5_SDT_25G;
+		macro->stpidx = macro->sidx - SPX5_SERDES_25G_START;
+	}
+}
+
 static int sparx5_phy_create(struct sparx5_serdes_private *priv,
 			   int idx, struct phy **phy)
 {
@@ -2389,16 +2403,8 @@ static int sparx5_phy_create(struct sparx5_serdes_private *priv,
 	macro->sidx = idx;
 	macro->priv = priv;
 	macro->speed = SPEED_UNKNOWN;
-	if (idx < SPX5_SERDES_10G_START) {
-		macro->serdestype = SPX5_SDT_6G;
-		macro->stpidx = macro->sidx;
-	} else if (idx < SPX5_SERDES_25G_START) {
-		macro->serdestype = SPX5_SDT_10G;
-		macro->stpidx = macro->sidx - SPX5_SERDES_10G_START;
-	} else {
-		macro->serdestype = SPX5_SDT_25G;
-		macro->stpidx = macro->sidx - SPX5_SERDES_25G_START;
-	}
+
+	priv->data->ops.serdes_type_set(macro, idx);
 
 	phy_set_drvdata(*phy, macro);
 
@@ -2512,6 +2518,9 @@ static const struct sparx5_serdes_match_data sparx5_desc = {
 		.sd_max       = 33,
 		.cmu_max      = 14,
 	},
+	.ops = {
+		.serdes_type_set      = &sparx5_serdes_type_set,
+	},
 };
 
 /* Client lookup function, uses serdes index */
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index 87c44bbaf368..785c7fe0bbeb 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -26,13 +26,29 @@ enum sparx5_serdes_mode {
 	SPX5_SD_MODE_SFI,
 };
 
+struct sparx5_serdes_macro {
+	struct sparx5_serdes_private *priv;
+	u32 sidx;
+	u32 stpidx;
+	enum sparx5_serdes_type serdestype;
+	enum sparx5_serdes_mode serdesmode;
+	phy_interface_t portmode;
+	int speed;
+	enum phy_media media;
+};
+
 struct sparx5_serdes_consts {
 	int sd_max;
 	int cmu_max;
 };
 
+struct sparx5_serdes_ops {
+	void (*serdes_type_set)(struct sparx5_serdes_macro *macro, int sidx);
+};
+
 struct sparx5_serdes_match_data {
 	const struct sparx5_serdes_consts consts;
+	const struct sparx5_serdes_ops ops;
 	const struct sparx5_serdes_io_resource *iomap;
 	int iomap_size;
 };
@@ -45,17 +61,6 @@ struct sparx5_serdes_private {
 	const struct sparx5_serdes_match_data *data;
 };
 
-struct sparx5_serdes_macro {
-	struct sparx5_serdes_private *priv;
-	u32 sidx;
-	u32 stpidx;
-	enum sparx5_serdes_type serdestype;
-	enum sparx5_serdes_mode serdesmode;
-	phy_interface_t portmode;
-	int speed;
-	enum phy_media media;
-};
-
 /* Read, Write and modify registers content.
  * The register definition macros start at the id
  */

-- 
2.34.1



From daniel.machon at microchip.com  Fri Sep  6 05:52:40 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 6 Sep 2024 14:52:40 +0200
Subject: [PATCH 3/9] phy: sparx5-serdes: add constant for the number of
 CMU's
In-Reply-To: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
References: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
Message-ID: <20240906-sparx5-lan969x-serdes-driver-v1-3-8d630614c58a@microchip.com>

The number of CMU's differ for Sparx5 and lan969x, so add a new field:
cmu_max and use it throughout.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c | 5 ++---
 drivers/phy/microchip/sparx5_serdes.h | 1 +
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index c3ed028fc74e..9c91545dd8e1 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -21,8 +21,6 @@
 
 #include "sparx5_serdes.h"
 
-#define SPX5_CMU_MAX          14
-
 #define SPX5_SERDES_10G_START 13
 #define SPX5_SERDES_25G_START 25
 #define SPX5_SERDES_6G10G_CNT SPX5_SERDES_25G_START
@@ -1101,7 +1099,7 @@ static void sparx5_serdes_cmu_power_off(struct sparx5_serdes_private *priv)
 	int i;
 
 	/* Power down each CMU */
-	for (i = 0; i < SPX5_CMU_MAX; i++) {
+	for (i = 0; i < priv->data->consts.cmu_max; i++) {
 		cmu_inst = sdx5_inst_get(priv, TARGET_SD_CMU, i);
 		cmu_cfg_inst = sdx5_inst_get(priv, TARGET_SD_CMU_CFG, i);
 
@@ -2512,6 +2510,7 @@ static const struct sparx5_serdes_match_data sparx5_desc = {
 	.iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
 	.consts = {
 		.sd_max       = 33,
+		.cmu_max      = 14,
 	},
 };
 
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index 8c27cfde4938..87c44bbaf368 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -28,6 +28,7 @@ enum sparx5_serdes_mode {
 
 struct sparx5_serdes_consts {
 	int sd_max;
+	int cmu_max;
 };
 
 struct sparx5_serdes_match_data {

-- 
2.34.1



From daniel.machon at microchip.com  Fri Sep  6 05:52:43 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 6 Sep 2024 14:52:43 +0200
Subject: [PATCH 6/9] phy: sparx5-serdes: add indirection layer to register
 macros
In-Reply-To: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
References: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
Message-ID: <20240906-sparx5-lan969x-serdes-driver-v1-6-8d630614c58a@microchip.com>

The register macros are used to read and write to the SERDES registers.
The registers are largely the same on Sparx5 and lan969x, however some
register target sizes differ. Therefore we introduce a new indirection
to the register macros. The target sizes are looked up, using a mapping
table (sparx5_serdes_tsize) that maps the register target to the
register target size.

With this addition, we can reuse all the existing macros for lan969x.

Also the autogenerated macros are now formatted slightly different, to
adhere to a 80 character limit.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c      |  14 +
 drivers/phy/microchip/sparx5_serdes.h      |   1 +
 drivers/phy/microchip/sparx5_serdes_regs.h | 746 +++++++++++++++++++----------
 3 files changed, 507 insertions(+), 254 deletions(-)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index 5b918a2716dd..8a716bfaa023 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -28,6 +28,17 @@
 /* Optimal power settings from GUC */
 #define SPX5_SERDES_QUIET_MODE_VAL 0x01ef4e0c
 
+/* Register target sizes */
+const unsigned int sparx5_serdes_tsize[TSIZE_LAST] = {
+	[TC_SD10G_LANE] = 12,
+	[TC_SD_CMU] = 14,
+	[TC_SD_CMU_CFG] = 14,
+	[TC_SD_LANE] = 25,
+};
+
+/* Pointer to the register target size table */
+const unsigned int *tsize;
+
 enum sparx5_sd25g28_mode_preset_type {
 	SPX5_SD25G28_MODE_PRESET_25000,
 	SPX5_SD25G28_MODE_PRESET_10000,
@@ -2506,6 +2517,7 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] =  {
 static const struct sparx5_serdes_match_data sparx5_desc = {
 	.iomap = sparx5_serdes_iomap,
 	.iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
+	.tsize = sparx5_serdes_tsize,
 	.consts = {
 		.sd_max       = 33,
 		.cmu_max      = 14,
@@ -2568,6 +2580,8 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 	if (!priv->data)
 		return -EINVAL;
 
+	tsize = priv->data->tsize;
+
 	/* Get coreclock */
 	clk = devm_clk_get(priv->dev, NULL);
 	if (IS_ERR(clk)) {
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index a7e92c1330e9..50900bf06c4c 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -60,6 +60,7 @@ struct sparx5_serdes_match_data {
 	const struct sparx5_serdes_ops ops;
 	const struct sparx5_serdes_io_resource *iomap;
 	int iomap_size;
+	const unsigned int *tsize;
 };
 
 struct sparx5_serdes_private {
diff --git a/drivers/phy/microchip/sparx5_serdes_regs.h b/drivers/phy/microchip/sparx5_serdes_regs.h
index d0543fd3dc94..11c4fdc593fa 100644
--- a/drivers/phy/microchip/sparx5_serdes_regs.h
+++ b/drivers/phy/microchip/sparx5_serdes_regs.h
@@ -1,11 +1,11 @@
 /* SPDX-License-Identifier: GPL-2.0+
  * Microchip Sparx5 SerDes driver
  *
- * Copyright (c) 2020 Microchip Technology Inc.
+ * Copyright (c) 2024 Microchip Technology Inc.
  */
 
-/* This file is autogenerated by cml-utils 2020-11-16 13:11:27 +0100.
- * Commit ID: 13bdf073131d8bf40c54901df6988ae4e9c8f29f
+/* This file is autogenerated by cml-utils 2023-04-13 15:02:00 +0200.
+ * Commit ID: 5ac560288d46048f872ecdb8add53717f1efc0e1
  */
 
 #ifndef _SPARX5_SERDES_REGS_H_
@@ -26,10 +26,25 @@ enum sparx5_serdes_target {
 	NUM_TARGETS = 332
 };
 
+enum sparx5_serdes_tsize_enum {
+	TC_SD10G_LANE,
+	TC_SD_CMU,
+	TC_SD_CMU_CFG,
+	TC_SD_LANE,
+	TSIZE_LAST,
+};
+
+/* sparx5_serdes.c */
+extern const unsigned int *tsize;
+
+#define TSIZE(o) tsize[o]
+
 #define __REG(...)    __VA_ARGS__
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_01 */
-#define SD10G_LANE_LANE_01(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 4, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_01 */
+#define SD10G_LANE_LANE_01(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 4, 0,  \
+	      1, 4)
 
 #define SD10G_LANE_LANE_01_CFG_PMA_TX_CK_BITWIDTH_2_0 GENMASK(2, 0)
 #define SD10G_LANE_LANE_01_CFG_PMA_TX_CK_BITWIDTH_2_0_SET(x)\
@@ -49,8 +64,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_01_CFG_RXDET_STR_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_01_CFG_RXDET_STR, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_02 */
-#define SD10G_LANE_LANE_02(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 8, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_02 */
+#define SD10G_LANE_LANE_02(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 8, 0,  \
+	      1, 4)
 
 #define SD10G_LANE_LANE_02_CFG_EN_ADV            BIT(0)
 #define SD10G_LANE_LANE_02_CFG_EN_ADV_SET(x)\
@@ -82,8 +99,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_02_CFG_TAP_ADV_3_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_02_CFG_TAP_ADV_3_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_03 */
-#define SD10G_LANE_LANE_03(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 12, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_03 */
+#define SD10G_LANE_LANE_03(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 12, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_03_CFG_TAP_MAIN          BIT(0)
 #define SD10G_LANE_LANE_03_CFG_TAP_MAIN_SET(x)\
@@ -91,8 +110,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_03_CFG_TAP_MAIN_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_03_CFG_TAP_MAIN, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_04 */
-#define SD10G_LANE_LANE_04(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 16, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_04 */
+#define SD10G_LANE_LANE_04(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 16, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0       GENMASK(4, 0)
 #define SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0_SET(x)\
@@ -100,8 +121,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_06 */
-#define SD10G_LANE_LANE_06(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 24, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_06 */
+#define SD10G_LANE_LANE_06(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 24, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_06_CFG_PD_DRIVER         BIT(0)
 #define SD10G_LANE_LANE_06_CFG_PD_DRIVER_SET(x)\
@@ -139,8 +162,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_06_CFG_EN_PREEMPH_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_06_CFG_EN_PREEMPH, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_0B */
-#define SD10G_LANE_LANE_0B(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 44, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0B */
+#define SD10G_LANE_LANE_0B(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 44, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_0B_CFG_EQ_RES_3_0        GENMASK(3, 0)
 #define SD10G_LANE_LANE_0B_CFG_EQ_RES_3_0_SET(x)\
@@ -172,8 +197,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_SQ_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_SQ, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_0C */
-#define SD10G_LANE_LANE_0C(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 48, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0C */
+#define SD10G_LANE_LANE_0C(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 48, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_0C_CFG_OSCAL_AFE         BIT(0)
 #define SD10G_LANE_LANE_0C_CFG_OSCAL_AFE_SET(x)\
@@ -223,8 +250,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_0C_CFG_RX_PCIE_GEN12_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_0C_CFG_RX_PCIE_GEN12, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_0D */
-#define SD10G_LANE_LANE_0D(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 52, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0D */
+#define SD10G_LANE_LANE_0D(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 52, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_0D_CFG_CTLE_M_THR_1_0    GENMASK(1, 0)
 #define SD10G_LANE_LANE_0D_CFG_CTLE_M_THR_1_0_SET(x)\
@@ -238,8 +267,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_0D_CFG_EQR_BYP_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_0D_CFG_EQR_BYP, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_0E */
-#define SD10G_LANE_LANE_0E(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 56, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0E */
+#define SD10G_LANE_LANE_0E(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 56, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_0E_CFG_EQC_FORCE_3_0     GENMASK(3, 0)
 #define SD10G_LANE_LANE_0E_CFG_EQC_FORCE_3_0_SET(x)\
@@ -265,8 +296,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_0E_CFG_SUM_SETCM_EN_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_0E_CFG_SUM_SETCM_EN, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_0F */
-#define SD10G_LANE_LANE_0F(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 60, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0F */
+#define SD10G_LANE_LANE_0F(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 60, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0      GENMASK(7, 0)
 #define SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0_SET(x)\
@@ -274,8 +307,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_13 */
-#define SD10G_LANE_LANE_13(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 76, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_13 */
+#define SD10G_LANE_LANE_13(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 76, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_13_CFG_DCDR_PD           BIT(0)
 #define SD10G_LANE_LANE_13_CFG_DCDR_PD_SET(x)\
@@ -295,8 +330,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_13_CFG_CDRCK_EN_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_13_CFG_CDRCK_EN, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_14 */
-#define SD10G_LANE_LANE_14(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 80, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_14 */
+#define SD10G_LANE_LANE_14(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 80, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0    GENMASK(7, 0)
 #define SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0_SET(x)\
@@ -304,8 +341,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_15 */
-#define SD10G_LANE_LANE_15(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 84, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_15 */
+#define SD10G_LANE_LANE_15(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 84, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8   GENMASK(7, 0)
 #define SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8_SET(x)\
@@ -313,8 +352,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_16 */
-#define SD10G_LANE_LANE_16(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 88, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_16 */
+#define SD10G_LANE_LANE_16(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 88, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16  GENMASK(7, 0)
 #define SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16_SET(x)\
@@ -322,8 +363,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_1A */
-#define SD10G_LANE_LANE_1A(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 104, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_1A */
+#define SD10G_LANE_LANE_1A(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 104, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_1A_CFG_PI_R_SCAN_EN      BIT(0)
 #define SD10G_LANE_LANE_1A_CFG_PI_R_SCAN_EN_SET(x)\
@@ -355,8 +398,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_1A_CFG_PI_FLOOP_STEPS_1_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_1A_CFG_PI_FLOOP_STEPS_1_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_22 */
-#define SD10G_LANE_LANE_22(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 136, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_22 */
+#define SD10G_LANE_LANE_22(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 136, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1     GENMASK(4, 0)
 #define SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1_SET(x)\
@@ -364,8 +409,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_23 */
-#define SD10G_LANE_LANE_23(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 140, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_23 */
+#define SD10G_LANE_LANE_23(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 140, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_23_CFG_DFE_PD            BIT(0)
 #define SD10G_LANE_LANE_23_CFG_DFE_PD_SET(x)\
@@ -397,8 +444,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_23_CFG_DFEDIG_M_2_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_23_CFG_DFEDIG_M_2_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_24 */
-#define SD10G_LANE_LANE_24(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 144, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_24 */
+#define SD10G_LANE_LANE_24(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 144, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_24_CFG_PI_BW_GEN1_3_0    GENMASK(3, 0)
 #define SD10G_LANE_LANE_24_CFG_PI_BW_GEN1_3_0_SET(x)\
@@ -412,8 +461,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_24_CFG_PI_BW_GEN2_3_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_24_CFG_PI_BW_GEN2_3_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_26 */
-#define SD10G_LANE_LANE_26(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 152, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_26 */
+#define SD10G_LANE_LANE_26(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 152, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0 GENMASK(7, 0)
 #define SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0_SET(x)\
@@ -421,8 +472,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_2F */
-#define SD10G_LANE_LANE_2F(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 188, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_2F */
+#define SD10G_LANE_LANE_2F(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 188, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_2F_CFG_VGA_CP_2_0        GENMASK(2, 0)
 #define SD10G_LANE_LANE_2F_CFG_VGA_CP_2_0_SET(x)\
@@ -436,8 +489,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_2F_CFG_VGA_CTRL_3_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_2F_CFG_VGA_CTRL_3_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_30 */
-#define SD10G_LANE_LANE_30(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 192, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_30 */
+#define SD10G_LANE_LANE_30(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 192, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_30_CFG_SUMMER_EN         BIT(0)
 #define SD10G_LANE_LANE_30_CFG_SUMMER_EN_SET(x)\
@@ -451,8 +506,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_30_CFG_RXDIV_SEL_2_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_30_CFG_RXDIV_SEL_2_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_31 */
-#define SD10G_LANE_LANE_31(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 196, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_31 */
+#define SD10G_LANE_LANE_31(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 196, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_31_CFG_PI_RSTN           BIT(0)
 #define SD10G_LANE_LANE_31_CFG_PI_RSTN_SET(x)\
@@ -490,8 +547,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_31_CFG_R50_EN_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_31_CFG_R50_EN, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_32 */
-#define SD10G_LANE_LANE_32(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 200, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_32 */
+#define SD10G_LANE_LANE_32(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 200, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_32_CFG_ITX_IPCLK_BASE_1_0 GENMASK(1, 0)
 #define SD10G_LANE_LANE_32_CFG_ITX_IPCLK_BASE_1_0_SET(x)\
@@ -505,8 +564,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_32_CFG_ITX_IPCML_BASE_1_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_32_CFG_ITX_IPCML_BASE_1_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_33 */
-#define SD10G_LANE_LANE_33(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 204, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_33 */
+#define SD10G_LANE_LANE_33(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 204, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_33_CFG_ITX_IPDRIVER_BASE_2_0 GENMASK(2, 0)
 #define SD10G_LANE_LANE_33_CFG_ITX_IPDRIVER_BASE_2_0_SET(x)\
@@ -520,8 +581,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_33_CFG_ITX_IPPREEMP_BASE_1_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_33_CFG_ITX_IPPREEMP_BASE_1_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_35 */
-#define SD10G_LANE_LANE_35(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 212, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_35 */
+#define SD10G_LANE_LANE_35(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 212, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_35_CFG_TXRATE_1_0        GENMASK(1, 0)
 #define SD10G_LANE_LANE_35_CFG_TXRATE_1_0_SET(x)\
@@ -535,8 +598,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_35_CFG_RXRATE_1_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_35_CFG_RXRATE_1_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_36 */
-#define SD10G_LANE_LANE_36(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 216, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_36 */
+#define SD10G_LANE_LANE_36(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 216, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_36_CFG_PREDRV_SLEWRATE_1_0 GENMASK(1, 0)
 #define SD10G_LANE_LANE_36_CFG_PREDRV_SLEWRATE_1_0_SET(x)\
@@ -568,8 +633,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_36_CFG_PRBS_SETB_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_36_CFG_PRBS_SETB, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_37 */
-#define SD10G_LANE_LANE_37(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 220, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_37 */
+#define SD10G_LANE_LANE_37(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 220, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_37_CFG_RXDET_COMP_PD     BIT(0)
 #define SD10G_LANE_LANE_37_CFG_RXDET_COMP_PD_SET(x)\
@@ -595,8 +662,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_37_CFG_IP_PRE_BASE_1_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_37_CFG_IP_PRE_BASE_1_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_39 */
-#define SD10G_LANE_LANE_39(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 228, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_39 */
+#define SD10G_LANE_LANE_39(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 228, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_39_CFG_RXFILT_Y_2_0      GENMASK(2, 0)
 #define SD10G_LANE_LANE_39_CFG_RXFILT_Y_2_0_SET(x)\
@@ -610,8 +679,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_39_CFG_RX_SSC_LH_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_39_CFG_RX_SSC_LH, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_3A */
-#define SD10G_LANE_LANE_3A(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 232, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_3A */
+#define SD10G_LANE_LANE_3A(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 232, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_3A_CFG_MP_MIN_3_0        GENMASK(3, 0)
 #define SD10G_LANE_LANE_3A_CFG_MP_MIN_3_0_SET(x)\
@@ -625,8 +696,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_3A_CFG_MP_MAX_3_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_3A_CFG_MP_MAX_3_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_3C */
-#define SD10G_LANE_LANE_3C(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 240, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_3C */
+#define SD10G_LANE_LANE_3C(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 240, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_3C_CFG_DIS_ACC           BIT(0)
 #define SD10G_LANE_LANE_3C_CFG_DIS_ACC_SET(x)\
@@ -640,8 +713,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_3C_CFG_DIS_2NDORDER_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_3C_CFG_DIS_2NDORDER, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_40 */
-#define SD10G_LANE_LANE_40(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 256, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_40 */
+#define SD10G_LANE_LANE_40(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 256, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0  GENMASK(7, 0)
 #define SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0_SET(x)\
@@ -649,8 +724,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_41 */
-#define SD10G_LANE_LANE_41(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 260, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_41 */
+#define SD10G_LANE_LANE_41(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 260, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8 GENMASK(7, 0)
 #define SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8_SET(x)\
@@ -658,8 +735,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_42 */
-#define SD10G_LANE_LANE_42(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 264, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_42 */
+#define SD10G_LANE_LANE_42(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 264, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_42_CFG_CDR_KF_GEN1_2_0   GENMASK(2, 0)
 #define SD10G_LANE_LANE_42_CFG_CDR_KF_GEN1_2_0_SET(x)\
@@ -673,8 +752,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_42_CFG_CDR_KF_GEN2_2_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_42_CFG_CDR_KF_GEN2_2_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_1:LANE_48 */
-#define SD10G_LANE_LANE_48(t)     __REG(TARGET_SD10G_LANE, t, 12, 288, 0, 1, 40, 0, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_1:LANE_48 */
+#define SD10G_LANE_LANE_48(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 288, 0, 1, 40, 0, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_48_CFG_ALOS_THR_3_0      GENMASK(3, 0)
 #define SD10G_LANE_LANE_48_CFG_ALOS_THR_3_0_SET(x)\
@@ -694,8 +775,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_48_CFG_CLK_ENQ_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_48_CFG_CLK_ENQ, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_1:LANE_50 */
-#define SD10G_LANE_LANE_50(t)     __REG(TARGET_SD10G_LANE, t, 12, 288, 0, 1, 40, 32, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_1:LANE_50 */
+#define SD10G_LANE_LANE_50(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 288, 0, 1, 40, 32, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_50_CFG_SSC_PI_STEP_1_0   GENMASK(1, 0)
 #define SD10G_LANE_LANE_50_CFG_SSC_PI_STEP_1_0_SET(x)\
@@ -727,8 +810,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_50_CFG_JT_EN_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_50_CFG_JT_EN, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_2:LANE_52 */
-#define SD10G_LANE_LANE_52(t)     __REG(TARGET_SD10G_LANE, t, 12, 328, 0, 1, 24, 0, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_2:LANE_52 */
+#define SD10G_LANE_LANE_52(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 328, 0, 1, 24, 0, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0 GENMASK(5, 0)
 #define SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0_SET(x)\
@@ -736,8 +821,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_4:LANE_83 */
-#define SD10G_LANE_LANE_83(t)     __REG(TARGET_SD10G_LANE, t, 12, 464, 0, 1, 112, 60, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_4:LANE_83 */
+#define SD10G_LANE_LANE_83(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 464, 0, 1, 112, 60,  \
+	      0, 1, 4)
 
 #define SD10G_LANE_LANE_83_R_TX_BIT_REVERSE      BIT(0)
 #define SD10G_LANE_LANE_83_R_TX_BIT_REVERSE_SET(x)\
@@ -781,8 +868,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_83_R_CTLE_RSTN_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_83_R_CTLE_RSTN, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_5:LANE_93 */
-#define SD10G_LANE_LANE_93(t)     __REG(TARGET_SD10G_LANE, t, 12, 576, 0, 1, 64, 12, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_5:LANE_93 */
+#define SD10G_LANE_LANE_93(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 576, 0, 1, 64, 12, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_93_R_RXEI_FIFO_RST_EN    BIT(0)
 #define SD10G_LANE_LANE_93_R_RXEI_FIFO_RST_EN_SET(x)\
@@ -832,8 +921,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_93_R_RX_PCIE_GEN12_FROM_HWT_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_93_R_RX_PCIE_GEN12_FROM_HWT, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_5:LANE_94 */
-#define SD10G_LANE_LANE_94(t)     __REG(TARGET_SD10G_LANE, t, 12, 576, 0, 1, 64, 16, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_5:LANE_94 */
+#define SD10G_LANE_LANE_94(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 576, 0, 1, 64, 16, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_94_R_DWIDTHCTRL_2_0      GENMASK(2, 0)
 #define SD10G_LANE_LANE_94_R_DWIDTHCTRL_2_0_SET(x)\
@@ -865,8 +956,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_94_R_SWING_REG_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_94_R_SWING_REG, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_5:LANE_9E */
-#define SD10G_LANE_LANE_9E(t)     __REG(TARGET_SD10G_LANE, t, 12, 576, 0, 1, 64, 56, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_5:LANE_9E */
+#define SD10G_LANE_LANE_9E(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 576, 0, 1, 64, 56, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_9E_R_RXEQ_REG            BIT(0)
 #define SD10G_LANE_LANE_9E_R_RXEQ_REG_SET(x)\
@@ -886,8 +979,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_9E_R_EN_AUTO_CDR_RSTN_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_9E_R_EN_AUTO_CDR_RSTN, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_6:LANE_A1 */
-#define SD10G_LANE_LANE_A1(t)     __REG(TARGET_SD10G_LANE, t, 12, 640, 0, 1, 128, 4, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_6:LANE_A1 */
+#define SD10G_LANE_LANE_A1(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 640, 0, 1, 128, 4, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_A1_R_PMA_TXCK_DIV_SEL_1_0 GENMASK(1, 0)
 #define SD10G_LANE_LANE_A1_R_PMA_TXCK_DIV_SEL_1_0_SET(x)\
@@ -919,8 +1014,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_A1_R_PCLK_GATING_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_A1_R_PCLK_GATING, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_6:LANE_A2 */
-#define SD10G_LANE_LANE_A2(t)     __REG(TARGET_SD10G_LANE, t, 12, 640, 0, 1, 128, 8, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_6:LANE_A2 */
+#define SD10G_LANE_LANE_A2(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 640, 0, 1, 128, 8, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0 GENMASK(4, 0)
 #define SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0_SET(x)\
@@ -928,8 +1025,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_8:LANE_DF */
-#define SD10G_LANE_LANE_DF(t)     __REG(TARGET_SD10G_LANE, t, 12, 832, 0, 1, 84, 60, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_8:LANE_DF */
+#define SD10G_LANE_LANE_DF(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 832, 0, 1, 84, 60, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_DF_LOL_UDL               BIT(0)
 #define SD10G_LANE_LANE_DF_LOL_UDL_SET(x)\
@@ -955,8 +1054,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_DF_SQUELCH_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_DF_SQUELCH, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_09 */
-#define SD25G_LANE_CMU_09(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 36, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_09 */
+#define SD25G_LANE_CMU_09(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 36, 0, 1, 4)
 
 #define SD25G_LANE_CMU_09_CFG_REFCK_TERM_EN      BIT(0)
 #define SD25G_LANE_CMU_09_CFG_REFCK_TERM_EN_SET(x)\
@@ -988,8 +1089,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_09_CFG_PLL_TP_SEL_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_09_CFG_PLL_TP_SEL_1_0, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_0B */
-#define SD25G_LANE_CMU_0B(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 44, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_0B */
+#define SD25G_LANE_CMU_0B(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 44, 0, 1, 4)
 
 #define SD25G_LANE_CMU_0B_CFG_FORCE_RX_FILT      BIT(0)
 #define SD25G_LANE_CMU_0B_CFG_FORCE_RX_FILT_SET(x)\
@@ -1039,8 +1142,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_0B_CFG_RST_TREE_PD_MAN_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_0B_CFG_RST_TREE_PD_MAN, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_0C */
-#define SD25G_LANE_CMU_0C(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 48, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_0C */
+#define SD25G_LANE_CMU_0C(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 48, 0, 1, 4)
 
 #define SD25G_LANE_CMU_0C_CFG_PLL_LOL_SET        BIT(0)
 #define SD25G_LANE_CMU_0C_CFG_PLL_LOL_SET_SET(x)\
@@ -1072,8 +1177,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_0C_CFG_VCO_DIV_MODE_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_0C_CFG_VCO_DIV_MODE_1_0, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_0D */
-#define SD25G_LANE_CMU_0D(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 52, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_0D */
+#define SD25G_LANE_CMU_0D(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 52, 0, 1, 4)
 
 #define SD25G_LANE_CMU_0D_CFG_CK_TREE_PD         BIT(0)
 #define SD25G_LANE_CMU_0D_CFG_CK_TREE_PD_SET(x)\
@@ -1105,8 +1212,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_0D_CFG_PRE_DIVSEL_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_0D_CFG_PRE_DIVSEL_1_0, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_0E */
-#define SD25G_LANE_CMU_0E(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 56, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_0E */
+#define SD25G_LANE_CMU_0E(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 56, 0, 1, 4)
 
 #define SD25G_LANE_CMU_0E_CFG_SEL_DIV_3_0        GENMASK(3, 0)
 #define SD25G_LANE_CMU_0E_CFG_SEL_DIV_3_0_SET(x)\
@@ -1120,8 +1229,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_0E_CFG_PMAA_CENTR_CK_PD_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_0E_CFG_PMAA_CENTR_CK_PD, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_13 */
-#define SD25G_LANE_CMU_13(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 76, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_13 */
+#define SD25G_LANE_CMU_13(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 76, 0, 1, 4)
 
 #define SD25G_LANE_CMU_13_CFG_PLL_RESERVE_3_0    GENMASK(3, 0)
 #define SD25G_LANE_CMU_13_CFG_PLL_RESERVE_3_0_SET(x)\
@@ -1135,8 +1246,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_13_CFG_JT_EN_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_13_CFG_JT_EN, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_18 */
-#define SD25G_LANE_CMU_18(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 96, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_18 */
+#define SD25G_LANE_CMU_18(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 96, 0, 1, 4)
 
 #define SD25G_LANE_CMU_18_R_PLL_RSTN             BIT(0)
 #define SD25G_LANE_CMU_18_R_PLL_RSTN_SET(x)\
@@ -1162,8 +1275,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_18_R_PLL_TP_SEL_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_18_R_PLL_TP_SEL_1_0, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_19 */
-#define SD25G_LANE_CMU_19(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 100, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_19 */
+#define SD25G_LANE_CMU_19(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 100, 0, 1, 4)
 
 #define SD25G_LANE_CMU_19_R_CK_RESETB            BIT(0)
 #define SD25G_LANE_CMU_19_R_CK_RESETB_SET(x)\
@@ -1177,8 +1292,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_19_R_PLL_DLOL_EN_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_19_R_PLL_DLOL_EN, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_1A */
-#define SD25G_LANE_CMU_1A(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 104, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_1A */
+#define SD25G_LANE_CMU_1A(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 104, 0, 1, 4)
 
 #define SD25G_LANE_CMU_1A_R_DWIDTHCTRL_2_0       GENMASK(2, 0)
 #define SD25G_LANE_CMU_1A_R_DWIDTHCTRL_2_0_SET(x)\
@@ -1204,8 +1321,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_1A_R_REG_MANUAL_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_1A_R_REG_MANUAL, x)
 
-/*      SD25G_TARGET:CMU_GRP_1:CMU_2A */
-#define SD25G_LANE_CMU_2A(t)      __REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 36, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_1:CMU_2A */
+#define SD25G_LANE_CMU_2A(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 36, 0, 1, 4)
 
 #define SD25G_LANE_CMU_2A_R_DBG_SEL_1_0          GENMASK(1, 0)
 #define SD25G_LANE_CMU_2A_R_DBG_SEL_1_0_SET(x)\
@@ -1225,8 +1344,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_2A_R_DBG_LOL_STATUS_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_2A_R_DBG_LOL_STATUS, x)
 
-/*      SD25G_TARGET:CMU_GRP_1:CMU_30 */
-#define SD25G_LANE_CMU_30(t)      __REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 60, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_1:CMU_30 */
+#define SD25G_LANE_CMU_30(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 60, 0, 1, 4)
 
 #define SD25G_LANE_CMU_30_R_TXFIFO_CK_DIV_PMAD_2_0 GENMASK(2, 0)
 #define SD25G_LANE_CMU_30_R_TXFIFO_CK_DIV_PMAD_2_0_SET(x)\
@@ -1240,8 +1361,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_30_R_RXFIFO_CK_DIV_PMAD_2_0_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_30_R_RXFIFO_CK_DIV_PMAD_2_0, x)
 
-/*      SD25G_TARGET:CMU_GRP_1:CMU_31 */
-#define SD25G_LANE_CMU_31(t)      __REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 64, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_1:CMU_31 */
+#define SD25G_LANE_CMU_31(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 64, 0, 1, 4)
 
 #define SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0 GENMASK(7, 0)
 #define SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0_SET(x)\
@@ -1249,8 +1372,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0, x)
 
-/*      SD25G_TARGET:CMU_GRP_2:CMU_40 */
-#define SD25G_LANE_CMU_40(t)      __REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 0, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_2:CMU_40 */
+#define SD25G_LANE_CMU_40(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 0, 0, 1, 4)
 
 #define SD25G_LANE_CMU_40_L0_CFG_CKSKEW_CTRL     BIT(0)
 #define SD25G_LANE_CMU_40_L0_CFG_CKSKEW_CTRL_SET(x)\
@@ -1288,8 +1413,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_40_L0_CFG_TXCAL_RST_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_40_L0_CFG_TXCAL_RST, x)
 
-/*      SD25G_TARGET:CMU_GRP_2:CMU_45 */
-#define SD25G_LANE_CMU_45(t)      __REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 20, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_2:CMU_45 */
+#define SD25G_LANE_CMU_45(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 20, 0, 1, 4)
 
 #define SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0  GENMASK(7, 0)
 #define SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0_SET(x)\
@@ -1297,8 +1424,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0, x)
 
-/*      SD25G_TARGET:CMU_GRP_2:CMU_46 */
-#define SD25G_LANE_CMU_46(t)      __REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 24, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_2:CMU_46 */
+#define SD25G_LANE_CMU_46(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 24, 0, 1, 4)
 
 #define SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8 GENMASK(7, 0)
 #define SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8_SET(x)\
@@ -1306,8 +1435,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8, x)
 
-/*      SD25G_TARGET:CMU_GRP_3:CMU_C0 */
-#define SD25G_LANE_CMU_C0(t)      __REG(TARGET_SD25G_LANE, t, 8, 768, 0, 1, 252, 0, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_3:CMU_C0 */
+#define SD25G_LANE_CMU_C0(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 768, 0, 1, 252, 0, 0, 1, 4)
 
 #define SD25G_LANE_CMU_C0_READ_VCO_CTUNE_3_0     GENMASK(3, 0)
 #define SD25G_LANE_CMU_C0_READ_VCO_CTUNE_3_0_SET(x)\
@@ -1321,8 +1452,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_C0_PLL_LOL_UDL_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_C0_PLL_LOL_UDL, x)
 
-/*      SD25G_TARGET:CMU_GRP_4:CMU_FF */
-#define SD25G_LANE_CMU_FF(t)      __REG(TARGET_SD25G_LANE, t, 8, 1020, 0, 1, 4, 0, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_4:CMU_FF */
+#define SD25G_LANE_CMU_FF(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 1020, 0, 1, 4, 0, 0, 1, 4)
 
 #define SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX   GENMASK(7, 0)
 #define SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX_SET(x)\
@@ -1330,8 +1463,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_00 */
-#define SD25G_LANE_LANE_00(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 0, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_00 */
+#define SD25G_LANE_LANE_00(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 0, 0, 1, 4)
 
 #define SD25G_LANE_LANE_00_LN_CFG_ITX_VC_DRIVER_3_0 GENMASK(3, 0)
 #define SD25G_LANE_LANE_00_LN_CFG_ITX_VC_DRIVER_3_0_SET(x)\
@@ -1345,8 +1480,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_00_LN_CFG_ITX_IPCML_BASE_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_00_LN_CFG_ITX_IPCML_BASE_1_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_01 */
-#define SD25G_LANE_LANE_01(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 4, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_01 */
+#define SD25G_LANE_LANE_01(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 4, 0, 1, 4)
 
 #define SD25G_LANE_LANE_01_LN_CFG_ITX_IPDRIVER_BASE_2_0 GENMASK(2, 0)
 #define SD25G_LANE_LANE_01_LN_CFG_ITX_IPDRIVER_BASE_2_0_SET(x)\
@@ -1360,8 +1497,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_01_LN_CFG_TX_PREDIV_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_01_LN_CFG_TX_PREDIV_1_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_03 */
-#define SD25G_LANE_LANE_03(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 12, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_03 */
+#define SD25G_LANE_LANE_03(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 12, 0, 1, 4)
 
 #define SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0    GENMASK(4, 0)
 #define SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0_SET(x)\
@@ -1369,8 +1508,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_04 */
-#define SD25G_LANE_LANE_04(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 16, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_04 */
+#define SD25G_LANE_LANE_04(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 16, 0, 1, 4)
 
 #define SD25G_LANE_LANE_04_LN_CFG_TX2RX_LP_EN    BIT(0)
 #define SD25G_LANE_LANE_04_LN_CFG_TX2RX_LP_EN_SET(x)\
@@ -1408,8 +1549,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_04_LN_CFG_TAP_MAIN_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_04_LN_CFG_TAP_MAIN, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_05 */
-#define SD25G_LANE_LANE_05(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 20, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_05 */
+#define SD25G_LANE_LANE_05(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 20, 0, 1, 4)
 
 #define SD25G_LANE_LANE_05_LN_CFG_TAP_DLY2_3_0   GENMASK(3, 0)
 #define SD25G_LANE_LANE_05_LN_CFG_TAP_DLY2_3_0_SET(x)\
@@ -1423,8 +1566,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_05_LN_CFG_BW_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_05_LN_CFG_BW_1_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_06 */
-#define SD25G_LANE_LANE_06(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 24, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_06 */
+#define SD25G_LANE_LANE_06(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 24, 0, 1, 4)
 
 #define SD25G_LANE_LANE_06_LN_CFG_EN_MAIN        BIT(0)
 #define SD25G_LANE_LANE_06_LN_CFG_EN_MAIN_SET(x)\
@@ -1438,8 +1583,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_06_LN_CFG_TAP_ADV_3_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_06_LN_CFG_TAP_ADV_3_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_07 */
-#define SD25G_LANE_LANE_07(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 28, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_07 */
+#define SD25G_LANE_LANE_07(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 28, 0, 1, 4)
 
 #define SD25G_LANE_LANE_07_LN_CFG_EN_ADV         BIT(0)
 #define SD25G_LANE_LANE_07_LN_CFG_EN_ADV_SET(x)\
@@ -1459,8 +1606,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_07_LN_CFG_EN_DLY_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_07_LN_CFG_EN_DLY, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_09 */
-#define SD25G_LANE_LANE_09(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 36, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_09 */
+#define SD25G_LANE_LANE_09(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 36, 0, 1, 4)
 
 #define SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0 GENMASK(3, 0)
 #define SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0_SET(x)\
@@ -1468,8 +1617,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_0A */
-#define SD25G_LANE_LANE_0A(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 40, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_0A */
+#define SD25G_LANE_LANE_0A(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 40, 0, 1, 4)
 
 #define SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0 GENMASK(5, 0)
 #define SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0_SET(x)\
@@ -1477,8 +1628,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_0B */
-#define SD25G_LANE_LANE_0B(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 44, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_0B */
+#define SD25G_LANE_LANE_0B(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 44, 0, 1, 4)
 
 #define SD25G_LANE_LANE_0B_LN_CFG_TXCAL_MAN_EN   BIT(0)
 #define SD25G_LANE_LANE_0B_LN_CFG_TXCAL_MAN_EN_SET(x)\
@@ -1498,8 +1651,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_0B_LN_CFG_QUAD_MAN_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_0B_LN_CFG_QUAD_MAN_1_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_0C */
-#define SD25G_LANE_LANE_0C(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 48, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_0C */
+#define SD25G_LANE_LANE_0C(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 48, 0, 1, 4)
 
 #define SD25G_LANE_LANE_0C_LN_CFG_PMA_TX_CK_BITWIDTH_2_0 GENMASK(2, 0)
 #define SD25G_LANE_LANE_0C_LN_CFG_PMA_TX_CK_BITWIDTH_2_0_SET(x)\
@@ -1519,8 +1674,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_0C_LN_CFG_RXTERM_PD_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_0C_LN_CFG_RXTERM_PD, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_0D */
-#define SD25G_LANE_LANE_0D(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 52, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_0D */
+#define SD25G_LANE_LANE_0D(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 52, 0, 1, 4)
 
 #define SD25G_LANE_LANE_0D_LN_CFG_RXTERM_2_0     GENMASK(2, 0)
 #define SD25G_LANE_LANE_0D_LN_CFG_RXTERM_2_0_SET(x)\
@@ -1552,8 +1709,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_0D_LN_CFG_DFECK_EN_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_0D_LN_CFG_DFECK_EN, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_0E */
-#define SD25G_LANE_LANE_0E(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 56, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_0E */
+#define SD25G_LANE_LANE_0E(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 56, 0, 1, 4)
 
 #define SD25G_LANE_LANE_0E_LN_CFG_ISCAN_EN       BIT(0)
 #define SD25G_LANE_LANE_0E_LN_CFG_ISCAN_EN_SET(x)\
@@ -1579,8 +1738,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_0E_LN_CFG_DFEDIG_M_2_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_0E_LN_CFG_DFEDIG_M_2_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_0F */
-#define SD25G_LANE_LANE_0F(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 60, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_0F */
+#define SD25G_LANE_LANE_0F(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 60, 0, 1, 4)
 
 #define SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1  GENMASK(4, 0)
 #define SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1_SET(x)\
@@ -1588,8 +1749,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_18 */
-#define SD25G_LANE_LANE_18(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 96, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_18 */
+#define SD25G_LANE_LANE_18(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 96, 0, 1, 4)
 
 #define SD25G_LANE_LANE_18_LN_CFG_CDRCK_EN       BIT(0)
 #define SD25G_LANE_LANE_18_LN_CFG_CDRCK_EN_SET(x)\
@@ -1621,8 +1784,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_18_LN_CFG_RXDIV_SEL_2_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_18_LN_CFG_RXDIV_SEL_2_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_19 */
-#define SD25G_LANE_LANE_19(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 100, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_19 */
+#define SD25G_LANE_LANE_19(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 100, 0, 1, 4)
 
 #define SD25G_LANE_LANE_19_LN_CFG_DCDR_PD        BIT(0)
 #define SD25G_LANE_LANE_19_LN_CFG_DCDR_PD_SET(x)\
@@ -1672,8 +1837,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_19_LN_CFG_PD_CTLE_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_19_LN_CFG_PD_CTLE, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_1A */
-#define SD25G_LANE_LANE_1A(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 104, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_1A */
+#define SD25G_LANE_LANE_1A(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 104, 0, 1, 4)
 
 #define SD25G_LANE_LANE_1A_LN_CFG_CTLE_TP_EN     BIT(0)
 #define SD25G_LANE_LANE_1A_LN_CFG_CTLE_TP_EN_SET(x)\
@@ -1687,8 +1854,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_1A_LN_CFG_CDR_KF_2_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_1A_LN_CFG_CDR_KF_2_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_1B */
-#define SD25G_LANE_LANE_1B(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 108, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_1B */
+#define SD25G_LANE_LANE_1B(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 108, 0, 1, 4)
 
 #define SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0      GENMASK(7, 0)
 #define SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0_SET(x)\
@@ -1696,8 +1865,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_1C */
-#define SD25G_LANE_LANE_1C(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 112, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_1C */
+#define SD25G_LANE_LANE_1C(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 112, 0, 1, 4)
 
 #define SD25G_LANE_LANE_1C_LN_CFG_CDR_RSTN       BIT(0)
 #define SD25G_LANE_LANE_1C_LN_CFG_CDR_RSTN_SET(x)\
@@ -1723,8 +1894,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_1C_LN_CFG_EQC_FORCE_3_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_1C_LN_CFG_EQC_FORCE_3_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_1D */
-#define SD25G_LANE_LANE_1D(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 116, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_1D */
+#define SD25G_LANE_LANE_1D(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 116, 0, 1, 4)
 
 #define SD25G_LANE_LANE_1D_LN_CFG_ISCAN_EXT_OVR  BIT(0)
 #define SD25G_LANE_LANE_1D_LN_CFG_ISCAN_EXT_OVR_SET(x)\
@@ -1774,8 +1947,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_1D_LN_CFG_PI_HOLD_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_1D_LN_CFG_PI_HOLD, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_1E */
-#define SD25G_LANE_LANE_1E(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 120, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_1E */
+#define SD25G_LANE_LANE_1E(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 120, 0, 1, 4)
 
 #define SD25G_LANE_LANE_1E_LN_CFG_PI_STEPS_1_0   GENMASK(1, 0)
 #define SD25G_LANE_LANE_1E_LN_CFG_PI_STEPS_1_0_SET(x)\
@@ -1807,8 +1982,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_1E_LN_CFG_PMAD_CK_PD_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_1E_LN_CFG_PMAD_CK_PD, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_21 */
-#define SD25G_LANE_LANE_21(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 132, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_21 */
+#define SD25G_LANE_LANE_21(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 132, 0, 1, 4)
 
 #define SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0 GENMASK(4, 0)
 #define SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0_SET(x)\
@@ -1816,8 +1993,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_22 */
-#define SD25G_LANE_LANE_22(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 136, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_22 */
+#define SD25G_LANE_LANE_22(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 136, 0, 1, 4)
 
 #define SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0  GENMASK(3, 0)
 #define SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0_SET(x)\
@@ -1825,8 +2004,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_25 */
-#define SD25G_LANE_LANE_25(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 148, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_25 */
+#define SD25G_LANE_LANE_25(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 148, 0, 1, 4)
 
 #define SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0 GENMASK(6, 0)
 #define SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0_SET(x)\
@@ -1834,8 +2015,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_26 */
-#define SD25G_LANE_LANE_26(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 152, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_26 */
+#define SD25G_LANE_LANE_26(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 152, 0, 1, 4)
 
 #define SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0 GENMASK(6, 0)
 #define SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0_SET(x)\
@@ -1843,8 +2026,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_28 */
-#define SD25G_LANE_LANE_28(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 160, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_28 */
+#define SD25G_LANE_LANE_28(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 160, 0, 1, 4)
 
 #define SD25G_LANE_LANE_28_LN_CFG_ISCAN_MODE_EN  BIT(0)
 #define SD25G_LANE_LANE_28_LN_CFG_ISCAN_MODE_EN_SET(x)\
@@ -1870,8 +2055,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_28_LN_CFG_RX_SUBRATE_2_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_28_LN_CFG_RX_SUBRATE_2_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_2B */
-#define SD25G_LANE_LANE_2B(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 172, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_2B */
+#define SD25G_LANE_LANE_2B(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 172, 0, 1, 4)
 
 #define SD25G_LANE_LANE_2B_LN_CFG_PI_BW_3_0      GENMASK(3, 0)
 #define SD25G_LANE_LANE_2B_LN_CFG_PI_BW_3_0_SET(x)\
@@ -1891,8 +2078,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_2B_LN_CFG_RSTN_TXDUPU_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_2B_LN_CFG_RSTN_TXDUPU, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_2C */
-#define SD25G_LANE_LANE_2C(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 176, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_2C */
+#define SD25G_LANE_LANE_2C(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 176, 0, 1, 4)
 
 #define SD25G_LANE_LANE_2C_LN_CFG_TX_SUBRATE_2_0 GENMASK(2, 0)
 #define SD25G_LANE_LANE_2C_LN_CFG_TX_SUBRATE_2_0_SET(x)\
@@ -1906,8 +2095,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_2C_LN_CFG_DIS_2NDORDER_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_2C_LN_CFG_DIS_2NDORDER, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_2D */
-#define SD25G_LANE_LANE_2D(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 180, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_2D */
+#define SD25G_LANE_LANE_2D(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 180, 0, 1, 4)
 
 #define SD25G_LANE_LANE_2D_LN_CFG_ALOS_THR_2_0   GENMASK(2, 0)
 #define SD25G_LANE_LANE_2D_LN_CFG_ALOS_THR_2_0_SET(x)\
@@ -1921,8 +2112,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_2D_LN_CFG_SAT_CNTSEL_2_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_2D_LN_CFG_SAT_CNTSEL_2_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_2E */
-#define SD25G_LANE_LANE_2E(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 184, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_2E */
+#define SD25G_LANE_LANE_2E(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 184, 0, 1, 4)
 
 #define SD25G_LANE_LANE_2E_LN_CFG_EN_FAST_ISCAN  BIT(0)
 #define SD25G_LANE_LANE_2E_LN_CFG_EN_FAST_ISCAN_SET(x)\
@@ -1972,8 +2165,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_2E_LN_CFG_CTLE_RSTN_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_2E_LN_CFG_CTLE_RSTN, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_40 */
-#define SD25G_LANE_LANE_40(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 256, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_40 */
+#define SD25G_LANE_LANE_40(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 256, 0, 1, 4)
 
 #define SD25G_LANE_LANE_40_LN_R_TX_BIT_REVERSE   BIT(0)
 #define SD25G_LANE_LANE_40_LN_R_TX_BIT_REVERSE_SET(x)\
@@ -2017,8 +2212,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_40_LN_R_CTLE_RSTN_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_40_LN_R_CTLE_RSTN, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_42 */
-#define SD25G_LANE_LANE_42(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 264, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_42 */
+#define SD25G_LANE_LANE_42(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 264, 0, 1, 4)
 
 #define SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0 GENMASK(7, 0)
 #define SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0_SET(x)\
@@ -2026,8 +2223,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_43 */
-#define SD25G_LANE_LANE_43(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 268, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_43 */
+#define SD25G_LANE_LANE_43(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 268, 0, 1, 4)
 
 #define SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8 GENMASK(7, 0)
 #define SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8_SET(x)\
@@ -2035,8 +2234,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_44 */
-#define SD25G_LANE_LANE_44(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 272, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_44 */
+#define SD25G_LANE_LANE_44(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 272, 0, 1, 4)
 
 #define SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0 GENMASK(7, 0)
 #define SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0_SET(x)\
@@ -2044,8 +2245,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_45 */
-#define SD25G_LANE_LANE_45(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 276, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_45 */
+#define SD25G_LANE_LANE_45(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 276, 0, 1, 4)
 
 #define SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8 GENMASK(7, 0)
 #define SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8_SET(x)\
@@ -2053,8 +2256,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8, x)
 
-/*      SD25G_TARGET:LANE_GRP_1:LANE_DE */
-#define SD25G_LANE_LANE_DE(t)     __REG(TARGET_SD25G_LANE, t, 8, 1792, 0, 1, 128, 120, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_1:LANE_DE */
+#define SD25G_LANE_LANE_DE(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1792, 0, 1, 128, 120, 0, 1, 4)
 
 #define SD25G_LANE_LANE_DE_LN_LOL_UDL            BIT(0)
 #define SD25G_LANE_LANE_DE_LN_LOL_UDL_SET(x)\
@@ -2080,8 +2285,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_DE_LN_PMA_RXEI_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_DE_LN_PMA_RXEI, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_8:LANE_DF */
-#define SD6G_LANE_LANE_DF(t)      __REG(TARGET_SD6G_LANE, t, 13, 832, 0, 1, 84, 60, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD10G_LANE_TARGET:LANE_GRP_8:LANE_DF */
+#define SD6G_LANE_LANE_DF(t)                                                   \
+	__REG(TARGET_SD6G_LANE, t, 13, 832, 0, 1, 84, 60, 0, 1, 4)
 
 #define SD6G_LANE_LANE_DF_LOL_UDL                BIT(0)
 #define SD6G_LANE_LANE_DF_LOL_UDL_SET(x)\
@@ -2107,8 +2314,9 @@ enum sparx5_serdes_target {
 #define SD6G_LANE_LANE_DF_SQUELCH_GET(x)\
 	FIELD_GET(SD6G_LANE_LANE_DF_SQUELCH, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_0:CMU_00 */
-#define SD_CMU_CMU_00(t)          __REG(TARGET_SD_CMU, t, 14, 0, 0, 1, 20, 0, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_0:CMU_00 */
+#define SD_CMU_CMU_00(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 0, 0, 1, 20, 0, 0, 1, 4)
 
 #define SD_CMU_CMU_00_R_HWT_SIMULATION_MODE      BIT(0)
 #define SD_CMU_CMU_00_R_HWT_SIMULATION_MODE_SET(x)\
@@ -2134,8 +2342,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_00_CFG_PLL_TP_SEL_1_0_GET(x)\
 	FIELD_GET(SD_CMU_CMU_00_CFG_PLL_TP_SEL_1_0, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_1:CMU_05 */
-#define SD_CMU_CMU_05(t)          __REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 0, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_05 */
+#define SD_CMU_CMU_05(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 20, 0, 1, 72, 0, 0, 1, 4)
 
 #define SD_CMU_CMU_05_CFG_REFCK_TERM_EN          BIT(0)
 #define SD_CMU_CMU_05_CFG_REFCK_TERM_EN_SET(x)\
@@ -2149,9 +2358,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0_GET(x)\
 	FIELD_GET(SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_1:CMU_06 */
-#define SD_CMU_CMU_06(t) \
-	__REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 4, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_06 */
+#define SD_CMU_CMU_06(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 20, 0, 1, 72, 4, 0, 1, 4)
 
 #define SD_CMU_CMU_06_CFG_DISLOS                 BIT(0)
 #define SD_CMU_CMU_06_CFG_DISLOS_SET(x)\
@@ -2201,9 +2410,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_06_CFG_VCO_CAL_BYP_GET(x)\
 	FIELD_GET(SD_CMU_CMU_06_CFG_VCO_CAL_BYP, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_1:CMU_08 */
-#define SD_CMU_CMU_08(t) \
-	__REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 12, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_08 */
+#define SD_CMU_CMU_08(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 20, 0, 1, 72, 12, 0, 1, 4)
 
 #define SD_CMU_CMU_08_CFG_VFILT2PAD              BIT(0)
 #define SD_CMU_CMU_08_CFG_VFILT2PAD_SET(x)\
@@ -2235,8 +2444,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_08_CFG_RST_TREE_PD_MAN_EN_GET(x)\
 	FIELD_GET(SD_CMU_CMU_08_CFG_RST_TREE_PD_MAN_EN, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_1:CMU_09 */
-#define SD_CMU_CMU_09(t)          __REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 16, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_09 */
+#define SD_CMU_CMU_09(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 20, 0, 1, 72, 16, 0, 1, 4)
 
 #define SD_CMU_CMU_09_CFG_EN_TX_CK_UP            BIT(0)
 #define SD_CMU_CMU_09_CFG_EN_TX_CK_UP_SET(x)\
@@ -2262,8 +2472,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_09_CFG_SW_10G_GET(x)\
 	FIELD_GET(SD_CMU_CMU_09_CFG_SW_10G, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_1:CMU_0D */
-#define SD_CMU_CMU_0D(t)          __REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 32, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_0D */
+#define SD_CMU_CMU_0D(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 20, 0, 1, 72, 32, 0, 1, 4)
 
 #define SD_CMU_CMU_0D_CFG_PD_DIV64               BIT(0)
 #define SD_CMU_CMU_0D_CFG_PD_DIV64_SET(x)\
@@ -2295,8 +2506,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_0D_CFG_REFCK_PD_GET(x)\
 	FIELD_GET(SD_CMU_CMU_0D_CFG_REFCK_PD, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_3:CMU_1B */
-#define SD_CMU_CMU_1B(t)          __REG(TARGET_SD_CMU, t, 14, 104, 0, 1, 20, 4, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_3:CMU_1B */
+#define SD_CMU_CMU_1B(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 104, 0, 1, 20, 4, 0, 1, 4)
 
 #define SD_CMU_CMU_1B_CFG_RESERVE_7_0            GENMASK(7, 0)
 #define SD_CMU_CMU_1B_CFG_RESERVE_7_0_SET(x)\
@@ -2304,8 +2516,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_1B_CFG_RESERVE_7_0_GET(x)\
 	FIELD_GET(SD_CMU_CMU_1B_CFG_RESERVE_7_0, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_4:CMU_1F */
-#define SD_CMU_CMU_1F(t)          __REG(TARGET_SD_CMU, t, 14, 124, 0, 1, 68, 0, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_4:CMU_1F */
+#define SD_CMU_CMU_1F(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 124, 0, 1, 68, 0, 0, 1, 4)
 
 #define SD_CMU_CMU_1F_CFG_BIAS_DN_EN             BIT(0)
 #define SD_CMU_CMU_1F_CFG_BIAS_DN_EN_SET(x)\
@@ -2331,8 +2544,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_1F_CFG_VTUNE_SEL_GET(x)\
 	FIELD_GET(SD_CMU_CMU_1F_CFG_VTUNE_SEL, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_5:CMU_30 */
-#define SD_CMU_CMU_30(t)          __REG(TARGET_SD_CMU, t, 14, 192, 0, 1, 72, 0, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_5:CMU_30 */
+#define SD_CMU_CMU_30(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 192, 0, 1, 72, 0, 0, 1, 4)
 
 #define SD_CMU_CMU_30_R_PLL_DLOL_EN              BIT(0)
 #define SD_CMU_CMU_30_R_PLL_DLOL_EN_SET(x)\
@@ -2340,8 +2554,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_30_R_PLL_DLOL_EN_GET(x)\
 	FIELD_GET(SD_CMU_CMU_30_R_PLL_DLOL_EN, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_6:CMU_44 */
-#define SD_CMU_CMU_44(t)          __REG(TARGET_SD_CMU, t, 14, 264, 0, 1, 632, 8, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_6:CMU_44 */
+#define SD_CMU_CMU_44(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 264, 0, 1, 632, 8, 0, 1, 4)
 
 #define SD_CMU_CMU_44_R_PLL_RSTN                 BIT(0)
 #define SD_CMU_CMU_44_R_PLL_RSTN_SET(x)\
@@ -2355,8 +2570,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_44_R_CK_RESETB_GET(x)\
 	FIELD_GET(SD_CMU_CMU_44_R_CK_RESETB, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_6:CMU_45 */
-#define SD_CMU_CMU_45(t)          __REG(TARGET_SD_CMU, t, 14, 264, 0, 1, 632, 12, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_6:CMU_45 */
+#define SD_CMU_CMU_45(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 264, 0, 1, 632, 12, 0, 1, 4)
 
 #define SD_CMU_CMU_45_R_EN_RATECHG_CTRL          BIT(0)
 #define SD_CMU_CMU_45_R_EN_RATECHG_CTRL_SET(x)\
@@ -2406,8 +2622,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_45_R_AUTO_RST_TREE_PD_MAN_GET(x)\
 	FIELD_GET(SD_CMU_CMU_45_R_AUTO_RST_TREE_PD_MAN, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_6:CMU_47 */
-#define SD_CMU_CMU_47(t)          __REG(TARGET_SD_CMU, t, 14, 264, 0, 1, 632, 20, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_6:CMU_47 */
+#define SD_CMU_CMU_47(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 264, 0, 1, 632, 20, 0, 1, 4)
 
 #define SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0      GENMASK(4, 0)
 #define SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0_SET(x)\
@@ -2415,8 +2632,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0_GET(x)\
 	FIELD_GET(SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_7:CMU_E0 */
-#define SD_CMU_CMU_E0(t)          __REG(TARGET_SD_CMU, t, 14, 896, 0, 1, 8, 0, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_7:CMU_E0 */
+#define SD_CMU_CMU_E0(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 896, 0, 1, 8, 0, 0, 1, 4)
 
 #define SD_CMU_CMU_E0_READ_VCO_CTUNE_3_0         GENMASK(3, 0)
 #define SD_CMU_CMU_E0_READ_VCO_CTUNE_3_0_SET(x)\
@@ -2430,8 +2648,10 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_E0_PLL_LOL_UDL_GET(x)\
 	FIELD_GET(SD_CMU_CMU_E0_PLL_LOL_UDL, x)
 
-/*      SD_CMU_TARGET:SD_CMU_CFG:SD_CMU_CFG */
-#define SD_CMU_CFG_SD_CMU_CFG(t)  __REG(TARGET_SD_CMU_CFG, t, 14, 0, 0, 1, 8, 0, 0, 1, 4)
+/* SD_CMU_TARGET:SD_CMU_CFG:SD_CMU_CFG */
+#define SD_CMU_CFG_SD_CMU_CFG(t)                                               \
+	__REG(TARGET_SD_CMU_CFG, t, TSIZE(TC_SD_CMU_CFG), 0, 0, 1, 8, 0, 0, 1, \
+	      4)
 
 #define SD_CMU_CFG_SD_CMU_CFG_CMU_RST            BIT(0)
 #define SD_CMU_CFG_SD_CMU_CFG_CMU_RST_SET(x)\
@@ -2445,8 +2665,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CFG_SD_CMU_CFG_EXT_CFG_RST_GET(x)\
 	FIELD_GET(SD_CMU_CFG_SD_CMU_CFG_EXT_CFG_RST, x)
 
-/*      SD_LANE_TARGET:SD_RESET:SD_SER_RST */
-#define SD_LANE_SD_SER_RST(t)     __REG(TARGET_SD_LANE, t, 25, 0, 0, 1, 8, 0, 0, 1, 4)
+/* SD_LANE_TARGET:SD_RESET:SD_SER_RST */
+#define SD_LANE_SD_SER_RST(t)                                                  \
+	__REG(TARGET_SD_LANE, t, TSIZE(TC_SD_LANE), 0, 0, 1, 8, 0, 0, 1, 4)
 
 #define SD_LANE_SD_SER_RST_SER_RST               BIT(0)
 #define SD_LANE_SD_SER_RST_SER_RST_SET(x)\
@@ -2454,8 +2675,9 @@ enum sparx5_serdes_target {
 #define SD_LANE_SD_SER_RST_SER_RST_GET(x)\
 	FIELD_GET(SD_LANE_SD_SER_RST_SER_RST, x)
 
-/*      SD_LANE_TARGET:SD_RESET:SD_DES_RST */
-#define SD_LANE_SD_DES_RST(t)     __REG(TARGET_SD_LANE, t, 25, 0, 0, 1, 8, 4, 0, 1, 4)
+/* SD_LANE_TARGET:SD_RESET:SD_DES_RST */
+#define SD_LANE_SD_DES_RST(t)                                                  \
+	__REG(TARGET_SD_LANE, t, TSIZE(TC_SD_LANE), 0, 0, 1, 8, 4, 0, 1, 4)
 
 #define SD_LANE_SD_DES_RST_DES_RST               BIT(0)
 #define SD_LANE_SD_DES_RST_DES_RST_SET(x)\
@@ -2463,8 +2685,9 @@ enum sparx5_serdes_target {
 #define SD_LANE_SD_DES_RST_DES_RST_GET(x)\
 	FIELD_GET(SD_LANE_SD_DES_RST_DES_RST, x)
 
-/*      SD_LANE_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG */
-#define SD_LANE_SD_LANE_CFG(t)    __REG(TARGET_SD_LANE, t, 25, 8, 0, 1, 8, 0, 0, 1, 4)
+/* SD_LANE_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG */
+#define SD_LANE_SD_LANE_CFG(t)                                                 \
+	__REG(TARGET_SD_LANE, t, TSIZE(TC_SD_LANE), 8, 0, 1, 8, 0, 0, 1, 4)
 
 #define SD_LANE_SD_LANE_CFG_MACRO_RST            BIT(0)
 #define SD_LANE_SD_LANE_CFG_MACRO_RST_SET(x)\
@@ -2508,8 +2731,9 @@ enum sparx5_serdes_target {
 #define SD_LANE_SD_LANE_CFG_LANE_RX_RST_GET(x)\
 	FIELD_GET(SD_LANE_SD_LANE_CFG_LANE_RX_RST, x)
 
-/*      SD_LANE_TARGET:SD_LANE_CFG_STAT:SD_LANE_STAT */
-#define SD_LANE_SD_LANE_STAT(t)   __REG(TARGET_SD_LANE, t, 25, 8, 0, 1, 8, 4, 0, 1, 4)
+/* SD_LANE_TARGET:SD_LANE_CFG_STAT:SD_LANE_STAT */
+#define SD_LANE_SD_LANE_STAT(t)                                                \
+	__REG(TARGET_SD_LANE, t, TSIZE(TC_SD_LANE), 8, 0, 1, 8, 4, 0, 1, 4)
 
 #define SD_LANE_SD_LANE_STAT_PMA_RST_DONE        BIT(0)
 #define SD_LANE_SD_LANE_STAT_PMA_RST_DONE_SET(x)\
@@ -2529,9 +2753,9 @@ enum sparx5_serdes_target {
 #define SD_LANE_SD_LANE_STAT_DBG_OBS_GET(x)\
 	FIELD_GET(SD_LANE_SD_LANE_STAT_DBG_OBS, x)
 
-/*      SD_LANE_TARGET:SD_PWR_CFG:QUIET_MODE_6G */
-#define SD_LANE_QUIET_MODE_6G(t) \
-	__REG(TARGET_SD_LANE, t, 25, 24, 0, 1, 8, 4, 0, 1, 4)
+/* SD_LANE_TARGET:SD_PWR_CFG:QUIET_MODE_6G */
+#define SD_LANE_QUIET_MODE_6G(t)                                               \
+	__REG(TARGET_SD_LANE, t, TSIZE(TC_SD_LANE), 24, 0, 1, 8, 4, 0, 1, 4)
 
 #define SD_LANE_QUIET_MODE_6G_QUIET_MODE         GENMASK(24, 0)
 #define SD_LANE_QUIET_MODE_6G_QUIET_MODE_SET(x)\
@@ -2539,8 +2763,9 @@ enum sparx5_serdes_target {
 #define SD_LANE_QUIET_MODE_6G_QUIET_MODE_GET(x)\
 	FIELD_GET(SD_LANE_QUIET_MODE_6G_QUIET_MODE, x)
 
-/*      SD_LANE_TARGET:CFG_STAT_FX100:MISC */
-#define SD_LANE_MISC(t)           __REG(TARGET_SD_LANE, t, 25, 56, 0, 1, 56, 0, 0, 1, 4)
+/* SD_LANE_TARGET:CFG_STAT_FX100:MISC */
+#define SD_LANE_MISC(t)                                                        \
+	__REG(TARGET_SD_LANE, t, TSIZE(TC_SD_LANE), 56, 0, 1, 56, 0, 0, 1, 4)
 
 #define SD_LANE_MISC_SD_125_RST_DIS              BIT(0)
 #define SD_LANE_MISC_SD_125_RST_DIS_SET(x)\
@@ -2560,14 +2785,16 @@ enum sparx5_serdes_target {
 #define SD_LANE_MISC_MUX_ENA_GET(x)\
 	FIELD_GET(SD_LANE_MISC_MUX_ENA, x)
 
+/* SPARX5 ONLY */
 #define SD_LANE_MISC_CORE_CLK_FREQ               GENMASK(5, 4)
 #define SD_LANE_MISC_CORE_CLK_FREQ_SET(x)\
 	FIELD_PREP(SD_LANE_MISC_CORE_CLK_FREQ, x)
 #define SD_LANE_MISC_CORE_CLK_FREQ_GET(x)\
 	FIELD_GET(SD_LANE_MISC_CORE_CLK_FREQ, x)
 
-/*      SD_LANE_TARGET:CFG_STAT_FX100:M_STAT_MISC */
-#define SD_LANE_M_STAT_MISC(t)    __REG(TARGET_SD_LANE, t, 25, 56, 0, 1, 56, 36, 0, 1, 4)
+/* SD_LANE_TARGET:CFG_STAT_FX100:M_STAT_MISC */
+#define SD_LANE_M_STAT_MISC(t)                                                 \
+	__REG(TARGET_SD_LANE, t, TSIZE(TC_SD_LANE), 56, 0, 1, 56, 36, 0, 1, 4)
 
 #define SD_LANE_M_STAT_MISC_M_RIS_EDGE_PTR_ADJ_SUM GENMASK(21, 0)
 #define SD_LANE_M_STAT_MISC_M_RIS_EDGE_PTR_ADJ_SUM_SET(x)\
@@ -2581,8 +2808,10 @@ enum sparx5_serdes_target {
 #define SD_LANE_M_STAT_MISC_M_LOCK_CNT_GET(x)\
 	FIELD_GET(SD_LANE_M_STAT_MISC_M_LOCK_CNT, x)
 
-/*      SD25G_CFG_TARGET:SD_RESET:SD_SER_RST */
-#define SD_LANE_25G_SD_SER_RST(t) __REG(TARGET_SD_LANE_25G, t, 8, 0, 0, 1, 8, 0, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_CFG_TARGET:SD_RESET:SD_SER_RST */
+#define SD_LANE_25G_SD_SER_RST(t)                                              \
+	__REG(TARGET_SD_LANE_25G, t, 8, 0, 0, 1, 8, 0, 0, 1, 4)
 
 #define SD_LANE_25G_SD_SER_RST_SER_RST           BIT(0)
 #define SD_LANE_25G_SD_SER_RST_SER_RST_SET(x)\
@@ -2590,8 +2819,10 @@ enum sparx5_serdes_target {
 #define SD_LANE_25G_SD_SER_RST_SER_RST_GET(x)\
 	FIELD_GET(SD_LANE_25G_SD_SER_RST_SER_RST, x)
 
-/*      SD25G_CFG_TARGET:SD_RESET:SD_DES_RST */
-#define SD_LANE_25G_SD_DES_RST(t) __REG(TARGET_SD_LANE_25G, t, 8, 0, 0, 1, 8, 4, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_CFG_TARGET:SD_RESET:SD_DES_RST */
+#define SD_LANE_25G_SD_DES_RST(t)                                              \
+	__REG(TARGET_SD_LANE_25G, t, 8, 0, 0, 1, 8, 4, 0, 1, 4)
 
 #define SD_LANE_25G_SD_DES_RST_DES_RST           BIT(0)
 #define SD_LANE_25G_SD_DES_RST_DES_RST_SET(x)\
@@ -2599,8 +2830,10 @@ enum sparx5_serdes_target {
 #define SD_LANE_25G_SD_DES_RST_DES_RST_GET(x)\
 	FIELD_GET(SD_LANE_25G_SD_DES_RST_DES_RST, x)
 
-/*      SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG */
-#define SD_LANE_25G_SD_LANE_CFG(t) __REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 0, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG */
+#define SD_LANE_25G_SD_LANE_CFG(t)                                             \
+	__REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 0, 0, 1, 4)
 
 #define SD_LANE_25G_SD_LANE_CFG_MACRO_RST        BIT(0)
 #define SD_LANE_25G_SD_LANE_CFG_MACRO_RST_SET(x)\
@@ -2698,8 +2931,10 @@ enum sparx5_serdes_target {
 #define SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXMARGIN_GET(x)\
 	FIELD_GET(SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXMARGIN, x)
 
-/*      SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG2 */
-#define SD_LANE_25G_SD_LANE_CFG2(t) __REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 4, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG2 */
+#define SD_LANE_25G_SD_LANE_CFG2(t)                                            \
+	__REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 4, 0, 1, 4)
 
 #define SD_LANE_25G_SD_LANE_CFG2_DATA_WIDTH_SEL  GENMASK(2, 0)
 #define SD_LANE_25G_SD_LANE_CFG2_DATA_WIDTH_SEL_SET(x)\
@@ -2767,8 +3002,10 @@ enum sparx5_serdes_target {
 #define SD_LANE_25G_SD_LANE_CFG2_RXRATE_SEL_GET(x)\
 	FIELD_GET(SD_LANE_25G_SD_LANE_CFG2_RXRATE_SEL, x)
 
-/*      SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_STAT */
-#define SD_LANE_25G_SD_LANE_STAT(t) __REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 8, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_STAT */
+#define SD_LANE_25G_SD_LANE_STAT(t)                                            \
+	__REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 8, 0, 1, 4)
 
 #define SD_LANE_25G_SD_LANE_STAT_PMA_RST_DONE    BIT(0)
 #define SD_LANE_25G_SD_LANE_STAT_PMA_RST_DONE_SET(x)\
@@ -2788,8 +3025,9 @@ enum sparx5_serdes_target {
 #define SD_LANE_25G_SD_LANE_STAT_DBG_OBS_GET(x)\
 	FIELD_GET(SD_LANE_25G_SD_LANE_STAT_DBG_OBS, x)
 
-/*      SD25G_CFG_TARGET:SD_PWR_CFG:QUIET_MODE_6G */
-#define SD_LANE_25G_QUIET_MODE_6G(t) \
+/* SPARX5 ONLY */
+/* SD25G_CFG_TARGET:SD_PWR_CFG:QUIET_MODE_6G */
+#define SD_LANE_25G_QUIET_MODE_6G(t)                                           \
 	__REG(TARGET_SD_LANE_25G, t, 8, 28, 0, 1, 8, 4, 0, 1, 4)
 
 #define SD_LANE_25G_QUIET_MODE_6G_QUIET_MODE     GENMASK(24, 0)

-- 
2.34.1



From daniel.machon at microchip.com  Fri Sep  6 05:52:42 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 6 Sep 2024 14:52:42 +0200
Subject: [PATCH 5/9] phy: sparx5-serdes: add function for getting the CMU
 index
In-Reply-To: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
References: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
Message-ID: <20240906-sparx5-lan969x-serdes-driver-v1-5-8d630614c58a@microchip.com>

The SERDES to CMU mapping is different on Sparx5 and lan969x. Therefore
create a function for getting the CMU index on Sparx5.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c | 11 ++---------
 drivers/phy/microchip/sparx5_serdes.h |  9 +++++++++
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index b1376a142b14..5b918a2716dd 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -28,14 +28,6 @@
 /* Optimal power settings from GUC */
 #define SPX5_SERDES_QUIET_MODE_VAL 0x01ef4e0c
 
-enum sparx5_10g28cmu_mode {
-	SPX5_SD10G28_CMU_MAIN = 0,
-	SPX5_SD10G28_CMU_AUX1 = 1,
-	SPX5_SD10G28_CMU_AUX2 = 3,
-	SPX5_SD10G28_CMU_NONE = 4,
-	SPX5_SD10G28_CMU_MAX,
-};
-
 enum sparx5_sd25g28_mode_preset_type {
 	SPX5_SD25G28_MODE_PRESET_25000,
 	SPX5_SD25G28_MODE_PRESET_10000,
@@ -1648,7 +1640,7 @@ static int sparx5_sd10g28_apply_params(struct sparx5_serdes_macro *macro,
 	if (params->skip_cmu_cfg)
 		return 0;
 
-	cmu_idx = sparx5_serdes_cmu_get(params->cmu_sel, lane_index);
+	cmu_idx = priv->data->ops.serdes_cmu_get(params->cmu_sel, macro->sidx);
 	err = sparx5_cmu_cfg(priv, cmu_idx);
 	if (err)
 		return err;
@@ -2520,6 +2512,7 @@ static const struct sparx5_serdes_match_data sparx5_desc = {
 	},
 	.ops = {
 		.serdes_type_set      = &sparx5_serdes_type_set,
+		.serdes_cmu_get       = &sparx5_serdes_cmu_get,
 	},
 };
 
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index 785c7fe0bbeb..a7e92c1330e9 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -26,6 +26,14 @@ enum sparx5_serdes_mode {
 	SPX5_SD_MODE_SFI,
 };
 
+enum sparx5_10g28cmu_mode {
+	SPX5_SD10G28_CMU_MAIN = 0,
+	SPX5_SD10G28_CMU_AUX1 = 1,
+	SPX5_SD10G28_CMU_AUX2 = 3,
+	SPX5_SD10G28_CMU_NONE = 4,
+	SPX5_SD10G28_CMU_MAX,
+};
+
 struct sparx5_serdes_macro {
 	struct sparx5_serdes_private *priv;
 	u32 sidx;
@@ -44,6 +52,7 @@ struct sparx5_serdes_consts {
 
 struct sparx5_serdes_ops {
 	void (*serdes_type_set)(struct sparx5_serdes_macro *macro, int sidx);
+	int (*serdes_cmu_get)(enum sparx5_10g28cmu_mode mode, int sd_index);
 };
 
 struct sparx5_serdes_match_data {

-- 
2.34.1



From daniel.machon at microchip.com  Fri Sep  6 05:52:45 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 6 Sep 2024 14:52:45 +0200
Subject: [PATCH 8/9] dt-bindings: phy: sparx5: document lan969x in sparx5
 dt-bindings
In-Reply-To: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
References: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
Message-ID: <20240906-sparx5-lan969x-serdes-driver-v1-8-8d630614c58a@microchip.com>

Document lan969x in the existing Sparx5 dt-bindings.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 .../bindings/phy/microchip,sparx5-serdes.yaml          | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml b/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
index bdbdb3bbddbe..1e07a311e8a5 100644
--- a/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
+++ b/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
@@ -8,6 +8,7 @@ title: Microchip Sparx5 Serdes controller
 
 maintainers:
   - Steen Hegelund <steen.hegelund at microchip.com>
+  - Daniel Machon <daniel.machon at microchip.com>
 
 description: |
   The Sparx5 SERDES interfaces share the same basic functionality, but
@@ -62,12 +63,17 @@ description: |
   * 10.3125 Gbps (10GBASE-R/10GBASE-KR/USXGMII)
   * 25.78125 Gbps (25GBASE-KR/25GBASE-CR/25GBASE-SR/25GBASE-LR/25GBASE-ER)
 
+  lan969x has ten SERDES10G interfaces that share the same features, operating
+  modes and data rates as the equivalent Sparx5 SERDES10G interfaces.
+
 properties:
   $nodename:
     pattern: "^serdes@[0-9a-f]+$"
 
   compatible:
-    const: microchip,sparx5-serdes
+    enum:
+      - microchip,sparx5-serdes
+      - microchip,lan969x-serdes
 
   reg:
     minItems: 1
@@ -90,11 +96,19 @@ additionalProperties: false
 
 examples:
   - |
-    serdes: serdes at 10808000 {
+    serdes at 10808000 {
       compatible = "microchip,sparx5-serdes";
       #phy-cells = <1>;
       clocks = <&sys_clk>;
       reg = <0x10808000 0x5d0000>;
     };
 
+  - |
+    serdes at e3410000 {
+      compatible = "microchip,lan969x-serdes";
+      #phy-cells = <1>;
+      clocks = <&fabric_clk>;
+      reg = <0xe3410000 0x150000>;
+    };
+
 ...

-- 
2.34.1



From daniel.machon at microchip.com  Fri Sep  6 05:52:46 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 6 Sep 2024 14:52:46 +0200
Subject: [PATCH 9/9] phy: lan969x-serdes: add support for lan969x serdes
 driver
In-Reply-To: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
References: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
Message-ID: <20240906-sparx5-lan969x-serdes-driver-v1-9-8d630614c58a@microchip.com>

Add support for lan969x SERDES driver. Lan969x has ten 10G SERDES'es
which share the same features and data rates as the Sparx5 SERDES'es.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c | 88 +++++++++++++++++++++++++++++++++++
 drivers/phy/microchip/sparx5_serdes.h |  2 +
 2 files changed, 90 insertions(+)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index 05fdf225ff43..39ebc5b21258 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -25,6 +25,8 @@
 #define SPX5_SERDES_25G_START 25
 #define SPX5_SERDES_6G10G_CNT SPX5_SERDES_25G_START
 
+#define LAN969X_SERDES_10G_CNT 10
+
 /* Optimal power settings from GUC */
 #define SPX5_SERDES_QUIET_MODE_VAL 0x01ef4e0c
 
@@ -36,6 +38,13 @@ const unsigned int sparx5_serdes_tsize[TSIZE_LAST] = {
 	[TC_SD_LANE] = 25,
 };
 
+const unsigned int lan969x_serdes_tsize[TSIZE_LAST] = {
+	[TC_SD10G_LANE] = 10,
+	[TC_SD_CMU] = 6,
+	[TC_SD_CMU_CFG] = 6,
+	[TC_SD_LANE] = 10,
+};
+
 /* Pointer to the register target size table */
 const unsigned int *tsize;
 
@@ -1096,6 +1105,24 @@ static int sparx5_serdes_cmu_get(enum sparx5_10g28cmu_mode mode, int sd_index)
 	return sparx5_serdes_cmu_map[mode][sd_index];
 }
 
+/* Map of 6G/10G serdes mode and index to CMU index. */
+static const int
+lan969x_serdes_cmu_map[SPX5_SD10G28_CMU_MAX][LAN969X_SERDES_10G_CNT] = {
+	[SPX5_SD10G28_CMU_MAIN] = { 2, 2, 2, 2, 2,
+				    2, 2, 2, 5, 5 },
+	[SPX5_SD10G28_CMU_AUX1] = { 0, 0, 3, 3, 3,
+				    3, 3, 3, 3, 3 },
+	[SPX5_SD10G28_CMU_AUX2] = { 1, 1, 1, 1, 4,
+				    4, 4, 4, 4, 4 },
+	[SPX5_SD10G28_CMU_NONE] = { 1, 1, 1, 1, 4,
+				    4, 4, 4, 4, 4 },
+};
+
+static int lan969x_serdes_cmu_get(enum sparx5_10g28cmu_mode mode, int sd_index)
+{
+	return lan969x_serdes_cmu_map[mode][sd_index];
+}
+
 static void sparx5_serdes_cmu_power_off(struct sparx5_serdes_private *priv)
 {
 	void __iomem *cmu_inst, *cmu_cfg_inst;
@@ -2184,6 +2211,10 @@ static int sparx5_serdes_clock_config(struct sparx5_serdes_macro *macro)
 {
 	struct sparx5_serdes_private *priv = macro->priv;
 
+	/* Clock is auto-detected in 100Base-FX mode on lan969x */
+	if (priv->data->type == SPX5_TARGET_LAN969X)
+		return 0;
+
 	if (macro->serdesmode == SPX5_SD_MODE_100FX) {
 		u32 freq = priv->coreclock == 250000000 ? 2 :
 			priv->coreclock == 500000000 ? 1 : 0;
@@ -2395,6 +2426,12 @@ static void sparx5_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
 	}
 }
 
+static void lan969x_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
+{
+	macro->serdestype = SPX5_SDT_10G;
+	macro->stpidx = macro->sidx;
+}
+
 static int sparx5_phy_create(struct sparx5_serdes_private *priv,
 			   int idx, struct phy **phy)
 {
@@ -2519,6 +2556,41 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] =  {
 	{ TARGET_SD_LANE_25G + 7, 0x5c8000 }, /* 0x610dd0000: sd_lane_25g_32 */
 };
 
+static const struct sparx5_serdes_io_resource lan969x_serdes_iomap[] =  {
+	{ TARGET_SD_CMU,               0x0     }, /* 0xe3410000 */
+	{ TARGET_SD_CMU +  1,          0x8000  }, /* 0xe3418000 */
+	{ TARGET_SD_CMU +  2,          0x10000 }, /* 0xe3420000 */
+	{ TARGET_SD_CMU +  3,          0x18000 }, /* 0xe3428000 */
+	{ TARGET_SD_CMU +  4,          0x20000 }, /* 0xe3430000 */
+	{ TARGET_SD_CMU +  5,          0x28000 }, /* 0xe3438000 */
+	{ TARGET_SD_CMU_CFG,           0x30000 }, /* 0xe3440000 */
+	{ TARGET_SD_CMU_CFG +  1,      0x38000 }, /* 0xe3448000 */
+	{ TARGET_SD_CMU_CFG +  2,      0x40000 }, /* 0xe3450000 */
+	{ TARGET_SD_CMU_CFG +  3,      0x48000 }, /* 0xe3458000 */
+	{ TARGET_SD_CMU_CFG +  4,      0x50000 }, /* 0xe3460000 */
+	{ TARGET_SD_CMU_CFG +  5,      0x58000 }, /* 0xe3468000 */
+	{ TARGET_SD10G_LANE,           0x60000 }, /* 0xe3470000 */
+	{ TARGET_SD10G_LANE +  1,      0x68000 }, /* 0xe3478000 */
+	{ TARGET_SD10G_LANE +  2,      0x70000 }, /* 0xe3480000 */
+	{ TARGET_SD10G_LANE +  3,      0x78000 }, /* 0xe3488000 */
+	{ TARGET_SD10G_LANE +  4,      0x80000 }, /* 0xe3490000 */
+	{ TARGET_SD10G_LANE +  5,      0x88000 }, /* 0xe3498000 */
+	{ TARGET_SD10G_LANE +  6,      0x90000 }, /* 0xe34a0000 */
+	{ TARGET_SD10G_LANE +  7,      0x98000 }, /* 0xe34a8000 */
+	{ TARGET_SD10G_LANE +  8,      0xa0000 }, /* 0xe34b0000 */
+	{ TARGET_SD10G_LANE +  9,      0xa8000 }, /* 0xe34b8000 */
+	{ TARGET_SD_LANE,             0x100000 }, /* 0xe3510000 */
+	{ TARGET_SD_LANE +  1,        0x108000 }, /* 0xe3518000 */
+	{ TARGET_SD_LANE +  2,        0x110000 }, /* 0xe3520000 */
+	{ TARGET_SD_LANE +  3,        0x118000 }, /* 0xe3528000 */
+	{ TARGET_SD_LANE +  4,        0x120000 }, /* 0xe3530000 */
+	{ TARGET_SD_LANE +  5,        0x128000 }, /* 0xe3538000 */
+	{ TARGET_SD_LANE +  6,        0x130000 }, /* 0xe3540000 */
+	{ TARGET_SD_LANE +  7,        0x138000 }, /* 0xe3548000 */
+	{ TARGET_SD_LANE +  8,        0x140000 }, /* 0xe3550000 */
+	{ TARGET_SD_LANE +  9,        0x148000 }, /* 0xe3558000 */
+};
+
 static const struct sparx5_serdes_match_data sparx5_desc = {
 	.type = SPX5_TARGET_SPARX5,
 	.iomap = sparx5_serdes_iomap,
@@ -2534,6 +2606,21 @@ static const struct sparx5_serdes_match_data sparx5_desc = {
 	},
 };
 
+static const struct sparx5_serdes_match_data lan969x_desc = {
+	.type = SPX5_TARGET_LAN969X,
+	.iomap = lan969x_serdes_iomap,
+	.iomap_size = ARRAY_SIZE(lan969x_serdes_iomap),
+	.tsize = lan969x_serdes_tsize,
+	.consts = {
+		.sd_max       = 10,
+		.cmu_max      = 6,
+	},
+	.ops = {
+		.serdes_type_set      = &lan969x_serdes_type_set,
+		.serdes_cmu_get       = &lan969x_serdes_cmu_get,
+	}
+};
+
 /* Client lookup function, uses serdes index */
 static struct phy *sparx5_serdes_xlate(struct device *dev,
 				     const struct of_phandle_args *args)
@@ -2635,6 +2722,7 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 
 static const struct of_device_id sparx5_serdes_match[] = {
 	{ .compatible = "microchip,sparx5-serdes", .data = &sparx5_desc },
+	{ .compatible = "microchip,lan969x-serdes", .data = &lan969x_desc },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, sparx5_serdes_match);
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index 1beaa3d05a5d..d7093d0b09c0 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -36,6 +36,8 @@ enum sparx5_10g28cmu_mode {
 
 enum sparx5_target {
 	SPX5_TARGET_SPARX5,
+	SPX5_TARGET_LAN969X,
+
 };
 
 struct sparx5_serdes_macro {

-- 
2.34.1



From daniel.machon at microchip.com  Fri Sep  6 05:52:44 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 6 Sep 2024 14:52:44 +0200
Subject: [PATCH 7/9] phy: sparx5-serdes: add support for branching on chip
 type
In-Reply-To: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
References: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
Message-ID: <20240906-sparx5-lan969x-serdes-driver-v1-7-8d630614c58a@microchip.com>

In preparation for lan969x, add a way to branch out on code that is to
be executed on either Sparx5 or lan969x.  Initially, this is required to
branch out when checking the SERDES types and SERDES speeds, since the
handling of these differ on the two platforms. This will also be used by
the lan969x driver introduced in a subsequent patch.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c | 29 ++++++++++++++++++-----------
 drivers/phy/microchip/sparx5_serdes.h |  5 +++++
 2 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index 8a716bfaa023..05fdf225ff43 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -2298,10 +2298,12 @@ static int sparx5_serdes_set_speed(struct phy *phy, int speed)
 {
 	struct sparx5_serdes_macro *macro = phy_get_drvdata(phy);
 
-	if (macro->sidx < SPX5_SERDES_10G_START && speed > SPEED_5000)
-		return -EINVAL;
-	if (macro->sidx < SPX5_SERDES_25G_START && speed > SPEED_10000)
-		return -EINVAL;
+	if (macro->priv->data->type == SPX5_TARGET_SPARX5) {
+		if (macro->sidx < SPX5_SERDES_10G_START && speed > SPEED_5000)
+			return -EINVAL;
+		if (macro->sidx < SPX5_SERDES_25G_START && speed > SPEED_10000)
+			return -EINVAL;
+	}
 	if (speed != macro->speed) {
 		macro->speed = speed;
 		if (macro->serdesmode != SPX5_SD_MODE_NONE)
@@ -2338,11 +2340,14 @@ static int sparx5_serdes_validate(struct phy *phy, enum phy_mode mode,
 	if (macro->speed == 0)
 		return -EINVAL;
 
-	if (macro->sidx < SPX5_SERDES_10G_START && macro->speed > SPEED_5000)
-		return -EINVAL;
-	if (macro->sidx < SPX5_SERDES_25G_START && macro->speed > SPEED_10000)
-		return -EINVAL;
-
+	if (macro->priv->data->type == SPX5_TARGET_SPARX5) {
+		if (macro->sidx < SPX5_SERDES_10G_START &&
+		    macro->speed > SPEED_5000)
+			return -EINVAL;
+		if (macro->sidx < SPX5_SERDES_25G_START &&
+		    macro->speed > SPEED_10000)
+			return -EINVAL;
+	}
 	switch (submode) {
 	case PHY_INTERFACE_MODE_1000BASEX:
 		if (macro->speed != SPEED_100 && /* This is for 100BASE-FX */
@@ -2515,6 +2520,7 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] =  {
 };
 
 static const struct sparx5_serdes_match_data sparx5_desc = {
+	.type = SPX5_TARGET_SPARX5,
 	.iomap = sparx5_serdes_iomap,
 	.iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
 	.tsize = sparx5_serdes_tsize,
@@ -2618,8 +2624,9 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 			return err;
 	}
 
-	/* Power down all CMUs by default */
-	sparx5_serdes_cmu_power_off(priv);
+	/* Power down all CMU's by default */
+	if (priv->data->type == SPX5_TARGET_SPARX5)
+		sparx5_serdes_cmu_power_off(priv);
 
 	provider = devm_of_phy_provider_register(priv->dev, sparx5_serdes_xlate);
 
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index 50900bf06c4c..1beaa3d05a5d 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -34,6 +34,10 @@ enum sparx5_10g28cmu_mode {
 	SPX5_SD10G28_CMU_MAX,
 };
 
+enum sparx5_target {
+	SPX5_TARGET_SPARX5,
+};
+
 struct sparx5_serdes_macro {
 	struct sparx5_serdes_private *priv;
 	u32 sidx;
@@ -56,6 +60,7 @@ struct sparx5_serdes_ops {
 };
 
 struct sparx5_serdes_match_data {
+	enum sparx5_target type;
 	const struct sparx5_serdes_consts consts;
 	const struct sparx5_serdes_ops ops;
 	const struct sparx5_serdes_io_resource *iomap;

-- 
2.34.1



From krzk at kernel.org  Fri Sep  6 05:59:57 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 6 Sep 2024 14:59:57 +0200
Subject: [PATCH 8/9] dt-bindings: phy: sparx5: document lan969x in sparx5
 dt-bindings
In-Reply-To: <20240906-sparx5-lan969x-serdes-driver-v1-8-8d630614c58a@microchip.com>
References: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
 <20240906-sparx5-lan969x-serdes-driver-v1-8-8d630614c58a@microchip.com>
Message-ID: <c0aa5342-a2af-4ac4-bc33-b6dbfff77f63@kernel.org>

On 06/09/2024 14:52, Daniel Machon wrote:
> Document lan969x in the existing Sparx5 dt-bindings.
> 

Say something useful, not copy of subject.

> Signed-off-by: Daniel Machon <daniel.machon at microchip.com>

A nit, subject: drop second/last, redundant "dt-bindings". The
"dt-bindings" prefix is already stating that these are bindings.
See also:
https://elixir.bootlin.com/linux/v6.7-rc8/source/Documentation/devicetree/bindings/submitting-patches.rst#L18


> Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
> ---
>  .../bindings/phy/microchip,sparx5-serdes.yaml          | 18 ++++++++++++++++--
>  1 file changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml b/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
> index bdbdb3bbddbe..1e07a311e8a5 100644
> --- a/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
> +++ b/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
> @@ -8,6 +8,7 @@ title: Microchip Sparx5 Serdes controller
>  
>  maintainers:
>    - Steen Hegelund <steen.hegelund at microchip.com>
> +  - Daniel Machon <daniel.machon at microchip.com>
>  
>  description: |
>    The Sparx5 SERDES interfaces share the same basic functionality, but
> @@ -62,12 +63,17 @@ description: |
>    * 10.3125 Gbps (10GBASE-R/10GBASE-KR/USXGMII)
>    * 25.78125 Gbps (25GBASE-KR/25GBASE-CR/25GBASE-SR/25GBASE-LR/25GBASE-ER)
>  
> +  lan969x has ten SERDES10G interfaces that share the same features, operating
> +  modes and data rates as the equivalent Sparx5 SERDES10G interfaces.
> +
>  properties:
>    $nodename:
>      pattern: "^serdes@[0-9a-f]+$"
>  
>    compatible:
> -    const: microchip,sparx5-serdes
> +    enum:
> +      - microchip,sparx5-serdes
> +      - microchip,lan969x-serdes

It seems there is no lan969x SoC/chip. Are you sure you are using
correct naming, matching what kernel is using? Maybe you just sent
whatever you had in downstream (hint: that's never a good idea).

>  
>    reg:
>      minItems: 1
> @@ -90,11 +96,19 @@ additionalProperties: false
>  
>  examples:
>    - |
> -    serdes: serdes at 10808000 {
> +    serdes at 10808000 {
>        compatible = "microchip,sparx5-serdes";
>        #phy-cells = <1>;
>        clocks = <&sys_clk>;
>        reg = <0x10808000 0x5d0000>;
>      };
>  
> +  - |
> +    serdes at e3410000 {
> +      compatible = "microchip,lan969x-serdes";
> +      #phy-cells = <1>;
> +      clocks = <&fabric_clk>;

No differences so no need for new example. Also please follow DTS coding
style in case of any DTS code.

Best regards,
Krzysztof



From p.zabel at pengutronix.de  Fri Sep  6 06:44:01 2024
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Fri, 06 Sep 2024 15:44:01 +0200
Subject: [PATCH v5 2/5] phy: stm32: Add support for STM32MP25 COMBOPHY.
In-Reply-To: <20240903121303.2953150-3-christian.bruel@foss.st.com>
References: <20240903121303.2953150-1-christian.bruel@foss.st.com>
	 <20240903121303.2953150-3-christian.bruel@foss.st.com>
Message-ID: <d743de28a5dd643cf775f4d8a3baaabd09d48c48.camel@pengutronix.de>

Hi,

On Di, 2024-09-03 at 14:13 +0200, Christian Bruel wrote:
> Addition of the COMBOPHY driver found on STM32MP25 platforms
> 
> This single lane PHY is shared (exclusive) between the USB3 and PCIE
> controllers.
> Supports 5Gbit/s for PCIE gen2 or 2.5Gbit/s for PCIE gen1.
> 
> Supports wakeup-source capability to wakeup system using remote-wakeup
> capable USB device
> 
> Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
> ---
>  drivers/phy/st/Kconfig              |  11 +
>  drivers/phy/st/Makefile             |   1 +
>  drivers/phy/st/phy-stm32-combophy.c | 590 ++++++++++++++++++++++++++++
>  3 files changed, 602 insertions(+)
>  create mode 100644 drivers/phy/st/phy-stm32-combophy.c
> 
[...]
> diff --git a/drivers/phy/st/phy-stm32-combophy.c b/drivers/phy/st/phy-stm32-combophy.c
> new file mode 100644
> index 000000000000..305ba124d092
> --- /dev/null
> +++ b/drivers/phy/st/phy-stm32-combophy.c
> @@ -0,0 +1,590 @@
[...]
> +static int stm32_combophy_pll_init(struct stm32_combophy *combophy)
> +{
> +	int ret;
> +	u32 refclksel, pllmult, propcntrl, val;
> +	u32 clk_rate;
> +	struct clk *clk;
> +
> +	if (combophy->have_pad_clk)
> +		clk = combophy->clks[PAD_CLK].clk;
> +	else
> +		clk = combophy->clks[KER_CLK].clk;
> +
> +	clk_rate = clk_get_rate(clk);
> +
> +	reset_control_assert(combophy->phy_reset);
> +
> +	dev_dbg(combophy->dev, "%s pll init rate %d\n",
> +		combophy->have_pad_clk ? "External" : "Ker", clk_rate);
> +
> +	/*
> +	 * vddcombophy is interconnected with vddcore. Isolation bit should be unset
> +	 * before using the ComboPHY.
> +	 */
> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
> +			   SYSCFG_COMBOPHY_CR2_ISO_DIS, SYSCFG_COMBOPHY_CR2_ISO_DIS);
> +
> +	if (combophy->type != PHY_TYPE_PCIE)
> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
> +				   SYSCFG_COMBOPHY_CR1_REFSSPEN, SYSCFG_COMBOPHY_CR1_REFSSPEN);

Could the multiple accesses to SYSCFG_COMBOPHY_CR1 be consolidated into
a single regmap_update_bits()?

> +
> +	if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
> +		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
> +				   STM32MP25_PCIEPRGCR_EN, STM32MP25_PCIEPRGCR_EN);
> +
> +	if (of_property_present(combophy->dev->of_node, "st,ssc-on")) {
> +		dev_dbg(combophy->dev, "Enabling clock with SSC\n");
> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
> +				   SYSCFG_COMBOPHY_CR1_SSCEN, SYSCFG_COMBOPHY_CR1_SSCEN);
> +	}
> +
> +	if (!of_property_read_u32(combophy->dev->of_node, "st,rx-equalizer", &val)) {
> +		dev_dbg(combophy->dev, "Set RX equalizer %u\n", val);
> +		if (val > SYSCFG_COMBOPHY_CR4_RX0_EQ) {
> +			dev_err(combophy->dev, "Invalid value %u for rx0 equalizer\n", val);

This path looks like it should deassert the phy_reset as well.

> +			return -EINVAL;
> +		}
> +
> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR4,
> +			   SYSCFG_COMBOPHY_CR4_RX0_EQ, val);
> +	}
> +
> +	if (combophy->type == PHY_TYPE_PCIE) {
> +		ret = stm32_impedance_tune(combophy);
> +		if (ret) {
> +			reset_control_deassert(combophy->phy_reset);
> +			goto out;
> +		}
> +
> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
> +				   SYSCFG_COMBOPHY_CR1_REFUSEPAD,
> +				   combophy->have_pad_clk ? SYSCFG_COMBOPHY_CR1_REFUSEPAD : 0);
> +	}
> +
> +	switch (clk_rate) {
> +	case 100000000:
> +		pllmult = MPLLMULT_100;
> +		refclksel = REFCLKSEL_0;
> +		propcntrl = 0x8u << 4;
> +		break;
> +	case 19200000:
> +		pllmult = MPLLMULT_19_2;
> +		refclksel = REFCLKSEL_1;
> +		propcntrl = 0x8u << 4;
> +		break;
> +	case 25000000:
> +		pllmult = MPLLMULT_25;
> +		refclksel = REFCLKSEL_0;
> +		propcntrl = 0xeu << 4;
> +		break;
> +	case 24000000:
> +		pllmult = MPLLMULT_24;
> +		refclksel = REFCLKSEL_1;
> +		propcntrl = 0xeu << 4;
> +		break;
> +	case 20000000:
> +		pllmult = MPLLMULT_20;
> +		refclksel = REFCLKSEL_0;
> +		propcntrl = 0xeu << 4;
> +		break;
> +	default:
> +		dev_err(combophy->dev, "Invalid rate 0x%x\n", clk_rate);
> +		reset_control_deassert(combophy->phy_reset);
> +		ret = -EINVAL;
> +		goto out;
> +	};
> +
> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
> +			   SYSCFG_COMBOPHY_CR1_REFCLKDIV2, REFCLDIV_0);
> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
> +			   SYSCFG_COMBOPHY_CR1_REFCLKSEL, refclksel);
> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
> +			   SYSCFG_COMBOPHY_CR1_MPLLMULT, pllmult);
> +
> +	/*
> +	 * Force elasticity buffer to be tuned for the reference clock as
> +	 * the separated clock model is not supported
> +	 */
> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR5,
> +			   SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS, SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS);
> +
> +	reset_control_deassert(combophy->phy_reset);
> +
> +	ret = regmap_read_poll_timeout(combophy->regmap, SYSCFG_COMBOPHY_SR, val,
> +				       !(val & STM32MP25_PIPE0_PHYSTATUS),
> +				       10, 1000);
> +	if (ret) {
> +		dev_err(combophy->dev, "timeout, cannot lock PLL\n");
> +		goto out;
> +	}
> +
> +	if (combophy->type == PHY_TYPE_PCIE) {
> +		val = readl_relaxed(combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
> +		val &= ~COMBOPHY_PROP_CNTRL;
> +		val |= propcntrl;
> +		writel_relaxed(val, combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
> +	}
> +
> +	return 0;
> +
> +out:
> +	if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
> +		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
> +				   STM32MP25_PCIEPRGCR_EN, 0);
> +
> +	if (combophy->type != PHY_TYPE_PCIE)
> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
> +				   SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
> +
> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
> +			   SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
> +
> +	return ret;
> +}
> +
[...]
> +
> +static int stm32_combophy_probe(struct platform_device *pdev)
> +{
> +	struct stm32_combophy *combophy;
> +	struct device *dev = &pdev->dev;
> +	struct phy_provider *phy_provider;
> +	int ret, irq;
> +
> +	combophy = devm_kzalloc(dev, sizeof(*combophy), GFP_KERNEL);
> +	if (!combophy)
> +		return -ENOMEM;
> +
> +	combophy->dev = dev;
> +
> +	dev_set_drvdata(dev, combophy);
> +
> +	combophy->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(combophy->base))
> +		return PTR_ERR(combophy->base);
> +
> +	if (stm32_combophy_get_clocks(combophy))
> +		return ret;
> +
> +	combophy->phy_reset = devm_reset_control_get(dev, "phy");

Please use devm_reset_control_get_exclusive() directly.

regards
Philipp


From christophe.jaillet at wanadoo.fr  Fri Sep  6 12:57:47 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Fri,  6 Sep 2024 21:57:47 +0200
Subject: [PATCH] phy: renesas: rcar-gen3-usb2: Fix an error handling path in rcar_gen3_phy_usb2_probe()
Message-ID: <fc9f7b444f0ca645411868992bbe16514aeccfed.1725652654.git.christophe.jaillet@wanadoo.fr>

If an error occurs after the rcar_gen3_phy_usb2_init_bus(),
reset_control_assert() must be called, as already done in the remove
function.

Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus")
Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 58e123305152..8577056491de 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -770,7 +770,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 		if (IS_ERR(channel->rphys[i].phy)) {
 			dev_err(dev, "Failed to create USB2 PHY\n");
 			ret = PTR_ERR(channel->rphys[i].phy);
-			goto error;
+			goto err_control_assert;
 		}
 		channel->rphys[i].ch = channel;
 		channel->rphys[i].int_enable_bits = rcar_gen3_int_enable[i];
@@ -784,7 +784,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 	if (IS_ERR(channel->vbus)) {
 		if (PTR_ERR(channel->vbus) == -EPROBE_DEFER) {
 			ret = PTR_ERR(channel->vbus);
-			goto error;
+			goto err_control_assert;
 		}
 		channel->vbus = NULL;
 	}
@@ -793,15 +793,17 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 	if (IS_ERR(provider)) {
 		dev_err(dev, "Failed to register PHY provider\n");
 		ret = PTR_ERR(provider);
-		goto error;
+		goto err_control_assert;
 	} else if (channel->is_otg_channel) {
 		ret = device_create_file(dev, &dev_attr_role);
 		if (ret < 0)
-			goto error;
+			goto err_control_assert;
 	}
 
 	return 0;
 
+err_control_assert:
+	reset_control_assert(channel->rstc);
 error:
 	pm_runtime_disable(dev);
 
-- 
2.46.0



From frieder at fris.de  Fri Sep  6 13:28:59 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Fri, 6 Sep 2024 22:28:59 +0200
Subject: [PATCH V6 4/5] phy: freescale: fsl-samsung-hdmi: Use closest
 divider
In-Reply-To: <CAHCN7xLo1RgkUPTdTpCtKjnT7w=gPDCfe_ZEbKj0joVvLG02Dw@mail.gmail.com>
References: <20240904233100.114611-1-aford173@gmail.com>
 <20240904233100.114611-5-aford173@gmail.com>
 <ZtpMPCHBnEgtkBWp@atmark-techno.com>
 <CAHCN7xLo1RgkUPTdTpCtKjnT7w=gPDCfe_ZEbKj0joVvLG02Dw@mail.gmail.com>
Message-ID: <ada922ea-b307-4ccf-9e2d-9a2a08fb97c1@fris.de>

On 06.09.24 02:57, Adam Ford wrote:
> On Thu, Sep 5, 2024 at 7:26?PM Dominique Martinet
> <dominique.martinet at atmark-techno.com> wrote:
>>
>>
>> (sorry I meant to send this yesterday but I'm being forced to adjust my
>> mail pipeline with work and gmail and it didn't go out -- trying
>> again. Sorry if it actually did go through. Hopefully I didn't misfire
>> anything else yesterday...)
>>
>> Adam Ford wrote on Wed, Sep 04, 2024 at 06:30:32PM -0500:
>>> Currently, if the clock values cannot be set to the exact rate,
>>> the round_rate and set_rate functions use the closest value found in
>>> the look-up-table.  In preparation of removing values from the LUT
>>> that can be calculated evenly with the integer calculator, it's
>>> necessary to ensure to check both the look-up-table and the integer
>>> divider clock values to get the closest values to the requested
>>> value.  It does this by measuring the difference between the
>>> requested clock value and the closest value in both integer divider
>>> calucator and the fractional clock look-up-table.
>>>
>>> Which ever has the smallest difference between them is returned as
>>> the cloesest rate.
>>>
>>> Signed-off-by: Adam Ford <aford173 at gmail.com>
>>> Signed-off-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
>>
>> b4 (or whatever you're using) probably picked that up from the patch I
>> included in my reply to this patch, this sob should go away.
>>
> For each iteration, I grabbed the patches from patchwork which
> contained any s-o-b messages, if present.  I didn't add anything
> manually.
>>
>>
>>> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
>>> index 4b13e386e5ba..9a21dbbf1a82 100644
>>> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
>>> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
>>> @@ -547,6 +547,16 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
>>>        return phy->cur_cfg->pixclk;
>>>   }
>>>
>>> +static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate,
>>> +                                              u32 int_div_clk, u32 frac_div_clk)
>>> +{
>>> +     /* The int_div_clk may be greater than rate, so cast it and use ABS */
>>> +     if (abs((long)rate - (long)int_div_clk) < (rate - frac_div_clk))
>>
>> I still think `rate - frac_div_clk` might not always hold in the future
>> (because there is no intrinsic reason we'd pick the smaller end in case
>> of inexact match and a future improvement might change this to the
>> closest value as well), so I'll argue again for having both use abs(),
>> but at least there's only one place to update if that changes in the
>> future now so hopefully whoever does this will notice...
> 
> I can add the ABS on the fractional divider.  I left it out on purpose
> since the LUT table always return a value equal or less, so the extra
> ABS seemed like busy work.  However, I can see the argument for being
> consistent.
> 
>>
>>> +             return int_div_clk;
>>> +
>>> +     return frac_div_clk;
>>> +}
>>> +
>>>   static long phy_clk_round_rate(struct clk_hw *hw,
>>>                               unsigned long rate, unsigned long *parent_rate)
>>>   {
>>> @@ -563,6 +573,7 @@ static long phy_clk_round_rate(struct clk_hw *hw,
>>>        for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
>>>                if (phy_pll_cfg[i].pixclk <= rate)
>>>                        break;
>>> +
>>
>> (unrelated)
> 
> I don't understand what you're asking here.
> 
>>
>>>        /* If the rate is an exact match, return it now */
>>>        if (rate == phy_pll_cfg[i].pixclk)
>>>                return phy_pll_cfg[i].pixclk;
>>> @@ -579,8 +590,7 @@ static long phy_clk_round_rate(struct clk_hw *hw,
>>>        if (int_div_clk == rate)
>>>                return int_div_clk;
>>>
>>> -     /* Fall back to the closest value in the LUT */
>>> -     return phy_pll_cfg[i].pixclk;
>>> +     return fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk, phy_pll_cfg[i].pixclk);
>>>   }
>>>
>>>   static int phy_clk_set_rate(struct clk_hw *hw,
>>> @@ -594,27 +604,37 @@ static int phy_clk_set_rate(struct clk_hw *hw,
>>>
>>>        /* If the integer divider works, just use it */
>>
>> I found this comment a bit confusing given the current flow as of this
>> patch. Might make more sense immediately before the if?
>>
> 
> This code evolved with each iteration, but I didn't necessarily
> reorganize the comments.  I can rearrange them.
>>
>>>        int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate * 5, &p, &m, &s) / 5;
>>> +     calculated_phy_pll_cfg.pixclk = int_div_clk;
>>> +     calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
>>> +     calculated_phy_pll_cfg.pll_div_regs[1] = m;
>>> +     calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
>>> +     phy->cur_cfg = &calculated_phy_pll_cfg;
>>>        if (int_div_clk == rate) {
>>>                dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using integer divider\n");
>>> -             calculated_phy_pll_cfg.pixclk = int_div_clk;
>>> -             calculated_phy_pll_cfg.pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
>>> -             calculated_phy_pll_cfg.pll_div_regs[1] = m;
>>> -             calculated_phy_pll_cfg.pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
>>> -             /* pll_div_regs 3-6 are fixed and pre-defined already */
>>
>> nitpick: might want to keep the above comment?
> 
> ok.
>>
>>> -             phy->cur_cfg  = &calculated_phy_pll_cfg;
>>> +             goto done;
>>>        } else {
>>>                /* Otherwise, search the LUT */
>>> -             dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
>>> -             for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
>>> -                     if (phy_pll_cfg[i].pixclk <= rate)
>>> +             for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--) {
>>> +                     if (phy_pll_cfg[i].pixclk == rate) {
>>> +                             dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider\n");
>>
>> nitpick: might make sense to print what was picked in case of inexact
>> match as well, but these are dbg warning so probably fine either way.
> 
> I can add the actual values returned.
> 
>>
>>
>> overall I find the flow of this function hard to read; it's a bit ugly
>> flow-wise but jumping in the clock comparison 'if' might help trim this?
>> (and if we're going out of our way to factor out the diff, maybe the lut
>> lookup could be as well)
>>
>> But I'm probably just being overcritical here, it's fine as is if you
>> pefer your version, just writing down this as an illustration of what I
>> meant with the above sentence as I'm not sure I was clear -- I'll be
>> just as happy to consider this series done so we can do more interesting
>> things :P
> 
> Now I am a bit more confused, because above I got the impression you
> were withdrawing your s-o-b, but now it sounds like you want to move
> it forward.
> 
> It sounded like Frieder was making some progress on understanding a
> little more about the fractional divider.

I think I managed to get behind the calculation of the fractional-n 
divider parameters. I came up with a spreadsheet to calculate the output 
frequency from existing register values and I have a crude Python script 
that can be used to search for parameters for a given pixel clock.

I tested this with three different non-CEA-861 pixel clock values 
(supported by my HDMI USB grabber) for which the integer PLL yielded 
deviations >0.5%. With the new LUT entries those modes work now.

I will clean things up a bit and then share what I have. I hope that 
this allows anyone to calculate parameters for their non-standard 
displays if required.

If someone feels extra motivated they could try to calculate the 
fractional parameters at runtime. However I'm not sure that this is 
feasible. The numerical computation of a large number of parameters is 
quite heavy and it's probably not easy to strip the algorithm down to 
something that can be run on the target without too much overhead.

> 
>>
>> {
>>      u32 int_div_clk, frac_div_clk;
>>      int i;
>>      u16 m;
>>      u8 p, s;
>>
>>      // (I haven't given up on that *5 to move inside this function...)
> 
> I wanted to keep the PMS calculator returning the real clock value
> since the calculations are based on equation in the ref manual, Fpll =
> Fref * M / (P*S)
> This way, the calling function can determine if it needs to be
> multiplied by 5.  I haven't fully determined how the fractional
> calculator determines what frequency it wants for a target frequency,
> and using the values for P, M and S from the fractional divider
> doesn't seem to always yield 5x like they did for the table entries
> using the integer divider.

For what I found out the factor of 5 always applies. For the integer 
part and also for the fractional part.

> 
> I am hoping someone from NXP can elaborate, or give us some clues on
> how to get better fractional divider values.



From dominique.martinet at atmark-techno.com  Fri Sep  6 21:49:59 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Sat, 7 Sep 2024 13:49:59 +0900
Subject: [PATCH V6 4/5] phy: freescale: fsl-samsung-hdmi: Use closest
 divider
In-Reply-To: <ada922ea-b307-4ccf-9e2d-9a2a08fb97c1@fris.de>
References: <20240904233100.114611-1-aford173@gmail.com>
 <20240904233100.114611-5-aford173@gmail.com>
 <ZtpMPCHBnEgtkBWp@atmark-techno.com>
 <CAHCN7xLo1RgkUPTdTpCtKjnT7w=gPDCfe_ZEbKj0joVvLG02Dw@mail.gmail.com>
 <ada922ea-b307-4ccf-9e2d-9a2a08fb97c1@fris.de>
Message-ID: <Ztvbd4XqY95YMAZd@atmark-techno.com>

Frieder Schrempf wrote on Fri, Sep 06, 2024 at 10:28:59PM +0200:
> I think I managed to get behind the calculation of the fractional-n divider
> parameters. I came up with a spreadsheet to calculate the output frequency
> from existing register values and I have a crude Python script that can be
> used to search for parameters for a given pixel clock.
> 
> I tested this with three different non-CEA-861 pixel clock values (supported
> by my HDMI USB grabber) for which the integer PLL yielded deviations >0.5%.
> With the new LUT entries those modes work now.
> 
> I will clean things up a bit and then share what I have. I hope that this
> allows anyone to calculate parameters for their non-standard displays if
> required.
> 
> If someone feels extra motivated they could try to calculate the fractional
> parameters at runtime. However I'm not sure that this is feasible. The
> numerical computation of a large number of parameters is quite heavy and
> it's probably not easy to strip the algorithm down to something that can be
> run on the target without too much overhead.

I think keeping the LUT is perfectly fine if we know where the values
come from - perhaps having your python program in a comment above the
LUT so anyone can check the values match?

My main problem with the LUT is just that -- there's no way of
checking. If the values come from somewhere sensible and can be verified
I think it makes sense to keep it to fill the holes where the integer
divider isn't enough.

> > This way, the calling function can determine if it needs to be
> > multiplied by 5.  I haven't fully determined how the fractional
> > calculator determines what frequency it wants for a target frequency,
> > and using the values for P, M and S from the fractional divider
> > doesn't seem to always yield 5x like they did for the table entries
> > using the integer divider.
> 
> For what I found out the factor of 5 always applies. For the integer part
> and also for the fractional part.

In that case I'm definitely in favor of moving it inside the function as
part of the calculation

Thank you both!
-- 
Dominique


From claudiu.beznea at tuxon.dev  Sat Sep  7 03:54:15 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sat, 7 Sep 2024 13:54:15 +0300
Subject: [PATCH] phy: renesas: rcar-gen3-usb2: Fix an error handling path
 in rcar_gen3_phy_usb2_probe()
In-Reply-To: <fc9f7b444f0ca645411868992bbe16514aeccfed.1725652654.git.christophe.jaillet@wanadoo.fr>
References: <fc9f7b444f0ca645411868992bbe16514aeccfed.1725652654.git.christophe.jaillet@wanadoo.fr>
Message-ID: <31112ec9-43cc-403b-a6c0-7e7804fdcda5@tuxon.dev>

Hi, Christophe,

On 06.09.2024 22:57, Christophe JAILLET wrote:
> If an error occurs after the rcar_gen3_phy_usb2_init_bus(),
> reset_control_assert() must be called, as already done in the remove
> function.
> 
> Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus")
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> ---
>  drivers/phy/renesas/phy-rcar-gen3-usb2.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> index 58e123305152..8577056491de 100644
> --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> @@ -770,7 +770,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
>  		if (IS_ERR(channel->rphys[i].phy)) {
>  			dev_err(dev, "Failed to create USB2 PHY\n");
>  			ret = PTR_ERR(channel->rphys[i].phy);
> -			goto error;
> +			goto err_control_assert;
>  		}
>  		channel->rphys[i].ch = channel;
>  		channel->rphys[i].int_enable_bits = rcar_gen3_int_enable[i];
> @@ -784,7 +784,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
>  	if (IS_ERR(channel->vbus)) {
>  		if (PTR_ERR(channel->vbus) == -EPROBE_DEFER) {
>  			ret = PTR_ERR(channel->vbus);
> -			goto error;
> +			goto err_control_assert;
>  		}
>  		channel->vbus = NULL;
>  	}
> @@ -793,15 +793,17 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
>  	if (IS_ERR(provider)) {
>  		dev_err(dev, "Failed to register PHY provider\n");
>  		ret = PTR_ERR(provider);
> -		goto error;
> +		goto err_control_assert;
>  	} else if (channel->is_otg_channel) {
>  		ret = device_create_file(dev, &dev_attr_role);
>  		if (ret < 0)
> -			goto error;
> +			goto err_control_assert;
>  	}
>  
>  	return 0;
>  
> +err_control_assert:
> +	reset_control_assert(channel->rstc);
>  error:

It would be simpler to fix it by calling here:
	reset_control_assert(channel->rstc);

as it's the case for rcar_gen3_phy_usb2_remove().

Thank you,
Claudiu Beznea

>  	pm_runtime_disable(dev);
>  


From christophe.jaillet at wanadoo.fr  Sat Sep  7 06:58:52 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sat,  7 Sep 2024 15:58:52 +0200
Subject: [PATCH v2] phy: renesas: rcar-gen3-usb2: Fix an error handling path in rcar_gen3_phy_usb2_probe()
Message-ID: <4efe2d0419cbe98163e2422ebe0c7896b8a5efed.1725717505.git.christophe.jaillet@wanadoo.fr>

If an error occurs after the rcar_gen3_phy_usb2_init_bus(),
reset_control_assert() must be called, as already done in the remove
function.

This is fine to re-use the existing error handling path, because even if
"channel->rstc" is still NULL at this point, it is safe to call
reset_control_assert(NULL).

Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus")
Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
Changes in v2:
  - Re-use 'error' to simplify the patch   [claudiu beznea]
  - Update the commit description to explain why it is safe.

v1: https://lore.kernel.org/all/fc9f7b444f0ca645411868992bbe16514aeccfed.1725652654.git.christophe.jaillet at wanadoo.fr/
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 58e123305152..ccb0b54b70f7 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -803,6 +803,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 	return 0;
 
 error:
+	reset_control_assert(channel->rstc);
 	pm_runtime_disable(dev);
 
 	return ret;
-- 
2.46.0



From abel.vesa at linaro.org  Sat Sep  7 08:25:21 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Sat, 07 Sep 2024 18:25:21 +0300
Subject: [PATCH] phy: qcom: edp: Add runtime PM support
Message-ID: <20240907-phy-qcom-edp-enable-runtime-pm-v1-1-8b9ee4210e1e@linaro.org>

Enable runtime PM support by adding proper ops which will handle the
clocks and regulators. These resources will now be handled on power_on and
power_off instead of init and exit PHY ops. Also enable these resources on
probe in order to balance out the disabling that is happening right after.
Prevent runtime PM from being ON by default as well.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/phy/qualcomm/phy-qcom-edp.c | 105 ++++++++++++++++++++++++++----------
 1 file changed, 77 insertions(+), 28 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
index da2b32fb5b45..3affeef261bf 100644
--- a/drivers/phy/qualcomm/phy-qcom-edp.c
+++ b/drivers/phy/qualcomm/phy-qcom-edp.c
@@ -192,14 +192,6 @@ static int qcom_edp_phy_init(struct phy *phy)
 	int ret;
 	u8 cfg8;
 
-	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
-	if (ret)
-		return ret;
-
-	ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
-	if (ret)
-		goto out_disable_supplies;
-
 	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
 	       DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
 	       edp->edp + DP_PHY_PD_CTL);
@@ -246,11 +238,6 @@ static int qcom_edp_phy_init(struct phy *phy)
 	msleep(20);
 
 	return 0;
-
-out_disable_supplies:
-	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
-
-	return ret;
 }
 
 static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configure_opts_dp *dp_opts)
@@ -721,6 +708,8 @@ static int qcom_edp_phy_power_on(struct phy *phy)
 	u32 val;
 	u8 cfg1;
 
+	pm_runtime_get_sync(&phy->dev);
+
 	ret = edp->cfg->ver_ops->com_power_on(edp);
 	if (ret)
 		return ret;
@@ -841,6 +830,8 @@ static int qcom_edp_phy_power_off(struct phy *phy)
 
 	writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL);
 
+	pm_runtime_put(&phy->dev);
+
 	return 0;
 }
 
@@ -856,23 +847,12 @@ static int qcom_edp_phy_set_mode(struct phy *phy, enum phy_mode mode, int submod
 	return 0;
 }
 
-static int qcom_edp_phy_exit(struct phy *phy)
-{
-	struct qcom_edp *edp = phy_get_drvdata(phy);
-
-	clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
-	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
-
-	return 0;
-}
-
 static const struct phy_ops qcom_edp_ops = {
 	.init		= qcom_edp_phy_init,
 	.configure	= qcom_edp_phy_configure,
 	.power_on	= qcom_edp_phy_power_on,
 	.power_off	= qcom_edp_phy_power_off,
 	.set_mode	= qcom_edp_phy_set_mode,
-	.exit		= qcom_edp_phy_exit,
 	.owner		= THIS_MODULE,
 };
 
@@ -1036,6 +1016,32 @@ static int qcom_edp_clks_register(struct qcom_edp *edp, struct device_node *np)
 	return devm_of_clk_add_hw_provider(edp->dev, of_clk_hw_onecell_get, data);
 }
 
+static int __maybe_unused qcom_edp_runtime_suspend(struct device *dev)
+{
+	struct qcom_edp *edp = dev_get_drvdata(dev);
+
+	dev_err(dev, "Suspending DP phy\n");
+
+	clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
+	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
+
+	return 0;
+}
+
+static int __maybe_unused qcom_edp_runtime_resume(struct device *dev)
+{
+	struct qcom_edp *edp = dev_get_drvdata(dev);
+	int ret;
+
+	dev_err(dev, "Resuming DP phy\n");
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
+	if (ret)
+		return ret;
+
+	return clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
+}
+
 static int qcom_edp_phy_probe(struct platform_device *pdev)
 {
 	struct phy_provider *phy_provider;
@@ -1091,20 +1097,57 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
-	if (ret)
+	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
+	if (ret) {
+		dev_err(dev, "failed to enable regulators, err=%d\n", ret);
 		return ret;
+	}
+
+	ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
+	if (ret) {
+		dev_err(dev, "failed to enable clocks, err=%d\n", ret);
+		goto err_disable_regulators;
+	}
+
+	ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
+	if (ret) {
+		dev_err(dev, "failed to register PHY clocks, err=%d\n", ret);
+		goto err_disable_clocks;
+	}
 
 	edp->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_edp_ops);
 	if (IS_ERR(edp->phy)) {
 		dev_err(dev, "failed to register phy\n");
-		return PTR_ERR(edp->phy);
+		ret = PTR_ERR(edp->phy);
+		goto err_disable_clocks;
 	}
 
+	pm_runtime_set_active(dev);
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		goto err_disable_clocks;
+	/*
+	 * Prevent runtime pm from being ON by default. Users can enable
+	 * it using power/control in sysfs.
+	 */
+	pm_runtime_forbid(dev);
+
+	dev_set_drvdata(dev, edp);
 	phy_set_drvdata(edp->phy, edp);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-	return PTR_ERR_OR_ZERO(phy_provider);
+	if (IS_ERR(phy_provider))
+		goto err_disable_clocks;
+
+	return 0;
+
+err_disable_clocks:
+	clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
+
+err_disable_regulators:
+	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
+
+	return ret;
 }
 
 static const struct of_device_id qcom_edp_phy_match_table[] = {
@@ -1117,10 +1160,16 @@ static const struct of_device_id qcom_edp_phy_match_table[] = {
 };
 MODULE_DEVICE_TABLE(of, qcom_edp_phy_match_table);
 
+static const struct dev_pm_ops qcom_edp_pm_ops = {
+	SET_RUNTIME_PM_OPS(qcom_edp_runtime_suspend,
+			   qcom_edp_runtime_resume, NULL)
+};
+
 static struct platform_driver qcom_edp_phy_driver = {
 	.probe		= qcom_edp_phy_probe,
 	.driver = {
 		.name	= "qcom-edp-phy",
+		.pm	= &qcom_edp_pm_ops,
 		.of_match_table = qcom_edp_phy_match_table,
 	},
 };

---
base-commit: 9aaeb87ce1e966169a57f53a02ba05b30880ffb8
change-id: 20240907-phy-qcom-edp-enable-runtime-pm-6fad07af8947

Best regards,
-- 
Abel Vesa <abel.vesa at linaro.org>



From dmitry.baryshkov at linaro.org  Sat Sep  7 10:52:14 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sat, 7 Sep 2024 20:52:14 +0300
Subject: [PATCH] phy: qcom: edp: Add runtime PM support
In-Reply-To: <20240907-phy-qcom-edp-enable-runtime-pm-v1-1-8b9ee4210e1e@linaro.org>
References: <20240907-phy-qcom-edp-enable-runtime-pm-v1-1-8b9ee4210e1e@linaro.org>
Message-ID: <CAA8EJpqw6pB4d_zQyYdhq9_prLnh+mLMdRSzJ+5EvAjT9wi86A@mail.gmail.com>

On Sat, 7 Sept 2024 at 18:25, Abel Vesa <abel.vesa at linaro.org> wrote:
>
> Enable runtime PM support by adding proper ops which will handle the
> clocks and regulators. These resources will now be handled on power_on and
> power_off instead of init and exit PHY ops. Also enable these resources on
> probe in order to balance out the disabling that is happening right after.
> Prevent runtime PM from being ON by default as well.
>
> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> ---
>  drivers/phy/qualcomm/phy-qcom-edp.c | 105 ++++++++++++++++++++++++++----------
>  1 file changed, 77 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> index da2b32fb5b45..3affeef261bf 100644
> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> @@ -192,14 +192,6 @@ static int qcom_edp_phy_init(struct phy *phy)
>         int ret;
>         u8 cfg8;
>
> -       ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> -       if (ret)
> -               return ret;
> -
> -       ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> -       if (ret)
> -               goto out_disable_supplies;
> -
>         writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
>                DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
>                edp->edp + DP_PHY_PD_CTL);
> @@ -246,11 +238,6 @@ static int qcom_edp_phy_init(struct phy *phy)
>         msleep(20);
>
>         return 0;
> -
> -out_disable_supplies:
> -       regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> -
> -       return ret;
>  }
>
>  static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configure_opts_dp *dp_opts)
> @@ -721,6 +708,8 @@ static int qcom_edp_phy_power_on(struct phy *phy)
>         u32 val;
>         u8 cfg1;
>
> +       pm_runtime_get_sync(&phy->dev);
> +
>         ret = edp->cfg->ver_ops->com_power_on(edp);
>         if (ret)
>                 return ret;
> @@ -841,6 +830,8 @@ static int qcom_edp_phy_power_off(struct phy *phy)
>
>         writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL);
>
> +       pm_runtime_put(&phy->dev);
> +
>         return 0;
>  }
>
> @@ -856,23 +847,12 @@ static int qcom_edp_phy_set_mode(struct phy *phy, enum phy_mode mode, int submod
>         return 0;
>  }
>
> -static int qcom_edp_phy_exit(struct phy *phy)
> -{
> -       struct qcom_edp *edp = phy_get_drvdata(phy);
> -
> -       clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> -       regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> -
> -       return 0;
> -}
> -
>  static const struct phy_ops qcom_edp_ops = {
>         .init           = qcom_edp_phy_init,
>         .configure      = qcom_edp_phy_configure,
>         .power_on       = qcom_edp_phy_power_on,
>         .power_off      = qcom_edp_phy_power_off,
>         .set_mode       = qcom_edp_phy_set_mode,
> -       .exit           = qcom_edp_phy_exit,
>         .owner          = THIS_MODULE,
>  };
>
> @@ -1036,6 +1016,32 @@ static int qcom_edp_clks_register(struct qcom_edp *edp, struct device_node *np)
>         return devm_of_clk_add_hw_provider(edp->dev, of_clk_hw_onecell_get, data);
>  }
>
> +static int __maybe_unused qcom_edp_runtime_suspend(struct device *dev)
> +{
> +       struct qcom_edp *edp = dev_get_drvdata(dev);
> +
> +       dev_err(dev, "Suspending DP phy\n");

Debug leftovers?

> +
> +       clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> +       regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> +
> +       return 0;
> +}
> +
> +static int __maybe_unused qcom_edp_runtime_resume(struct device *dev)
> +{
> +       struct qcom_edp *edp = dev_get_drvdata(dev);
> +       int ret;
> +
> +       dev_err(dev, "Resuming DP phy\n");

Debug leftovers?

> +
> +       ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> +       if (ret)
> +               return ret;
> +
> +       return clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);

Missing error handling

> +}
> +
>  static int qcom_edp_phy_probe(struct platform_device *pdev)
>  {
>         struct phy_provider *phy_provider;
> @@ -1091,20 +1097,57 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
>                 return ret;
>         }
>
> -       ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
> -       if (ret)
> +       ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> +       if (ret) {
> +               dev_err(dev, "failed to enable regulators, err=%d\n", ret);
>                 return ret;
> +       }
> +
> +       ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> +       if (ret) {
> +               dev_err(dev, "failed to enable clocks, err=%d\n", ret);
> +               goto err_disable_regulators;
> +       }

Please use pm_runtime_get_sync() instead().

> +
> +       ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
> +       if (ret) {
> +               dev_err(dev, "failed to register PHY clocks, err=%d\n", ret);
> +               goto err_disable_clocks;
> +       }
>
>         edp->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_edp_ops);
>         if (IS_ERR(edp->phy)) {
>                 dev_err(dev, "failed to register phy\n");
> -               return PTR_ERR(edp->phy);
> +               ret = PTR_ERR(edp->phy);
> +               goto err_disable_clocks;
>         }
>
> +       pm_runtime_set_active(dev);
> +       ret = devm_pm_runtime_enable(dev);

If this handles earlier, you don't need to call pm_runtime_set_active() manually

> +       if (ret)
> +               goto err_disable_clocks;
> +       /*
> +        * Prevent runtime pm from being ON by default. Users can enable
> +        * it using power/control in sysfs.

why?

> +        */
> +       pm_runtime_forbid(dev);
> +
> +       dev_set_drvdata(dev, edp);
>         phy_set_drvdata(edp->phy, edp);
>
>         phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> -       return PTR_ERR_OR_ZERO(phy_provider);
> +       if (IS_ERR(phy_provider))
> +               goto err_disable_clocks;
> +
> +       return 0;
> +
> +err_disable_clocks:
> +       clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> +
> +err_disable_regulators:
> +       regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);

Ideally this should be handled by pm_runtime. Or at least by pm_runtime_put().

> +
> +       return ret;
>  }
>
>  static const struct of_device_id qcom_edp_phy_match_table[] = {
> @@ -1117,10 +1160,16 @@ static const struct of_device_id qcom_edp_phy_match_table[] = {
>  };
>  MODULE_DEVICE_TABLE(of, qcom_edp_phy_match_table);
>
> +static const struct dev_pm_ops qcom_edp_pm_ops = {
> +       SET_RUNTIME_PM_OPS(qcom_edp_runtime_suspend,
> +                          qcom_edp_runtime_resume, NULL)
> +};
> +
>  static struct platform_driver qcom_edp_phy_driver = {
>         .probe          = qcom_edp_phy_probe,
>         .driver = {
>                 .name   = "qcom-edp-phy",
> +               .pm     = &qcom_edp_pm_ops,
>                 .of_match_table = qcom_edp_phy_match_table,
>         },
>  };
>
> ---
> base-commit: 9aaeb87ce1e966169a57f53a02ba05b30880ffb8
> change-id: 20240907-phy-qcom-edp-enable-runtime-pm-6fad07af8947
>
> Best regards,
> --
> Abel Vesa <abel.vesa at linaro.org>
>


-- 
With best wishes
Dmitry


From lkp at intel.com  Sat Sep  7 16:22:15 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 8 Sep 2024 07:22:15 +0800
Subject: [PATCH 19/19] arm64: dts: qcom: add base QCS8300 RIDE dts
In-Reply-To: <20240904-qcs8300_initial_dtsi-v1-19-d0ea9afdc007@quicinc.com>
References: <20240904-qcs8300_initial_dtsi-v1-19-d0ea9afdc007@quicinc.com>
Message-ID: <202409080754.6Zv1y3pX-lkp@intel.com>

Hi Jingyi,

kernel test robot noticed the following build errors:

[auto build test ERROR on eb8c5ca373cbb018a84eb4db25c863302c9b6314]

url:    https://github.com/intel-lab-lkp/linux/commits/Jingyi-Wang/dt-bindings-remoteproc-qcom-sa8775p-pas-Document-QCS8300-remoteproc/20240904-164345
base:   eb8c5ca373cbb018a84eb4db25c863302c9b6314
patch link:    https://lore.kernel.org/r/20240904-qcs8300_initial_dtsi-v1-19-d0ea9afdc007%40quicinc.com
patch subject: [PATCH 19/19] arm64: dts: qcom: add base QCS8300 RIDE dts
config: arm64-randconfig-003-20240908 (https://download.01.org/0day-ci/archive/20240908/202409080754.6Zv1y3pX-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 05f5a91d00b02f4369f46d076411c700755ae041)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240908/202409080754.6Zv1y3pX-lkp at 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 at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409080754.6Zv1y3pX-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from arch/arm64/boot/dts/qcom/qcs8300-ride.dts:11:
>> arch/arm64/boot/dts/qcom/qcs8300.dtsi:6:10: fatal error: 'dt-bindings/clock/qcom,qcs8300-gcc.h' file not found
       6 | #include <dt-bindings/clock/qcom,qcs8300-gcc.h>
         |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1 error generated.


vim +6 arch/arm64/boot/dts/qcom/qcs8300.dtsi

984d43bac8bbd3 Jingyi Wang 2024-09-04  @6  #include <dt-bindings/clock/qcom,qcs8300-gcc.h>
984d43bac8bbd3 Jingyi Wang 2024-09-04   7  #include <dt-bindings/clock/qcom,rpmh.h>
984d43bac8bbd3 Jingyi Wang 2024-09-04   8  #include <dt-bindings/interconnect/qcom,icc.h>
984d43bac8bbd3 Jingyi Wang 2024-09-04   9  #include <dt-bindings/interconnect/qcom,qcs8300-rpmh.h>
984d43bac8bbd3 Jingyi Wang 2024-09-04  10  #include <dt-bindings/interrupt-controller/arm-gic.h>
984d43bac8bbd3 Jingyi Wang 2024-09-04  11  #include <dt-bindings/mailbox/qcom-ipcc.h>
984d43bac8bbd3 Jingyi Wang 2024-09-04  12  #include <dt-bindings/power/qcom,rpmhpd.h>
984d43bac8bbd3 Jingyi Wang 2024-09-04  13  #include <dt-bindings/power/qcom-rpmpd.h>
984d43bac8bbd3 Jingyi Wang 2024-09-04  14  #include <dt-bindings/soc/qcom,rpmh-rsc.h>
984d43bac8bbd3 Jingyi Wang 2024-09-04  15  

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


From andersson at kernel.org  Sat Sep  7 20:19:42 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Sat, 7 Sep 2024 22:19:42 -0500
Subject: [PATCH] phy: qcom: edp: Add runtime PM support
In-Reply-To: <20240907-phy-qcom-edp-enable-runtime-pm-v1-1-8b9ee4210e1e@linaro.org>
References: <20240907-phy-qcom-edp-enable-runtime-pm-v1-1-8b9ee4210e1e@linaro.org>
Message-ID: <v6jzz6q5eutbmdy6vwagdhenjnvxucf3u3nl5qdjte65wlc77e@tzvxcm3xnuht>

On Sat, Sep 07, 2024 at 06:25:21PM GMT, Abel Vesa wrote:
> Enable runtime PM support by adding proper ops which will handle the
> clocks and regulators. These resources will now be handled on power_on and
> power_off instead of init and exit PHY ops. Also enable these resources on
> probe in order to balance out the disabling that is happening right after.

Sounds good, I assume there's a good reason for doing this?

Please provide a proper problem description, as defined in:
https://docs.kernel.org/process/submitting-patches.html#describe-your-changes

> Prevent runtime PM from being ON by default as well.
> 

Why?

> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> ---
>  drivers/phy/qualcomm/phy-qcom-edp.c | 105 ++++++++++++++++++++++++++----------
>  1 file changed, 77 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> index da2b32fb5b45..3affeef261bf 100644
> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> @@ -192,14 +192,6 @@ static int qcom_edp_phy_init(struct phy *phy)
>  	int ret;
>  	u8 cfg8;
>  
> -	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> -	if (ret)
> -		return ret;
> -
> -	ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> -	if (ret)
> -		goto out_disable_supplies;
> -
>  	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
>  	       DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
>  	       edp->edp + DP_PHY_PD_CTL);
> @@ -246,11 +238,6 @@ static int qcom_edp_phy_init(struct phy *phy)
>  	msleep(20);
>  
>  	return 0;
> -
> -out_disable_supplies:
> -	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> -
> -	return ret;
>  }
>  
>  static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configure_opts_dp *dp_opts)
> @@ -721,6 +708,8 @@ static int qcom_edp_phy_power_on(struct phy *phy)
>  	u32 val;
>  	u8 cfg1;
>  
> +	pm_runtime_get_sync(&phy->dev);
> +
>  	ret = edp->cfg->ver_ops->com_power_on(edp);
>  	if (ret)
>  		return ret;
> @@ -841,6 +830,8 @@ static int qcom_edp_phy_power_off(struct phy *phy)
>  
>  	writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL);
>  
> +	pm_runtime_put(&phy->dev);
> +
>  	return 0;
>  }
>  
> @@ -856,23 +847,12 @@ static int qcom_edp_phy_set_mode(struct phy *phy, enum phy_mode mode, int submod
>  	return 0;
>  }
>  
> -static int qcom_edp_phy_exit(struct phy *phy)
> -{
> -	struct qcom_edp *edp = phy_get_drvdata(phy);
> -
> -	clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> -	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> -
> -	return 0;
> -}
> -
>  static const struct phy_ops qcom_edp_ops = {
>  	.init		= qcom_edp_phy_init,
>  	.configure	= qcom_edp_phy_configure,
>  	.power_on	= qcom_edp_phy_power_on,
>  	.power_off	= qcom_edp_phy_power_off,
>  	.set_mode	= qcom_edp_phy_set_mode,
> -	.exit		= qcom_edp_phy_exit,
>  	.owner		= THIS_MODULE,
>  };
>  
> @@ -1036,6 +1016,32 @@ static int qcom_edp_clks_register(struct qcom_edp *edp, struct device_node *np)
>  	return devm_of_clk_add_hw_provider(edp->dev, of_clk_hw_onecell_get, data);
>  }
>  
> +static int __maybe_unused qcom_edp_runtime_suspend(struct device *dev)
> +{
> +	struct qcom_edp *edp = dev_get_drvdata(dev);
> +
> +	dev_err(dev, "Suspending DP phy\n");
> +
> +	clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> +	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused qcom_edp_runtime_resume(struct device *dev)
> +{
> +	struct qcom_edp *edp = dev_get_drvdata(dev);
> +	int ret;
> +
> +	dev_err(dev, "Resuming DP phy\n");
> +
> +	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> +	if (ret)
> +		return ret;
> +
> +	return clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> +}
> +
>  static int qcom_edp_phy_probe(struct platform_device *pdev)
>  {
>  	struct phy_provider *phy_provider;
> @@ -1091,20 +1097,57 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> -	ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
> -	if (ret)
> +	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> +	if (ret) {
> +		dev_err(dev, "failed to enable regulators, err=%d\n", ret);
>  		return ret;
> +	}
> +
> +	ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> +	if (ret) {
> +		dev_err(dev, "failed to enable clocks, err=%d\n", ret);
> +		goto err_disable_regulators;
> +	}
> +
> +	ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
> +	if (ret) {
> +		dev_err(dev, "failed to register PHY clocks, err=%d\n", ret);
> +		goto err_disable_clocks;
> +	}
>  
>  	edp->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_edp_ops);
>  	if (IS_ERR(edp->phy)) {
>  		dev_err(dev, "failed to register phy\n");
> -		return PTR_ERR(edp->phy);
> +		ret = PTR_ERR(edp->phy);
> +		goto err_disable_clocks;
>  	}
>  
> +	pm_runtime_set_active(dev);
> +	ret = devm_pm_runtime_enable(dev);
> +	if (ret)
> +		goto err_disable_clocks;
> +	/*
> +	 * Prevent runtime pm from being ON by default. Users can enable
> +	 * it using power/control in sysfs.

That is what this call do, please describe why it's done instead.

Regards,
Bjorn

> +	 */
> +	pm_runtime_forbid(dev);
> +
> +	dev_set_drvdata(dev, edp);
>  	phy_set_drvdata(edp->phy, edp);
>  
>  	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> -	return PTR_ERR_OR_ZERO(phy_provider);
> +	if (IS_ERR(phy_provider))
> +		goto err_disable_clocks;
> +
> +	return 0;
> +
> +err_disable_clocks:
> +	clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> +
> +err_disable_regulators:
> +	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> +
> +	return ret;
>  }
>  
>  static const struct of_device_id qcom_edp_phy_match_table[] = {
> @@ -1117,10 +1160,16 @@ static const struct of_device_id qcom_edp_phy_match_table[] = {
>  };
>  MODULE_DEVICE_TABLE(of, qcom_edp_phy_match_table);
>  
> +static const struct dev_pm_ops qcom_edp_pm_ops = {
> +	SET_RUNTIME_PM_OPS(qcom_edp_runtime_suspend,
> +			   qcom_edp_runtime_resume, NULL)
> +};
> +
>  static struct platform_driver qcom_edp_phy_driver = {
>  	.probe		= qcom_edp_phy_probe,
>  	.driver = {
>  		.name	= "qcom-edp-phy",
> +		.pm	= &qcom_edp_pm_ops,
>  		.of_match_table = qcom_edp_phy_match_table,
>  	},
>  };
> 
> ---
> base-commit: 9aaeb87ce1e966169a57f53a02ba05b30880ffb8
> change-id: 20240907-phy-qcom-edp-enable-runtime-pm-6fad07af8947
> 
> Best regards,
> -- 
> Abel Vesa <abel.vesa at linaro.org>
> 
> 


From josua at solid-run.com  Sun Sep  8 01:34:48 2024
From: josua at solid-run.com (Josua Mayer)
Date: Sun, 08 Sep 2024 11:34:48 +0300
Subject: [PATCH v3] phy: mvebu-cp110-utmi: support swapping d+/d- lanes by
 dts property
Message-ID: <20240908-mvebu-utmi-phy-v3-1-88c50950e7d2@solid-run.com>

CP11x UTMI PHY supports swapping D+/D- signals via digital control
register 1.

Add support for the "swap-dx-lanes" device-tree property, which lists
the port-ids that should swap D+ and D-.
The property is evaluated in probe and applied before power-on
during mvebu_cp110_utmi_port_setup.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
Changes in v3:
- add description for new struct member
  (Reported-by: kernel test robot <lkp at intel.com>)
- Link to v2: https://lore.kernel.org/r/20240903-mvebu-utmi-phy-v2-1-7f49c131fad0 at solid-run.com

Changes in v2:
- fixed compile error introduced with v6.11-rc1:
  parameters of of_property_for_each_u32 were changed from 5 to 3.
  (Reported-by: Vinod Koul <vkoul at kernel.org>)
- rebased on v6.11-rc1
- Link to v1: https://lore.kernel.org/r/20240704-mvebu-utmi-phy-v1-1-9d3c8eea46e5 at solid-run.com
---
 drivers/phy/marvell/phy-mvebu-cp110-utmi.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/phy/marvell/phy-mvebu-cp110-utmi.c b/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
index 4922a5f3327d..59903f86b13f 100644
--- a/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
+++ b/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
@@ -62,6 +62,8 @@
 #define   SQ_AMP_CAL_MASK			GENMASK(2, 0)
 #define   SQ_AMP_CAL_VAL			1
 #define   SQ_AMP_CAL_EN				BIT(3)
+#define UTMI_DIG_CTRL1_REG			0x20
+#define   SWAP_DPDM				BIT(15)
 #define UTMI_CTRL_STATUS0_REG			0x24
 #define   SUSPENDM				BIT(22)
 #define   TEST_SEL				BIT(25)
@@ -99,11 +101,13 @@ struct mvebu_cp110_utmi {
  * @priv: PHY driver data
  * @id: PHY port ID
  * @dr_mode: PHY connection: USB_DR_MODE_HOST or USB_DR_MODE_PERIPHERAL
+ * @swap_dx: whether to swap d+/d- signals
  */
 struct mvebu_cp110_utmi_port {
 	struct mvebu_cp110_utmi *priv;
 	u32 id;
 	enum usb_dr_mode dr_mode;
+	bool swap_dx;
 };
 
 static void mvebu_cp110_utmi_port_setup(struct mvebu_cp110_utmi_port *port)
@@ -159,6 +163,13 @@ static void mvebu_cp110_utmi_port_setup(struct mvebu_cp110_utmi_port *port)
 	reg &= ~(VDAT_MASK | VSRC_MASK);
 	reg |= (VDAT_VAL << VDAT_OFFSET) | (VSRC_VAL << VSRC_OFFSET);
 	writel(reg, PORT_REGS(port) + UTMI_CHGDTC_CTRL_REG);
+
+	/* Swap D+/D- */
+	reg = readl(PORT_REGS(port) + UTMI_DIG_CTRL1_REG);
+	reg &= ~(SWAP_DPDM);
+	if (port->swap_dx)
+		reg |= SWAP_DPDM;
+	writel(reg, PORT_REGS(port) + UTMI_DIG_CTRL1_REG);
 }
 
 static int mvebu_cp110_utmi_phy_power_off(struct phy *phy)
@@ -286,6 +297,7 @@ static int mvebu_cp110_utmi_phy_probe(struct platform_device *pdev)
 	struct phy_provider *provider;
 	struct device_node *child;
 	u32 usb_devices = 0;
+	u32 swap_dx = 0;
 
 	utmi = devm_kzalloc(dev, sizeof(*utmi), GFP_KERNEL);
 	if (!utmi)
@@ -345,6 +357,10 @@ static int mvebu_cp110_utmi_phy_probe(struct platform_device *pdev)
 			}
 		}
 
+		of_property_for_each_u32(dev->of_node, "swap-dx-lanes", swap_dx)
+			if (swap_dx == port_id)
+				port->swap_dx = 1;
+
 		/* Retrieve PHY capabilities */
 		utmi->ops = &mvebu_cp110_utmi_phy_ops;
 

---
base-commit: 8400291e289ee6b2bf9779ff1c83a291501f017b
change-id: 20240704-mvebu-utmi-phy-84aa3bf3957d

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



From biju.das.jz at bp.renesas.com  Sun Sep  8 09:39:27 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Sun, 8 Sep 2024 16:39:27 +0000
Subject: [PATCH v2] phy: renesas: rcar-gen3-usb2: Fix an error handling
 path in rcar_gen3_phy_usb2_probe()
In-Reply-To: <4efe2d0419cbe98163e2422ebe0c7896b8a5efed.1725717505.git.christophe.jaillet@wanadoo.fr>
References: <4efe2d0419cbe98163e2422ebe0c7896b8a5efed.1725717505.git.christophe.jaillet@wanadoo.fr>
Message-ID: <TY3PR01MB113468D1573C1E50AC9F97DCF86982@TY3PR01MB11346.jpnprd01.prod.outlook.com>

Hi Christophe JAILLET,

Thanks for the patch.

> -----Original Message-----
> From: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> Sent: Saturday, September 7, 2024 2:59 PM
> Subject: [PATCH v2] phy: renesas: rcar-gen3-usb2: Fix an error handling path in
> rcar_gen3_phy_usb2_probe()
> 
> If an error occurs after the rcar_gen3_phy_usb2_init_bus(),
> reset_control_assert() must be called, as already done in the remove function.
> 
> This is fine to re-use the existing error handling path, because even if "channel->rstc" is still NULL
> at this point, it is safe to call reset_control_assert(NULL).
> 
> Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus")
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> ---
> Changes in v2:
>   - Re-use 'error' to simplify the patch   [claudiu beznea]
>   - Update the commit description to explain why it is safe.
> 
> v1:
> https://lore.kernel.org/all/fc9f7b444f0ca645411868992bbe16514aeccfed.1725652654.git.christophe.jaillet
> @wanadoo.fr/
> ---
>  drivers/phy/renesas/phy-rcar-gen3-usb2.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> index 58e123305152..ccb0b54b70f7 100644
> --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> @@ -803,6 +803,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
>  	return 0;
> 
>  error:
> +	reset_control_assert(channel->rstc);

This will result in either kernel crash [1] or reset usage count imbalance in case
of error [2] and [3] in rcar_gen3_phy_usb2_init_bus() see [4]. Also reset control API is not
respected for SoCs other than RZ/G3S. For those SoC's reset assert is
called without calling a get(). Maybe add a check (phy_data->init_bus) for
assert api's, that guarantees assert is called after calling a get() as it
valid only for RZ/G3S??

[1]
channel->rstc = devm_reset_control_array_get_shared(dev);
	if (IS_ERR(channel->rstc))
		return PTR_ERR(channel->rstc);

[2] 
ret = pm_runtime_resume_and_get(dev);
	if (ret)
		return ret;
[3]
ret = reset_control_deassert(channel->rstc);
	if (ret)
		goto rpm_put;

[4] https://elixir.bootlin.com/linux/v6.11-rc6/source/drivers/reset/core.c#L483

Cheers,
Biju

>  	pm_runtime_disable(dev);
> 
>  	return ret;
> --
> 2.46.0
> 



From christophe.jaillet at wanadoo.fr  Sun Sep  8 09:58:52 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sun, 8 Sep 2024 18:58:52 +0200
Subject: [PATCH v2] phy: renesas: rcar-gen3-usb2: Fix an error handling
 path in rcar_gen3_phy_usb2_probe()
In-Reply-To: <TY3PR01MB113468D1573C1E50AC9F97DCF86982@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <4efe2d0419cbe98163e2422ebe0c7896b8a5efed.1725717505.git.christophe.jaillet@wanadoo.fr>
 <TY3PR01MB113468D1573C1E50AC9F97DCF86982@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <d01bed96-7811-4ace-8b92-1ee9fafac649@wanadoo.fr>

Le 08/09/2024 ? 18:39, Biju Das a ?crit?:
> Hi Christophe JAILLET,
> 
> Thanks for the patch.
> 
>> -----Original Message-----
>> From: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
>> Sent: Saturday, September 7, 2024 2:59 PM
>> Subject: [PATCH v2] phy: renesas: rcar-gen3-usb2: Fix an error handling path in
>> rcar_gen3_phy_usb2_probe()
>>
>> If an error occurs after the rcar_gen3_phy_usb2_init_bus(),
>> reset_control_assert() must be called, as already done in the remove function.
>>
>> This is fine to re-use the existing error handling path, because even if "channel->rstc" is still NULL
>> at this point, it is safe to call reset_control_assert(NULL).
>>
>> Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus")
>> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
>> ---
>> Changes in v2:
>>    - Re-use 'error' to simplify the patch   [claudiu beznea]
>>    - Update the commit description to explain why it is safe.
>>
>> v1:
>> https://lore.kernel.org/all/fc9f7b444f0ca645411868992bbe16514aeccfed.1725652654.git.christophe.jaillet
>> @wanadoo.fr/
>> ---
>>   drivers/phy/renesas/phy-rcar-gen3-usb2.c | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
>> index 58e123305152..ccb0b54b70f7 100644
>> --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
>> +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
>> @@ -803,6 +803,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
>>   	return 0;
>>
>>   error:
>> +	reset_control_assert(channel->rstc);
> 
> This will result in either kernel crash [1] or reset usage count imbalance in case
> of error [2] and [3] in rcar_gen3_phy_usb2_init_bus() see [4]. Also reset control API is not
> respected for SoCs other than RZ/G3S. For those SoC's reset assert is
> called without calling a get(). Maybe add a check (phy_data->init_bus) for
> assert api's, that guarantees assert is called after calling a get() as it
> valid only for RZ/G3S??
> 
> [1]
> channel->rstc = devm_reset_control_array_get_shared(dev);
> 	if (IS_ERR(channel->rstc))
> 		return PTR_ERR(channel->rstc);
> 
> [2]
> ret = pm_runtime_resume_and_get(dev);
> 	if (ret)
> 		return ret;
> [3]
> ret = reset_control_deassert(channel->rstc);
> 	if (ret)
> 		goto rpm_put;
> 
> [4] https://elixir.bootlin.com/linux/v6.11-rc6/source/drivers/reset/core.c#L483

So, if I understand correctly, v1 [5] was correct. :)


I don't think that [1] would crash, because of [6]. It would only 
WARN_ON. But with v1, it is not called.

With v1, reset_control_assert() is not called if 
rcar_gen3_phy_usb2_init_bus() fails. So [2] and [3] can't occur.

I can send a v3, which is the same of v1, or you can pick v1 as-is (if 
I'm correct... :)) or you can just ignore it if "reset control API is 
not respected for SoCs".


If of interest, I spotted it with one of my coccinelle script that 
compares functions called in .remove function, but not in error handling 
path of probe.


CJ

[5]: 
https://lore.kernel.org/all/fc9f7b444f0ca645411868992bbe16514aeccfed.1725652654.git.christophe.jaillet at wanadoo.fr/

[6]: 
https://elixir.bootlin.com/linux/v6.11-rc6/source/drivers/reset/core.c#L473

> 
> Cheers,
> Biju
> 
>>   	pm_runtime_disable(dev);
>>
>>   	return ret;
>> --
>> 2.46.0
>>
> 
> 
> 



From abel.vesa at linaro.org  Sun Sep  8 11:12:37 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Sun, 8 Sep 2024 21:12:37 +0300
Subject: [PATCH] phy: qcom: edp: Add runtime PM support
In-Reply-To: <CAA8EJpqw6pB4d_zQyYdhq9_prLnh+mLMdRSzJ+5EvAjT9wi86A@mail.gmail.com>
References: <20240907-phy-qcom-edp-enable-runtime-pm-v1-1-8b9ee4210e1e@linaro.org>
 <CAA8EJpqw6pB4d_zQyYdhq9_prLnh+mLMdRSzJ+5EvAjT9wi86A@mail.gmail.com>
Message-ID: <Zt3pFdndtTw/nbgs@linaro.org>

On 24-09-07 20:52:14, Dmitry Baryshkov wrote:
> On Sat, 7 Sept 2024 at 18:25, Abel Vesa <abel.vesa at linaro.org> wrote:
> >
> > Enable runtime PM support by adding proper ops which will handle the
> > clocks and regulators. These resources will now be handled on power_on and
> > power_off instead of init and exit PHY ops. Also enable these resources on
> > probe in order to balance out the disabling that is happening right after.
> > Prevent runtime PM from being ON by default as well.
> >
> > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > ---
> >  drivers/phy/qualcomm/phy-qcom-edp.c | 105 ++++++++++++++++++++++++++----------
> >  1 file changed, 77 insertions(+), 28 deletions(-)
> >
> > diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> > index da2b32fb5b45..3affeef261bf 100644
> > --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> > +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> > @@ -192,14 +192,6 @@ static int qcom_edp_phy_init(struct phy *phy)
> >         int ret;
> >         u8 cfg8;
> >
> > -       ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > -       if (ret)
> > -               return ret;
> > -
> > -       ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> > -       if (ret)
> > -               goto out_disable_supplies;
> > -
> >         writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> >                DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
> >                edp->edp + DP_PHY_PD_CTL);
> > @@ -246,11 +238,6 @@ static int qcom_edp_phy_init(struct phy *phy)
> >         msleep(20);
> >
> >         return 0;
> > -
> > -out_disable_supplies:
> > -       regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > -
> > -       return ret;
> >  }
> >
> >  static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configure_opts_dp *dp_opts)
> > @@ -721,6 +708,8 @@ static int qcom_edp_phy_power_on(struct phy *phy)
> >         u32 val;
> >         u8 cfg1;
> >
> > +       pm_runtime_get_sync(&phy->dev);
> > +
> >         ret = edp->cfg->ver_ops->com_power_on(edp);
> >         if (ret)
> >                 return ret;
> > @@ -841,6 +830,8 @@ static int qcom_edp_phy_power_off(struct phy *phy)
> >
> >         writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL);
> >
> > +       pm_runtime_put(&phy->dev);
> > +
> >         return 0;
> >  }
> >
> > @@ -856,23 +847,12 @@ static int qcom_edp_phy_set_mode(struct phy *phy, enum phy_mode mode, int submod
> >         return 0;
> >  }
> >
> > -static int qcom_edp_phy_exit(struct phy *phy)
> > -{
> > -       struct qcom_edp *edp = phy_get_drvdata(phy);
> > -
> > -       clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> > -       regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > -
> > -       return 0;
> > -}
> > -
> >  static const struct phy_ops qcom_edp_ops = {
> >         .init           = qcom_edp_phy_init,
> >         .configure      = qcom_edp_phy_configure,
> >         .power_on       = qcom_edp_phy_power_on,
> >         .power_off      = qcom_edp_phy_power_off,
> >         .set_mode       = qcom_edp_phy_set_mode,
> > -       .exit           = qcom_edp_phy_exit,
> >         .owner          = THIS_MODULE,
> >  };
> >
> > @@ -1036,6 +1016,32 @@ static int qcom_edp_clks_register(struct qcom_edp *edp, struct device_node *np)
> >         return devm_of_clk_add_hw_provider(edp->dev, of_clk_hw_onecell_get, data);
> >  }
> >
> > +static int __maybe_unused qcom_edp_runtime_suspend(struct device *dev)
> > +{
> > +       struct qcom_edp *edp = dev_get_drvdata(dev);
> > +
> > +       dev_err(dev, "Suspending DP phy\n");
> 
> Debug leftovers?

Well, I should've made those dev_vdbg instead. 

> 
> > +
> > +       clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> > +       regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > +
> > +       return 0;
> > +}
> > +
> > +static int __maybe_unused qcom_edp_runtime_resume(struct device *dev)
> > +{
> > +       struct qcom_edp *edp = dev_get_drvdata(dev);
> > +       int ret;
> > +
> > +       dev_err(dev, "Resuming DP phy\n");
> 
> Debug leftovers?
> 

See above.

> > +
> > +       ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > +       if (ret)
> > +               return ret;
> > +
> > +       return clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> 
> Missing error handling
> 

Yep, will fix.

> > +}
> > +
> >  static int qcom_edp_phy_probe(struct platform_device *pdev)
> >  {
> >         struct phy_provider *phy_provider;
> > @@ -1091,20 +1097,57 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
> >                 return ret;
> >         }
> >
> > -       ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
> > -       if (ret)
> > +       ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > +       if (ret) {
> > +               dev_err(dev, "failed to enable regulators, err=%d\n", ret);
> >                 return ret;
> > +       }
> > +
> > +       ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> > +       if (ret) {
> > +               dev_err(dev, "failed to enable clocks, err=%d\n", ret);
> > +               goto err_disable_regulators;
> > +       }
> 
> Please use pm_runtime_get_sync() instead().
> 

So let me explain how I thought this through first. This DP PHY is
usually used on platforms where display is left enabled by the
bootloader. So doing pm_runtime_get_sync would mean we increment the
device's usage counter while it is known to be already enabled, even if
genpd doesn't consider it so. So doing set_active instead would be more
accurate. Now, for the regulator and clock generic frameworks, that
seemed OK to do at the time. Now I can see that the same argument can be
made for those as well. So I'm thinking maybe I just drop the enable
here and don't do _get_sync, but rather rely on the resume being done
on power on instead. 

> > +
> > +       ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
> > +       if (ret) {
> > +               dev_err(dev, "failed to register PHY clocks, err=%d\n", ret);
> > +               goto err_disable_clocks;
> > +       }
> >
> >         edp->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_edp_ops);
> >         if (IS_ERR(edp->phy)) {
> >                 dev_err(dev, "failed to register phy\n");
> > -               return PTR_ERR(edp->phy);
> > +               ret = PTR_ERR(edp->phy);
> > +               goto err_disable_clocks;
> >         }
> >
> > +       pm_runtime_set_active(dev);
> > +       ret = devm_pm_runtime_enable(dev);
> 
> If this handles earlier, you don't need to call pm_runtime_set_active() manually
> 

Enable and set_active are two separate things. Maybe I'm
misunderstanding your comment.

> > +       if (ret)
> > +               goto err_disable_clocks;
> > +       /*
> > +        * Prevent runtime pm from being ON by default. Users can enable
> > +        * it using power/control in sysfs.
> 
> why?
> 

OK, so this is a tricky one. If there is any platform out there that
makes use of this PHY but the resources are not properly described, we
might get in trouble. So I was thinking that maybe we don't risk that
but let the user enable it via sysfs. That way, this patch will not
break by default such platforms.

Also, this would be in line with the rest of the other Qcom PHYs.

> > +        */
> > +       pm_runtime_forbid(dev);
> > +
> > +       dev_set_drvdata(dev, edp);
> >         phy_set_drvdata(edp->phy, edp);
> >
> >         phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> > -       return PTR_ERR_OR_ZERO(phy_provider);
> > +       if (IS_ERR(phy_provider))
> > +               goto err_disable_clocks;
> > +
> > +       return 0;
> > +
> > +err_disable_clocks:
> > +       clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> > +
> > +err_disable_regulators:
> > +       regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> 
> Ideally this should be handled by pm_runtime. Or at least by pm_runtime_put().

Will drop entirely. Again, lets not enable anything on probe for now.

> 
> > +
> > +       return ret;
> >  }
> >
> >  static const struct of_device_id qcom_edp_phy_match_table[] = {
> > @@ -1117,10 +1160,16 @@ static const struct of_device_id qcom_edp_phy_match_table[] = {
> >  };
> >  MODULE_DEVICE_TABLE(of, qcom_edp_phy_match_table);
> >
> > +static const struct dev_pm_ops qcom_edp_pm_ops = {
> > +       SET_RUNTIME_PM_OPS(qcom_edp_runtime_suspend,
> > +                          qcom_edp_runtime_resume, NULL)
> > +};
> > +
> >  static struct platform_driver qcom_edp_phy_driver = {
> >         .probe          = qcom_edp_phy_probe,
> >         .driver = {
> >                 .name   = "qcom-edp-phy",
> > +               .pm     = &qcom_edp_pm_ops,
> >                 .of_match_table = qcom_edp_phy_match_table,
> >         },
> >  };
> >
> > ---
> > base-commit: 9aaeb87ce1e966169a57f53a02ba05b30880ffb8
> > change-id: 20240907-phy-qcom-edp-enable-runtime-pm-6fad07af8947
> >
> > Best regards,
> > --
> > Abel Vesa <abel.vesa at linaro.org>
> >
> 
> 
> -- 
> With best wishes
> Dmitry


From abel.vesa at linaro.org  Sun Sep  8 11:22:46 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Sun, 8 Sep 2024 21:22:46 +0300
Subject: [PATCH] phy: qcom: edp: Add runtime PM support
In-Reply-To: <v6jzz6q5eutbmdy6vwagdhenjnvxucf3u3nl5qdjte65wlc77e@tzvxcm3xnuht>
References: <20240907-phy-qcom-edp-enable-runtime-pm-v1-1-8b9ee4210e1e@linaro.org>
 <v6jzz6q5eutbmdy6vwagdhenjnvxucf3u3nl5qdjte65wlc77e@tzvxcm3xnuht>
Message-ID: <Zt3rdqPs4Kpa4O3T@linaro.org>

On 24-09-07 22:19:42, Bjorn Andersson wrote:
> On Sat, Sep 07, 2024 at 06:25:21PM GMT, Abel Vesa wrote:
> > Enable runtime PM support by adding proper ops which will handle the
> > clocks and regulators. These resources will now be handled on power_on and
> > power_off instead of init and exit PHY ops. Also enable these resources on
> > probe in order to balance out the disabling that is happening right after.
> 
> Sounds good, I assume there's a good reason for doing this?

Replied to Dmitry's comment about this already, but will summarize here
as well. Basically, this PHY is usually left enabled as part of display
SS by the bootloader on most of the platforms it is used. My rationale
here was initially that maybe incrementing device's usage counter would
be wrong considering that it is already enabled. But then enabling
clocks and regulators here would move the wrong logic to their generic
framework. This I haven't thought through initially. So I decided to
just drop the votes entirely on probe. The resources will be enabled on
power_on via runtime PM get call.

> 
> Please provide a proper problem description, as defined in:
> https://docs.kernel.org/process/submitting-patches.html#describe-your-changes

Yep, will describe the impact/necessity better in the next version.

> 
> > Prevent runtime PM from being ON by default as well.
> > 
> 
> Why?

Also replied to Dmitry to his similar comment. Long story short, if any
of the platforms that use this PHY have any missing/wrong resources
voted for, it might render display broken on the first runtime suspend,
if runtime PM is allowed by default. Plus, all other Qcom PHY drivers
follow the same logic. Anyway, will drop in the next version.

> 
> > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > ---
> >  drivers/phy/qualcomm/phy-qcom-edp.c | 105 ++++++++++++++++++++++++++----------
> >  1 file changed, 77 insertions(+), 28 deletions(-)
> > 
> > diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> > index da2b32fb5b45..3affeef261bf 100644
> > --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> > +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> > @@ -192,14 +192,6 @@ static int qcom_edp_phy_init(struct phy *phy)
> >  	int ret;
> >  	u8 cfg8;
> >  
> > -	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > -	if (ret)
> > -		return ret;
> > -
> > -	ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> > -	if (ret)
> > -		goto out_disable_supplies;
> > -
> >  	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> >  	       DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
> >  	       edp->edp + DP_PHY_PD_CTL);
> > @@ -246,11 +238,6 @@ static int qcom_edp_phy_init(struct phy *phy)
> >  	msleep(20);
> >  
> >  	return 0;
> > -
> > -out_disable_supplies:
> > -	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > -
> > -	return ret;
> >  }
> >  
> >  static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configure_opts_dp *dp_opts)
> > @@ -721,6 +708,8 @@ static int qcom_edp_phy_power_on(struct phy *phy)
> >  	u32 val;
> >  	u8 cfg1;
> >  
> > +	pm_runtime_get_sync(&phy->dev);
> > +
> >  	ret = edp->cfg->ver_ops->com_power_on(edp);
> >  	if (ret)
> >  		return ret;
> > @@ -841,6 +830,8 @@ static int qcom_edp_phy_power_off(struct phy *phy)
> >  
> >  	writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL);
> >  
> > +	pm_runtime_put(&phy->dev);
> > +
> >  	return 0;
> >  }
> >  
> > @@ -856,23 +847,12 @@ static int qcom_edp_phy_set_mode(struct phy *phy, enum phy_mode mode, int submod
> >  	return 0;
> >  }
> >  
> > -static int qcom_edp_phy_exit(struct phy *phy)
> > -{
> > -	struct qcom_edp *edp = phy_get_drvdata(phy);
> > -
> > -	clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> > -	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > -
> > -	return 0;
> > -}
> > -
> >  static const struct phy_ops qcom_edp_ops = {
> >  	.init		= qcom_edp_phy_init,
> >  	.configure	= qcom_edp_phy_configure,
> >  	.power_on	= qcom_edp_phy_power_on,
> >  	.power_off	= qcom_edp_phy_power_off,
> >  	.set_mode	= qcom_edp_phy_set_mode,
> > -	.exit		= qcom_edp_phy_exit,
> >  	.owner		= THIS_MODULE,
> >  };
> >  
> > @@ -1036,6 +1016,32 @@ static int qcom_edp_clks_register(struct qcom_edp *edp, struct device_node *np)
> >  	return devm_of_clk_add_hw_provider(edp->dev, of_clk_hw_onecell_get, data);
> >  }
> >  
> > +static int __maybe_unused qcom_edp_runtime_suspend(struct device *dev)
> > +{
> > +	struct qcom_edp *edp = dev_get_drvdata(dev);
> > +
> > +	dev_err(dev, "Suspending DP phy\n");
> > +
> > +	clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> > +	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > +
> > +	return 0;
> > +}
> > +
> > +static int __maybe_unused qcom_edp_runtime_resume(struct device *dev)
> > +{
> > +	struct qcom_edp *edp = dev_get_drvdata(dev);
> > +	int ret;
> > +
> > +	dev_err(dev, "Resuming DP phy\n");
> > +
> > +	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> > +}
> > +
> >  static int qcom_edp_phy_probe(struct platform_device *pdev)
> >  {
> >  	struct phy_provider *phy_provider;
> > @@ -1091,20 +1097,57 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
> >  		return ret;
> >  	}
> >  
> > -	ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
> > -	if (ret)
> > +	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > +	if (ret) {
> > +		dev_err(dev, "failed to enable regulators, err=%d\n", ret);
> >  		return ret;
> > +	}
> > +
> > +	ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> > +	if (ret) {
> > +		dev_err(dev, "failed to enable clocks, err=%d\n", ret);
> > +		goto err_disable_regulators;
> > +	}
> > +
> > +	ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
> > +	if (ret) {
> > +		dev_err(dev, "failed to register PHY clocks, err=%d\n", ret);
> > +		goto err_disable_clocks;
> > +	}
> >  
> >  	edp->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_edp_ops);
> >  	if (IS_ERR(edp->phy)) {
> >  		dev_err(dev, "failed to register phy\n");
> > -		return PTR_ERR(edp->phy);
> > +		ret = PTR_ERR(edp->phy);
> > +		goto err_disable_clocks;
> >  	}
> >  
> > +	pm_runtime_set_active(dev);
> > +	ret = devm_pm_runtime_enable(dev);
> > +	if (ret)
> > +		goto err_disable_clocks;
> > +	/*
> > +	 * Prevent runtime pm from being ON by default. Users can enable
> > +	 * it using power/control in sysfs.
> 
> That is what this call do, please describe why it's done instead.

Will drop, as mentioned above.

> 
> Regards,
> Bjorn
> 
> > +	 */
> > +	pm_runtime_forbid(dev);
> > +
> > +	dev_set_drvdata(dev, edp);
> >  	phy_set_drvdata(edp->phy, edp);
> >  
> >  	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> > -	return PTR_ERR_OR_ZERO(phy_provider);
> > +	if (IS_ERR(phy_provider))
> > +		goto err_disable_clocks;
> > +
> > +	return 0;
> > +
> > +err_disable_clocks:
> > +	clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> > +
> > +err_disable_regulators:
> > +	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > +
> > +	return ret;
> >  }
> >  
> >  static const struct of_device_id qcom_edp_phy_match_table[] = {
> > @@ -1117,10 +1160,16 @@ static const struct of_device_id qcom_edp_phy_match_table[] = {
> >  };
> >  MODULE_DEVICE_TABLE(of, qcom_edp_phy_match_table);
> >  
> > +static const struct dev_pm_ops qcom_edp_pm_ops = {
> > +	SET_RUNTIME_PM_OPS(qcom_edp_runtime_suspend,
> > +			   qcom_edp_runtime_resume, NULL)
> > +};
> > +
> >  static struct platform_driver qcom_edp_phy_driver = {
> >  	.probe		= qcom_edp_phy_probe,
> >  	.driver = {
> >  		.name	= "qcom-edp-phy",
> > +		.pm	= &qcom_edp_pm_ops,
> >  		.of_match_table = qcom_edp_phy_match_table,
> >  	},
> >  };
> > 
> > ---
> > base-commit: 9aaeb87ce1e966169a57f53a02ba05b30880ffb8
> > change-id: 20240907-phy-qcom-edp-enable-runtime-pm-6fad07af8947
> > 
> > Best regards,
> > -- 
> > Abel Vesa <abel.vesa at linaro.org>
> > 
> > 


From dmitry.baryshkov at linaro.org  Sun Sep  8 11:43:01 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sun, 8 Sep 2024 21:43:01 +0300
Subject: [PATCH] phy: qcom: edp: Add runtime PM support
In-Reply-To: <Zt3pFdndtTw/nbgs@linaro.org>
References: <20240907-phy-qcom-edp-enable-runtime-pm-v1-1-8b9ee4210e1e@linaro.org>
 <CAA8EJpqw6pB4d_zQyYdhq9_prLnh+mLMdRSzJ+5EvAjT9wi86A@mail.gmail.com> <Zt3pFdndtTw/nbgs@linaro.org>
Message-ID: <CAA8EJppTp5S1L-rHKDW58uXQO08p6o=aNbE3kA9UjVKZsyJ-Jw@mail.gmail.com>

On Sun, 8 Sept 2024 at 21:12, Abel Vesa <abel.vesa at linaro.org> wrote:
>
> On 24-09-07 20:52:14, Dmitry Baryshkov wrote:
> > On Sat, 7 Sept 2024 at 18:25, Abel Vesa <abel.vesa at linaro.org> wrote:
> > >
> > > Enable runtime PM support by adding proper ops which will handle the
> > > clocks and regulators. These resources will now be handled on power_on and
> > > power_off instead of init and exit PHY ops. Also enable these resources on
> > > probe in order to balance out the disabling that is happening right after.
> > > Prevent runtime PM from being ON by default as well.
> > >
> > > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > > ---
> > >  drivers/phy/qualcomm/phy-qcom-edp.c | 105 ++++++++++++++++++++++++++----------
> > >  1 file changed, 77 insertions(+), 28 deletions(-)
> > >
> > > diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> > > index da2b32fb5b45..3affeef261bf 100644
> > > --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> > > +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> > > @@ -192,14 +192,6 @@ static int qcom_edp_phy_init(struct phy *phy)
> > >         int ret;
> > >         u8 cfg8;
> > >
> > > -       ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > > -       if (ret)
> > > -               return ret;
> > > -
> > > -       ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> > > -       if (ret)
> > > -               goto out_disable_supplies;
> > > -
> > >         writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> > >                DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
> > >                edp->edp + DP_PHY_PD_CTL);
> > > @@ -246,11 +238,6 @@ static int qcom_edp_phy_init(struct phy *phy)
> > >         msleep(20);
> > >
> > >         return 0;
> > > -
> > > -out_disable_supplies:
> > > -       regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > > -
> > > -       return ret;
> > >  }
> > >
> > >  static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configure_opts_dp *dp_opts)
> > > @@ -721,6 +708,8 @@ static int qcom_edp_phy_power_on(struct phy *phy)
> > >         u32 val;
> > >         u8 cfg1;
> > >
> > > +       pm_runtime_get_sync(&phy->dev);
> > > +
> > >         ret = edp->cfg->ver_ops->com_power_on(edp);
> > >         if (ret)
> > >                 return ret;
> > > @@ -841,6 +830,8 @@ static int qcom_edp_phy_power_off(struct phy *phy)
> > >
> > >         writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL);
> > >
> > > +       pm_runtime_put(&phy->dev);
> > > +
> > >         return 0;
> > >  }
> > >
> > > @@ -856,23 +847,12 @@ static int qcom_edp_phy_set_mode(struct phy *phy, enum phy_mode mode, int submod
> > >         return 0;
> > >  }
> > >
> > > -static int qcom_edp_phy_exit(struct phy *phy)
> > > -{
> > > -       struct qcom_edp *edp = phy_get_drvdata(phy);
> > > -
> > > -       clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> > > -       regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > > -
> > > -       return 0;
> > > -}
> > > -
> > >  static const struct phy_ops qcom_edp_ops = {
> > >         .init           = qcom_edp_phy_init,
> > >         .configure      = qcom_edp_phy_configure,
> > >         .power_on       = qcom_edp_phy_power_on,
> > >         .power_off      = qcom_edp_phy_power_off,
> > >         .set_mode       = qcom_edp_phy_set_mode,
> > > -       .exit           = qcom_edp_phy_exit,
> > >         .owner          = THIS_MODULE,
> > >  };
> > >
> > > @@ -1036,6 +1016,32 @@ static int qcom_edp_clks_register(struct qcom_edp *edp, struct device_node *np)
> > >         return devm_of_clk_add_hw_provider(edp->dev, of_clk_hw_onecell_get, data);
> > >  }
> > >
> > > +static int __maybe_unused qcom_edp_runtime_suspend(struct device *dev)
> > > +{
> > > +       struct qcom_edp *edp = dev_get_drvdata(dev);
> > > +
> > > +       dev_err(dev, "Suspending DP phy\n");
> >
> > Debug leftovers?
>
> Well, I should've made those dev_vdbg instead.
>
> >
> > > +
> > > +       clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> > > +       regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +static int __maybe_unused qcom_edp_runtime_resume(struct device *dev)
> > > +{
> > > +       struct qcom_edp *edp = dev_get_drvdata(dev);
> > > +       int ret;
> > > +
> > > +       dev_err(dev, "Resuming DP phy\n");
> >
> > Debug leftovers?
> >
>
> See above.
>
> > > +
> > > +       ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > > +       if (ret)
> > > +               return ret;
> > > +
> > > +       return clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> >
> > Missing error handling
> >
>
> Yep, will fix.
>
> > > +}
> > > +
> > >  static int qcom_edp_phy_probe(struct platform_device *pdev)
> > >  {
> > >         struct phy_provider *phy_provider;
> > > @@ -1091,20 +1097,57 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
> > >                 return ret;
> > >         }
> > >
> > > -       ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
> > > -       if (ret)
> > > +       ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > > +       if (ret) {
> > > +               dev_err(dev, "failed to enable regulators, err=%d\n", ret);
> > >                 return ret;
> > > +       }
> > > +
> > > +       ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> > > +       if (ret) {
> > > +               dev_err(dev, "failed to enable clocks, err=%d\n", ret);
> > > +               goto err_disable_regulators;
> > > +       }
> >
> > Please use pm_runtime_get_sync() instead().
> >
>
> So let me explain how I thought this through first. This DP PHY is
> usually used on platforms where display is left enabled by the
> bootloader. So doing pm_runtime_get_sync would mean we increment the
> device's usage counter while it is known to be already enabled, even if
> genpd doesn't consider it so. So doing set_active instead would be more
> accurate. Now, for the regulator and clock generic frameworks, that
> seemed OK to do at the time. Now I can see that the same argument can be
> made for those as well. So I'm thinking maybe I just drop the enable
> here and don't do _get_sync, but rather rely on the resume being done
> on power on instead.

Please don't rely on the bootloader. The device should be in the
resumed state when registering clocks. Also devm_pm_runtime_enable()
should also be called before, so that the CCF makes note of PM being
enabled.

>
> > > +
> > > +       ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
> > > +       if (ret) {
> > > +               dev_err(dev, "failed to register PHY clocks, err=%d\n", ret);
> > > +               goto err_disable_clocks;
> > > +       }
> > >
> > >         edp->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_edp_ops);
> > >         if (IS_ERR(edp->phy)) {
> > >                 dev_err(dev, "failed to register phy\n");
> > > -               return PTR_ERR(edp->phy);
> > > +               ret = PTR_ERR(edp->phy);
> > > +               goto err_disable_clocks;
> > >         }
> > >
> > > +       pm_runtime_set_active(dev);
> > > +       ret = devm_pm_runtime_enable(dev);
> >
> > If this handles earlier, you don't need to call pm_runtime_set_active() manually
> >
>
> Enable and set_active are two separate things. Maybe I'm
> misunderstanding your comment.

Yeah, I wrote something strange here. I meant that if enable is called
earlier and then if the device is resumed, there is no need to call
set_active.

>
> > > +       if (ret)
> > > +               goto err_disable_clocks;
> > > +       /*
> > > +        * Prevent runtime pm from being ON by default. Users can enable
> > > +        * it using power/control in sysfs.
> >
> > why?
> >
>
> OK, so this is a tricky one. If there is any platform out there that
> makes use of this PHY but the resources are not properly described, we
> might get in trouble. So I was thinking that maybe we don't risk that
> but let the user enable it via sysfs. That way, this patch will not
> break by default such platforms.

If the platform doesn't describe resources, it is broken, there is no
need to support it.
>
> Also, this would be in line with the rest of the other Qcom PHYs.

I think it's a bit of a cargo cult. Such code was added in 2018 and
then it was c&p'ed since that time.

>
> > > +        */
> > > +       pm_runtime_forbid(dev);
> > > +
> > > +       dev_set_drvdata(dev, edp);
> > >         phy_set_drvdata(edp->phy, edp);
> > >
> > >         phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> > > -       return PTR_ERR_OR_ZERO(phy_provider);
> > > +       if (IS_ERR(phy_provider))
> > > +               goto err_disable_clocks;
> > > +
> > > +       return 0;
> > > +
> > > +err_disable_clocks:
> > > +       clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> > > +
> > > +err_disable_regulators:
> > > +       regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> >
> > Ideally this should be handled by pm_runtime. Or at least by pm_runtime_put().
>
> Will drop entirely. Again, lets not enable anything on probe for now.

NAK.

>
> >
> > > +
> > > +       return ret;
> > >  }
> > >
> > >  static const struct of_device_id qcom_edp_phy_match_table[] = {
> > > @@ -1117,10 +1160,16 @@ static const struct of_device_id qcom_edp_phy_match_table[] = {
> > >  };
> > >  MODULE_DEVICE_TABLE(of, qcom_edp_phy_match_table);
> > >
> > > +static const struct dev_pm_ops qcom_edp_pm_ops = {
> > > +       SET_RUNTIME_PM_OPS(qcom_edp_runtime_suspend,
> > > +                          qcom_edp_runtime_resume, NULL)
> > > +};
> > > +
> > >  static struct platform_driver qcom_edp_phy_driver = {
> > >         .probe          = qcom_edp_phy_probe,
> > >         .driver = {
> > >                 .name   = "qcom-edp-phy",
> > > +               .pm     = &qcom_edp_pm_ops,
> > >                 .of_match_table = qcom_edp_phy_match_table,
> > >         },
> > >  };
> > >
> > > ---
> > > base-commit: 9aaeb87ce1e966169a57f53a02ba05b30880ffb8
> > > change-id: 20240907-phy-qcom-edp-enable-runtime-pm-6fad07af8947
> > >
> > > Best regards,
> > > --
> > > Abel Vesa <abel.vesa at linaro.org>
> > >
> >
> >
> > --
> > With best wishes
> > Dmitry



-- 
With best wishes
Dmitry


From abel.vesa at linaro.org  Sun Sep  8 11:55:22 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Sun, 8 Sep 2024 21:55:22 +0300
Subject: [PATCH] phy: qcom: edp: Add runtime PM support
In-Reply-To: <CAA8EJppTp5S1L-rHKDW58uXQO08p6o=aNbE3kA9UjVKZsyJ-Jw@mail.gmail.com>
References: <20240907-phy-qcom-edp-enable-runtime-pm-v1-1-8b9ee4210e1e@linaro.org>
 <CAA8EJpqw6pB4d_zQyYdhq9_prLnh+mLMdRSzJ+5EvAjT9wi86A@mail.gmail.com>
 <Zt3pFdndtTw/nbgs@linaro.org>
 <CAA8EJppTp5S1L-rHKDW58uXQO08p6o=aNbE3kA9UjVKZsyJ-Jw@mail.gmail.com>
Message-ID: <Zt3zGg6VhZJ7qdgz@linaro.org>

On 24-09-08 21:43:01, Dmitry Baryshkov wrote:
> On Sun, 8 Sept 2024 at 21:12, Abel Vesa <abel.vesa at linaro.org> wrote:
> >
> > On 24-09-07 20:52:14, Dmitry Baryshkov wrote:
> > > On Sat, 7 Sept 2024 at 18:25, Abel Vesa <abel.vesa at linaro.org> wrote:
> > > >
> > > > Enable runtime PM support by adding proper ops which will handle the
> > > > clocks and regulators. These resources will now be handled on power_on and
> > > > power_off instead of init and exit PHY ops. Also enable these resources on
> > > > probe in order to balance out the disabling that is happening right after.
> > > > Prevent runtime PM from being ON by default as well.
> > > >
> > > > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > > > ---
> > > >  drivers/phy/qualcomm/phy-qcom-edp.c | 105 ++++++++++++++++++++++++++----------
> > > >  1 file changed, 77 insertions(+), 28 deletions(-)
> > > >
> > > > diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> > > > index da2b32fb5b45..3affeef261bf 100644
> > > > --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> > > > +++ b/drivers/phy/qualcomm/phy-qcom-edp.c

[...]

> > > > +}
> > > > +
> > > >  static int qcom_edp_phy_probe(struct platform_device *pdev)
> > > >  {
> > > >         struct phy_provider *phy_provider;
> > > > @@ -1091,20 +1097,57 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
> > > >                 return ret;
> > > >         }
> > > >
> > > > -       ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
> > > > -       if (ret)
> > > > +       ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > > > +       if (ret) {
> > > > +               dev_err(dev, "failed to enable regulators, err=%d\n", ret);
> > > >                 return ret;
> > > > +       }
> > > > +
> > > > +       ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
> > > > +       if (ret) {
> > > > +               dev_err(dev, "failed to enable clocks, err=%d\n", ret);
> > > > +               goto err_disable_regulators;
> > > > +       }
> > >
> > > Please use pm_runtime_get_sync() instead().
> > >
> >
> > So let me explain how I thought this through first. This DP PHY is
> > usually used on platforms where display is left enabled by the
> > bootloader. So doing pm_runtime_get_sync would mean we increment the
> > device's usage counter while it is known to be already enabled, even if
> > genpd doesn't consider it so. So doing set_active instead would be more
> > accurate. Now, for the regulator and clock generic frameworks, that
> > seemed OK to do at the time. Now I can see that the same argument can be
> > made for those as well. So I'm thinking maybe I just drop the enable
> > here and don't do _get_sync, but rather rely on the resume being done
> > on power on instead.
> 
> Please don't rely on the bootloader. The device should be in the
> resumed state when registering clocks. Also devm_pm_runtime_enable()
> should also be called before, so that the CCF makes note of PM being
> enabled.

Fair enough. Will do that.

> 
> >
> > > > +
> > > > +       ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
> > > > +       if (ret) {
> > > > +               dev_err(dev, "failed to register PHY clocks, err=%d\n", ret);
> > > > +               goto err_disable_clocks;
> > > > +       }
> > > >
> > > >         edp->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_edp_ops);
> > > >         if (IS_ERR(edp->phy)) {
> > > >                 dev_err(dev, "failed to register phy\n");
> > > > -               return PTR_ERR(edp->phy);
> > > > +               ret = PTR_ERR(edp->phy);
> > > > +               goto err_disable_clocks;
> > > >         }
> > > >
> > > > +       pm_runtime_set_active(dev);
> > > > +       ret = devm_pm_runtime_enable(dev);
> > >
> > > If this handles earlier, you don't need to call pm_runtime_set_active() manually
> > >
> >
> > Enable and set_active are two separate things. Maybe I'm
> > misunderstanding your comment.
> 
> Yeah, I wrote something strange here. I meant that if enable is called
> earlier and then if the device is resumed, there is no need to call
> set_active.

I guess you meant "that if _get_sync is called earlier and then ...", right?
Enable won't resume it.

> 
> >
> > > > +       if (ret)
> > > > +               goto err_disable_clocks;
> > > > +       /*
> > > > +        * Prevent runtime pm from being ON by default. Users can enable
> > > > +        * it using power/control in sysfs.
> > >
> > > why?
> > >
> >
> > OK, so this is a tricky one. If there is any platform out there that
> > makes use of this PHY but the resources are not properly described, we
> > might get in trouble. So I was thinking that maybe we don't risk that
> > but let the user enable it via sysfs. That way, this patch will not
> > break by default such platforms.
> 
> If the platform doesn't describe resources, it is broken, there is no
> need to support it.
> >
> > Also, this would be in line with the rest of the other Qcom PHYs.
> 
> I think it's a bit of a cargo cult. Such code was added in 2018 and
> then it was c&p'ed since that time.

OK, will drop it.

> 
> >
> > > > +        */
> > > > +       pm_runtime_forbid(dev);
> > > > +
> > > > +       dev_set_drvdata(dev, edp);
> > > >         phy_set_drvdata(edp->phy, edp);
> > > >
> > > >         phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> > > > -       return PTR_ERR_OR_ZERO(phy_provider);
> > > > +       if (IS_ERR(phy_provider))
> > > > +               goto err_disable_clocks;
> > > > +
> > > > +       return 0;
> > > > +
> > > > +err_disable_clocks:
> > > > +       clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
> > > > +
> > > > +err_disable_regulators:
> > > > +       regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
> > >
> > > Ideally this should be handled by pm_runtime. Or at least by pm_runtime_put().
> >
> > Will drop entirely. Again, lets not enable anything on probe for now.
> 
> NAK.

OK, your argument above about the registering of clocks needing the
PHY resumed makes sense. Will do _get_sync on probe.



From biju.das.jz at bp.renesas.com  Sun Sep  8 23:00:16 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Mon, 9 Sep 2024 06:00:16 +0000
Subject: [PATCH v2] phy: renesas: rcar-gen3-usb2: Fix an error handling
 path in rcar_gen3_phy_usb2_probe()
In-Reply-To: <d01bed96-7811-4ace-8b92-1ee9fafac649@wanadoo.fr>
References: <4efe2d0419cbe98163e2422ebe0c7896b8a5efed.1725717505.git.christophe.jaillet@wanadoo.fr>
 <TY3PR01MB113468D1573C1E50AC9F97DCF86982@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <d01bed96-7811-4ace-8b92-1ee9fafac649@wanadoo.fr>
Message-ID: <TY3PR01MB113466A2B99EE80E8BB0A94AD86992@TY3PR01MB11346.jpnprd01.prod.outlook.com>

Hi Christophe JAILLET,

> -----Original Message-----
> From: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> Sent: Sunday, September 8, 2024 5:59 PM
> Subject: Re: [PATCH v2] phy: renesas: rcar-gen3-usb2: Fix an error handling path in
> rcar_gen3_phy_usb2_probe()
> 
> Le 08/09/2024 ? 18:39, Biju Das a ?crit?:
> > Hi Christophe JAILLET,
> >
> > Thanks for the patch.
> >
> >> -----Original Message-----
> >> From: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> >> Sent: Saturday, September 7, 2024 2:59 PM
> >> Subject: [PATCH v2] phy: renesas: rcar-gen3-usb2: Fix an error
> >> handling path in
> >> rcar_gen3_phy_usb2_probe()
> >>
> >> If an error occurs after the rcar_gen3_phy_usb2_init_bus(),
> >> reset_control_assert() must be called, as already done in the remove function.
> >>
> >> This is fine to re-use the existing error handling path, because even
> >> if "channel->rstc" is still NULL at this point, it is safe to call reset_control_assert(NULL).
> >>
> >> Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to
> >> initialize the bus")
> >> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> >> ---
> >> Changes in v2:
> >>    - Re-use 'error' to simplify the patch   [claudiu beznea]
> >>    - Update the commit description to explain why it is safe.
> >>
> >> v1:
> >> https://lore.kernel.org/all/fc9f7b444f0ca645411868992bbe16514aeccfed.
> >> 1725652654.git.christophe.jaillet
> >> @wanadoo.fr/
> >> ---
> >>   drivers/phy/renesas/phy-rcar-gen3-usb2.c | 1 +
> >>   1 file changed, 1 insertion(+)
> >>
> >> diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> >> b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> >> index 58e123305152..ccb0b54b70f7 100644
> >> --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> >> +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> >> @@ -803,6 +803,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
> >>   	return 0;
> >>
> >>   error:
> >> +	reset_control_assert(channel->rstc);
> >
> > This will result in either kernel crash [1] or reset usage count
> > imbalance in case of error [2] and [3] in
> > rcar_gen3_phy_usb2_init_bus() see [4]. Also reset control API is not
> > respected for SoCs other than RZ/G3S. For those SoC's reset assert is
> > called without calling a get(). Maybe add a check (phy_data->init_bus)
> > for assert api's, that guarantees assert is called after calling a get() as it valid only for
> RZ/G3S??
> >
> > [1]
> > channel->rstc = devm_reset_control_array_get_shared(dev);
> > 	if (IS_ERR(channel->rstc))
> > 		return PTR_ERR(channel->rstc);
> >
> > [2]
> > ret = pm_runtime_resume_and_get(dev);
> > 	if (ret)
> > 		return ret;
> > [3]
> > ret = reset_control_deassert(channel->rstc);
> > 	if (ret)
> > 		goto rpm_put;
> >
> > [4]
> > https://elixir.bootlin.com/linux/v6.11-rc6/source/drivers/reset/core.c
> > #L483
> 
> So, if I understand correctly, v1 [5] was correct. :)

Yes, I agree v1 [5] is correct, if we ignore "reset control API is not respected for SoCs".

Another solution could be using action_or_reset() for cleanup for
rcar_gen3_phy_usb2_init_bus(), so that it is applicable only for RZ/G3S??

Cheers,
Biju

> 
> 
> I don't think that [1] would crash, because of [6]. It would only WARN_ON. But with v1, it is not
> called.
> 
> With v1, reset_control_assert() is not called if
> rcar_gen3_phy_usb2_init_bus() fails. So [2] and [3] can't occur.
> 
> I can send a v3, which is the same of v1, or you can pick v1 as-is (if I'm correct... :)) or you can
> just ignore it if "reset control API is not respected for SoCs".
> 
> 
> If of interest, I spotted it with one of my coccinelle script that compares functions called
> in .remove function, but not in error handling path of probe.
> 
> 
> CJ
> 
> [5]:
> https://lore.kernel.org/all/fc9f7b444f0ca645411868992bbe16514aeccfed.1725652654.git.christophe.jaillet
> @wanadoo.fr/
> 
> [6]:
> https://elixir.bootlin.com/linux/v6.11-rc6/source/drivers/reset/core.c#L473
> 
> >
> > Cheers,
> > Biju
> >
> >>   	pm_runtime_disable(dev);
> >>
> >>   	return ret;
> >> --
> >> 2.46.0
> >>
> >
> >
> >


From claudiu.beznea at tuxon.dev  Mon Sep  9 00:07:48 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Mon, 9 Sep 2024 10:07:48 +0300
Subject: [PATCH v2] phy: renesas: rcar-gen3-usb2: Fix an error handling
 path in rcar_gen3_phy_usb2_probe()
In-Reply-To: <TY3PR01MB113466A2B99EE80E8BB0A94AD86992@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <4efe2d0419cbe98163e2422ebe0c7896b8a5efed.1725717505.git.christophe.jaillet@wanadoo.fr>
 <TY3PR01MB113468D1573C1E50AC9F97DCF86982@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <d01bed96-7811-4ace-8b92-1ee9fafac649@wanadoo.fr>
 <TY3PR01MB113466A2B99EE80E8BB0A94AD86992@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <503ed037-a16c-41b0-bb13-4ea11fcd2362@tuxon.dev>



On 09.09.2024 09:00, Biju Das wrote:
> Hi Christophe JAILLET,
> 
>> -----Original Message-----
>> From: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
>> Sent: Sunday, September 8, 2024 5:59 PM
>> Subject: Re: [PATCH v2] phy: renesas: rcar-gen3-usb2: Fix an error handling path in
>> rcar_gen3_phy_usb2_probe()
>>
>> Le 08/09/2024 ? 18:39, Biju Das a ?crit?:
>>> Hi Christophe JAILLET,
>>>
>>> Thanks for the patch.
>>>
>>>> -----Original Message-----
>>>> From: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
>>>> Sent: Saturday, September 7, 2024 2:59 PM
>>>> Subject: [PATCH v2] phy: renesas: rcar-gen3-usb2: Fix an error
>>>> handling path in
>>>> rcar_gen3_phy_usb2_probe()
>>>>
>>>> If an error occurs after the rcar_gen3_phy_usb2_init_bus(),
>>>> reset_control_assert() must be called, as already done in the remove function.
>>>>
>>>> This is fine to re-use the existing error handling path, because even
>>>> if "channel->rstc" is still NULL at this point, it is safe to call reset_control_assert(NULL).
>>>>
>>>> Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to
>>>> initialize the bus")
>>>> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
>>>> ---
>>>> Changes in v2:
>>>>    - Re-use 'error' to simplify the patch   [claudiu beznea]
>>>>    - Update the commit description to explain why it is safe.
>>>>
>>>> v1:
>>>> https://lore.kernel.org/all/fc9f7b444f0ca645411868992bbe16514aeccfed.
>>>> 1725652654.git.christophe.jaillet
>>>> @wanadoo.fr/
>>>> ---
>>>>   drivers/phy/renesas/phy-rcar-gen3-usb2.c | 1 +
>>>>   1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
>>>> b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
>>>> index 58e123305152..ccb0b54b70f7 100644
>>>> --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
>>>> +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
>>>> @@ -803,6 +803,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
>>>>   	return 0;
>>>>
>>>>   error:
>>>> +	reset_control_assert(channel->rstc);
>>>
>>> This will result in either kernel crash [1] or reset usage count
>>> imbalance in case of error [2] and [3] in
>>> rcar_gen3_phy_usb2_init_bus() see [4]. Also reset control API is not
>>> respected for SoCs other than RZ/G3S. For those SoC's reset assert is
>>> called without calling a get(). Maybe add a check (phy_data->init_bus)
>>> for assert api's, that guarantees assert is called after calling a get() as it valid only for
>> RZ/G3S??
>>>
>>> [1]
>>> channel->rstc = devm_reset_control_array_get_shared(dev);
>>> 	if (IS_ERR(channel->rstc))
>>> 		return PTR_ERR(channel->rstc);
>>>
>>> [2]
>>> ret = pm_runtime_resume_and_get(dev);
>>> 	if (ret)
>>> 		return ret;
>>> [3]
>>> ret = reset_control_deassert(channel->rstc);
>>> 	if (ret)
>>> 		goto rpm_put;

Indeed, I missed that. Thank you, Biju, for pointing it out.

>>>
>>> [4]
>>> https://elixir.bootlin.com/linux/v6.11-rc6/source/drivers/reset/core.c
>>> #L483
>>
>> So, if I understand correctly, v1 [5] was correct. :)
> 
> Yes, I agree v1 [5] is correct, if we ignore "reset control API is not respected for SoCs".
> 
> Another solution could be using action_or_reset() for cleanup for
> rcar_gen3_phy_usb2_init_bus(), so that it is applicable only for RZ/G3S??

That seems like a cleaner solution to me.

Thank you,
Claudiu Beznea

> 
> Cheers,
> Biju
> 
>>
>>
>> I don't think that [1] would crash, because of [6]. It would only WARN_ON. But with v1, it is not
>> called.
>>
>> With v1, reset_control_assert() is not called if
>> rcar_gen3_phy_usb2_init_bus() fails. So [2] and [3] can't occur.
>>
>> I can send a v3, which is the same of v1, or you can pick v1 as-is (if I'm correct... :)) or you can
>> just ignore it if "reset control API is not respected for SoCs".
>>
>>
>> If of interest, I spotted it with one of my coccinelle script that compares functions called
>> in .remove function, but not in error handling path of probe.
>>
>>
>> CJ
>>
>> [5]:
>> https://lore.kernel.org/all/fc9f7b444f0ca645411868992bbe16514aeccfed.1725652654.git.christophe.jaillet
>> @wanadoo.fr/
>>
>> [6]:
>> https://elixir.bootlin.com/linux/v6.11-rc6/source/drivers/reset/core.c#L473
>>
>>>
>>> Cheers,
>>> Biju
>>>
>>>>   	pm_runtime_disable(dev);
>>>>
>>>>   	return ret;
>>>> --
>>>> 2.46.0
>>>>
>>>
>>>
>>>
> 


From daniel.machon at microchip.com  Mon Sep  9 01:22:41 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Mon, 9 Sep 2024 08:22:41 +0000
Subject: [PATCH 8/9] dt-bindings: phy: sparx5: document lan969x in sparx5
 dt-bindings
In-Reply-To: <c0aa5342-a2af-4ac4-bc33-b6dbfff77f63@kernel.org>
References: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
 <20240906-sparx5-lan969x-serdes-driver-v1-8-8d630614c58a@microchip.com>
 <c0aa5342-a2af-4ac4-bc33-b6dbfff77f63@kernel.org>
Message-ID: <20240909082241.hvw3a7yig3pujrsk@DEN-DL-M70577>

Hi Krzysztof,

Thanks your comments.

> On 06/09/2024 14:52, Daniel Machon wrote:
> > Document lan969x in the existing Sparx5 dt-bindings.
> >
> 
> Say something useful, not copy of subject.
> 
> > Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
> 
> A nit, subject: drop second/last, redundant "dt-bindings". The
> "dt-bindings" prefix is already stating that these are bindings.
> See also:
> https://elixir.bootlin.com/linux/v6.7-rc8/source/Documentation/devicetree/bindings/submitting-patches.rst#L18

Duly noted.

> 
> 
> > Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
> > ---
> >  .../bindings/phy/microchip,sparx5-serdes.yaml          | 18 ++++++++++++++++--
> >  1 file changed, 16 insertions(+), 2 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml b/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
> > index bdbdb3bbddbe..1e07a311e8a5 100644
> > --- a/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
> > +++ b/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
> > @@ -8,6 +8,7 @@ title: Microchip Sparx5 Serdes controller
> >
> >  maintainers:
> >    - Steen Hegelund <steen.hegelund at microchip.com>
> > +  - Daniel Machon <daniel.machon at microchip.com>
> >
> >  description: |
> >    The Sparx5 SERDES interfaces share the same basic functionality, but
> > @@ -62,12 +63,17 @@ description: |
> >    * 10.3125 Gbps (10GBASE-R/10GBASE-KR/USXGMII)
> >    * 25.78125 Gbps (25GBASE-KR/25GBASE-CR/25GBASE-SR/25GBASE-LR/25GBASE-ER)
> >
> > +  lan969x has ten SERDES10G interfaces that share the same features, operating
> > +  modes and data rates as the equivalent Sparx5 SERDES10G interfaces.
> > +
> >  properties:
> >    $nodename:
> >      pattern: "^serdes@[0-9a-f]+$"
> >
> >    compatible:
> > -    const: microchip,sparx5-serdes
> > +    enum:
> > +      - microchip,sparx5-serdes
> > +      - microchip,lan969x-serdes
> 
> It seems there is no lan969x SoC/chip. Are you sure you are using
> correct naming, matching what kernel is using? Maybe you just sent
> whatever you had in downstream (hint: that's never a good idea).

You are right. There is no upstream support for lan969x SoC yet. The
upstreaming of the lan969x SoC has just begun, and this series is part
of that upstreaming effort. The lan969x switch driver (not submitted
yet) will depend on this SERDES driver, however, their functionality is
really independent of each other. That is why I am also upstreaming the
SERDES- and switch driver series independent of each other.

If these series needs to somehow be connected, by link or whatever, then
fine.  If there is some preferred way to do this, then please let me
know or point me in some direction. Thanks.

> 
> >
> >    reg:
> >      minItems: 1
> > @@ -90,11 +96,19 @@ additionalProperties: false
> >
> >  examples:
> >    - |
> > -    serdes: serdes at 10808000 {
> > +    serdes at 10808000 {
> >        compatible = "microchip,sparx5-serdes";
> >        #phy-cells = <1>;
> >        clocks = <&sys_clk>;
> >        reg = <0x10808000 0x5d0000>;
> >      };
> >
> > +  - |
> > +    serdes at e3410000 {
> > +      compatible = "microchip,lan969x-serdes";
> > +      #phy-cells = <1>;
> > +      clocks = <&fabric_clk>;
> 
> No differences so no need for new example. Also please follow DTS coding
> style in case of any DTS code.
> 

Ack.

> Best regards,
> Krzysztof
> 

/Daniel


From krzk at kernel.org  Mon Sep  9 01:35:18 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Sep 2024 10:35:18 +0200
Subject: [PATCH 8/9] dt-bindings: phy: sparx5: document lan969x in sparx5
 dt-bindings
In-Reply-To: <20240909082241.hvw3a7yig3pujrsk@DEN-DL-M70577>
References: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
 <20240906-sparx5-lan969x-serdes-driver-v1-8-8d630614c58a@microchip.com>
 <c0aa5342-a2af-4ac4-bc33-b6dbfff77f63@kernel.org>
 <20240909082241.hvw3a7yig3pujrsk@DEN-DL-M70577>
Message-ID: <ee4d4375-873b-4b9c-b694-f0191e5c2c54@kernel.org>

On 09/09/2024 10:22, Daniel Machon wrote:
> Hi Krzysztof,
> 
> Thanks your comments.
> 
>> On 06/09/2024 14:52, Daniel Machon wrote:
>>> Document lan969x in the existing Sparx5 dt-bindings.
>>>
>>
>> Say something useful, not copy of subject.
>>
>>> Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
>>
>> A nit, subject: drop second/last, redundant "dt-bindings". The
>> "dt-bindings" prefix is already stating that these are bindings.
>> See also:
>> https://elixir.bootlin.com/linux/v6.7-rc8/source/Documentation/devicetree/bindings/submitting-patches.rst#L18
> 
> Duly noted.
> 
>>
>>
>>> Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
>>> ---
>>>  .../bindings/phy/microchip,sparx5-serdes.yaml          | 18 ++++++++++++++++--
>>>  1 file changed, 16 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml b/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
>>> index bdbdb3bbddbe..1e07a311e8a5 100644
>>> --- a/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
>>> +++ b/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
>>> @@ -8,6 +8,7 @@ title: Microchip Sparx5 Serdes controller
>>>
>>>  maintainers:
>>>    - Steen Hegelund <steen.hegelund at microchip.com>
>>> +  - Daniel Machon <daniel.machon at microchip.com>
>>>
>>>  description: |
>>>    The Sparx5 SERDES interfaces share the same basic functionality, but
>>> @@ -62,12 +63,17 @@ description: |
>>>    * 10.3125 Gbps (10GBASE-R/10GBASE-KR/USXGMII)
>>>    * 25.78125 Gbps (25GBASE-KR/25GBASE-CR/25GBASE-SR/25GBASE-LR/25GBASE-ER)
>>>
>>> +  lan969x has ten SERDES10G interfaces that share the same features, operating
>>> +  modes and data rates as the equivalent Sparx5 SERDES10G interfaces.
>>> +
>>>  properties:
>>>    $nodename:
>>>      pattern: "^serdes@[0-9a-f]+$"
>>>
>>>    compatible:
>>> -    const: microchip,sparx5-serdes
>>> +    enum:
>>> +      - microchip,sparx5-serdes
>>> +      - microchip,lan969x-serdes
>>
>> It seems there is no lan969x SoC/chip. Are you sure you are using
>> correct naming, matching what kernel is using? Maybe you just sent
>> whatever you had in downstream (hint: that's never a good idea).
> 
> You are right. There is no upstream support for lan969x SoC yet. The
> upstreaming of the lan969x SoC has just begun, and this series is part
> of that upstreaming effort. The lan969x switch driver (not submitted
> yet) will depend on this SERDES driver, however, their functionality is
> really independent of each other. That is why I am also upstreaming the
> SERDES- and switch driver series independent of each other.

That's not exactly my point. Becayse lan969x appears. I claim you use
incorrect name, so are you sure you do not use wildcards?
Best regards,
Krzysztof



From christian.bruel at foss.st.com  Mon Sep  9 01:40:44 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Mon, 9 Sep 2024 10:40:44 +0200
Subject: [PATCH v5 2/5] phy: stm32: Add support for STM32MP25 COMBOPHY.
In-Reply-To: <d743de28a5dd643cf775f4d8a3baaabd09d48c48.camel@pengutronix.de>
References: <20240903121303.2953150-1-christian.bruel@foss.st.com>
 <20240903121303.2953150-3-christian.bruel@foss.st.com>
 <d743de28a5dd643cf775f4d8a3baaabd09d48c48.camel@pengutronix.de>
Message-ID: <f7cead97-7f26-4923-b04d-7ce812a32577@foss.st.com>

Hi,

On 9/6/24 15:44, Philipp Zabel wrote:
> Hi,
> 
> On Di, 2024-09-03 at 14:13 +0200, Christian Bruel wrote:
>> Addition of the COMBOPHY driver found on STM32MP25 platforms
>>
>> This single lane PHY is shared (exclusive) between the USB3 and PCIE
>> controllers.
>> Supports 5Gbit/s for PCIE gen2 or 2.5Gbit/s for PCIE gen1.
>>
>> Supports wakeup-source capability to wakeup system using remote-wakeup
>> capable USB device
>>
>> Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
>> ---
>>   drivers/phy/st/Kconfig              |  11 +
>>   drivers/phy/st/Makefile             |   1 +
>>   drivers/phy/st/phy-stm32-combophy.c | 590 ++++++++++++++++++++++++++++
>>   3 files changed, 602 insertions(+)
>>   create mode 100644 drivers/phy/st/phy-stm32-combophy.c
>>
> [...]
>> diff --git a/drivers/phy/st/phy-stm32-combophy.c b/drivers/phy/st/phy-stm32-combophy.c
>> new file mode 100644
>> index 000000000000..305ba124d092
>> --- /dev/null
>> +++ b/drivers/phy/st/phy-stm32-combophy.c
>> @@ -0,0 +1,590 @@
> [...]
>> +static int stm32_combophy_pll_init(struct stm32_combophy *combophy)
>> +{
>> +	int ret;
>> +	u32 refclksel, pllmult, propcntrl, val;
>> +	u32 clk_rate;
>> +	struct clk *clk;
>> +
>> +	if (combophy->have_pad_clk)
>> +		clk = combophy->clks[PAD_CLK].clk;
>> +	else
>> +		clk = combophy->clks[KER_CLK].clk;
>> +
>> +	clk_rate = clk_get_rate(clk);
>> +
>> +	reset_control_assert(combophy->phy_reset);
>> +
>> +	dev_dbg(combophy->dev, "%s pll init rate %d\n",
>> +		combophy->have_pad_clk ? "External" : "Ker", clk_rate);
>> +
>> +	/*
>> +	 * vddcombophy is interconnected with vddcore. Isolation bit should be unset
>> +	 * before using the ComboPHY.
>> +	 */
>> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
>> +			   SYSCFG_COMBOPHY_CR2_ISO_DIS, SYSCFG_COMBOPHY_CR2_ISO_DIS);
>> +
>> +	if (combophy->type != PHY_TYPE_PCIE)
>> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
>> +				   SYSCFG_COMBOPHY_CR1_REFSSPEN, SYSCFG_COMBOPHY_CR1_REFSSPEN);
> 
> Could the multiple accesses to SYSCFG_COMBOPHY_CR1 be consolidated into
> a single regmap_update_bits()?

yes, thanks

> 
>> +
>> +	if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
>> +		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
>> +				   STM32MP25_PCIEPRGCR_EN, STM32MP25_PCIEPRGCR_EN);
>> +
>> +	if (of_property_present(combophy->dev->of_node, "st,ssc-on")) {
>> +		dev_dbg(combophy->dev, "Enabling clock with SSC\n");
>> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
>> +				   SYSCFG_COMBOPHY_CR1_SSCEN, SYSCFG_COMBOPHY_CR1_SSCEN);
>> +	}
>> +
>> +	if (!of_property_read_u32(combophy->dev->of_node, "st,rx-equalizer", &val)) {
>> +		dev_dbg(combophy->dev, "Set RX equalizer %u\n", val);
>> +		if (val > SYSCFG_COMBOPHY_CR4_RX0_EQ) {
>> +			dev_err(combophy->dev, "Invalid value %u for rx0 equalizer\n", val);
> 
> This path looks like it should deassert the phy_reset as well.

Ack

> 
>> +			return -EINVAL;
>> +		}
>> +
>> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR4,
>> +			   SYSCFG_COMBOPHY_CR4_RX0_EQ, val);
>> +	}
>> +
>> +	if (combophy->type == PHY_TYPE_PCIE) {
>> +		ret = stm32_impedance_tune(combophy);
>> +		if (ret) {
>> +			reset_control_deassert(combophy->phy_reset);
>> +			goto out;
>> +		}
>> +
>> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
>> +				   SYSCFG_COMBOPHY_CR1_REFUSEPAD,
>> +				   combophy->have_pad_clk ? SYSCFG_COMBOPHY_CR1_REFUSEPAD : 0);
>> +	}
>> +
>> +	switch (clk_rate) {
>> +	case 100000000:
>> +		pllmult = MPLLMULT_100;
>> +		refclksel = REFCLKSEL_0;
>> +		propcntrl = 0x8u << 4;
>> +		break;
>> +	case 19200000:
>> +		pllmult = MPLLMULT_19_2;
>> +		refclksel = REFCLKSEL_1;
>> +		propcntrl = 0x8u << 4;
>> +		break;
>> +	case 25000000:
>> +		pllmult = MPLLMULT_25;
>> +		refclksel = REFCLKSEL_0;
>> +		propcntrl = 0xeu << 4;
>> +		break;
>> +	case 24000000:
>> +		pllmult = MPLLMULT_24;
>> +		refclksel = REFCLKSEL_1;
>> +		propcntrl = 0xeu << 4;
>> +		break;
>> +	case 20000000:
>> +		pllmult = MPLLMULT_20;
>> +		refclksel = REFCLKSEL_0;
>> +		propcntrl = 0xeu << 4;
>> +		break;
>> +	default:
>> +		dev_err(combophy->dev, "Invalid rate 0x%x\n", clk_rate);
>> +		reset_control_deassert(combophy->phy_reset);
>> +		ret = -EINVAL;
>> +		goto out;
>> +	};
>> +
>> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
>> +			   SYSCFG_COMBOPHY_CR1_REFCLKDIV2, REFCLDIV_0);
>> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
>> +			   SYSCFG_COMBOPHY_CR1_REFCLKSEL, refclksel);
>> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
>> +			   SYSCFG_COMBOPHY_CR1_MPLLMULT, pllmult);
>> +
>> +	/*
>> +	 * Force elasticity buffer to be tuned for the reference clock as
>> +	 * the separated clock model is not supported
>> +	 */
>> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR5,
>> +			   SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS, SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS);
>> +
>> +	reset_control_deassert(combophy->phy_reset);
>> +
>> +	ret = regmap_read_poll_timeout(combophy->regmap, SYSCFG_COMBOPHY_SR, val,
>> +				       !(val & STM32MP25_PIPE0_PHYSTATUS),
>> +				       10, 1000);
>> +	if (ret) {
>> +		dev_err(combophy->dev, "timeout, cannot lock PLL\n");
>> +		goto out;
>> +	}
>> +
>> +	if (combophy->type == PHY_TYPE_PCIE) {
>> +		val = readl_relaxed(combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
>> +		val &= ~COMBOPHY_PROP_CNTRL;
>> +		val |= propcntrl;
>> +		writel_relaxed(val, combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
>> +	}
>> +
>> +	return 0;
>> +
>> +out:
>> +	if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
>> +		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
>> +				   STM32MP25_PCIEPRGCR_EN, 0);
>> +
>> +	if (combophy->type != PHY_TYPE_PCIE)
>> +		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
>> +				   SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
>> +
>> +	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
>> +			   SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
>> +
>> +	return ret;
>> +}
>> +
> [...]
>> +
>> +static int stm32_combophy_probe(struct platform_device *pdev)
>> +{
>> +	struct stm32_combophy *combophy;
>> +	struct device *dev = &pdev->dev;
>> +	struct phy_provider *phy_provider;
>> +	int ret, irq;
>> +
>> +	combophy = devm_kzalloc(dev, sizeof(*combophy), GFP_KERNEL);
>> +	if (!combophy)
>> +		return -ENOMEM;
>> +
>> +	combophy->dev = dev;
>> +
>> +	dev_set_drvdata(dev, combophy);
>> +
>> +	combophy->base = devm_platform_ioremap_resource(pdev, 0);
>> +	if (IS_ERR(combophy->base))
>> +		return PTR_ERR(combophy->base);
>> +
>> +	if (stm32_combophy_get_clocks(combophy))
>> +		return ret;
>> +
>> +	combophy->phy_reset = devm_reset_control_get(dev, "phy");
> 
> Please use devm_reset_control_get_exclusive() directly.

OK,

thanks,
Christian
> 
> regards
> Philipp


From daniel.machon at microchip.com  Mon Sep  9 02:43:24 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Mon, 9 Sep 2024 09:43:24 +0000
Subject: [PATCH 8/9] dt-bindings: phy: sparx5: document lan969x in sparx5
 dt-bindings
In-Reply-To: <ee4d4375-873b-4b9c-b694-f0191e5c2c54@kernel.org>
References: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
 <20240906-sparx5-lan969x-serdes-driver-v1-8-8d630614c58a@microchip.com>
 <c0aa5342-a2af-4ac4-bc33-b6dbfff77f63@kernel.org>
 <20240909082241.hvw3a7yig3pujrsk@DEN-DL-M70577>
 <ee4d4375-873b-4b9c-b694-f0191e5c2c54@kernel.org>
Message-ID: <20240909094324.u2aahgnrmxkxt7fc@DEN-DL-M70577>

> >>>    compatible:
> >>> -    const: microchip,sparx5-serdes
> >>> +    enum:
> >>> +      - microchip,sparx5-serdes
> >>> +      - microchip,lan969x-serdes
> >>
> >> It seems there is no lan969x SoC/chip. Are you sure you are using
> >> correct naming, matching what kernel is using? Maybe you just sent
> >> whatever you had in downstream (hint: that's never a good idea).
> >
> > You are right. There is no upstream support for lan969x SoC yet. The
> > upstreaming of the lan969x SoC has just begun, and this series is part
> > of that upstreaming effort. The lan969x switch driver (not submitted
> > yet) will depend on this SERDES driver, however, their functionality is
> > really independent of each other. That is why I am also upstreaming the
> > SERDES- and switch driver series independent of each other.
> 
> That's not exactly my point. Becayse lan969x appears. I claim you use
> incorrect name, so are you sure you do not use wildcards?
> Best regards,
> Krzysztof

Ahh.

So the problem is the 'x' in lan969x, right? I think we have a habbit of
documenting compatible strings like this in bindings. Anyway, what I can
do is document the different part numbers in the bindings: lan9691,
lan9692, lan9693, lan9694, lan9696 and lan9698.

/Daniel



From krzk at kernel.org  Mon Sep  9 03:42:33 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Sep 2024 12:42:33 +0200
Subject: [PATCH 8/9] dt-bindings: phy: sparx5: document lan969x in sparx5
 dt-bindings
In-Reply-To: <20240909094324.u2aahgnrmxkxt7fc@DEN-DL-M70577>
References: <20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a@microchip.com>
 <20240906-sparx5-lan969x-serdes-driver-v1-8-8d630614c58a@microchip.com>
 <c0aa5342-a2af-4ac4-bc33-b6dbfff77f63@kernel.org>
 <20240909082241.hvw3a7yig3pujrsk@DEN-DL-M70577>
 <ee4d4375-873b-4b9c-b694-f0191e5c2c54@kernel.org>
 <20240909094324.u2aahgnrmxkxt7fc@DEN-DL-M70577>
Message-ID: <121d4b0d-dd8e-4beb-a64b-f237bbbed7ad@kernel.org>

On 09/09/2024 11:43, Daniel Machon wrote:
>>>>>    compatible:
>>>>> -    const: microchip,sparx5-serdes
>>>>> +    enum:
>>>>> +      - microchip,sparx5-serdes
>>>>> +      - microchip,lan969x-serdes
>>>>
>>>> It seems there is no lan969x SoC/chip. Are you sure you are using
>>>> correct naming, matching what kernel is using? Maybe you just sent
>>>> whatever you had in downstream (hint: that's never a good idea).
>>>
>>> You are right. There is no upstream support for lan969x SoC yet. The
>>> upstreaming of the lan969x SoC has just begun, and this series is part
>>> of that upstreaming effort. The lan969x switch driver (not submitted
>>> yet) will depend on this SERDES driver, however, their functionality is
>>> really independent of each other. That is why I am also upstreaming the
>>> SERDES- and switch driver series independent of each other.
>>
>> That's not exactly my point. Becayse lan969x appears. I claim you use
>> incorrect name, so are you sure you do not use wildcards?
>> Best regards,
>> Krzysztof
> 
> Ahh.
> 
> So the problem is the 'x' in lan969x, right? I think we have a habbit of
> documenting compatible strings like this in bindings. Anyway, what I can
> do is document the different part numbers in the bindings: lan9691,
> lan9692, lan9693, lan9694, lan9696 and lan9698.

Depends. I remember I was confused about such wildcards before and for
some cases wildcard was ok. For some not. I don't remember, I don't know
which case is here.

Best regards,
Krzysztof



From conor.dooley at microchip.com  Mon Sep  9 04:02:49 2024
From: conor.dooley at microchip.com (Conor Dooley)
Date: Mon, 9 Sep 2024 12:02:49 +0100
Subject: [PATCH v3 1/1] phy: starfive: jh7110-usb: Fix link configuration
 to controller
In-Reply-To: <20240902111127.15155-2-minda.chen@starfivetech.com>
References: <20240902111127.15155-1-minda.chen@starfivetech.com>
 <20240902111127.15155-2-minda.chen@starfivetech.com>
Message-ID: <20240909-drizzle-hydroxide-dd405c4c3a6d@wendy>

On Mon, Sep 02, 2024 at 07:11:27PM +0800, Minda Chen wrote:
> From: Jan Kiszka <jan.kiszka at siemens.com>
> 
> In order to connect the USB 2.0 PHY to its controller, we also need to
> set "u0_pdrstn_split_sw_usbpipe_plugen" [1]. Some downstream U-Boot
> versions did that, but upstream firmware does not, and the kernel must
> not rely on such behavior anyway. Failing to set this left the USB
> gadget port invisible to connected hosts behind.
> 
> Link: https://doc-en.rvspace.org/JH7110/TRM/JH7110_TRM/sys_syscon.html#sys_syscon__section_b3l_fqs_wsb [1]
> Fixes: 16d3a71c20cf ("phy: starfive: Add JH7110 USB 2.0 PHY driver")
> Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
> Signed-off-by: Minda Chen <minda.chen at starfivetech.com>

Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20240909/6417e556/attachment.sig>

From aford173 at gmail.com  Mon Sep  9 05:46:41 2024
From: aford173 at gmail.com (Adam Ford)
Date: Mon, 9 Sep 2024 07:46:41 -0500
Subject: [PATCH V6 4/5] phy: freescale: fsl-samsung-hdmi: Use closest divider
In-Reply-To: <Ztvbd4XqY95YMAZd@atmark-techno.com>
References: <20240904233100.114611-1-aford173@gmail.com> <20240904233100.114611-5-aford173@gmail.com>
 <ZtpMPCHBnEgtkBWp@atmark-techno.com> <CAHCN7xLo1RgkUPTdTpCtKjnT7w=gPDCfe_ZEbKj0joVvLG02Dw@mail.gmail.com>
 <ada922ea-b307-4ccf-9e2d-9a2a08fb97c1@fris.de> <Ztvbd4XqY95YMAZd@atmark-techno.com>
Message-ID: <CAHCN7xLvFkcFhE51fGXumoin4FWON2ZQ7duXJX40kkqK_ugXgw@mail.gmail.com>

On Fri, Sep 6, 2024 at 11:50?PM Dominique Martinet
<dominique.martinet at atmark-techno.com> wrote:
>
> Frieder Schrempf wrote on Fri, Sep 06, 2024 at 10:28:59PM +0200:
> > I think I managed to get behind the calculation of the fractional-n divider
> > parameters. I came up with a spreadsheet to calculate the output frequency
> > from existing register values and I have a crude Python script that can be
> > used to search for parameters for a given pixel clock.
> >
> > I tested this with three different non-CEA-861 pixel clock values (supported
> > by my HDMI USB grabber) for which the integer PLL yielded deviations >0.5%.
> > With the new LUT entries those modes work now.
> >
> > I will clean things up a bit and then share what I have. I hope that this
> > allows anyone to calculate parameters for their non-standard displays if
> > required.
> >
> > If someone feels extra motivated they could try to calculate the fractional
> > parameters at runtime. However I'm not sure that this is feasible. The
> > numerical computation of a large number of parameters is quite heavy and
> > it's probably not easy to strip the algorithm down to something that can be
> > run on the target without too much overhead.
>
> I think keeping the LUT is perfectly fine if we know where the values
> come from - perhaps having your python program in a comment above the
> LUT so anyone can check the values match?
>
> My main problem with the LUT is just that -- there's no way of
> checking. If the values come from somewhere sensible and can be verified
> I think it makes sense to keep it to fill the holes where the integer
> divider isn't enough.
>
> > > This way, the calling function can determine if it needs to be
> > > multiplied by 5.  I haven't fully determined how the fractional
> > > calculator determines what frequency it wants for a target frequency,
> > > and using the values for P, M and S from the fractional divider
> > > doesn't seem to always yield 5x like they did for the table entries
> > > using the integer divider.
> >
> > For what I found out the factor of 5 always applies. For the integer part
> > and also for the fractional part.
>
> In that case I'm definitely in favor of moving it inside the function as
> part of the calculation

I'll do a V7 with the 5x factor moved into the integer calculator.
I'll also try to rearrange the flow a bit as you requested.  Depending
on how much changes, I may strip off any s-o-b notes.
I was traveling over the weekend and I'm likely traveling the next
weekends, so I will try to get to it this week before I go, but I
can't promise anything quickly.

adam

>
> Thank you both!
> --
> Dominique


From daniel.machon at microchip.com  Mon Sep  9 08:14:44 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Mon, 9 Sep 2024 17:14:44 +0200
Subject: [PATCH v2 4/9] phy: sparx5-serdes: add ops to match data
In-Reply-To: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
References: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
Message-ID: <20240909-sparx5-lan969x-serdes-driver-v2-4-d695bcb57b84@microchip.com>

We need to handle code differently in a few places. Add a struct:
sparx5_serdes_ops for this purpose, and populate it a with function to
set the SERDES type.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c | 29 +++++++++++++++++++----------
 drivers/phy/microchip/sparx5_serdes.h | 27 ++++++++++++++++-----------
 2 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index 9c91545dd8e1..b1376a142b14 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -2373,6 +2373,20 @@ static const struct phy_ops sparx5_serdes_ops = {
 	.owner		= THIS_MODULE,
 };
 
+static void sparx5_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
+{
+	if (sidx < SPX5_SERDES_10G_START) {
+		macro->serdestype = SPX5_SDT_6G;
+		macro->stpidx = macro->sidx;
+	} else if (sidx < SPX5_SERDES_25G_START) {
+		macro->serdestype = SPX5_SDT_10G;
+		macro->stpidx = macro->sidx - SPX5_SERDES_10G_START;
+	} else {
+		macro->serdestype = SPX5_SDT_25G;
+		macro->stpidx = macro->sidx - SPX5_SERDES_25G_START;
+	}
+}
+
 static int sparx5_phy_create(struct sparx5_serdes_private *priv,
 			   int idx, struct phy **phy)
 {
@@ -2389,16 +2403,8 @@ static int sparx5_phy_create(struct sparx5_serdes_private *priv,
 	macro->sidx = idx;
 	macro->priv = priv;
 	macro->speed = SPEED_UNKNOWN;
-	if (idx < SPX5_SERDES_10G_START) {
-		macro->serdestype = SPX5_SDT_6G;
-		macro->stpidx = macro->sidx;
-	} else if (idx < SPX5_SERDES_25G_START) {
-		macro->serdestype = SPX5_SDT_10G;
-		macro->stpidx = macro->sidx - SPX5_SERDES_10G_START;
-	} else {
-		macro->serdestype = SPX5_SDT_25G;
-		macro->stpidx = macro->sidx - SPX5_SERDES_25G_START;
-	}
+
+	priv->data->ops.serdes_type_set(macro, idx);
 
 	phy_set_drvdata(*phy, macro);
 
@@ -2512,6 +2518,9 @@ static const struct sparx5_serdes_match_data sparx5_desc = {
 		.sd_max       = 33,
 		.cmu_max      = 14,
 	},
+	.ops = {
+		.serdes_type_set      = &sparx5_serdes_type_set,
+	},
 };
 
 /* Client lookup function, uses serdes index */
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index 87c44bbaf368..785c7fe0bbeb 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -26,13 +26,29 @@ enum sparx5_serdes_mode {
 	SPX5_SD_MODE_SFI,
 };
 
+struct sparx5_serdes_macro {
+	struct sparx5_serdes_private *priv;
+	u32 sidx;
+	u32 stpidx;
+	enum sparx5_serdes_type serdestype;
+	enum sparx5_serdes_mode serdesmode;
+	phy_interface_t portmode;
+	int speed;
+	enum phy_media media;
+};
+
 struct sparx5_serdes_consts {
 	int sd_max;
 	int cmu_max;
 };
 
+struct sparx5_serdes_ops {
+	void (*serdes_type_set)(struct sparx5_serdes_macro *macro, int sidx);
+};
+
 struct sparx5_serdes_match_data {
 	const struct sparx5_serdes_consts consts;
+	const struct sparx5_serdes_ops ops;
 	const struct sparx5_serdes_io_resource *iomap;
 	int iomap_size;
 };
@@ -45,17 +61,6 @@ struct sparx5_serdes_private {
 	const struct sparx5_serdes_match_data *data;
 };
 
-struct sparx5_serdes_macro {
-	struct sparx5_serdes_private *priv;
-	u32 sidx;
-	u32 stpidx;
-	enum sparx5_serdes_type serdestype;
-	enum sparx5_serdes_mode serdesmode;
-	phy_interface_t portmode;
-	int speed;
-	enum phy_media media;
-};
-
 /* Read, Write and modify registers content.
  * The register definition macros start at the id
  */

-- 
2.34.1



From daniel.machon at microchip.com  Mon Sep  9 08:14:41 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Mon, 9 Sep 2024 17:14:41 +0200
Subject: [PATCH v2 1/9] phy: sparx5-serdes: add support for private match
 data
In-Reply-To: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
References: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
Message-ID: <20240909-sparx5-lan969x-serdes-driver-v2-1-d695bcb57b84@microchip.com>

In order to reuse the existing Sparx5 SERDES driver for lan969x, we add
support for private match data, with initial fields for the iomap and
imap_size.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c | 16 +++++++++++++---
 drivers/phy/microchip/sparx5_serdes.h |  6 ++++++
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index 7cb85029fab3..5427e8627a78 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -2507,6 +2507,11 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] =  {
 	{ TARGET_SD_LANE_25G + 7, 0x5c8000 }, /* 0x610dd0000: sd_lane_25g_32 */
 };
 
+static const struct sparx5_serdes_match_data sparx5_desc = {
+	.iomap = sparx5_serdes_iomap,
+	.iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
+};
+
 /* Client lookup function, uses serdes index */
 static struct phy *sparx5_serdes_xlate(struct device *dev,
 				     const struct of_phandle_args *args)
@@ -2555,6 +2560,10 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, priv);
 	priv->dev = &pdev->dev;
 
+	priv->data = device_get_match_data(priv->dev);
+	if (!priv->data)
+		return -EINVAL;
+
 	/* Get coreclock */
 	clk = devm_clk_get(priv->dev, NULL);
 	if (IS_ERR(clk)) {
@@ -2579,8 +2588,9 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 			iores->name);
 		return -ENOMEM;
 	}
-	for (idx = 0; idx < ARRAY_SIZE(sparx5_serdes_iomap); idx++) {
-		struct sparx5_serdes_io_resource *iomap = &sparx5_serdes_iomap[idx];
+	for (idx = 0; idx < priv->data->iomap_size; idx++) {
+		const struct sparx5_serdes_io_resource *iomap =
+			&priv->data->iomap[idx];
 
 		priv->regs[iomap->id] = iomem + iomap->offset;
 	}
@@ -2599,7 +2609,7 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id sparx5_serdes_match[] = {
-	{ .compatible = "microchip,sparx5-serdes" },
+	{ .compatible = "microchip,sparx5-serdes", .data = &sparx5_desc },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, sparx5_serdes_match);
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index 13f94a29225a..128f8c53172f 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -26,11 +26,17 @@ enum sparx5_serdes_mode {
 	SPX5_SD_MODE_SFI,
 };
 
+struct sparx5_serdes_match_data {
+	const struct sparx5_serdes_io_resource *iomap;
+	int iomap_size;
+};
+
 struct sparx5_serdes_private {
 	struct device *dev;
 	void __iomem *regs[NUM_TARGETS];
 	struct phy *phys[SPX5_SERDES_MAX];
 	unsigned long coreclock;
+	const struct sparx5_serdes_match_data *data;
 };
 
 struct sparx5_serdes_macro {

-- 
2.34.1



From daniel.machon at microchip.com  Mon Sep  9 08:14:40 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Mon, 9 Sep 2024 17:14:40 +0200
Subject: [PATCH v2 0/9] phy: sparx5-serdes: add support for lan969x serdes
 driver
Message-ID: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>

The lan969x switch chip (upstreaming efforts beginning soon) has ten 10G
SERDES'es which share the same features and data rates as the Sparx5 10G
SERDES'es. Lets take advantage of this and reuse the existing SERDES
driver for lan969x.

In order to do this, we add a new indirection layer to the register
macros, that takes register differences into account. Additionally, we
add driver match data for other differences that we need to handle.
These other differences are handled by a combination of constants (eg.
the number of SERDES'es), ops and if's

Patch #1 adds support for match data.

Patch #2 adds a struct to handle constants and adds a constant for the
number of SERDES'es.

Patch #3 adds a constant for the number of CMU's

Patch #4 adds a struct for ops and adds a function for setting SERDES
type.

Patch #5 adds a function for getting the number of CMU's.

Patch #6 adds register macro indirection layer.

Patch #7 adds SERDES target types (eg. Sparx5, lan969x) to be used for
branching out based on the target.

Patch #8 adds support for lan969x in the Sparx5 dt-bindings.

Patch #9 introduces the new lan969x SERDES driver.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
Changes in v2:
- Changed the subject and commit description.
- Added compatible strings for all lan969x SKU's in the dt-bindings.
- Got rid of example in dt-bindings.
- Added new compatible string: lan9691-serdes to driver.
- Link to v1: https://lore.kernel.org/r/20240906-sparx5-lan969x-serdes-driver-v1-0-8d630614c58a at microchip.com

---
Daniel Machon (9):
      phy: sparx5-serdes: add support for private match data
      phy: sparx5-serdes: add constants to match data
      phy: sparx5-serdes: add constant for the number of CMU's
      phy: sparx5-serdes: add ops to match data
      phy: sparx5-serdes: add function for getting the CMU index
      phy: sparx5-serdes: add indirection layer to register macros
      phy: sparx5-serdes: add support for branching on chip type
      dt-bindings: phy: sparx5: document lan969x
      phy: lan969x-serdes: add support for lan969x serdes driver

 .../bindings/phy/microchip,sparx5-serdes.yaml      |  17 +-
 drivers/phy/microchip/sparx5_serdes.c              | 195 +++++-
 drivers/phy/microchip/sparx5_serdes.h              |  44 +-
 drivers/phy/microchip/sparx5_serdes_regs.h         | 746 ++++++++++++++-------
 4 files changed, 706 insertions(+), 296 deletions(-)
---
base-commit: 221f9cce949ac8042f65b71ed1fde13b99073256
change-id: 20240822-sparx5-lan969x-serdes-driver-8389dbdd9a89

Best regards,
-- 
Daniel Machon <daniel.machon at microchip.com>



From daniel.machon at microchip.com  Mon Sep  9 08:14:42 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Mon, 9 Sep 2024 17:14:42 +0200
Subject: [PATCH v2 2/9] phy: sparx5-serdes: add constants to match data
In-Reply-To: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
References: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
Message-ID: <20240909-sparx5-lan969x-serdes-driver-v2-2-d695bcb57b84@microchip.com>

We need to handle a few different constants that differ for Sparx5 and
lan969x. Add a new struct: sparx5_serdes_consts for this purpose. We
populate it with an initial field for the number of SERDES'es: sd_max.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c | 7 +++++--
 drivers/phy/microchip/sparx5_serdes.h | 5 +++++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index 5427e8627a78..c3ed028fc74e 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -2510,6 +2510,9 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] =  {
 static const struct sparx5_serdes_match_data sparx5_desc = {
 	.iomap = sparx5_serdes_iomap,
 	.iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
+	.consts = {
+		.sd_max       = 33,
+	},
 };
 
 /* Client lookup function, uses serdes index */
@@ -2526,7 +2529,7 @@ static struct phy *sparx5_serdes_xlate(struct device *dev,
 	sidx = args->args[0];
 
 	/* Check validity: ERR_PTR(-ENODEV) if not valid */
-	for (idx = 0; idx < SPX5_SERDES_MAX; idx++) {
+	for (idx = 0; idx < priv->data->consts.sd_max; idx++) {
 		struct sparx5_serdes_macro *macro =
 			phy_get_drvdata(priv->phys[idx]);
 
@@ -2594,7 +2597,7 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 
 		priv->regs[iomap->id] = iomem + iomap->offset;
 	}
-	for (idx = 0; idx < SPX5_SERDES_MAX; idx++) {
+	for (idx = 0; idx < priv->data->consts.sd_max; idx++) {
 		err = sparx5_phy_create(priv, idx, &priv->phys[idx]);
 		if (err)
 			return err;
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index 128f8c53172f..8c27cfde4938 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -26,7 +26,12 @@ enum sparx5_serdes_mode {
 	SPX5_SD_MODE_SFI,
 };
 
+struct sparx5_serdes_consts {
+	int sd_max;
+};
+
 struct sparx5_serdes_match_data {
+	const struct sparx5_serdes_consts consts;
 	const struct sparx5_serdes_io_resource *iomap;
 	int iomap_size;
 };

-- 
2.34.1



From daniel.machon at microchip.com  Mon Sep  9 08:14:43 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Mon, 9 Sep 2024 17:14:43 +0200
Subject: [PATCH v2 3/9] phy: sparx5-serdes: add constant for the number of
 CMU's
In-Reply-To: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
References: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
Message-ID: <20240909-sparx5-lan969x-serdes-driver-v2-3-d695bcb57b84@microchip.com>

The number of CMU's differ for Sparx5 and lan969x, so add a new field:
cmu_max and use it throughout.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c | 5 ++---
 drivers/phy/microchip/sparx5_serdes.h | 1 +
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index c3ed028fc74e..9c91545dd8e1 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -21,8 +21,6 @@
 
 #include "sparx5_serdes.h"
 
-#define SPX5_CMU_MAX          14
-
 #define SPX5_SERDES_10G_START 13
 #define SPX5_SERDES_25G_START 25
 #define SPX5_SERDES_6G10G_CNT SPX5_SERDES_25G_START
@@ -1101,7 +1099,7 @@ static void sparx5_serdes_cmu_power_off(struct sparx5_serdes_private *priv)
 	int i;
 
 	/* Power down each CMU */
-	for (i = 0; i < SPX5_CMU_MAX; i++) {
+	for (i = 0; i < priv->data->consts.cmu_max; i++) {
 		cmu_inst = sdx5_inst_get(priv, TARGET_SD_CMU, i);
 		cmu_cfg_inst = sdx5_inst_get(priv, TARGET_SD_CMU_CFG, i);
 
@@ -2512,6 +2510,7 @@ static const struct sparx5_serdes_match_data sparx5_desc = {
 	.iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
 	.consts = {
 		.sd_max       = 33,
+		.cmu_max      = 14,
 	},
 };
 
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index 8c27cfde4938..87c44bbaf368 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -28,6 +28,7 @@ enum sparx5_serdes_mode {
 
 struct sparx5_serdes_consts {
 	int sd_max;
+	int cmu_max;
 };
 
 struct sparx5_serdes_match_data {

-- 
2.34.1



From daniel.machon at microchip.com  Mon Sep  9 08:14:47 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Mon, 9 Sep 2024 17:14:47 +0200
Subject: [PATCH v2 7/9] phy: sparx5-serdes: add support for branching on
 chip type
In-Reply-To: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
References: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
Message-ID: <20240909-sparx5-lan969x-serdes-driver-v2-7-d695bcb57b84@microchip.com>

In preparation for lan969x, add a way to branch out on code that is to
be executed on either Sparx5 or lan969x.  Initially, this is required to
branch out when checking the SERDES types and SERDES speeds, since the
handling of these differ on the two platforms. This will also be used by
the lan969x driver introduced in a subsequent patch.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c | 29 ++++++++++++++++++-----------
 drivers/phy/microchip/sparx5_serdes.h |  5 +++++
 2 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index 8a716bfaa023..05fdf225ff43 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -2298,10 +2298,12 @@ static int sparx5_serdes_set_speed(struct phy *phy, int speed)
 {
 	struct sparx5_serdes_macro *macro = phy_get_drvdata(phy);
 
-	if (macro->sidx < SPX5_SERDES_10G_START && speed > SPEED_5000)
-		return -EINVAL;
-	if (macro->sidx < SPX5_SERDES_25G_START && speed > SPEED_10000)
-		return -EINVAL;
+	if (macro->priv->data->type == SPX5_TARGET_SPARX5) {
+		if (macro->sidx < SPX5_SERDES_10G_START && speed > SPEED_5000)
+			return -EINVAL;
+		if (macro->sidx < SPX5_SERDES_25G_START && speed > SPEED_10000)
+			return -EINVAL;
+	}
 	if (speed != macro->speed) {
 		macro->speed = speed;
 		if (macro->serdesmode != SPX5_SD_MODE_NONE)
@@ -2338,11 +2340,14 @@ static int sparx5_serdes_validate(struct phy *phy, enum phy_mode mode,
 	if (macro->speed == 0)
 		return -EINVAL;
 
-	if (macro->sidx < SPX5_SERDES_10G_START && macro->speed > SPEED_5000)
-		return -EINVAL;
-	if (macro->sidx < SPX5_SERDES_25G_START && macro->speed > SPEED_10000)
-		return -EINVAL;
-
+	if (macro->priv->data->type == SPX5_TARGET_SPARX5) {
+		if (macro->sidx < SPX5_SERDES_10G_START &&
+		    macro->speed > SPEED_5000)
+			return -EINVAL;
+		if (macro->sidx < SPX5_SERDES_25G_START &&
+		    macro->speed > SPEED_10000)
+			return -EINVAL;
+	}
 	switch (submode) {
 	case PHY_INTERFACE_MODE_1000BASEX:
 		if (macro->speed != SPEED_100 && /* This is for 100BASE-FX */
@@ -2515,6 +2520,7 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] =  {
 };
 
 static const struct sparx5_serdes_match_data sparx5_desc = {
+	.type = SPX5_TARGET_SPARX5,
 	.iomap = sparx5_serdes_iomap,
 	.iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
 	.tsize = sparx5_serdes_tsize,
@@ -2618,8 +2624,9 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 			return err;
 	}
 
-	/* Power down all CMUs by default */
-	sparx5_serdes_cmu_power_off(priv);
+	/* Power down all CMU's by default */
+	if (priv->data->type == SPX5_TARGET_SPARX5)
+		sparx5_serdes_cmu_power_off(priv);
 
 	provider = devm_of_phy_provider_register(priv->dev, sparx5_serdes_xlate);
 
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index 50900bf06c4c..1beaa3d05a5d 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -34,6 +34,10 @@ enum sparx5_10g28cmu_mode {
 	SPX5_SD10G28_CMU_MAX,
 };
 
+enum sparx5_target {
+	SPX5_TARGET_SPARX5,
+};
+
 struct sparx5_serdes_macro {
 	struct sparx5_serdes_private *priv;
 	u32 sidx;
@@ -56,6 +60,7 @@ struct sparx5_serdes_ops {
 };
 
 struct sparx5_serdes_match_data {
+	enum sparx5_target type;
 	const struct sparx5_serdes_consts consts;
 	const struct sparx5_serdes_ops ops;
 	const struct sparx5_serdes_io_resource *iomap;

-- 
2.34.1



From daniel.machon at microchip.com  Mon Sep  9 08:14:46 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Mon, 9 Sep 2024 17:14:46 +0200
Subject: [PATCH v2 6/9] phy: sparx5-serdes: add indirection layer to
 register macros
In-Reply-To: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
References: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
Message-ID: <20240909-sparx5-lan969x-serdes-driver-v2-6-d695bcb57b84@microchip.com>

The register macros are used to read and write to the SERDES registers.
The registers are largely the same on Sparx5 and lan969x, however some
register target sizes differ. Therefore we introduce a new indirection
to the register macros. The target sizes are looked up, using a mapping
table (sparx5_serdes_tsize) that maps the register target to the
register target size.

With this addition, we can reuse all the existing macros for lan969x.

Also the autogenerated macros are now formatted slightly different, to
adhere to a 80 character limit.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c      |  14 +
 drivers/phy/microchip/sparx5_serdes.h      |   1 +
 drivers/phy/microchip/sparx5_serdes_regs.h | 746 +++++++++++++++++++----------
 3 files changed, 507 insertions(+), 254 deletions(-)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index 5b918a2716dd..8a716bfaa023 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -28,6 +28,17 @@
 /* Optimal power settings from GUC */
 #define SPX5_SERDES_QUIET_MODE_VAL 0x01ef4e0c
 
+/* Register target sizes */
+const unsigned int sparx5_serdes_tsize[TSIZE_LAST] = {
+	[TC_SD10G_LANE] = 12,
+	[TC_SD_CMU] = 14,
+	[TC_SD_CMU_CFG] = 14,
+	[TC_SD_LANE] = 25,
+};
+
+/* Pointer to the register target size table */
+const unsigned int *tsize;
+
 enum sparx5_sd25g28_mode_preset_type {
 	SPX5_SD25G28_MODE_PRESET_25000,
 	SPX5_SD25G28_MODE_PRESET_10000,
@@ -2506,6 +2517,7 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] =  {
 static const struct sparx5_serdes_match_data sparx5_desc = {
 	.iomap = sparx5_serdes_iomap,
 	.iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
+	.tsize = sparx5_serdes_tsize,
 	.consts = {
 		.sd_max       = 33,
 		.cmu_max      = 14,
@@ -2568,6 +2580,8 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 	if (!priv->data)
 		return -EINVAL;
 
+	tsize = priv->data->tsize;
+
 	/* Get coreclock */
 	clk = devm_clk_get(priv->dev, NULL);
 	if (IS_ERR(clk)) {
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index a7e92c1330e9..50900bf06c4c 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -60,6 +60,7 @@ struct sparx5_serdes_match_data {
 	const struct sparx5_serdes_ops ops;
 	const struct sparx5_serdes_io_resource *iomap;
 	int iomap_size;
+	const unsigned int *tsize;
 };
 
 struct sparx5_serdes_private {
diff --git a/drivers/phy/microchip/sparx5_serdes_regs.h b/drivers/phy/microchip/sparx5_serdes_regs.h
index d0543fd3dc94..11c4fdc593fa 100644
--- a/drivers/phy/microchip/sparx5_serdes_regs.h
+++ b/drivers/phy/microchip/sparx5_serdes_regs.h
@@ -1,11 +1,11 @@
 /* SPDX-License-Identifier: GPL-2.0+
  * Microchip Sparx5 SerDes driver
  *
- * Copyright (c) 2020 Microchip Technology Inc.
+ * Copyright (c) 2024 Microchip Technology Inc.
  */
 
-/* This file is autogenerated by cml-utils 2020-11-16 13:11:27 +0100.
- * Commit ID: 13bdf073131d8bf40c54901df6988ae4e9c8f29f
+/* This file is autogenerated by cml-utils 2023-04-13 15:02:00 +0200.
+ * Commit ID: 5ac560288d46048f872ecdb8add53717f1efc0e1
  */
 
 #ifndef _SPARX5_SERDES_REGS_H_
@@ -26,10 +26,25 @@ enum sparx5_serdes_target {
 	NUM_TARGETS = 332
 };
 
+enum sparx5_serdes_tsize_enum {
+	TC_SD10G_LANE,
+	TC_SD_CMU,
+	TC_SD_CMU_CFG,
+	TC_SD_LANE,
+	TSIZE_LAST,
+};
+
+/* sparx5_serdes.c */
+extern const unsigned int *tsize;
+
+#define TSIZE(o) tsize[o]
+
 #define __REG(...)    __VA_ARGS__
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_01 */
-#define SD10G_LANE_LANE_01(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 4, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_01 */
+#define SD10G_LANE_LANE_01(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 4, 0,  \
+	      1, 4)
 
 #define SD10G_LANE_LANE_01_CFG_PMA_TX_CK_BITWIDTH_2_0 GENMASK(2, 0)
 #define SD10G_LANE_LANE_01_CFG_PMA_TX_CK_BITWIDTH_2_0_SET(x)\
@@ -49,8 +64,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_01_CFG_RXDET_STR_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_01_CFG_RXDET_STR, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_02 */
-#define SD10G_LANE_LANE_02(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 8, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_02 */
+#define SD10G_LANE_LANE_02(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 8, 0,  \
+	      1, 4)
 
 #define SD10G_LANE_LANE_02_CFG_EN_ADV            BIT(0)
 #define SD10G_LANE_LANE_02_CFG_EN_ADV_SET(x)\
@@ -82,8 +99,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_02_CFG_TAP_ADV_3_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_02_CFG_TAP_ADV_3_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_03 */
-#define SD10G_LANE_LANE_03(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 12, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_03 */
+#define SD10G_LANE_LANE_03(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 12, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_03_CFG_TAP_MAIN          BIT(0)
 #define SD10G_LANE_LANE_03_CFG_TAP_MAIN_SET(x)\
@@ -91,8 +110,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_03_CFG_TAP_MAIN_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_03_CFG_TAP_MAIN, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_04 */
-#define SD10G_LANE_LANE_04(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 16, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_04 */
+#define SD10G_LANE_LANE_04(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 16, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0       GENMASK(4, 0)
 #define SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0_SET(x)\
@@ -100,8 +121,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_06 */
-#define SD10G_LANE_LANE_06(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 24, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_06 */
+#define SD10G_LANE_LANE_06(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 24, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_06_CFG_PD_DRIVER         BIT(0)
 #define SD10G_LANE_LANE_06_CFG_PD_DRIVER_SET(x)\
@@ -139,8 +162,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_06_CFG_EN_PREEMPH_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_06_CFG_EN_PREEMPH, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_0B */
-#define SD10G_LANE_LANE_0B(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 44, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0B */
+#define SD10G_LANE_LANE_0B(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 44, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_0B_CFG_EQ_RES_3_0        GENMASK(3, 0)
 #define SD10G_LANE_LANE_0B_CFG_EQ_RES_3_0_SET(x)\
@@ -172,8 +197,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_SQ_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_SQ, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_0C */
-#define SD10G_LANE_LANE_0C(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 48, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0C */
+#define SD10G_LANE_LANE_0C(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 48, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_0C_CFG_OSCAL_AFE         BIT(0)
 #define SD10G_LANE_LANE_0C_CFG_OSCAL_AFE_SET(x)\
@@ -223,8 +250,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_0C_CFG_RX_PCIE_GEN12_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_0C_CFG_RX_PCIE_GEN12, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_0D */
-#define SD10G_LANE_LANE_0D(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 52, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0D */
+#define SD10G_LANE_LANE_0D(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 52, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_0D_CFG_CTLE_M_THR_1_0    GENMASK(1, 0)
 #define SD10G_LANE_LANE_0D_CFG_CTLE_M_THR_1_0_SET(x)\
@@ -238,8 +267,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_0D_CFG_EQR_BYP_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_0D_CFG_EQR_BYP, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_0E */
-#define SD10G_LANE_LANE_0E(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 56, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0E */
+#define SD10G_LANE_LANE_0E(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 56, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_0E_CFG_EQC_FORCE_3_0     GENMASK(3, 0)
 #define SD10G_LANE_LANE_0E_CFG_EQC_FORCE_3_0_SET(x)\
@@ -265,8 +296,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_0E_CFG_SUM_SETCM_EN_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_0E_CFG_SUM_SETCM_EN, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_0F */
-#define SD10G_LANE_LANE_0F(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 60, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0F */
+#define SD10G_LANE_LANE_0F(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 60, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0      GENMASK(7, 0)
 #define SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0_SET(x)\
@@ -274,8 +307,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_13 */
-#define SD10G_LANE_LANE_13(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 76, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_13 */
+#define SD10G_LANE_LANE_13(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 76, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_13_CFG_DCDR_PD           BIT(0)
 #define SD10G_LANE_LANE_13_CFG_DCDR_PD_SET(x)\
@@ -295,8 +330,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_13_CFG_CDRCK_EN_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_13_CFG_CDRCK_EN, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_14 */
-#define SD10G_LANE_LANE_14(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 80, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_14 */
+#define SD10G_LANE_LANE_14(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 80, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0    GENMASK(7, 0)
 #define SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0_SET(x)\
@@ -304,8 +341,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_15 */
-#define SD10G_LANE_LANE_15(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 84, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_15 */
+#define SD10G_LANE_LANE_15(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 84, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8   GENMASK(7, 0)
 #define SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8_SET(x)\
@@ -313,8 +352,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_16 */
-#define SD10G_LANE_LANE_16(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 88, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_16 */
+#define SD10G_LANE_LANE_16(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 88, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16  GENMASK(7, 0)
 #define SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16_SET(x)\
@@ -322,8 +363,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_1A */
-#define SD10G_LANE_LANE_1A(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 104, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_1A */
+#define SD10G_LANE_LANE_1A(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 104, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_1A_CFG_PI_R_SCAN_EN      BIT(0)
 #define SD10G_LANE_LANE_1A_CFG_PI_R_SCAN_EN_SET(x)\
@@ -355,8 +398,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_1A_CFG_PI_FLOOP_STEPS_1_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_1A_CFG_PI_FLOOP_STEPS_1_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_22 */
-#define SD10G_LANE_LANE_22(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 136, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_22 */
+#define SD10G_LANE_LANE_22(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 136, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1     GENMASK(4, 0)
 #define SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1_SET(x)\
@@ -364,8 +409,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_23 */
-#define SD10G_LANE_LANE_23(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 140, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_23 */
+#define SD10G_LANE_LANE_23(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 140, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_23_CFG_DFE_PD            BIT(0)
 #define SD10G_LANE_LANE_23_CFG_DFE_PD_SET(x)\
@@ -397,8 +444,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_23_CFG_DFEDIG_M_2_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_23_CFG_DFEDIG_M_2_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_24 */
-#define SD10G_LANE_LANE_24(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 144, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_24 */
+#define SD10G_LANE_LANE_24(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 144, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_24_CFG_PI_BW_GEN1_3_0    GENMASK(3, 0)
 #define SD10G_LANE_LANE_24_CFG_PI_BW_GEN1_3_0_SET(x)\
@@ -412,8 +461,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_24_CFG_PI_BW_GEN2_3_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_24_CFG_PI_BW_GEN2_3_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_26 */
-#define SD10G_LANE_LANE_26(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 152, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_26 */
+#define SD10G_LANE_LANE_26(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 152, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0 GENMASK(7, 0)
 #define SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0_SET(x)\
@@ -421,8 +472,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_2F */
-#define SD10G_LANE_LANE_2F(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 188, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_2F */
+#define SD10G_LANE_LANE_2F(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 188, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_2F_CFG_VGA_CP_2_0        GENMASK(2, 0)
 #define SD10G_LANE_LANE_2F_CFG_VGA_CP_2_0_SET(x)\
@@ -436,8 +489,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_2F_CFG_VGA_CTRL_3_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_2F_CFG_VGA_CTRL_3_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_30 */
-#define SD10G_LANE_LANE_30(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 192, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_30 */
+#define SD10G_LANE_LANE_30(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 192, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_30_CFG_SUMMER_EN         BIT(0)
 #define SD10G_LANE_LANE_30_CFG_SUMMER_EN_SET(x)\
@@ -451,8 +506,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_30_CFG_RXDIV_SEL_2_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_30_CFG_RXDIV_SEL_2_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_31 */
-#define SD10G_LANE_LANE_31(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 196, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_31 */
+#define SD10G_LANE_LANE_31(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 196, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_31_CFG_PI_RSTN           BIT(0)
 #define SD10G_LANE_LANE_31_CFG_PI_RSTN_SET(x)\
@@ -490,8 +547,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_31_CFG_R50_EN_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_31_CFG_R50_EN, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_32 */
-#define SD10G_LANE_LANE_32(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 200, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_32 */
+#define SD10G_LANE_LANE_32(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 200, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_32_CFG_ITX_IPCLK_BASE_1_0 GENMASK(1, 0)
 #define SD10G_LANE_LANE_32_CFG_ITX_IPCLK_BASE_1_0_SET(x)\
@@ -505,8 +564,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_32_CFG_ITX_IPCML_BASE_1_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_32_CFG_ITX_IPCML_BASE_1_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_33 */
-#define SD10G_LANE_LANE_33(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 204, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_33 */
+#define SD10G_LANE_LANE_33(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 204, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_33_CFG_ITX_IPDRIVER_BASE_2_0 GENMASK(2, 0)
 #define SD10G_LANE_LANE_33_CFG_ITX_IPDRIVER_BASE_2_0_SET(x)\
@@ -520,8 +581,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_33_CFG_ITX_IPPREEMP_BASE_1_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_33_CFG_ITX_IPPREEMP_BASE_1_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_35 */
-#define SD10G_LANE_LANE_35(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 212, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_35 */
+#define SD10G_LANE_LANE_35(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 212, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_35_CFG_TXRATE_1_0        GENMASK(1, 0)
 #define SD10G_LANE_LANE_35_CFG_TXRATE_1_0_SET(x)\
@@ -535,8 +598,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_35_CFG_RXRATE_1_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_35_CFG_RXRATE_1_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_36 */
-#define SD10G_LANE_LANE_36(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 216, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_36 */
+#define SD10G_LANE_LANE_36(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 216, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_36_CFG_PREDRV_SLEWRATE_1_0 GENMASK(1, 0)
 #define SD10G_LANE_LANE_36_CFG_PREDRV_SLEWRATE_1_0_SET(x)\
@@ -568,8 +633,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_36_CFG_PRBS_SETB_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_36_CFG_PRBS_SETB, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_37 */
-#define SD10G_LANE_LANE_37(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 220, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_37 */
+#define SD10G_LANE_LANE_37(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 220, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_37_CFG_RXDET_COMP_PD     BIT(0)
 #define SD10G_LANE_LANE_37_CFG_RXDET_COMP_PD_SET(x)\
@@ -595,8 +662,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_37_CFG_IP_PRE_BASE_1_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_37_CFG_IP_PRE_BASE_1_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_39 */
-#define SD10G_LANE_LANE_39(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 228, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_39 */
+#define SD10G_LANE_LANE_39(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 228, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_39_CFG_RXFILT_Y_2_0      GENMASK(2, 0)
 #define SD10G_LANE_LANE_39_CFG_RXFILT_Y_2_0_SET(x)\
@@ -610,8 +679,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_39_CFG_RX_SSC_LH_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_39_CFG_RX_SSC_LH, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_3A */
-#define SD10G_LANE_LANE_3A(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 232, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_3A */
+#define SD10G_LANE_LANE_3A(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 232, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_3A_CFG_MP_MIN_3_0        GENMASK(3, 0)
 #define SD10G_LANE_LANE_3A_CFG_MP_MIN_3_0_SET(x)\
@@ -625,8 +696,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_3A_CFG_MP_MAX_3_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_3A_CFG_MP_MAX_3_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_3C */
-#define SD10G_LANE_LANE_3C(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 240, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_3C */
+#define SD10G_LANE_LANE_3C(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 240, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_3C_CFG_DIS_ACC           BIT(0)
 #define SD10G_LANE_LANE_3C_CFG_DIS_ACC_SET(x)\
@@ -640,8 +713,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_3C_CFG_DIS_2NDORDER_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_3C_CFG_DIS_2NDORDER, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_40 */
-#define SD10G_LANE_LANE_40(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 256, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_40 */
+#define SD10G_LANE_LANE_40(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 256, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0  GENMASK(7, 0)
 #define SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0_SET(x)\
@@ -649,8 +724,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_41 */
-#define SD10G_LANE_LANE_41(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 260, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_41 */
+#define SD10G_LANE_LANE_41(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 260, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8 GENMASK(7, 0)
 #define SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8_SET(x)\
@@ -658,8 +735,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_0:LANE_42 */
-#define SD10G_LANE_LANE_42(t)     __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 264, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_42 */
+#define SD10G_LANE_LANE_42(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 0, 0, 1, 288, 264, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_42_CFG_CDR_KF_GEN1_2_0   GENMASK(2, 0)
 #define SD10G_LANE_LANE_42_CFG_CDR_KF_GEN1_2_0_SET(x)\
@@ -673,8 +752,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_42_CFG_CDR_KF_GEN2_2_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_42_CFG_CDR_KF_GEN2_2_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_1:LANE_48 */
-#define SD10G_LANE_LANE_48(t)     __REG(TARGET_SD10G_LANE, t, 12, 288, 0, 1, 40, 0, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_1:LANE_48 */
+#define SD10G_LANE_LANE_48(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 288, 0, 1, 40, 0, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_48_CFG_ALOS_THR_3_0      GENMASK(3, 0)
 #define SD10G_LANE_LANE_48_CFG_ALOS_THR_3_0_SET(x)\
@@ -694,8 +775,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_48_CFG_CLK_ENQ_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_48_CFG_CLK_ENQ, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_1:LANE_50 */
-#define SD10G_LANE_LANE_50(t)     __REG(TARGET_SD10G_LANE, t, 12, 288, 0, 1, 40, 32, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_1:LANE_50 */
+#define SD10G_LANE_LANE_50(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 288, 0, 1, 40, 32, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_50_CFG_SSC_PI_STEP_1_0   GENMASK(1, 0)
 #define SD10G_LANE_LANE_50_CFG_SSC_PI_STEP_1_0_SET(x)\
@@ -727,8 +810,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_50_CFG_JT_EN_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_50_CFG_JT_EN, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_2:LANE_52 */
-#define SD10G_LANE_LANE_52(t)     __REG(TARGET_SD10G_LANE, t, 12, 328, 0, 1, 24, 0, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_2:LANE_52 */
+#define SD10G_LANE_LANE_52(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 328, 0, 1, 24, 0, 0, \
+	      1, 4)
 
 #define SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0 GENMASK(5, 0)
 #define SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0_SET(x)\
@@ -736,8 +821,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_4:LANE_83 */
-#define SD10G_LANE_LANE_83(t)     __REG(TARGET_SD10G_LANE, t, 12, 464, 0, 1, 112, 60, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_4:LANE_83 */
+#define SD10G_LANE_LANE_83(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 464, 0, 1, 112, 60,  \
+	      0, 1, 4)
 
 #define SD10G_LANE_LANE_83_R_TX_BIT_REVERSE      BIT(0)
 #define SD10G_LANE_LANE_83_R_TX_BIT_REVERSE_SET(x)\
@@ -781,8 +868,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_83_R_CTLE_RSTN_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_83_R_CTLE_RSTN, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_5:LANE_93 */
-#define SD10G_LANE_LANE_93(t)     __REG(TARGET_SD10G_LANE, t, 12, 576, 0, 1, 64, 12, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_5:LANE_93 */
+#define SD10G_LANE_LANE_93(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 576, 0, 1, 64, 12, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_93_R_RXEI_FIFO_RST_EN    BIT(0)
 #define SD10G_LANE_LANE_93_R_RXEI_FIFO_RST_EN_SET(x)\
@@ -832,8 +921,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_93_R_RX_PCIE_GEN12_FROM_HWT_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_93_R_RX_PCIE_GEN12_FROM_HWT, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_5:LANE_94 */
-#define SD10G_LANE_LANE_94(t)     __REG(TARGET_SD10G_LANE, t, 12, 576, 0, 1, 64, 16, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_5:LANE_94 */
+#define SD10G_LANE_LANE_94(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 576, 0, 1, 64, 16, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_94_R_DWIDTHCTRL_2_0      GENMASK(2, 0)
 #define SD10G_LANE_LANE_94_R_DWIDTHCTRL_2_0_SET(x)\
@@ -865,8 +956,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_94_R_SWING_REG_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_94_R_SWING_REG, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_5:LANE_9E */
-#define SD10G_LANE_LANE_9E(t)     __REG(TARGET_SD10G_LANE, t, 12, 576, 0, 1, 64, 56, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_5:LANE_9E */
+#define SD10G_LANE_LANE_9E(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 576, 0, 1, 64, 56, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_9E_R_RXEQ_REG            BIT(0)
 #define SD10G_LANE_LANE_9E_R_RXEQ_REG_SET(x)\
@@ -886,8 +979,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_9E_R_EN_AUTO_CDR_RSTN_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_9E_R_EN_AUTO_CDR_RSTN, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_6:LANE_A1 */
-#define SD10G_LANE_LANE_A1(t)     __REG(TARGET_SD10G_LANE, t, 12, 640, 0, 1, 128, 4, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_6:LANE_A1 */
+#define SD10G_LANE_LANE_A1(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 640, 0, 1, 128, 4, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_A1_R_PMA_TXCK_DIV_SEL_1_0 GENMASK(1, 0)
 #define SD10G_LANE_LANE_A1_R_PMA_TXCK_DIV_SEL_1_0_SET(x)\
@@ -919,8 +1014,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_A1_R_PCLK_GATING_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_A1_R_PCLK_GATING, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_6:LANE_A2 */
-#define SD10G_LANE_LANE_A2(t)     __REG(TARGET_SD10G_LANE, t, 12, 640, 0, 1, 128, 8, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_6:LANE_A2 */
+#define SD10G_LANE_LANE_A2(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 640, 0, 1, 128, 8, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0 GENMASK(4, 0)
 #define SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0_SET(x)\
@@ -928,8 +1025,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_8:LANE_DF */
-#define SD10G_LANE_LANE_DF(t)     __REG(TARGET_SD10G_LANE, t, 12, 832, 0, 1, 84, 60, 0, 1, 4)
+/* SD10G_LANE_TARGET:LANE_GRP_8:LANE_DF */
+#define SD10G_LANE_LANE_DF(t)                                                  \
+	__REG(TARGET_SD10G_LANE, t, TSIZE(TC_SD10G_LANE), 832, 0, 1, 84, 60, 0,\
+	      1, 4)
 
 #define SD10G_LANE_LANE_DF_LOL_UDL               BIT(0)
 #define SD10G_LANE_LANE_DF_LOL_UDL_SET(x)\
@@ -955,8 +1054,10 @@ enum sparx5_serdes_target {
 #define SD10G_LANE_LANE_DF_SQUELCH_GET(x)\
 	FIELD_GET(SD10G_LANE_LANE_DF_SQUELCH, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_09 */
-#define SD25G_LANE_CMU_09(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 36, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_09 */
+#define SD25G_LANE_CMU_09(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 36, 0, 1, 4)
 
 #define SD25G_LANE_CMU_09_CFG_REFCK_TERM_EN      BIT(0)
 #define SD25G_LANE_CMU_09_CFG_REFCK_TERM_EN_SET(x)\
@@ -988,8 +1089,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_09_CFG_PLL_TP_SEL_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_09_CFG_PLL_TP_SEL_1_0, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_0B */
-#define SD25G_LANE_CMU_0B(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 44, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_0B */
+#define SD25G_LANE_CMU_0B(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 44, 0, 1, 4)
 
 #define SD25G_LANE_CMU_0B_CFG_FORCE_RX_FILT      BIT(0)
 #define SD25G_LANE_CMU_0B_CFG_FORCE_RX_FILT_SET(x)\
@@ -1039,8 +1142,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_0B_CFG_RST_TREE_PD_MAN_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_0B_CFG_RST_TREE_PD_MAN, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_0C */
-#define SD25G_LANE_CMU_0C(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 48, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_0C */
+#define SD25G_LANE_CMU_0C(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 48, 0, 1, 4)
 
 #define SD25G_LANE_CMU_0C_CFG_PLL_LOL_SET        BIT(0)
 #define SD25G_LANE_CMU_0C_CFG_PLL_LOL_SET_SET(x)\
@@ -1072,8 +1177,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_0C_CFG_VCO_DIV_MODE_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_0C_CFG_VCO_DIV_MODE_1_0, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_0D */
-#define SD25G_LANE_CMU_0D(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 52, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_0D */
+#define SD25G_LANE_CMU_0D(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 52, 0, 1, 4)
 
 #define SD25G_LANE_CMU_0D_CFG_CK_TREE_PD         BIT(0)
 #define SD25G_LANE_CMU_0D_CFG_CK_TREE_PD_SET(x)\
@@ -1105,8 +1212,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_0D_CFG_PRE_DIVSEL_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_0D_CFG_PRE_DIVSEL_1_0, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_0E */
-#define SD25G_LANE_CMU_0E(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 56, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_0E */
+#define SD25G_LANE_CMU_0E(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 56, 0, 1, 4)
 
 #define SD25G_LANE_CMU_0E_CFG_SEL_DIV_3_0        GENMASK(3, 0)
 #define SD25G_LANE_CMU_0E_CFG_SEL_DIV_3_0_SET(x)\
@@ -1120,8 +1229,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_0E_CFG_PMAA_CENTR_CK_PD_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_0E_CFG_PMAA_CENTR_CK_PD, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_13 */
-#define SD25G_LANE_CMU_13(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 76, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_13 */
+#define SD25G_LANE_CMU_13(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 76, 0, 1, 4)
 
 #define SD25G_LANE_CMU_13_CFG_PLL_RESERVE_3_0    GENMASK(3, 0)
 #define SD25G_LANE_CMU_13_CFG_PLL_RESERVE_3_0_SET(x)\
@@ -1135,8 +1246,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_13_CFG_JT_EN_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_13_CFG_JT_EN, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_18 */
-#define SD25G_LANE_CMU_18(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 96, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_18 */
+#define SD25G_LANE_CMU_18(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 96, 0, 1, 4)
 
 #define SD25G_LANE_CMU_18_R_PLL_RSTN             BIT(0)
 #define SD25G_LANE_CMU_18_R_PLL_RSTN_SET(x)\
@@ -1162,8 +1275,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_18_R_PLL_TP_SEL_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_18_R_PLL_TP_SEL_1_0, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_19 */
-#define SD25G_LANE_CMU_19(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 100, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_19 */
+#define SD25G_LANE_CMU_19(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 100, 0, 1, 4)
 
 #define SD25G_LANE_CMU_19_R_CK_RESETB            BIT(0)
 #define SD25G_LANE_CMU_19_R_CK_RESETB_SET(x)\
@@ -1177,8 +1292,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_19_R_PLL_DLOL_EN_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_19_R_PLL_DLOL_EN, x)
 
-/*      SD25G_TARGET:CMU_GRP_0:CMU_1A */
-#define SD25G_LANE_CMU_1A(t)      __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 104, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_0:CMU_1A */
+#define SD25G_LANE_CMU_1A(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 104, 0, 1, 4)
 
 #define SD25G_LANE_CMU_1A_R_DWIDTHCTRL_2_0       GENMASK(2, 0)
 #define SD25G_LANE_CMU_1A_R_DWIDTHCTRL_2_0_SET(x)\
@@ -1204,8 +1321,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_1A_R_REG_MANUAL_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_1A_R_REG_MANUAL, x)
 
-/*      SD25G_TARGET:CMU_GRP_1:CMU_2A */
-#define SD25G_LANE_CMU_2A(t)      __REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 36, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_1:CMU_2A */
+#define SD25G_LANE_CMU_2A(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 36, 0, 1, 4)
 
 #define SD25G_LANE_CMU_2A_R_DBG_SEL_1_0          GENMASK(1, 0)
 #define SD25G_LANE_CMU_2A_R_DBG_SEL_1_0_SET(x)\
@@ -1225,8 +1344,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_2A_R_DBG_LOL_STATUS_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_2A_R_DBG_LOL_STATUS, x)
 
-/*      SD25G_TARGET:CMU_GRP_1:CMU_30 */
-#define SD25G_LANE_CMU_30(t)      __REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 60, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_1:CMU_30 */
+#define SD25G_LANE_CMU_30(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 60, 0, 1, 4)
 
 #define SD25G_LANE_CMU_30_R_TXFIFO_CK_DIV_PMAD_2_0 GENMASK(2, 0)
 #define SD25G_LANE_CMU_30_R_TXFIFO_CK_DIV_PMAD_2_0_SET(x)\
@@ -1240,8 +1361,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_30_R_RXFIFO_CK_DIV_PMAD_2_0_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_30_R_RXFIFO_CK_DIV_PMAD_2_0, x)
 
-/*      SD25G_TARGET:CMU_GRP_1:CMU_31 */
-#define SD25G_LANE_CMU_31(t)      __REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 64, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_1:CMU_31 */
+#define SD25G_LANE_CMU_31(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 64, 0, 1, 4)
 
 #define SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0 GENMASK(7, 0)
 #define SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0_SET(x)\
@@ -1249,8 +1372,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0, x)
 
-/*      SD25G_TARGET:CMU_GRP_2:CMU_40 */
-#define SD25G_LANE_CMU_40(t)      __REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 0, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_2:CMU_40 */
+#define SD25G_LANE_CMU_40(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 0, 0, 1, 4)
 
 #define SD25G_LANE_CMU_40_L0_CFG_CKSKEW_CTRL     BIT(0)
 #define SD25G_LANE_CMU_40_L0_CFG_CKSKEW_CTRL_SET(x)\
@@ -1288,8 +1413,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_40_L0_CFG_TXCAL_RST_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_40_L0_CFG_TXCAL_RST, x)
 
-/*      SD25G_TARGET:CMU_GRP_2:CMU_45 */
-#define SD25G_LANE_CMU_45(t)      __REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 20, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_2:CMU_45 */
+#define SD25G_LANE_CMU_45(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 20, 0, 1, 4)
 
 #define SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0  GENMASK(7, 0)
 #define SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0_SET(x)\
@@ -1297,8 +1424,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0, x)
 
-/*      SD25G_TARGET:CMU_GRP_2:CMU_46 */
-#define SD25G_LANE_CMU_46(t)      __REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 24, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_2:CMU_46 */
+#define SD25G_LANE_CMU_46(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 24, 0, 1, 4)
 
 #define SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8 GENMASK(7, 0)
 #define SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8_SET(x)\
@@ -1306,8 +1435,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8, x)
 
-/*      SD25G_TARGET:CMU_GRP_3:CMU_C0 */
-#define SD25G_LANE_CMU_C0(t)      __REG(TARGET_SD25G_LANE, t, 8, 768, 0, 1, 252, 0, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_3:CMU_C0 */
+#define SD25G_LANE_CMU_C0(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 768, 0, 1, 252, 0, 0, 1, 4)
 
 #define SD25G_LANE_CMU_C0_READ_VCO_CTUNE_3_0     GENMASK(3, 0)
 #define SD25G_LANE_CMU_C0_READ_VCO_CTUNE_3_0_SET(x)\
@@ -1321,8 +1452,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_C0_PLL_LOL_UDL_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_C0_PLL_LOL_UDL, x)
 
-/*      SD25G_TARGET:CMU_GRP_4:CMU_FF */
-#define SD25G_LANE_CMU_FF(t)      __REG(TARGET_SD25G_LANE, t, 8, 1020, 0, 1, 4, 0, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:CMU_GRP_4:CMU_FF */
+#define SD25G_LANE_CMU_FF(t)                                                   \
+	__REG(TARGET_SD25G_LANE, t, 8, 1020, 0, 1, 4, 0, 0, 1, 4)
 
 #define SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX   GENMASK(7, 0)
 #define SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX_SET(x)\
@@ -1330,8 +1463,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX_GET(x)\
 	FIELD_GET(SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_00 */
-#define SD25G_LANE_LANE_00(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 0, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_00 */
+#define SD25G_LANE_LANE_00(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 0, 0, 1, 4)
 
 #define SD25G_LANE_LANE_00_LN_CFG_ITX_VC_DRIVER_3_0 GENMASK(3, 0)
 #define SD25G_LANE_LANE_00_LN_CFG_ITX_VC_DRIVER_3_0_SET(x)\
@@ -1345,8 +1480,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_00_LN_CFG_ITX_IPCML_BASE_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_00_LN_CFG_ITX_IPCML_BASE_1_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_01 */
-#define SD25G_LANE_LANE_01(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 4, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_01 */
+#define SD25G_LANE_LANE_01(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 4, 0, 1, 4)
 
 #define SD25G_LANE_LANE_01_LN_CFG_ITX_IPDRIVER_BASE_2_0 GENMASK(2, 0)
 #define SD25G_LANE_LANE_01_LN_CFG_ITX_IPDRIVER_BASE_2_0_SET(x)\
@@ -1360,8 +1497,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_01_LN_CFG_TX_PREDIV_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_01_LN_CFG_TX_PREDIV_1_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_03 */
-#define SD25G_LANE_LANE_03(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 12, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_03 */
+#define SD25G_LANE_LANE_03(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 12, 0, 1, 4)
 
 #define SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0    GENMASK(4, 0)
 #define SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0_SET(x)\
@@ -1369,8 +1508,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_04 */
-#define SD25G_LANE_LANE_04(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 16, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_04 */
+#define SD25G_LANE_LANE_04(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 16, 0, 1, 4)
 
 #define SD25G_LANE_LANE_04_LN_CFG_TX2RX_LP_EN    BIT(0)
 #define SD25G_LANE_LANE_04_LN_CFG_TX2RX_LP_EN_SET(x)\
@@ -1408,8 +1549,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_04_LN_CFG_TAP_MAIN_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_04_LN_CFG_TAP_MAIN, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_05 */
-#define SD25G_LANE_LANE_05(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 20, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_05 */
+#define SD25G_LANE_LANE_05(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 20, 0, 1, 4)
 
 #define SD25G_LANE_LANE_05_LN_CFG_TAP_DLY2_3_0   GENMASK(3, 0)
 #define SD25G_LANE_LANE_05_LN_CFG_TAP_DLY2_3_0_SET(x)\
@@ -1423,8 +1566,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_05_LN_CFG_BW_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_05_LN_CFG_BW_1_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_06 */
-#define SD25G_LANE_LANE_06(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 24, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_06 */
+#define SD25G_LANE_LANE_06(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 24, 0, 1, 4)
 
 #define SD25G_LANE_LANE_06_LN_CFG_EN_MAIN        BIT(0)
 #define SD25G_LANE_LANE_06_LN_CFG_EN_MAIN_SET(x)\
@@ -1438,8 +1583,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_06_LN_CFG_TAP_ADV_3_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_06_LN_CFG_TAP_ADV_3_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_07 */
-#define SD25G_LANE_LANE_07(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 28, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_07 */
+#define SD25G_LANE_LANE_07(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 28, 0, 1, 4)
 
 #define SD25G_LANE_LANE_07_LN_CFG_EN_ADV         BIT(0)
 #define SD25G_LANE_LANE_07_LN_CFG_EN_ADV_SET(x)\
@@ -1459,8 +1606,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_07_LN_CFG_EN_DLY_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_07_LN_CFG_EN_DLY, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_09 */
-#define SD25G_LANE_LANE_09(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 36, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_09 */
+#define SD25G_LANE_LANE_09(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 36, 0, 1, 4)
 
 #define SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0 GENMASK(3, 0)
 #define SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0_SET(x)\
@@ -1468,8 +1617,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_0A */
-#define SD25G_LANE_LANE_0A(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 40, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_0A */
+#define SD25G_LANE_LANE_0A(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 40, 0, 1, 4)
 
 #define SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0 GENMASK(5, 0)
 #define SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0_SET(x)\
@@ -1477,8 +1628,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_0B */
-#define SD25G_LANE_LANE_0B(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 44, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_0B */
+#define SD25G_LANE_LANE_0B(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 44, 0, 1, 4)
 
 #define SD25G_LANE_LANE_0B_LN_CFG_TXCAL_MAN_EN   BIT(0)
 #define SD25G_LANE_LANE_0B_LN_CFG_TXCAL_MAN_EN_SET(x)\
@@ -1498,8 +1651,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_0B_LN_CFG_QUAD_MAN_1_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_0B_LN_CFG_QUAD_MAN_1_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_0C */
-#define SD25G_LANE_LANE_0C(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 48, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_0C */
+#define SD25G_LANE_LANE_0C(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 48, 0, 1, 4)
 
 #define SD25G_LANE_LANE_0C_LN_CFG_PMA_TX_CK_BITWIDTH_2_0 GENMASK(2, 0)
 #define SD25G_LANE_LANE_0C_LN_CFG_PMA_TX_CK_BITWIDTH_2_0_SET(x)\
@@ -1519,8 +1674,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_0C_LN_CFG_RXTERM_PD_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_0C_LN_CFG_RXTERM_PD, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_0D */
-#define SD25G_LANE_LANE_0D(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 52, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_0D */
+#define SD25G_LANE_LANE_0D(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 52, 0, 1, 4)
 
 #define SD25G_LANE_LANE_0D_LN_CFG_RXTERM_2_0     GENMASK(2, 0)
 #define SD25G_LANE_LANE_0D_LN_CFG_RXTERM_2_0_SET(x)\
@@ -1552,8 +1709,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_0D_LN_CFG_DFECK_EN_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_0D_LN_CFG_DFECK_EN, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_0E */
-#define SD25G_LANE_LANE_0E(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 56, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_0E */
+#define SD25G_LANE_LANE_0E(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 56, 0, 1, 4)
 
 #define SD25G_LANE_LANE_0E_LN_CFG_ISCAN_EN       BIT(0)
 #define SD25G_LANE_LANE_0E_LN_CFG_ISCAN_EN_SET(x)\
@@ -1579,8 +1738,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_0E_LN_CFG_DFEDIG_M_2_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_0E_LN_CFG_DFEDIG_M_2_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_0F */
-#define SD25G_LANE_LANE_0F(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 60, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_0F */
+#define SD25G_LANE_LANE_0F(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 60, 0, 1, 4)
 
 #define SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1  GENMASK(4, 0)
 #define SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1_SET(x)\
@@ -1588,8 +1749,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_18 */
-#define SD25G_LANE_LANE_18(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 96, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_18 */
+#define SD25G_LANE_LANE_18(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 96, 0, 1, 4)
 
 #define SD25G_LANE_LANE_18_LN_CFG_CDRCK_EN       BIT(0)
 #define SD25G_LANE_LANE_18_LN_CFG_CDRCK_EN_SET(x)\
@@ -1621,8 +1784,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_18_LN_CFG_RXDIV_SEL_2_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_18_LN_CFG_RXDIV_SEL_2_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_19 */
-#define SD25G_LANE_LANE_19(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 100, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_19 */
+#define SD25G_LANE_LANE_19(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 100, 0, 1, 4)
 
 #define SD25G_LANE_LANE_19_LN_CFG_DCDR_PD        BIT(0)
 #define SD25G_LANE_LANE_19_LN_CFG_DCDR_PD_SET(x)\
@@ -1672,8 +1837,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_19_LN_CFG_PD_CTLE_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_19_LN_CFG_PD_CTLE, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_1A */
-#define SD25G_LANE_LANE_1A(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 104, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_1A */
+#define SD25G_LANE_LANE_1A(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 104, 0, 1, 4)
 
 #define SD25G_LANE_LANE_1A_LN_CFG_CTLE_TP_EN     BIT(0)
 #define SD25G_LANE_LANE_1A_LN_CFG_CTLE_TP_EN_SET(x)\
@@ -1687,8 +1854,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_1A_LN_CFG_CDR_KF_2_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_1A_LN_CFG_CDR_KF_2_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_1B */
-#define SD25G_LANE_LANE_1B(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 108, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_1B */
+#define SD25G_LANE_LANE_1B(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 108, 0, 1, 4)
 
 #define SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0      GENMASK(7, 0)
 #define SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0_SET(x)\
@@ -1696,8 +1865,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_1C */
-#define SD25G_LANE_LANE_1C(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 112, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_1C */
+#define SD25G_LANE_LANE_1C(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 112, 0, 1, 4)
 
 #define SD25G_LANE_LANE_1C_LN_CFG_CDR_RSTN       BIT(0)
 #define SD25G_LANE_LANE_1C_LN_CFG_CDR_RSTN_SET(x)\
@@ -1723,8 +1894,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_1C_LN_CFG_EQC_FORCE_3_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_1C_LN_CFG_EQC_FORCE_3_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_1D */
-#define SD25G_LANE_LANE_1D(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 116, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_1D */
+#define SD25G_LANE_LANE_1D(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 116, 0, 1, 4)
 
 #define SD25G_LANE_LANE_1D_LN_CFG_ISCAN_EXT_OVR  BIT(0)
 #define SD25G_LANE_LANE_1D_LN_CFG_ISCAN_EXT_OVR_SET(x)\
@@ -1774,8 +1947,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_1D_LN_CFG_PI_HOLD_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_1D_LN_CFG_PI_HOLD, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_1E */
-#define SD25G_LANE_LANE_1E(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 120, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_1E */
+#define SD25G_LANE_LANE_1E(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 120, 0, 1, 4)
 
 #define SD25G_LANE_LANE_1E_LN_CFG_PI_STEPS_1_0   GENMASK(1, 0)
 #define SD25G_LANE_LANE_1E_LN_CFG_PI_STEPS_1_0_SET(x)\
@@ -1807,8 +1982,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_1E_LN_CFG_PMAD_CK_PD_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_1E_LN_CFG_PMAD_CK_PD, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_21 */
-#define SD25G_LANE_LANE_21(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 132, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_21 */
+#define SD25G_LANE_LANE_21(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 132, 0, 1, 4)
 
 #define SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0 GENMASK(4, 0)
 #define SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0_SET(x)\
@@ -1816,8 +1993,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_22 */
-#define SD25G_LANE_LANE_22(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 136, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_22 */
+#define SD25G_LANE_LANE_22(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 136, 0, 1, 4)
 
 #define SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0  GENMASK(3, 0)
 #define SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0_SET(x)\
@@ -1825,8 +2004,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_25 */
-#define SD25G_LANE_LANE_25(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 148, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_25 */
+#define SD25G_LANE_LANE_25(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 148, 0, 1, 4)
 
 #define SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0 GENMASK(6, 0)
 #define SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0_SET(x)\
@@ -1834,8 +2015,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_26 */
-#define SD25G_LANE_LANE_26(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 152, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_26 */
+#define SD25G_LANE_LANE_26(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 152, 0, 1, 4)
 
 #define SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0 GENMASK(6, 0)
 #define SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0_SET(x)\
@@ -1843,8 +2026,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_28 */
-#define SD25G_LANE_LANE_28(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 160, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_28 */
+#define SD25G_LANE_LANE_28(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 160, 0, 1, 4)
 
 #define SD25G_LANE_LANE_28_LN_CFG_ISCAN_MODE_EN  BIT(0)
 #define SD25G_LANE_LANE_28_LN_CFG_ISCAN_MODE_EN_SET(x)\
@@ -1870,8 +2055,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_28_LN_CFG_RX_SUBRATE_2_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_28_LN_CFG_RX_SUBRATE_2_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_2B */
-#define SD25G_LANE_LANE_2B(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 172, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_2B */
+#define SD25G_LANE_LANE_2B(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 172, 0, 1, 4)
 
 #define SD25G_LANE_LANE_2B_LN_CFG_PI_BW_3_0      GENMASK(3, 0)
 #define SD25G_LANE_LANE_2B_LN_CFG_PI_BW_3_0_SET(x)\
@@ -1891,8 +2078,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_2B_LN_CFG_RSTN_TXDUPU_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_2B_LN_CFG_RSTN_TXDUPU, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_2C */
-#define SD25G_LANE_LANE_2C(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 176, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_2C */
+#define SD25G_LANE_LANE_2C(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 176, 0, 1, 4)
 
 #define SD25G_LANE_LANE_2C_LN_CFG_TX_SUBRATE_2_0 GENMASK(2, 0)
 #define SD25G_LANE_LANE_2C_LN_CFG_TX_SUBRATE_2_0_SET(x)\
@@ -1906,8 +2095,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_2C_LN_CFG_DIS_2NDORDER_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_2C_LN_CFG_DIS_2NDORDER, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_2D */
-#define SD25G_LANE_LANE_2D(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 180, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_2D */
+#define SD25G_LANE_LANE_2D(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 180, 0, 1, 4)
 
 #define SD25G_LANE_LANE_2D_LN_CFG_ALOS_THR_2_0   GENMASK(2, 0)
 #define SD25G_LANE_LANE_2D_LN_CFG_ALOS_THR_2_0_SET(x)\
@@ -1921,8 +2112,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_2D_LN_CFG_SAT_CNTSEL_2_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_2D_LN_CFG_SAT_CNTSEL_2_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_2E */
-#define SD25G_LANE_LANE_2E(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 184, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_2E */
+#define SD25G_LANE_LANE_2E(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 184, 0, 1, 4)
 
 #define SD25G_LANE_LANE_2E_LN_CFG_EN_FAST_ISCAN  BIT(0)
 #define SD25G_LANE_LANE_2E_LN_CFG_EN_FAST_ISCAN_SET(x)\
@@ -1972,8 +2165,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_2E_LN_CFG_CTLE_RSTN_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_2E_LN_CFG_CTLE_RSTN, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_40 */
-#define SD25G_LANE_LANE_40(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 256, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_40 */
+#define SD25G_LANE_LANE_40(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 256, 0, 1, 4)
 
 #define SD25G_LANE_LANE_40_LN_R_TX_BIT_REVERSE   BIT(0)
 #define SD25G_LANE_LANE_40_LN_R_TX_BIT_REVERSE_SET(x)\
@@ -2017,8 +2212,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_40_LN_R_CTLE_RSTN_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_40_LN_R_CTLE_RSTN, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_42 */
-#define SD25G_LANE_LANE_42(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 264, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_42 */
+#define SD25G_LANE_LANE_42(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 264, 0, 1, 4)
 
 #define SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0 GENMASK(7, 0)
 #define SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0_SET(x)\
@@ -2026,8 +2223,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_43 */
-#define SD25G_LANE_LANE_43(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 268, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_43 */
+#define SD25G_LANE_LANE_43(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 268, 0, 1, 4)
 
 #define SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8 GENMASK(7, 0)
 #define SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8_SET(x)\
@@ -2035,8 +2234,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_44 */
-#define SD25G_LANE_LANE_44(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 272, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_44 */
+#define SD25G_LANE_LANE_44(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 272, 0, 1, 4)
 
 #define SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0 GENMASK(7, 0)
 #define SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0_SET(x)\
@@ -2044,8 +2245,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0, x)
 
-/*      SD25G_TARGET:LANE_GRP_0:LANE_45 */
-#define SD25G_LANE_LANE_45(t)     __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 276, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_0:LANE_45 */
+#define SD25G_LANE_LANE_45(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 276, 0, 1, 4)
 
 #define SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8 GENMASK(7, 0)
 #define SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8_SET(x)\
@@ -2053,8 +2256,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8, x)
 
-/*      SD25G_TARGET:LANE_GRP_1:LANE_DE */
-#define SD25G_LANE_LANE_DE(t)     __REG(TARGET_SD25G_LANE, t, 8, 1792, 0, 1, 128, 120, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_TARGET:LANE_GRP_1:LANE_DE */
+#define SD25G_LANE_LANE_DE(t)                                                  \
+	__REG(TARGET_SD25G_LANE, t, 8, 1792, 0, 1, 128, 120, 0, 1, 4)
 
 #define SD25G_LANE_LANE_DE_LN_LOL_UDL            BIT(0)
 #define SD25G_LANE_LANE_DE_LN_LOL_UDL_SET(x)\
@@ -2080,8 +2285,10 @@ enum sparx5_serdes_target {
 #define SD25G_LANE_LANE_DE_LN_PMA_RXEI_GET(x)\
 	FIELD_GET(SD25G_LANE_LANE_DE_LN_PMA_RXEI, x)
 
-/*      SD10G_LANE_TARGET:LANE_GRP_8:LANE_DF */
-#define SD6G_LANE_LANE_DF(t)      __REG(TARGET_SD6G_LANE, t, 13, 832, 0, 1, 84, 60, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD10G_LANE_TARGET:LANE_GRP_8:LANE_DF */
+#define SD6G_LANE_LANE_DF(t)                                                   \
+	__REG(TARGET_SD6G_LANE, t, 13, 832, 0, 1, 84, 60, 0, 1, 4)
 
 #define SD6G_LANE_LANE_DF_LOL_UDL                BIT(0)
 #define SD6G_LANE_LANE_DF_LOL_UDL_SET(x)\
@@ -2107,8 +2314,9 @@ enum sparx5_serdes_target {
 #define SD6G_LANE_LANE_DF_SQUELCH_GET(x)\
 	FIELD_GET(SD6G_LANE_LANE_DF_SQUELCH, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_0:CMU_00 */
-#define SD_CMU_CMU_00(t)          __REG(TARGET_SD_CMU, t, 14, 0, 0, 1, 20, 0, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_0:CMU_00 */
+#define SD_CMU_CMU_00(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 0, 0, 1, 20, 0, 0, 1, 4)
 
 #define SD_CMU_CMU_00_R_HWT_SIMULATION_MODE      BIT(0)
 #define SD_CMU_CMU_00_R_HWT_SIMULATION_MODE_SET(x)\
@@ -2134,8 +2342,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_00_CFG_PLL_TP_SEL_1_0_GET(x)\
 	FIELD_GET(SD_CMU_CMU_00_CFG_PLL_TP_SEL_1_0, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_1:CMU_05 */
-#define SD_CMU_CMU_05(t)          __REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 0, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_05 */
+#define SD_CMU_CMU_05(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 20, 0, 1, 72, 0, 0, 1, 4)
 
 #define SD_CMU_CMU_05_CFG_REFCK_TERM_EN          BIT(0)
 #define SD_CMU_CMU_05_CFG_REFCK_TERM_EN_SET(x)\
@@ -2149,9 +2358,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0_GET(x)\
 	FIELD_GET(SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_1:CMU_06 */
-#define SD_CMU_CMU_06(t) \
-	__REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 4, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_06 */
+#define SD_CMU_CMU_06(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 20, 0, 1, 72, 4, 0, 1, 4)
 
 #define SD_CMU_CMU_06_CFG_DISLOS                 BIT(0)
 #define SD_CMU_CMU_06_CFG_DISLOS_SET(x)\
@@ -2201,9 +2410,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_06_CFG_VCO_CAL_BYP_GET(x)\
 	FIELD_GET(SD_CMU_CMU_06_CFG_VCO_CAL_BYP, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_1:CMU_08 */
-#define SD_CMU_CMU_08(t) \
-	__REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 12, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_08 */
+#define SD_CMU_CMU_08(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 20, 0, 1, 72, 12, 0, 1, 4)
 
 #define SD_CMU_CMU_08_CFG_VFILT2PAD              BIT(0)
 #define SD_CMU_CMU_08_CFG_VFILT2PAD_SET(x)\
@@ -2235,8 +2444,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_08_CFG_RST_TREE_PD_MAN_EN_GET(x)\
 	FIELD_GET(SD_CMU_CMU_08_CFG_RST_TREE_PD_MAN_EN, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_1:CMU_09 */
-#define SD_CMU_CMU_09(t)          __REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 16, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_09 */
+#define SD_CMU_CMU_09(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 20, 0, 1, 72, 16, 0, 1, 4)
 
 #define SD_CMU_CMU_09_CFG_EN_TX_CK_UP            BIT(0)
 #define SD_CMU_CMU_09_CFG_EN_TX_CK_UP_SET(x)\
@@ -2262,8 +2472,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_09_CFG_SW_10G_GET(x)\
 	FIELD_GET(SD_CMU_CMU_09_CFG_SW_10G, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_1:CMU_0D */
-#define SD_CMU_CMU_0D(t)          __REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 32, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_0D */
+#define SD_CMU_CMU_0D(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 20, 0, 1, 72, 32, 0, 1, 4)
 
 #define SD_CMU_CMU_0D_CFG_PD_DIV64               BIT(0)
 #define SD_CMU_CMU_0D_CFG_PD_DIV64_SET(x)\
@@ -2295,8 +2506,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_0D_CFG_REFCK_PD_GET(x)\
 	FIELD_GET(SD_CMU_CMU_0D_CFG_REFCK_PD, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_3:CMU_1B */
-#define SD_CMU_CMU_1B(t)          __REG(TARGET_SD_CMU, t, 14, 104, 0, 1, 20, 4, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_3:CMU_1B */
+#define SD_CMU_CMU_1B(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 104, 0, 1, 20, 4, 0, 1, 4)
 
 #define SD_CMU_CMU_1B_CFG_RESERVE_7_0            GENMASK(7, 0)
 #define SD_CMU_CMU_1B_CFG_RESERVE_7_0_SET(x)\
@@ -2304,8 +2516,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_1B_CFG_RESERVE_7_0_GET(x)\
 	FIELD_GET(SD_CMU_CMU_1B_CFG_RESERVE_7_0, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_4:CMU_1F */
-#define SD_CMU_CMU_1F(t)          __REG(TARGET_SD_CMU, t, 14, 124, 0, 1, 68, 0, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_4:CMU_1F */
+#define SD_CMU_CMU_1F(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 124, 0, 1, 68, 0, 0, 1, 4)
 
 #define SD_CMU_CMU_1F_CFG_BIAS_DN_EN             BIT(0)
 #define SD_CMU_CMU_1F_CFG_BIAS_DN_EN_SET(x)\
@@ -2331,8 +2544,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_1F_CFG_VTUNE_SEL_GET(x)\
 	FIELD_GET(SD_CMU_CMU_1F_CFG_VTUNE_SEL, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_5:CMU_30 */
-#define SD_CMU_CMU_30(t)          __REG(TARGET_SD_CMU, t, 14, 192, 0, 1, 72, 0, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_5:CMU_30 */
+#define SD_CMU_CMU_30(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 192, 0, 1, 72, 0, 0, 1, 4)
 
 #define SD_CMU_CMU_30_R_PLL_DLOL_EN              BIT(0)
 #define SD_CMU_CMU_30_R_PLL_DLOL_EN_SET(x)\
@@ -2340,8 +2554,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_30_R_PLL_DLOL_EN_GET(x)\
 	FIELD_GET(SD_CMU_CMU_30_R_PLL_DLOL_EN, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_6:CMU_44 */
-#define SD_CMU_CMU_44(t)          __REG(TARGET_SD_CMU, t, 14, 264, 0, 1, 632, 8, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_6:CMU_44 */
+#define SD_CMU_CMU_44(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 264, 0, 1, 632, 8, 0, 1, 4)
 
 #define SD_CMU_CMU_44_R_PLL_RSTN                 BIT(0)
 #define SD_CMU_CMU_44_R_PLL_RSTN_SET(x)\
@@ -2355,8 +2570,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_44_R_CK_RESETB_GET(x)\
 	FIELD_GET(SD_CMU_CMU_44_R_CK_RESETB, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_6:CMU_45 */
-#define SD_CMU_CMU_45(t)          __REG(TARGET_SD_CMU, t, 14, 264, 0, 1, 632, 12, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_6:CMU_45 */
+#define SD_CMU_CMU_45(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 264, 0, 1, 632, 12, 0, 1, 4)
 
 #define SD_CMU_CMU_45_R_EN_RATECHG_CTRL          BIT(0)
 #define SD_CMU_CMU_45_R_EN_RATECHG_CTRL_SET(x)\
@@ -2406,8 +2622,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_45_R_AUTO_RST_TREE_PD_MAN_GET(x)\
 	FIELD_GET(SD_CMU_CMU_45_R_AUTO_RST_TREE_PD_MAN, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_6:CMU_47 */
-#define SD_CMU_CMU_47(t)          __REG(TARGET_SD_CMU, t, 14, 264, 0, 1, 632, 20, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_6:CMU_47 */
+#define SD_CMU_CMU_47(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 264, 0, 1, 632, 20, 0, 1, 4)
 
 #define SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0      GENMASK(4, 0)
 #define SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0_SET(x)\
@@ -2415,8 +2632,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0_GET(x)\
 	FIELD_GET(SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0, x)
 
-/*      SD10G_CMU_TARGET:CMU_GRP_7:CMU_E0 */
-#define SD_CMU_CMU_E0(t)          __REG(TARGET_SD_CMU, t, 14, 896, 0, 1, 8, 0, 0, 1, 4)
+/* SD10G_CMU_TARGET:CMU_GRP_7:CMU_E0 */
+#define SD_CMU_CMU_E0(t)                                                       \
+	__REG(TARGET_SD_CMU, t, TSIZE(TC_SD_CMU), 896, 0, 1, 8, 0, 0, 1, 4)
 
 #define SD_CMU_CMU_E0_READ_VCO_CTUNE_3_0         GENMASK(3, 0)
 #define SD_CMU_CMU_E0_READ_VCO_CTUNE_3_0_SET(x)\
@@ -2430,8 +2648,10 @@ enum sparx5_serdes_target {
 #define SD_CMU_CMU_E0_PLL_LOL_UDL_GET(x)\
 	FIELD_GET(SD_CMU_CMU_E0_PLL_LOL_UDL, x)
 
-/*      SD_CMU_TARGET:SD_CMU_CFG:SD_CMU_CFG */
-#define SD_CMU_CFG_SD_CMU_CFG(t)  __REG(TARGET_SD_CMU_CFG, t, 14, 0, 0, 1, 8, 0, 0, 1, 4)
+/* SD_CMU_TARGET:SD_CMU_CFG:SD_CMU_CFG */
+#define SD_CMU_CFG_SD_CMU_CFG(t)                                               \
+	__REG(TARGET_SD_CMU_CFG, t, TSIZE(TC_SD_CMU_CFG), 0, 0, 1, 8, 0, 0, 1, \
+	      4)
 
 #define SD_CMU_CFG_SD_CMU_CFG_CMU_RST            BIT(0)
 #define SD_CMU_CFG_SD_CMU_CFG_CMU_RST_SET(x)\
@@ -2445,8 +2665,9 @@ enum sparx5_serdes_target {
 #define SD_CMU_CFG_SD_CMU_CFG_EXT_CFG_RST_GET(x)\
 	FIELD_GET(SD_CMU_CFG_SD_CMU_CFG_EXT_CFG_RST, x)
 
-/*      SD_LANE_TARGET:SD_RESET:SD_SER_RST */
-#define SD_LANE_SD_SER_RST(t)     __REG(TARGET_SD_LANE, t, 25, 0, 0, 1, 8, 0, 0, 1, 4)
+/* SD_LANE_TARGET:SD_RESET:SD_SER_RST */
+#define SD_LANE_SD_SER_RST(t)                                                  \
+	__REG(TARGET_SD_LANE, t, TSIZE(TC_SD_LANE), 0, 0, 1, 8, 0, 0, 1, 4)
 
 #define SD_LANE_SD_SER_RST_SER_RST               BIT(0)
 #define SD_LANE_SD_SER_RST_SER_RST_SET(x)\
@@ -2454,8 +2675,9 @@ enum sparx5_serdes_target {
 #define SD_LANE_SD_SER_RST_SER_RST_GET(x)\
 	FIELD_GET(SD_LANE_SD_SER_RST_SER_RST, x)
 
-/*      SD_LANE_TARGET:SD_RESET:SD_DES_RST */
-#define SD_LANE_SD_DES_RST(t)     __REG(TARGET_SD_LANE, t, 25, 0, 0, 1, 8, 4, 0, 1, 4)
+/* SD_LANE_TARGET:SD_RESET:SD_DES_RST */
+#define SD_LANE_SD_DES_RST(t)                                                  \
+	__REG(TARGET_SD_LANE, t, TSIZE(TC_SD_LANE), 0, 0, 1, 8, 4, 0, 1, 4)
 
 #define SD_LANE_SD_DES_RST_DES_RST               BIT(0)
 #define SD_LANE_SD_DES_RST_DES_RST_SET(x)\
@@ -2463,8 +2685,9 @@ enum sparx5_serdes_target {
 #define SD_LANE_SD_DES_RST_DES_RST_GET(x)\
 	FIELD_GET(SD_LANE_SD_DES_RST_DES_RST, x)
 
-/*      SD_LANE_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG */
-#define SD_LANE_SD_LANE_CFG(t)    __REG(TARGET_SD_LANE, t, 25, 8, 0, 1, 8, 0, 0, 1, 4)
+/* SD_LANE_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG */
+#define SD_LANE_SD_LANE_CFG(t)                                                 \
+	__REG(TARGET_SD_LANE, t, TSIZE(TC_SD_LANE), 8, 0, 1, 8, 0, 0, 1, 4)
 
 #define SD_LANE_SD_LANE_CFG_MACRO_RST            BIT(0)
 #define SD_LANE_SD_LANE_CFG_MACRO_RST_SET(x)\
@@ -2508,8 +2731,9 @@ enum sparx5_serdes_target {
 #define SD_LANE_SD_LANE_CFG_LANE_RX_RST_GET(x)\
 	FIELD_GET(SD_LANE_SD_LANE_CFG_LANE_RX_RST, x)
 
-/*      SD_LANE_TARGET:SD_LANE_CFG_STAT:SD_LANE_STAT */
-#define SD_LANE_SD_LANE_STAT(t)   __REG(TARGET_SD_LANE, t, 25, 8, 0, 1, 8, 4, 0, 1, 4)
+/* SD_LANE_TARGET:SD_LANE_CFG_STAT:SD_LANE_STAT */
+#define SD_LANE_SD_LANE_STAT(t)                                                \
+	__REG(TARGET_SD_LANE, t, TSIZE(TC_SD_LANE), 8, 0, 1, 8, 4, 0, 1, 4)
 
 #define SD_LANE_SD_LANE_STAT_PMA_RST_DONE        BIT(0)
 #define SD_LANE_SD_LANE_STAT_PMA_RST_DONE_SET(x)\
@@ -2529,9 +2753,9 @@ enum sparx5_serdes_target {
 #define SD_LANE_SD_LANE_STAT_DBG_OBS_GET(x)\
 	FIELD_GET(SD_LANE_SD_LANE_STAT_DBG_OBS, x)
 
-/*      SD_LANE_TARGET:SD_PWR_CFG:QUIET_MODE_6G */
-#define SD_LANE_QUIET_MODE_6G(t) \
-	__REG(TARGET_SD_LANE, t, 25, 24, 0, 1, 8, 4, 0, 1, 4)
+/* SD_LANE_TARGET:SD_PWR_CFG:QUIET_MODE_6G */
+#define SD_LANE_QUIET_MODE_6G(t)                                               \
+	__REG(TARGET_SD_LANE, t, TSIZE(TC_SD_LANE), 24, 0, 1, 8, 4, 0, 1, 4)
 
 #define SD_LANE_QUIET_MODE_6G_QUIET_MODE         GENMASK(24, 0)
 #define SD_LANE_QUIET_MODE_6G_QUIET_MODE_SET(x)\
@@ -2539,8 +2763,9 @@ enum sparx5_serdes_target {
 #define SD_LANE_QUIET_MODE_6G_QUIET_MODE_GET(x)\
 	FIELD_GET(SD_LANE_QUIET_MODE_6G_QUIET_MODE, x)
 
-/*      SD_LANE_TARGET:CFG_STAT_FX100:MISC */
-#define SD_LANE_MISC(t)           __REG(TARGET_SD_LANE, t, 25, 56, 0, 1, 56, 0, 0, 1, 4)
+/* SD_LANE_TARGET:CFG_STAT_FX100:MISC */
+#define SD_LANE_MISC(t)                                                        \
+	__REG(TARGET_SD_LANE, t, TSIZE(TC_SD_LANE), 56, 0, 1, 56, 0, 0, 1, 4)
 
 #define SD_LANE_MISC_SD_125_RST_DIS              BIT(0)
 #define SD_LANE_MISC_SD_125_RST_DIS_SET(x)\
@@ -2560,14 +2785,16 @@ enum sparx5_serdes_target {
 #define SD_LANE_MISC_MUX_ENA_GET(x)\
 	FIELD_GET(SD_LANE_MISC_MUX_ENA, x)
 
+/* SPARX5 ONLY */
 #define SD_LANE_MISC_CORE_CLK_FREQ               GENMASK(5, 4)
 #define SD_LANE_MISC_CORE_CLK_FREQ_SET(x)\
 	FIELD_PREP(SD_LANE_MISC_CORE_CLK_FREQ, x)
 #define SD_LANE_MISC_CORE_CLK_FREQ_GET(x)\
 	FIELD_GET(SD_LANE_MISC_CORE_CLK_FREQ, x)
 
-/*      SD_LANE_TARGET:CFG_STAT_FX100:M_STAT_MISC */
-#define SD_LANE_M_STAT_MISC(t)    __REG(TARGET_SD_LANE, t, 25, 56, 0, 1, 56, 36, 0, 1, 4)
+/* SD_LANE_TARGET:CFG_STAT_FX100:M_STAT_MISC */
+#define SD_LANE_M_STAT_MISC(t)                                                 \
+	__REG(TARGET_SD_LANE, t, TSIZE(TC_SD_LANE), 56, 0, 1, 56, 36, 0, 1, 4)
 
 #define SD_LANE_M_STAT_MISC_M_RIS_EDGE_PTR_ADJ_SUM GENMASK(21, 0)
 #define SD_LANE_M_STAT_MISC_M_RIS_EDGE_PTR_ADJ_SUM_SET(x)\
@@ -2581,8 +2808,10 @@ enum sparx5_serdes_target {
 #define SD_LANE_M_STAT_MISC_M_LOCK_CNT_GET(x)\
 	FIELD_GET(SD_LANE_M_STAT_MISC_M_LOCK_CNT, x)
 
-/*      SD25G_CFG_TARGET:SD_RESET:SD_SER_RST */
-#define SD_LANE_25G_SD_SER_RST(t) __REG(TARGET_SD_LANE_25G, t, 8, 0, 0, 1, 8, 0, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_CFG_TARGET:SD_RESET:SD_SER_RST */
+#define SD_LANE_25G_SD_SER_RST(t)                                              \
+	__REG(TARGET_SD_LANE_25G, t, 8, 0, 0, 1, 8, 0, 0, 1, 4)
 
 #define SD_LANE_25G_SD_SER_RST_SER_RST           BIT(0)
 #define SD_LANE_25G_SD_SER_RST_SER_RST_SET(x)\
@@ -2590,8 +2819,10 @@ enum sparx5_serdes_target {
 #define SD_LANE_25G_SD_SER_RST_SER_RST_GET(x)\
 	FIELD_GET(SD_LANE_25G_SD_SER_RST_SER_RST, x)
 
-/*      SD25G_CFG_TARGET:SD_RESET:SD_DES_RST */
-#define SD_LANE_25G_SD_DES_RST(t) __REG(TARGET_SD_LANE_25G, t, 8, 0, 0, 1, 8, 4, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_CFG_TARGET:SD_RESET:SD_DES_RST */
+#define SD_LANE_25G_SD_DES_RST(t)                                              \
+	__REG(TARGET_SD_LANE_25G, t, 8, 0, 0, 1, 8, 4, 0, 1, 4)
 
 #define SD_LANE_25G_SD_DES_RST_DES_RST           BIT(0)
 #define SD_LANE_25G_SD_DES_RST_DES_RST_SET(x)\
@@ -2599,8 +2830,10 @@ enum sparx5_serdes_target {
 #define SD_LANE_25G_SD_DES_RST_DES_RST_GET(x)\
 	FIELD_GET(SD_LANE_25G_SD_DES_RST_DES_RST, x)
 
-/*      SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG */
-#define SD_LANE_25G_SD_LANE_CFG(t) __REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 0, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG */
+#define SD_LANE_25G_SD_LANE_CFG(t)                                             \
+	__REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 0, 0, 1, 4)
 
 #define SD_LANE_25G_SD_LANE_CFG_MACRO_RST        BIT(0)
 #define SD_LANE_25G_SD_LANE_CFG_MACRO_RST_SET(x)\
@@ -2698,8 +2931,10 @@ enum sparx5_serdes_target {
 #define SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXMARGIN_GET(x)\
 	FIELD_GET(SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXMARGIN, x)
 
-/*      SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG2 */
-#define SD_LANE_25G_SD_LANE_CFG2(t) __REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 4, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG2 */
+#define SD_LANE_25G_SD_LANE_CFG2(t)                                            \
+	__REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 4, 0, 1, 4)
 
 #define SD_LANE_25G_SD_LANE_CFG2_DATA_WIDTH_SEL  GENMASK(2, 0)
 #define SD_LANE_25G_SD_LANE_CFG2_DATA_WIDTH_SEL_SET(x)\
@@ -2767,8 +3002,10 @@ enum sparx5_serdes_target {
 #define SD_LANE_25G_SD_LANE_CFG2_RXRATE_SEL_GET(x)\
 	FIELD_GET(SD_LANE_25G_SD_LANE_CFG2_RXRATE_SEL, x)
 
-/*      SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_STAT */
-#define SD_LANE_25G_SD_LANE_STAT(t) __REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 8, 0, 1, 4)
+/* SPARX5 ONLY */
+/* SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_STAT */
+#define SD_LANE_25G_SD_LANE_STAT(t)                                            \
+	__REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 8, 0, 1, 4)
 
 #define SD_LANE_25G_SD_LANE_STAT_PMA_RST_DONE    BIT(0)
 #define SD_LANE_25G_SD_LANE_STAT_PMA_RST_DONE_SET(x)\
@@ -2788,8 +3025,9 @@ enum sparx5_serdes_target {
 #define SD_LANE_25G_SD_LANE_STAT_DBG_OBS_GET(x)\
 	FIELD_GET(SD_LANE_25G_SD_LANE_STAT_DBG_OBS, x)
 
-/*      SD25G_CFG_TARGET:SD_PWR_CFG:QUIET_MODE_6G */
-#define SD_LANE_25G_QUIET_MODE_6G(t) \
+/* SPARX5 ONLY */
+/* SD25G_CFG_TARGET:SD_PWR_CFG:QUIET_MODE_6G */
+#define SD_LANE_25G_QUIET_MODE_6G(t)                                           \
 	__REG(TARGET_SD_LANE_25G, t, 8, 28, 0, 1, 8, 4, 0, 1, 4)
 
 #define SD_LANE_25G_QUIET_MODE_6G_QUIET_MODE     GENMASK(24, 0)

-- 
2.34.1



From daniel.machon at microchip.com  Mon Sep  9 08:14:48 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Mon, 9 Sep 2024 17:14:48 +0200
Subject: [PATCH v2 8/9] dt-bindings: phy: sparx5: document lan969x
In-Reply-To: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
References: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
Message-ID: <20240909-sparx5-lan969x-serdes-driver-v2-8-d695bcb57b84@microchip.com>

Lan969x is going to reuse the existing Sparx5 SERDES driver - document
that by adding compatible strings for the different SKU's that we
support, and a short description of the SERDES types and data rates
supported.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 .../bindings/phy/microchip,sparx5-serdes.yaml           | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml b/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
index bdbdb3bbddbe..fa0b02916dac 100644
--- a/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
+++ b/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
@@ -8,6 +8,7 @@ title: Microchip Sparx5 Serdes controller
 
 maintainers:
   - Steen Hegelund <steen.hegelund at microchip.com>
+  - Daniel Machon <daniel.machon at microchip.com>
 
 description: |
   The Sparx5 SERDES interfaces share the same basic functionality, but
@@ -62,12 +63,26 @@ description: |
   * 10.3125 Gbps (10GBASE-R/10GBASE-KR/USXGMII)
   * 25.78125 Gbps (25GBASE-KR/25GBASE-CR/25GBASE-SR/25GBASE-LR/25GBASE-ER)
 
+  lan969x has ten SERDES10G interfaces that share the same features, operating
+  modes and data rates as the equivalent Sparx5 SERDES10G interfaces.
+
 properties:
   $nodename:
     pattern: "^serdes@[0-9a-f]+$"
 
   compatible:
-    const: microchip,sparx5-serdes
+    oneOf:
+      - enum:
+          - microchip,sparx5-serdes
+          - microchip,lan9691-serdes
+      - items:
+          - enum:
+              - microchip,lan9698-serdes
+              - microchip,lan9696-serdes
+              - microchip,lan9694-serdes
+              - microchip,lan9693-serdes
+              - microchip,lan9692-serdes
+          - const: microchip,lan9691-serdes
 
   reg:
     minItems: 1

-- 
2.34.1



From daniel.machon at microchip.com  Mon Sep  9 08:14:45 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Mon, 9 Sep 2024 17:14:45 +0200
Subject: [PATCH v2 5/9] phy: sparx5-serdes: add function for getting the
 CMU index
In-Reply-To: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
References: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
Message-ID: <20240909-sparx5-lan969x-serdes-driver-v2-5-d695bcb57b84@microchip.com>

The SERDES to CMU mapping is different on Sparx5 and lan969x. Therefore
create a function for getting the CMU index on Sparx5.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c | 11 ++---------
 drivers/phy/microchip/sparx5_serdes.h |  9 +++++++++
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index b1376a142b14..5b918a2716dd 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -28,14 +28,6 @@
 /* Optimal power settings from GUC */
 #define SPX5_SERDES_QUIET_MODE_VAL 0x01ef4e0c
 
-enum sparx5_10g28cmu_mode {
-	SPX5_SD10G28_CMU_MAIN = 0,
-	SPX5_SD10G28_CMU_AUX1 = 1,
-	SPX5_SD10G28_CMU_AUX2 = 3,
-	SPX5_SD10G28_CMU_NONE = 4,
-	SPX5_SD10G28_CMU_MAX,
-};
-
 enum sparx5_sd25g28_mode_preset_type {
 	SPX5_SD25G28_MODE_PRESET_25000,
 	SPX5_SD25G28_MODE_PRESET_10000,
@@ -1648,7 +1640,7 @@ static int sparx5_sd10g28_apply_params(struct sparx5_serdes_macro *macro,
 	if (params->skip_cmu_cfg)
 		return 0;
 
-	cmu_idx = sparx5_serdes_cmu_get(params->cmu_sel, lane_index);
+	cmu_idx = priv->data->ops.serdes_cmu_get(params->cmu_sel, macro->sidx);
 	err = sparx5_cmu_cfg(priv, cmu_idx);
 	if (err)
 		return err;
@@ -2520,6 +2512,7 @@ static const struct sparx5_serdes_match_data sparx5_desc = {
 	},
 	.ops = {
 		.serdes_type_set      = &sparx5_serdes_type_set,
+		.serdes_cmu_get       = &sparx5_serdes_cmu_get,
 	},
 };
 
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index 785c7fe0bbeb..a7e92c1330e9 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -26,6 +26,14 @@ enum sparx5_serdes_mode {
 	SPX5_SD_MODE_SFI,
 };
 
+enum sparx5_10g28cmu_mode {
+	SPX5_SD10G28_CMU_MAIN = 0,
+	SPX5_SD10G28_CMU_AUX1 = 1,
+	SPX5_SD10G28_CMU_AUX2 = 3,
+	SPX5_SD10G28_CMU_NONE = 4,
+	SPX5_SD10G28_CMU_MAX,
+};
+
 struct sparx5_serdes_macro {
 	struct sparx5_serdes_private *priv;
 	u32 sidx;
@@ -44,6 +52,7 @@ struct sparx5_serdes_consts {
 
 struct sparx5_serdes_ops {
 	void (*serdes_type_set)(struct sparx5_serdes_macro *macro, int sidx);
+	int (*serdes_cmu_get)(enum sparx5_10g28cmu_mode mode, int sd_index);
 };
 
 struct sparx5_serdes_match_data {

-- 
2.34.1



From daniel.machon at microchip.com  Mon Sep  9 08:14:49 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Mon, 9 Sep 2024 17:14:49 +0200
Subject: [PATCH v2 9/9] phy: lan969x-serdes: add support for lan969x serdes
 driver
In-Reply-To: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
References: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
Message-ID: <20240909-sparx5-lan969x-serdes-driver-v2-9-d695bcb57b84@microchip.com>

Add support for lan969x SERDES driver. Lan969x has ten 10G SERDES'es
which share the same features and data rates as the Sparx5 SERDES'es.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
---
 drivers/phy/microchip/sparx5_serdes.c | 88 +++++++++++++++++++++++++++++++++++
 drivers/phy/microchip/sparx5_serdes.h |  2 +
 2 files changed, 90 insertions(+)

diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index 05fdf225ff43..320cf5b50a8c 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -25,6 +25,8 @@
 #define SPX5_SERDES_25G_START 25
 #define SPX5_SERDES_6G10G_CNT SPX5_SERDES_25G_START
 
+#define LAN969X_SERDES_10G_CNT 10
+
 /* Optimal power settings from GUC */
 #define SPX5_SERDES_QUIET_MODE_VAL 0x01ef4e0c
 
@@ -36,6 +38,13 @@ const unsigned int sparx5_serdes_tsize[TSIZE_LAST] = {
 	[TC_SD_LANE] = 25,
 };
 
+const unsigned int lan969x_serdes_tsize[TSIZE_LAST] = {
+	[TC_SD10G_LANE] = 10,
+	[TC_SD_CMU] = 6,
+	[TC_SD_CMU_CFG] = 6,
+	[TC_SD_LANE] = 10,
+};
+
 /* Pointer to the register target size table */
 const unsigned int *tsize;
 
@@ -1096,6 +1105,24 @@ static int sparx5_serdes_cmu_get(enum sparx5_10g28cmu_mode mode, int sd_index)
 	return sparx5_serdes_cmu_map[mode][sd_index];
 }
 
+/* Map of 6G/10G serdes mode and index to CMU index. */
+static const int
+lan969x_serdes_cmu_map[SPX5_SD10G28_CMU_MAX][LAN969X_SERDES_10G_CNT] = {
+	[SPX5_SD10G28_CMU_MAIN] = { 2, 2, 2, 2, 2,
+				    2, 2, 2, 5, 5 },
+	[SPX5_SD10G28_CMU_AUX1] = { 0, 0, 3, 3, 3,
+				    3, 3, 3, 3, 3 },
+	[SPX5_SD10G28_CMU_AUX2] = { 1, 1, 1, 1, 4,
+				    4, 4, 4, 4, 4 },
+	[SPX5_SD10G28_CMU_NONE] = { 1, 1, 1, 1, 4,
+				    4, 4, 4, 4, 4 },
+};
+
+static int lan969x_serdes_cmu_get(enum sparx5_10g28cmu_mode mode, int sd_index)
+{
+	return lan969x_serdes_cmu_map[mode][sd_index];
+}
+
 static void sparx5_serdes_cmu_power_off(struct sparx5_serdes_private *priv)
 {
 	void __iomem *cmu_inst, *cmu_cfg_inst;
@@ -2184,6 +2211,10 @@ static int sparx5_serdes_clock_config(struct sparx5_serdes_macro *macro)
 {
 	struct sparx5_serdes_private *priv = macro->priv;
 
+	/* Clock is auto-detected in 100Base-FX mode on lan969x */
+	if (priv->data->type == SPX5_TARGET_LAN969X)
+		return 0;
+
 	if (macro->serdesmode == SPX5_SD_MODE_100FX) {
 		u32 freq = priv->coreclock == 250000000 ? 2 :
 			priv->coreclock == 500000000 ? 1 : 0;
@@ -2395,6 +2426,12 @@ static void sparx5_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
 	}
 }
 
+static void lan969x_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
+{
+	macro->serdestype = SPX5_SDT_10G;
+	macro->stpidx = macro->sidx;
+}
+
 static int sparx5_phy_create(struct sparx5_serdes_private *priv,
 			   int idx, struct phy **phy)
 {
@@ -2519,6 +2556,41 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] =  {
 	{ TARGET_SD_LANE_25G + 7, 0x5c8000 }, /* 0x610dd0000: sd_lane_25g_32 */
 };
 
+static const struct sparx5_serdes_io_resource lan969x_serdes_iomap[] =  {
+	{ TARGET_SD_CMU,               0x0     }, /* 0xe3410000 */
+	{ TARGET_SD_CMU +  1,          0x8000  }, /* 0xe3418000 */
+	{ TARGET_SD_CMU +  2,          0x10000 }, /* 0xe3420000 */
+	{ TARGET_SD_CMU +  3,          0x18000 }, /* 0xe3428000 */
+	{ TARGET_SD_CMU +  4,          0x20000 }, /* 0xe3430000 */
+	{ TARGET_SD_CMU +  5,          0x28000 }, /* 0xe3438000 */
+	{ TARGET_SD_CMU_CFG,           0x30000 }, /* 0xe3440000 */
+	{ TARGET_SD_CMU_CFG +  1,      0x38000 }, /* 0xe3448000 */
+	{ TARGET_SD_CMU_CFG +  2,      0x40000 }, /* 0xe3450000 */
+	{ TARGET_SD_CMU_CFG +  3,      0x48000 }, /* 0xe3458000 */
+	{ TARGET_SD_CMU_CFG +  4,      0x50000 }, /* 0xe3460000 */
+	{ TARGET_SD_CMU_CFG +  5,      0x58000 }, /* 0xe3468000 */
+	{ TARGET_SD10G_LANE,           0x60000 }, /* 0xe3470000 */
+	{ TARGET_SD10G_LANE +  1,      0x68000 }, /* 0xe3478000 */
+	{ TARGET_SD10G_LANE +  2,      0x70000 }, /* 0xe3480000 */
+	{ TARGET_SD10G_LANE +  3,      0x78000 }, /* 0xe3488000 */
+	{ TARGET_SD10G_LANE +  4,      0x80000 }, /* 0xe3490000 */
+	{ TARGET_SD10G_LANE +  5,      0x88000 }, /* 0xe3498000 */
+	{ TARGET_SD10G_LANE +  6,      0x90000 }, /* 0xe34a0000 */
+	{ TARGET_SD10G_LANE +  7,      0x98000 }, /* 0xe34a8000 */
+	{ TARGET_SD10G_LANE +  8,      0xa0000 }, /* 0xe34b0000 */
+	{ TARGET_SD10G_LANE +  9,      0xa8000 }, /* 0xe34b8000 */
+	{ TARGET_SD_LANE,             0x100000 }, /* 0xe3510000 */
+	{ TARGET_SD_LANE +  1,        0x108000 }, /* 0xe3518000 */
+	{ TARGET_SD_LANE +  2,        0x110000 }, /* 0xe3520000 */
+	{ TARGET_SD_LANE +  3,        0x118000 }, /* 0xe3528000 */
+	{ TARGET_SD_LANE +  4,        0x120000 }, /* 0xe3530000 */
+	{ TARGET_SD_LANE +  5,        0x128000 }, /* 0xe3538000 */
+	{ TARGET_SD_LANE +  6,        0x130000 }, /* 0xe3540000 */
+	{ TARGET_SD_LANE +  7,        0x138000 }, /* 0xe3548000 */
+	{ TARGET_SD_LANE +  8,        0x140000 }, /* 0xe3550000 */
+	{ TARGET_SD_LANE +  9,        0x148000 }, /* 0xe3558000 */
+};
+
 static const struct sparx5_serdes_match_data sparx5_desc = {
 	.type = SPX5_TARGET_SPARX5,
 	.iomap = sparx5_serdes_iomap,
@@ -2534,6 +2606,21 @@ static const struct sparx5_serdes_match_data sparx5_desc = {
 	},
 };
 
+static const struct sparx5_serdes_match_data lan969x_desc = {
+	.type = SPX5_TARGET_LAN969X,
+	.iomap = lan969x_serdes_iomap,
+	.iomap_size = ARRAY_SIZE(lan969x_serdes_iomap),
+	.tsize = lan969x_serdes_tsize,
+	.consts = {
+		.sd_max       = 10,
+		.cmu_max      = 6,
+	},
+	.ops = {
+		.serdes_type_set      = &lan969x_serdes_type_set,
+		.serdes_cmu_get       = &lan969x_serdes_cmu_get,
+	}
+};
+
 /* Client lookup function, uses serdes index */
 static struct phy *sparx5_serdes_xlate(struct device *dev,
 				     const struct of_phandle_args *args)
@@ -2635,6 +2722,7 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 
 static const struct of_device_id sparx5_serdes_match[] = {
 	{ .compatible = "microchip,sparx5-serdes", .data = &sparx5_desc },
+	{ .compatible = "microchip,lan9691-serdes", .data = &lan969x_desc },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, sparx5_serdes_match);
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
index 1beaa3d05a5d..d7093d0b09c0 100644
--- a/drivers/phy/microchip/sparx5_serdes.h
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -36,6 +36,8 @@ enum sparx5_10g28cmu_mode {
 
 enum sparx5_target {
 	SPX5_TARGET_SPARX5,
+	SPX5_TARGET_LAN969X,
+
 };
 
 struct sparx5_serdes_macro {

-- 
2.34.1



From xu.yang_2 at nxp.com  Tue Sep 10 00:03:35 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Tue, 10 Sep 2024 15:03:35 +0800
Subject: [PATCH v4 1/5] dt-bindings: phy: imx8mq-usb: add compatible "fsl,imx95-usb-phy"
Message-ID: <20240910070339.4150883-1-xu.yang_2@nxp.com>

The usb phy in i.MX95 is compatible with i.MX8MP's, this will add a
compatible "fsl,imx95-usb-phy" for i.MX95. Also change reg maxItems
to 2 since i.MX95 needs another regmap to control Type-C Assist (TCA)
block. Since i.MX95 usb phy is able to switch SS lanes, this will also
add orientation-switch and port property to the file.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - replace minItems with description in reg property
 - remove orientation-switch and port
 - refer to usb-switch.yaml
 - use unevaluatedProperties
Changes in v3:
 - add Rb tag
Changes in v4:
 - no changes
---
 .../bindings/phy/fsl,imx8mq-usb-phy.yaml      | 42 ++++++++++++++++---
 1 file changed, 37 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
index dc3a3f709fea..6d6d211883ae 100644
--- a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
@@ -11,12 +11,17 @@ maintainers:
 
 properties:
   compatible:
-    enum:
-      - fsl,imx8mq-usb-phy
-      - fsl,imx8mp-usb-phy
+    oneOf:
+      - enum:
+          - fsl,imx8mq-usb-phy
+          - fsl,imx8mp-usb-phy
+      - items:
+          - const: fsl,imx95-usb-phy
+          - const: fsl,imx8mp-usb-phy
 
   reg:
-    maxItems: 1
+    minItems: 1
+    maxItems: 2
 
   "#phy-cells":
     const: 0
@@ -89,7 +94,34 @@ required:
   - clocks
   - clock-names
 
-additionalProperties: false
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx95-usb-phy
+    then:
+      properties:
+        reg:
+          items:
+            - description: USB PHY Control range
+            - description: USB PHY TCA Block range
+    else:
+      properties:
+        reg:
+          maxItems: 1
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx95-usb-phy
+    then:
+      $ref: /schemas/usb/usb-switch.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
-- 
2.34.1



From xu.yang_2 at nxp.com  Tue Sep 10 00:03:36 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Tue, 10 Sep 2024 15:03:36 +0800
Subject: [PATCH v4 2/5] dt-bindings: usb: dwc3-imx8mp: add compatible string for imx95
In-Reply-To: <20240910070339.4150883-1-xu.yang_2@nxp.com>
References: <20240910070339.4150883-1-xu.yang_2@nxp.com>
Message-ID: <20240910070339.4150883-2-xu.yang_2@nxp.com>

The i.MX95 is compatible with i.MX8MP's usb controller. This will add a
compatible string "fsl,imx95-dwc3" for i.MX95.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - add Ack-by tag
Changes in v3:
 - no changes
Changes in v4:
 - no changes
---
 Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
index 9ea1e4cd0709..baf130669c38 100644
--- a/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
@@ -12,7 +12,11 @@ maintainers:
 
 properties:
   compatible:
-    const: fsl,imx8mp-dwc3
+    oneOf:
+      - items:
+          - const: fsl,imx95-dwc3
+          - const: fsl,imx8mp-dwc3
+      - const: fsl,imx8mp-dwc3
 
   reg:
     items:
-- 
2.34.1



From xu.yang_2 at nxp.com  Tue Sep 10 00:03:37 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Tue, 10 Sep 2024 15:03:37 +0800
Subject: [PATCH v4 3/5] phy: fsl-imx8mq-usb: add tca function driver for imx95
In-Reply-To: <20240910070339.4150883-1-xu.yang_2@nxp.com>
References: <20240910070339.4150883-1-xu.yang_2@nxp.com>
Message-ID: <20240910070339.4150883-3-xu.yang_2@nxp.com>

The i.MX95 USB3 phy has a Type-C Assist block (TCA). This block consists
two functional blocks (XBar assist and VBus assist) and one system
access interface using APB.

The primary functionality of XBar assist is:
 - switching lane for flip
 - moving unused lanes into lower power states.

This info can be get from:
i.MX95 RM Chapter 163.3.8 Type-C assist (TCA) block.

This will add support for TCA block to achieve lane switching and tca
lower power functionality.

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

---
Changes in v2:
 - return the value of imx95_usb_phy_get_tca()
Changes in v3:
 - no changes
Changes in v4:
 - remove compatible check for imx95
 - check whether tca register region exist or not, yes means has tca,
   otherwise skip tca setup
---
 drivers/phy/freescale/Kconfig              |   1 +
 drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 243 +++++++++++++++++++++
 2 files changed, 244 insertions(+)

diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index dcd9acff6d01..81f53564ee15 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -5,6 +5,7 @@ if (ARCH_MXC && ARM64) || COMPILE_TEST
 config PHY_FSL_IMX8MQ_USB
 	tristate "Freescale i.MX8M USB3 PHY"
 	depends on OF && HAS_IOMEM
+	depends on TYPEC || TYPEC=n
 	select GENERIC_PHY
 	default ARCH_MXC && ARM64
 
diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
index adc6394626ce..f97f86644b2c 100644
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
@@ -10,6 +10,7 @@
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/usb/typec_mux.h>
 
 #define PHY_CTRL0			0x0
 #define PHY_CTRL0_REF_SSP_EN		BIT(2)
@@ -50,11 +51,66 @@
 
 #define PHY_TUNE_DEFAULT		0xffffffff
 
+#define TCA_CLK_RST			0x00
+#define TCA_CLK_RST_SW			BIT(9)
+#define TCA_CLK_RST_REF_CLK_EN		BIT(1)
+#define TCA_CLK_RST_SUSPEND_CLK_EN	BIT(0)
+
+#define TCA_INTR_EN			0x04
+#define TCA_INTR_STS			0x08
+
+#define TCA_GCFG			0x10
+#define TCA_GCFG_ROLE_HSTDEV		BIT(4)
+#define TCA_GCFG_OP_MODE		GENMASK(1, 0)
+#define TCA_GCFG_OP_MODE_SYSMODE	0
+#define TCA_GCFG_OP_MODE_SYNCMODE	1
+
+#define TCA_TCPC			0x14
+#define TCA_TCPC_VALID			BIT(4)
+#define TCA_TCPC_LOW_POWER_EN		BIT(3)
+#define TCA_TCPC_ORIENTATION_NORMAL	BIT(2)
+#define TCA_TCPC_MUX_CONTRL		GENMASK(1, 0)
+#define TCA_TCPC_MUX_CONTRL_NO_CONN	0
+#define TCA_TCPC_MUX_CONTRL_USB_CONN	1
+
+#define TCA_SYSMODE_CFG			0x18
+#define TCA_SYSMODE_TCPC_DISABLE	BIT(3)
+#define TCA_SYSMODE_TCPC_FLIP		BIT(2)
+
+#define TCA_CTRLSYNCMODE_CFG0		0x20
+#define TCA_CTRLSYNCMODE_CFG1           0x20
+
+#define TCA_PSTATE			0x30
+#define TCA_PSTATE_CM_STS		BIT(4)
+#define TCA_PSTATE_TX_STS		BIT(3)
+#define TCA_PSTATE_RX_PLL_STS		BIT(2)
+#define TCA_PSTATE_PIPE0_POWER_DOWN	GENMASK(1, 0)
+
+#define TCA_GEN_STATUS			0x34
+#define TCA_GEN_DEV_POR			BIT(12)
+#define TCA_GEN_REF_CLK_SEL		BIT(8)
+#define TCA_GEN_TYPEC_FLIP_INVERT	BIT(4)
+#define TCA_GEN_PHY_TYPEC_DISABLE	BIT(3)
+#define TCA_GEN_PHY_TYPEC_FLIP		BIT(2)
+
+#define TCA_VBUS_CTRL			0x40
+#define TCA_VBUS_STATUS			0x44
+
+#define TCA_INFO			0xFC
+
+struct tca_blk {
+	struct typec_switch_dev *sw;
+	void __iomem *base;
+	struct mutex mutex;
+	enum typec_orientation orientation;
+};
+
 struct imx8mq_usb_phy {
 	struct phy *phy;
 	struct clk *clk;
 	void __iomem *base;
 	struct regulator *vbus;
+	struct tca_blk *tca;
 	u32 pcs_tx_swing_full;
 	u32 pcs_tx_deemph_3p5db;
 	u32 tx_vref_tune;
@@ -64,6 +120,175 @@ struct imx8mq_usb_phy {
 	u32 comp_dis_tune;
 };
 
+
+static void tca_blk_orientation_set(struct tca_blk *tca,
+				enum typec_orientation orientation);
+
+#ifdef CONFIG_TYPEC
+
+static int tca_blk_typec_switch_set(struct typec_switch_dev *sw,
+				enum typec_orientation orientation)
+{
+	struct imx8mq_usb_phy *imx_phy = typec_switch_get_drvdata(sw);
+	struct tca_blk *tca = imx_phy->tca;
+	int ret;
+
+	if (tca->orientation == orientation)
+		return 0;
+
+	ret = clk_prepare_enable(imx_phy->clk);
+	if (ret)
+		return ret;
+
+	tca_blk_orientation_set(tca, orientation);
+	clk_disable_unprepare(imx_phy->clk);
+
+	return 0;
+}
+
+static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device *pdev,
+					struct imx8mq_usb_phy *imx_phy)
+{
+	struct device *dev = &pdev->dev;
+	struct typec_switch_dev *sw;
+	struct typec_switch_desc sw_desc = { };
+
+	sw_desc.drvdata = imx_phy;
+	sw_desc.fwnode = dev->fwnode;
+	sw_desc.set = tca_blk_typec_switch_set;
+	sw_desc.name = NULL;
+
+	sw = typec_switch_register(dev, &sw_desc);
+	if (IS_ERR(sw)) {
+		dev_err(dev, "Error register tca orientation switch: %ld",
+				PTR_ERR(sw));
+		return NULL;
+	}
+
+	return sw;
+}
+
+static void tca_blk_put_typec_switch(struct typec_switch_dev *sw)
+{
+	typec_switch_unregister(sw);
+}
+
+#else
+
+static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device *pdev,
+			struct imx8mq_usb_phy *imx_phy)
+{
+	return NULL;
+}
+
+static void tca_blk_put_typec_switch(struct typec_switch_dev *sw) {}
+
+#endif /* CONFIG_TYPEC */
+
+static void tca_blk_orientation_set(struct tca_blk *tca,
+				enum typec_orientation orientation)
+{
+	u32 val;
+
+	mutex_lock(&tca->mutex);
+
+	if (orientation == TYPEC_ORIENTATION_NONE) {
+		/*
+		 * use Controller Synced Mode for TCA low power enable and
+		 * put PHY to USB safe state.
+		 */
+		val = readl(tca->base + TCA_GCFG);
+		val = FIELD_PREP(TCA_GCFG_OP_MODE, TCA_GCFG_OP_MODE_SYNCMODE);
+		writel(val, tca->base + TCA_GCFG);
+
+		val = readl(tca->base + TCA_TCPC);
+		val = TCA_TCPC_VALID | TCA_TCPC_LOW_POWER_EN;
+		writel(val, tca->base + TCA_TCPC);
+
+		goto out;
+	}
+
+	/* use System Configuration Mode for TCA mux control. */
+	val = readl(tca->base + TCA_GCFG);
+	val = FIELD_PREP(TCA_GCFG_OP_MODE, TCA_GCFG_OP_MODE_SYSMODE);
+	writel(val, tca->base + TCA_GCFG);
+
+	/* Disable TCA module */
+	val = readl(tca->base + TCA_SYSMODE_CFG);
+	val |= TCA_SYSMODE_TCPC_DISABLE;
+	writel(val, tca->base + TCA_SYSMODE_CFG);
+
+	if (orientation == TYPEC_ORIENTATION_REVERSE)
+		val |= TCA_SYSMODE_TCPC_FLIP;
+	else if (orientation == TYPEC_ORIENTATION_NORMAL)
+		val &= ~TCA_SYSMODE_TCPC_FLIP;
+
+	writel(val, tca->base + TCA_SYSMODE_CFG);
+
+	/* Enable TCA module */
+	val &= ~TCA_SYSMODE_TCPC_DISABLE;
+	writel(val, tca->base + TCA_SYSMODE_CFG);
+
+out:
+	tca->orientation = orientation;
+	mutex_unlock(&tca->mutex);
+}
+
+static void tca_blk_init(struct tca_blk *tca)
+{
+	u32 val;
+
+	/* reset XBar block */
+	val = readl(tca->base + TCA_CLK_RST);
+	val &= ~TCA_CLK_RST_SW;
+	writel(val, tca->base + TCA_CLK_RST);
+
+	udelay(100);
+
+	/* clear reset */
+	val |= TCA_CLK_RST_SW;
+	writel(val, tca->base + TCA_CLK_RST);
+
+	tca_blk_orientation_set(tca, tca->orientation);
+}
+
+static struct tca_blk *imx95_usb_phy_get_tca(struct platform_device *pdev,
+				struct imx8mq_usb_phy *imx_phy)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct tca_blk *tca;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res)
+		return 0;
+
+	tca = devm_kzalloc(dev, sizeof(*tca), GFP_KERNEL);
+	if (!tca)
+		return ERR_PTR(-ENOMEM);
+
+	tca->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(tca->base))
+		return tca->base;
+
+	mutex_init(&tca->mutex);
+
+	tca->orientation = TYPEC_ORIENTATION_NORMAL;
+	tca->sw = tca_blk_get_typec_switch(pdev, imx_phy);
+
+	return tca;
+}
+
+static void imx95_usb_phy_put_tca(struct imx8mq_usb_phy *imx_phy)
+{
+	struct tca_blk *tca = imx_phy->tca;
+
+	if (!tca)
+		return;
+
+	tca_blk_put_typec_switch(tca->sw);
+}
+
 static u32 phy_tx_vref_tune_from_property(u32 percent)
 {
 	percent = clamp(percent, 94U, 124U);
@@ -315,6 +540,9 @@ static int imx8mp_usb_phy_init(struct phy *phy)
 
 	imx8m_phy_tune(imx_phy);
 
+	if (imx_phy->tca)
+		tca_blk_init(imx_phy->tca);
+
 	return 0;
 }
 
@@ -359,6 +587,8 @@ static const struct of_device_id imx8mq_usb_phy_of_match[] = {
 	 .data = &imx8mq_usb_phy_ops,},
 	{.compatible = "fsl,imx8mp-usb-phy",
 	 .data = &imx8mp_usb_phy_ops,},
+	{.compatible = "fsl,imx95-usb-phy",
+	 .data = &imx8mp_usb_phy_ops,},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, imx8mq_usb_phy_of_match);
@@ -398,6 +628,11 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 
 	phy_set_drvdata(imx_phy->phy, imx_phy);
 
+	imx_phy->tca = imx95_usb_phy_get_tca(pdev, imx_phy);
+	if (IS_ERR(imx_phy->tca))
+		return dev_err_probe(dev, PTR_ERR(imx_phy->tca),
+					"failed to get tca\n");
+
 	imx8m_get_phy_tuning_data(imx_phy);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
@@ -405,8 +640,16 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 	return PTR_ERR_OR_ZERO(phy_provider);
 }
 
+static void imx8mq_usb_phy_remove(struct platform_device *pdev)
+{
+	struct imx8mq_usb_phy *imx_phy = platform_get_drvdata(pdev);
+
+	imx95_usb_phy_put_tca(imx_phy);
+}
+
 static struct platform_driver imx8mq_usb_phy_driver = {
 	.probe	= imx8mq_usb_phy_probe,
+	.remove = imx8mq_usb_phy_remove,
 	.driver = {
 		.name	= "imx8mq-usb-phy",
 		.of_match_table	= imx8mq_usb_phy_of_match,
-- 
2.34.1



From xu.yang_2 at nxp.com  Tue Sep 10 00:03:38 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Tue, 10 Sep 2024 15:03:38 +0800
Subject: [PATCH v4 4/5] arm64: dts: imx95: add usb3 related nodes
In-Reply-To: <20240910070339.4150883-1-xu.yang_2@nxp.com>
References: <20240910070339.4150883-1-xu.yang_2@nxp.com>
Message-ID: <20240910070339.4150883-4-xu.yang_2@nxp.com>

Add usb3 phy and controller nodes for imx95.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - no changes
Changes in v3:
 - no changes
Changes in v4:
 - reorder nodes
---
 arch/arm64/boot/dts/freescale/imx95.dtsi | 43 ++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
index 425272aa5a81..2377b3ade95a 100644
--- a/arch/arm64/boot/dts/freescale/imx95.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
@@ -1188,5 +1188,48 @@ pcie1_ep: pcie-ep at 4c380000 {
 			power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
 			status = "disabled";
 		};
+
+		usb3: usb at 4c010010 {
+			compatible = "fsl,imx95-dwc3", "fsl,imx8mp-dwc3";
+			reg = <0x0 0x4c010010 0x0 0x04>,
+			      <0x0 0x4c1f0000 0x0 0x20>;
+			clocks = <&scmi_clk IMX95_CLK_HSIO>,
+				 <&scmi_clk IMX95_CLK_32K>;
+			clock-names = "hsio", "suspend";
+			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
+			dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
+			status = "disabled";
+
+			usb3_dwc3: usb at 4c100000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x4c100000 0x0 0x10000>;
+				clocks = <&scmi_clk IMX95_CLK_HSIO>,
+					 <&scmi_clk IMX95_CLK_24M>,
+					 <&scmi_clk IMX95_CLK_32K>;
+				clock-names = "bus_early", "ref", "suspend";
+				interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+				phys = <&usb3_phy>, <&usb3_phy>;
+				phy-names = "usb2-phy", "usb3-phy";
+				snps,gfladj-refclk-lpm-sel-quirk;
+				snps,parkmode-disable-ss-quirk;
+				iommus = <&smmu 0xe>;
+			};
+		};
+
+		usb3_phy: phy at 4c1f0040 {
+			compatible = "fsl,imx95-usb-phy", "fsl,imx8mp-usb-phy";
+			reg = <0x0 0x4c1f0040 0x0 0x40>,
+			      <0x0 0x4c1fc000 0x0 0x100>;
+			clocks = <&scmi_clk IMX95_CLK_HSIO>;
+			clock-names = "phy";
+			#phy-cells = <0>;
+			power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
+			orientation-switch;
+			status = "disabled";
+		};
 	};
 };
-- 
2.34.1



From xu.yang_2 at nxp.com  Tue Sep 10 00:03:39 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Tue, 10 Sep 2024 15:03:39 +0800
Subject: [PATCH v4 5/5] arm64: dts: imx95-19x19-evk: add typec nodes and enable usb3 node
In-Reply-To: <20240910070339.4150883-1-xu.yang_2@nxp.com>
References: <20240910070339.4150883-1-xu.yang_2@nxp.com>
Message-ID: <20240910070339.4150883-5-xu.yang_2@nxp.com>

This board has one Type-C port which has USB3 capability. This will
add typec nodes and enable usb3 node.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - no changes
Changes in v3:
 - no changes
Changes in v4:
 - no changes
---
 .../boot/dts/freescale/imx95-19x19-evk.dts    | 81 +++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
index d14a54ab4fd4..46a9cd3d4403 100644
--- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/usb/pd.h>
 #include "imx95.dtsi"
 
 / {
@@ -99,6 +100,48 @@ i2c7_pcal6524: i2c7-gpio at 22 {
 		interrupt-parent = <&gpio5>;
 		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
 	};
+
+	ptn5110: tcpc at 50 {
+		compatible = "nxp,ptn5110", "tcpci";
+		reg = <0x50>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_typec>;
+		interrupt-parent = <&gpio5>;
+		interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
+
+		typec_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			power-role = "dual";
+			data-role = "dual";
+			try-power-role = "sink";
+			source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+			sink-pdos = <PDO_FIXED(5000, 0, PDO_FIXED_USB_COMM)>;
+			op-sink-microwatt = <0>;
+			self-powered;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					typec_con_hs: endpoint {
+						remote-endpoint = <&usb3_data_hs>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					typec_con_ss: endpoint {
+						remote-endpoint = <&usb3_data_ss>;
+					};
+				};
+			};
+		};
+	};
 };
 
 &lpuart1 {
@@ -128,6 +171,38 @@ &pcie1 {
 	status = "okay";
 };
 
+&usb3 {
+	status = "okay";
+};
+
+&usb3_phy {
+	status = "okay";
+
+	port {
+		usb3_data_ss: endpoint {
+			remote-endpoint = <&typec_con_ss>;
+		};
+	};
+};
+
+&usb3_dwc3 {
+	dr_mode = "otg";
+	hnp-disable;
+	srp-disable;
+	adp-disable;
+	usb-role-switch;
+	role-switch-default-mode = "peripheral";
+	snps,dis-u1-entry-quirk;
+	snps,dis-u2-entry-quirk;
+	status = "okay";
+
+	port {
+		usb3_data_hs: endpoint {
+			remote-endpoint = <&typec_con_hs>;
+		};
+	};
+};
+
 &usdhc1 {
 	pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
 	pinctrl-0 = <&pinctrl_usdhc1>;
@@ -245,6 +320,12 @@ IMX95_PAD_SD2_RESET_B__GPIO3_IO_BIT7		0x31e
 		>;
 	};
 
+	pinctrl_typec: typecgrp {
+		fsl,pins = <
+			IMX95_PAD_GPIO_IO34__GPIO5_IO_BIT14			0x31e
+		>;
+	};
+
 	pinctrl_usdhc2_gpio: usdhc2gpiogrp {
 		fsl,pins = <
 			IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0		0x31e
-- 
2.34.1



From krzk at kernel.org  Tue Sep 10 00:40:12 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 10 Sep 2024 09:40:12 +0200
Subject: [PATCH v2 8/9] dt-bindings: phy: sparx5: document lan969x
In-Reply-To: <20240909-sparx5-lan969x-serdes-driver-v2-8-d695bcb57b84@microchip.com>
References: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
 <20240909-sparx5-lan969x-serdes-driver-v2-8-d695bcb57b84@microchip.com>
Message-ID: <wd3gzn3lpmw64qor3xslif6rnp7htycfhu33pa2xpxvv6mrwqe@nv6pcwkstywe>

On Mon, Sep 09, 2024 at 05:14:48PM +0200, Daniel Machon wrote:
> Lan969x is going to reuse the existing Sparx5 SERDES driver - document
> that by adding compatible strings for the different SKU's that we
> support, and a short description of the SERDES types and data rates
> supported.
> 
> Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
> Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
> ---
>  .../bindings/phy/microchip,sparx5-serdes.yaml           | 17 ++++++++++++++++-
>  1 file changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml b/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
> index bdbdb3bbddbe..fa0b02916dac 100644
> --- a/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
> +++ b/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
> @@ -8,6 +8,7 @@ title: Microchip Sparx5 Serdes controller
>  
>  maintainers:
>    - Steen Hegelund <steen.hegelund at microchip.com>
> +  - Daniel Machon <daniel.machon at microchip.com>
>  
>  description: |
>    The Sparx5 SERDES interfaces share the same basic functionality, but
> @@ -62,12 +63,26 @@ description: |
>    * 10.3125 Gbps (10GBASE-R/10GBASE-KR/USXGMII)
>    * 25.78125 Gbps (25GBASE-KR/25GBASE-CR/25GBASE-SR/25GBASE-LR/25GBASE-ER)
>  
> +  lan969x has ten SERDES10G interfaces that share the same features, operating
> +  modes and data rates as the equivalent Sparx5 SERDES10G interfaces.
> +
>  properties:
>    $nodename:
>      pattern: "^serdes@[0-9a-f]+$"
>  
>    compatible:
> -    const: microchip,sparx5-serdes
> +    oneOf:
> +      - enum:
> +          - microchip,sparx5-serdes
> +          - microchip,lan9691-serdes
> +      - items:
> +          - enum:
> +              - microchip,lan9698-serdes
> +              - microchip,lan9696-serdes
> +              - microchip,lan9694-serdes
> +              - microchip,lan9693-serdes
> +              - microchip,lan9692-serdes

If there is going to be a new version, keep rather increasing/growing
alphanumerical order, but no need to resend just for this.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From daniel.machon at microchip.com  Tue Sep 10 01:59:52 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Tue, 10 Sep 2024 08:59:52 +0000
Subject: [PATCH v2 8/9] dt-bindings: phy: sparx5: document lan969x
In-Reply-To: <wd3gzn3lpmw64qor3xslif6rnp7htycfhu33pa2xpxvv6mrwqe@nv6pcwkstywe>
References: <20240909-sparx5-lan969x-serdes-driver-v2-0-d695bcb57b84@microchip.com>
 <20240909-sparx5-lan969x-serdes-driver-v2-8-d695bcb57b84@microchip.com>
 <wd3gzn3lpmw64qor3xslif6rnp7htycfhu33pa2xpxvv6mrwqe@nv6pcwkstywe>
Message-ID: <20240910085952.azwmrvuntyvuc3nb@DEN-DL-M70577>

> >  maintainers:
> >    - Steen Hegelund <steen.hegelund at microchip.com>
> > +  - Daniel Machon <daniel.machon at microchip.com>
> >
> >  description: |
> >    The Sparx5 SERDES interfaces share the same basic functionality, but
> > @@ -62,12 +63,26 @@ description: |
> >    * 10.3125 Gbps (10GBASE-R/10GBASE-KR/USXGMII)
> >    * 25.78125 Gbps (25GBASE-KR/25GBASE-CR/25GBASE-SR/25GBASE-LR/25GBASE-ER)
> >
> > +  lan969x has ten SERDES10G interfaces that share the same features, operating
> > +  modes and data rates as the equivalent Sparx5 SERDES10G interfaces.
> > +
> >  properties:
> >    $nodename:
> >      pattern: "^serdes@[0-9a-f]+$"
> >
> >    compatible:
> > -    const: microchip,sparx5-serdes
> > +    oneOf:
> > +      - enum:
> > +          - microchip,sparx5-serdes
> > +          - microchip,lan9691-serdes
> > +      - items:
> > +          - enum:
> > +              - microchip,lan9698-serdes
> > +              - microchip,lan9696-serdes
> > +              - microchip,lan9694-serdes
> > +              - microchip,lan9693-serdes
> > +              - microchip,lan9692-serdes
> 
> If there is going to be a new version, keep rather increasing/growing
> alphanumerical order, but no need to resend just for this.

Ack.

> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> Best regards,
> Krzysztof
>

Thanks for reviewing!

/Daniel


From s-vadapalli at ti.com  Tue Sep 10 02:17:14 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Tue, 10 Sep 2024 14:47:14 +0530
Subject: [PATCH] phy: ti: phy-j721e-wiz: fix usxgmii configuration
Message-ID: <20240910091714.1082191-1-s-vadapalli@ti.com>

Commit b64a85fb8f53 ("phy: ti: phy-j721e-wiz.c: Add usxgmii support in
wiz driver") added support for USXGMII mode. In doing so, P0_REFCLK_SEL
was set to "pcs_mac_clk_divx1_ln_0" (0x3) and P0_STANDARD_MODE was set to
LANE_MODE_GEN1, which results in a data rate of 5.15625 Gbps. However,
since the USXGMII mode can support up to 10.3125 Gbps data rate, the
aforementioned fields should be set to "pcs_mac_clk_divx0_ln_0" (0x2) and
LANE_MODE_GEN2 respectively. Fix the configuration accordingly to truly
support USXGMII up to 10G.

Fixes: b64a85fb8f53 ("phy: ti: phy-j721e-wiz.c: Add usxgmii support in wiz driver")
Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---

Hello,

This patch is based on commit
bc83b4d1f086 Merge tag 'bcachefs-2024-09-09' of git://evilpiepirate.org/bcachefs
of Mainline Linux.

Regards,
Siddharth.

 drivers/phy/ti/phy-j721e-wiz.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index 7f626c597025..aa45d77dd733 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -450,8 +450,8 @@ static int wiz_mode_select(struct wiz *wiz)
 		} else if (wiz->lane_phy_type[i] == PHY_TYPE_USXGMII) {
 			ret = regmap_field_write(wiz->p0_mac_src_sel[i], 0x3);
 			ret = regmap_field_write(wiz->p0_rxfclk_sel[i], 0x3);
-			ret = regmap_field_write(wiz->p0_refclk_sel[i], 0x3);
-			mode = LANE_MODE_GEN1;
+			ret = regmap_field_write(wiz->p0_refclk_sel[i], 0x2);
+			mode = LANE_MODE_GEN2;
 		} else {
 			continue;
 		}
-- 
2.40.1



From frieder at fris.de  Tue Sep 10 11:14:51 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Tue, 10 Sep 2024 20:14:51 +0200
Subject: [PATCH 0/2] Extending PLL LUT for i.MX8MP Samsung HDMI PHY
Message-ID: <20240910181544.214797-1-frieder@fris.de>

This small series depends on Adam's series here [1].

The parameters have been determined using the script here [2] and validated by
trying the modes on a Kontron BL i.MX8MP with a HDMI USB grabber.

[1] https://patchwork.kernel.org/project/linux-phy/cover/20240904233100.114611-1-aford173 at gmail.com/
[2] https://codeberg.org/fschrempf/samsung-hdmi-phy-pll-calculator/src/branch/main/pll.py

Frieder Schrempf (2):
  phy: freescale: fsl-samsung-hdmi: Add references for calculating LUT
    parameters to comment
  phy: freescale: fsl-samsung-hdmi: Add PLL LUT entries for some
    non-CEA-861 modes

 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

-- 
2.46.0



From frieder at fris.de  Tue Sep 10 11:14:52 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Tue, 10 Sep 2024 20:14:52 +0200
Subject: [PATCH 1/2] phy: freescale: fsl-samsung-hdmi: Add references for calculating LUT parameters to comment
In-Reply-To: <20240910181544.214797-1-frieder@fris.de>
References: <20240910181544.214797-1-frieder@fris.de>
Message-ID: <20240910181544.214797-2-frieder@fris.de>

Mention the Reference Manual and the scripts and tools available
to help calculating the PLL parameters for additional LUT entries.

Suggested-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
Signed-off-by: Frieder Schrempf <frieder at fris.de>
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 1203143bad7a..401178bfcdda 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -61,7 +61,13 @@ static struct phy_config calculated_phy_pll_cfg = {
 	.pll_div_regs = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
 };
 
-/* The lookup table contains values for which the fractional divder is used */
+/*
+ * The lookup table contains values for which the fractional divder is used.
+ * Please see the i.MX8MP Reference Manual and the resources at [1] for
+ * additional information on calculating values for table entries.
+ *
+ * [1] https://codeberg.org/fschrempf/samsung-hdmi-phy-pll-calculator
+ */
 static const struct phy_config phy_pll_cfg[] = {
 	{
 		.pixclk = 22250000,
-- 
2.46.0



From frieder at fris.de  Tue Sep 10 11:14:53 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Tue, 10 Sep 2024 20:14:53 +0200
Subject: [PATCH 2/2] phy: freescale: fsl-samsung-hdmi: Add PLL LUT entries for some non-CEA-861 modes
In-Reply-To: <20240910181544.214797-1-frieder@fris.de>
References: <20240910181544.214797-1-frieder@fris.de>
Message-ID: <20240910181544.214797-3-frieder@fris.de>

In order to support some pixel clock values not specified in CEA-861
and not achievable by the integer PLL algorithm, we add some new LUT
entries. This allows to use the fractional-N PLL to achieve pixel
clocks of 75 MHz, 88.75 MHz and 296.703 MHz with high accuracy.

Signed-off-by: Frieder Schrempf <frieder at fris.de>
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 401178bfcdda..6b36318630b2 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -156,6 +156,9 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 74250000,
 		.pll_div_regs = { 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
+	}, {
+		.pixclk = 75000000,
+		.pll_div_regs = { 0xD1, 0x3E, 0x30, 0x9F, 0x0E, 0x82, 0x41 },
 	}, {
 		.pixclk = 78500000,
 		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
@@ -165,6 +168,9 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 82500000,
 		.pll_div_regs = { 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
+	}, {
+		.pixclk = 88750000,
+		.pll_div_regs = { 0xD1, 0x6E, 0x50, 0x8B, 0x06, 0x81, 0x40 },
 	}, {
 		.pixclk = 89000000,
 		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
@@ -277,6 +283,9 @@ static const struct phy_config phy_pll_cfg[] = {
 		.pixclk = 277500000,
 		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
 	},  {
+		.pixclk = 296703000,
+		.pll_div_regs = { 0xd1, 0x7b, 0x18, 0xe0, 0x3d, 0x8a, 0x41 },
+	}, {
 		.pixclk = 297000000,
 		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
 	},
-- 
2.46.0



From Frank.li at nxp.com  Tue Sep 10 12:14:50 2024
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 10 Sep 2024 15:14:50 -0400
Subject: [PATCH v4 5/5] arm64: dts: imx95-19x19-evk: add typec nodes and
 enable usb3 node
In-Reply-To: <20240910070339.4150883-5-xu.yang_2@nxp.com>
References: <20240910070339.4150883-1-xu.yang_2@nxp.com>
 <20240910070339.4150883-5-xu.yang_2@nxp.com>
Message-ID: <ZuCaquGr+ocHmD6x@lizhi-Precision-Tower-5810>

On Tue, Sep 10, 2024 at 03:03:39PM +0800, Xu Yang wrote:
> This board has one Type-C port which has USB3 capability. This will
> add typec nodes and enable usb3 node.
>
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
>
> ---
> Changes in v2:
>  - no changes
> Changes in v3:
>  - no changes
> Changes in v4:
>  - no changes
> ---
>  .../boot/dts/freescale/imx95-19x19-evk.dts    | 81 +++++++++++++++++++
>  1 file changed, 81 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
> index d14a54ab4fd4..46a9cd3d4403 100644
> --- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
> @@ -5,6 +5,7 @@
>
>  /dts-v1/;
>
> +#include <dt-bindings/usb/pd.h>
>  #include "imx95.dtsi"
>
>  / {
> @@ -99,6 +100,48 @@ i2c7_pcal6524: i2c7-gpio at 22 {
>  		interrupt-parent = <&gpio5>;
>  		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
>  	};
> +
> +	ptn5110: tcpc at 50 {
> +		compatible = "nxp,ptn5110", "tcpci";
> +		reg = <0x50>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_typec>;
> +		interrupt-parent = <&gpio5>;
> +		interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
> +
> +		typec_con: connector {
> +			compatible = "usb-c-connector";
> +			label = "USB-C";
> +			power-role = "dual";
> +			data-role = "dual";
> +			try-power-role = "sink";
> +			source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
> +			sink-pdos = <PDO_FIXED(5000, 0, PDO_FIXED_USB_COMM)>;
> +			op-sink-microwatt = <0>;
> +			self-powered;
> +
> +			ports {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +				port at 0 {
> +					reg = <0>;
> +
> +					typec_con_hs: endpoint {
> +						remote-endpoint = <&usb3_data_hs>;
> +					};
> +				};
> +
> +				port at 1 {
> +					reg = <1>;
> +
> +					typec_con_ss: endpoint {
> +						remote-endpoint = <&usb3_data_ss>;
> +					};
> +				};
> +			};
> +		};
> +	};
>  };
>
>  &lpuart1 {
> @@ -128,6 +171,38 @@ &pcie1 {
>  	status = "okay";
>  };
>
> +&usb3 {
> +	status = "okay";
> +};
> +
> +&usb3_phy {
> +	status = "okay";
> +
> +	port {
> +		usb3_data_ss: endpoint {
> +			remote-endpoint = <&typec_con_ss>;
> +		};
> +	};
> +};

Please keep node name alphabet order
usb3_phy should be after usb3_dwc3.

Frank

> +
> +&usb3_dwc3 {
> +	dr_mode = "otg";
> +	hnp-disable;
> +	srp-disable;
> +	adp-disable;
> +	usb-role-switch;
> +	role-switch-default-mode = "peripheral";
> +	snps,dis-u1-entry-quirk;
> +	snps,dis-u2-entry-quirk;
> +	status = "okay";
> +
> +	port {
> +		usb3_data_hs: endpoint {
> +			remote-endpoint = <&typec_con_hs>;
> +		};
> +	};
> +};
> +
>  &usdhc1 {
>  	pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
>  	pinctrl-0 = <&pinctrl_usdhc1>;
> @@ -245,6 +320,12 @@ IMX95_PAD_SD2_RESET_B__GPIO3_IO_BIT7		0x31e
>  		>;
>  	};
>
> +	pinctrl_typec: typecgrp {
> +		fsl,pins = <
> +			IMX95_PAD_GPIO_IO34__GPIO5_IO_BIT14			0x31e
> +		>;
> +	};
> +
>  	pinctrl_usdhc2_gpio: usdhc2gpiogrp {
>  		fsl,pins = <
>  			IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0		0x31e
> --
> 2.34.1
>


From dominique.martinet at atmark-techno.com  Tue Sep 10 17:23:31 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Wed, 11 Sep 2024 09:23:31 +0900
Subject: [PATCH 0/2] Extending PLL LUT for i.MX8MP Samsung HDMI PHY
In-Reply-To: <20240910181544.214797-1-frieder@fris.de>
References: <20240910181544.214797-1-frieder@fris.de>
Message-ID: <ZuDjAwPxHeJTvXAp@atmark-techno.com>

Frieder Schrempf wrote on Tue, Sep 10, 2024 at 08:14:51PM +0200:
> [2] https://codeberg.org/fschrempf/samsung-hdmi-phy-pll-calculator/src/branch/main/pll.py

Great work! Thanks!

I was curious about the existing table entries, recomputing existing
values doesn't yield the same values. For example, the first entry is
{
        .pixclk = 22250000,
        .pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
}
but computing it yields
{
    .pixclk = 22250000,
    .pll_div_regs = { 0xd1, 0x4a, 0xf0, 0xef, 0x10, 0x81, 0x40 },
}

I assume there just are multiple ways to generate the same frequencies,
which is fine in itself, but it'd be great to be able to "back-compute"
the entries as a sanity check.

I've played a bit with your script and spent more time on it than I'd
like to admit, but something like this seems to do the trick, plugging
in the regs from the kernel:

---
pll = FractionalNPLL(freq_ref)

regs = [0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40]
# assume fractional
if not regs[0] & 0xD0:
    print("reg[0] missing 0xD0")
    sys.exit(1)
pll.freq_frac = True
pll.params["p"] = regs[0] & 0x2f
pll.params["m"] = regs[1]
pll.params["s"] = (regs[2] >> 4) + 1
pll.params["n2"] = ((regs[2] >> 3) & 0x1) + 1
pll.params["n"] = (regs[2] & 0x7) + 4
pll.params["lc"] = regs[3] & 0x7f
if regs[4] & 0x80:
    pll.params["lc"] = - pll.params["lc"]
pll.params["k"] = regs[4] & 0x7f
pll.params["lc_s"] = regs[5] & 0x7f
pll.params["k_s"] = regs[6] & 0xbf


f_vco = int(pll.params["m"] * pll.f_ref / pll.params["p"])
if f_vco < 750000000 or f_vco > 3000000000:
    print(f"f_vco {f_vco} out of range")
    sys.exit(1)
f_calc = f_vco / pll.params["s"] / 5
pll.freq_int = round(f_calc)
print(f_calc)
sdc = pll.calc_sdc(pll.params)
frac = pll.calc_f_frac(sdc, pll.params)
print(frac)
freq = pll.freq_int + frac
print(freq)
pll.print_reg_driver_data(freq)
exit(0);
---
yields this back (comments added manually)
---
22500000.0 (integer part)
-250000.0 (fractional part)
22250000.0 (summed)

PHY Driver Table Entry:
{
    .pixclk = 22250000.0,
    .pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x81, 0x40 },
}
---

so if I find some time I'll whip some loop to check all other values...




That aside, I see no problem with this, just one meta-comment about
adding a link to the script in an external repo: I see some other
drivers have python scripts in their trees e.g.
drivers/comedi/drivers/ni_routing/tools/*py
drivers/gpu/drm/ci/xfails/update-xfails.py
drivers/gpu/drm/msm/registers/gen_header.py

would it make sense to commit the script here instead of linking to a
repo that might be lost in the future?

I'm not quite sure what policy the linux repo has here, so leaving that
as an open question.
-- 
Dominique


From aford173 at gmail.com  Tue Sep 10 18:16:04 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 10 Sep 2024 20:16:04 -0500
Subject: [PATCH 0/2] Extending PLL LUT for i.MX8MP Samsung HDMI PHY
In-Reply-To: <ZuDjAwPxHeJTvXAp@atmark-techno.com>
References: <20240910181544.214797-1-frieder@fris.de> <ZuDjAwPxHeJTvXAp@atmark-techno.com>
Message-ID: <CAHCN7xJD8jsqyZX1JkWxrA84XkZ8YYN19hXW6KVe+jkOFugqrw@mail.gmail.com>

On Tue, Sep 10, 2024 at 7:23?PM Dominique Martinet
<dominique.martinet at atmark-techno.com> wrote:
>
> Frieder Schrempf wrote on Tue, Sep 10, 2024 at 08:14:51PM +0200:
> > [2] https://codeberg.org/fschrempf/samsung-hdmi-phy-pll-calculator/src/branch/main/pll.py
>
> Great work! Thanks!
>
> I was curious about the existing table entries, recomputing existing
> values doesn't yield the same values. For example, the first entry is
> {
>         .pixclk = 22250000,
>         .pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
> }
> but computing it yields
> {
>     .pixclk = 22250000,
>     .pll_div_regs = { 0xd1, 0x4a, 0xf0, 0xef, 0x10, 0x81, 0x40 },
> }
>
> I assume there just are multiple ways to generate the same frequencies,
> which is fine in itself, but it'd be great to be able to "back-compute"
> the entries as a sanity check.
>
> I've played a bit with your script and spent more time on it than I'd
> like to admit, but something like this seems to do the trick, plugging
> in the regs from the kernel:
>
> ---
> pll = FractionalNPLL(freq_ref)
>
> regs = [0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40]
> # assume fractional
> if not regs[0] & 0xD0:
>     print("reg[0] missing 0xD0")
>     sys.exit(1)
> pll.freq_frac = True
> pll.params["p"] = regs[0] & 0x2f
> pll.params["m"] = regs[1]
> pll.params["s"] = (regs[2] >> 4) + 1
> pll.params["n2"] = ((regs[2] >> 3) & 0x1) + 1
> pll.params["n"] = (regs[2] & 0x7) + 4
> pll.params["lc"] = regs[3] & 0x7f
> if regs[4] & 0x80:
>     pll.params["lc"] = - pll.params["lc"]
> pll.params["k"] = regs[4] & 0x7f
> pll.params["lc_s"] = regs[5] & 0x7f
> pll.params["k_s"] = regs[6] & 0xbf
>
>
> f_vco = int(pll.params["m"] * pll.f_ref / pll.params["p"])
> if f_vco < 750000000 or f_vco > 3000000000:
>     print(f"f_vco {f_vco} out of range")
>     sys.exit(1)
> f_calc = f_vco / pll.params["s"] / 5
> pll.freq_int = round(f_calc)
> print(f_calc)
> sdc = pll.calc_sdc(pll.params)
> frac = pll.calc_f_frac(sdc, pll.params)
> print(frac)
> freq = pll.freq_int + frac
> print(freq)
> pll.print_reg_driver_data(freq)
> exit(0);
> ---
> yields this back (comments added manually)
> ---
> 22500000.0 (integer part)
> -250000.0 (fractional part)
> 22250000.0 (summed)
>
> PHY Driver Table Entry:
> {
>     .pixclk = 22250000.0,
>     .pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x81, 0x40 },
> }
> ---
>
> so if I find some time I'll whip some loop to check all other values...
>
>
>
>
> That aside, I see no problem with this, just one meta-comment about
> adding a link to the script in an external repo: I see some other
> drivers have python scripts in their trees e.g.
> drivers/comedi/drivers/ni_routing/tools/*py
> drivers/gpu/drm/ci/xfails/update-xfails.py
> drivers/gpu/drm/msm/registers/gen_header.py
>
> would it make sense to commit the script here instead of linking to a
> repo that might be lost in the future?
>
> I'm not quite sure what policy the linux repo has here, so leaving that
> as an open question.

Is there a reason this couldn't be coded in C and used to expand my
integer calculator series?  With that, we could drop the lookup table.

adam
> --
> Dominique


From dominique.martinet at atmark-techno.com  Tue Sep 10 18:27:33 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Wed, 11 Sep 2024 10:27:33 +0900
Subject: [PATCH 0/2] Extending PLL LUT for i.MX8MP Samsung HDMI PHY
In-Reply-To: <CAHCN7xJD8jsqyZX1JkWxrA84XkZ8YYN19hXW6KVe+jkOFugqrw@mail.gmail.com>
References: <20240910181544.214797-1-frieder@fris.de>
 <ZuDjAwPxHeJTvXAp@atmark-techno.com>
 <CAHCN7xJD8jsqyZX1JkWxrA84XkZ8YYN19hXW6KVe+jkOFugqrw@mail.gmail.com>
Message-ID: <ZuDyBQ1I2vcGzAqX@atmark-techno.com>

Adam Ford wrote on Tue, Sep 10, 2024 at 08:16:04PM -0500:
> > That aside, I see no problem with this, just one meta-comment about
> > adding a link to the script in an external repo: I see some other
> > drivers have python scripts in their trees e.g.
> > drivers/comedi/drivers/ni_routing/tools/*py
> > drivers/gpu/drm/ci/xfails/update-xfails.py
> > drivers/gpu/drm/msm/registers/gen_header.py
> >
> > would it make sense to commit the script here instead of linking to a
> > repo that might be lost in the future?
> >
> > I'm not quite sure what policy the linux repo has here, so leaving that
> > as an open question.
> 
> Is there a reason this couldn't be coded in C and used to expand my
> integer calculator series?  With that, we could drop the lookup table.

Quoting a previous mail from Frieder:
> I will clean things up a bit and then share what I have. I hope that this
> allows anyone to calculate parameters for their non-standard displays if
> required.
> 
> If someone feels extra motivated they could try to calculate the fractional
> parameters at runtime. However I'm not sure that this is feasible. The
> numerical computation of a large number of parameters is quite heavy and it's
> probably not easy to strip the algorithm down to something that can be run on
> the target without too much overhead.

Trying a random frequency with the algorithm he has implemented it
easily takes 10 seconds to run on my imx8mp board, so even if we asssume
C is 3-4 times faster I think the current algorithm is too slow for
runtime and it makes more sense to extended the LUT to me (as long as
the values can be & are checked at least once, which we now can)

The current algorithm brute-forces its way through so there could be a
better way of computing the fractional part of the divider, but I'm not
sure it's worth the effort at this point; I guess it's a good
intellectual challenge though so someone might do it in the future.

-- 
Dominique


From aford173 at gmail.com  Tue Sep 10 18:28:06 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 10 Sep 2024 20:28:06 -0500
Subject: [PATCH V7 0/5] phy: freescale: fsl-samsung-hdmi: Expand phy clock options
Message-ID: <20240911012838.944630-1-aford173@gmail.com>

Currently, there is a look-up-table to describe all the clock options the HDMI PHY
can use.  Some of these entries in the LUT are using a fractional divider which does
not have a well documented algorithm for determinging values, but the the integer
divider can use an algorithm to calculate the integer divder values dynamically
beyond those listed in the LUT and also duplicates some of the entries.

The first two patches do not do anything functionally other than simplify
some of the register accesses and de-duplicates some of the register look-ups.

The third patch adds support for the integer divider and uses it whenever the
clock request is an exact match.  Otherwise, it will use the LUT as before.
The rouding is still based on the LUT if the integer clock isn't an exact match.

The forth patch updates thes set_rate and round_rate functions to use either
the fractional clock LUT or the the integer divder mechanism to determine
which ever clock rate might be closest match.

The last patch removes the integer divider entries from the LUT since by then
it'll be comparing both the integer divider calculator and the closest value
in the LUT.

In my testing with a AOC 4K monitor, I was able to add 4 entries in my modetest
table.  I do not have an HDMI analyzer, so I just used my monitor to determine
if this series worked.


Adam Ford (5):
  phy: freescale: fsl-samsung-hdmi: Replace register defines with macro
  phy: freescale: fsl-samsung-hdmi: Simplify REG21_PMS_S_MASK lookup
  xphy: freescale: fsl-samsung-hdmi: Support dynamic integer
  phy: freescale: fsl-samsung-hdmi: Use closest divider
  phy: freescale: fsl-samsung-hdmi: Remove unnecessary LUT entries

 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 596 ++++++++++---------
 1 file changed, 318 insertions(+), 278 deletions(-)

-- 
2.43.0



From aford173 at gmail.com  Tue Sep 10 18:28:07 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 10 Sep 2024 20:28:07 -0500
Subject: [PATCH V7 1/5] phy: freescale: fsl-samsung-hdmi: Replace register defines with macro
In-Reply-To: <20240911012838.944630-1-aford173@gmail.com>
References: <20240911012838.944630-1-aford173@gmail.com>
Message-ID: <20240911012838.944630-2-aford173@gmail.com>

There are 47 registers defined as PHY_REG_xx were xx goes from 00 to
47.  Simplify this by replacing them all with a macro which is passed
the register number to return the proper register offset.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 133 ++++++-------------
 1 file changed, 43 insertions(+), 90 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 9048cdc760c2..acea7008aefc 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -14,76 +14,29 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 
-#define PHY_REG_00		0x00
-#define PHY_REG_01		0x04
-#define PHY_REG_02		0x08
-#define PHY_REG_08		0x20
-#define PHY_REG_09		0x24
-#define PHY_REG_10		0x28
-#define PHY_REG_11		0x2c
-
-#define PHY_REG_12		0x30
-#define  REG12_CK_DIV_MASK	GENMASK(5, 4)
-
-#define PHY_REG_13		0x34
-#define  REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
-
-#define PHY_REG_14		0x38
-#define  REG14_TOL_MASK		GENMASK(7, 4)
-#define  REG14_RP_CODE_MASK	GENMASK(3, 1)
-#define  REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
-
-#define PHY_REG_15		0x3c
-#define PHY_REG_16		0x40
-#define PHY_REG_17		0x44
-#define PHY_REG_18		0x48
-#define PHY_REG_19		0x4c
-#define PHY_REG_20		0x50
-
-#define PHY_REG_21		0x54
-#define  REG21_SEL_TX_CK_INV	BIT(7)
-#define  REG21_PMS_S_MASK	GENMASK(3, 0)
-
-#define PHY_REG_22		0x58
-#define PHY_REG_23		0x5c
-#define PHY_REG_24		0x60
-#define PHY_REG_25		0x64
-#define PHY_REG_26		0x68
-#define PHY_REG_27		0x6c
-#define PHY_REG_28		0x70
-#define PHY_REG_29		0x74
-#define PHY_REG_30		0x78
-#define PHY_REG_31		0x7c
-#define PHY_REG_32		0x80
+#define PHY_REG(reg)		(reg * 4)
 
+#define REG12_CK_DIV_MASK	GENMASK(5, 4)
+
+#define REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
+
+#define REG14_TOL_MASK		GENMASK(7, 4)
+#define REG14_RP_CODE_MASK	GENMASK(3, 1)
+#define REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
+
+#define REG21_SEL_TX_CK_INV	BIT(7)
+#define REG21_PMS_S_MASK	GENMASK(3, 0)
 /*
  * REG33 does not match the ref manual. According to Sandor Yu from NXP,
  * "There is a doc issue on the i.MX8MP latest RM"
  * REG33 is being used per guidance from Sandor
  */
+#define REG33_MODE_SET_DONE	BIT(7)
+#define REG33_FIX_DA		BIT(1)
 
-#define PHY_REG_33		0x84
-#define  REG33_MODE_SET_DONE	BIT(7)
-#define  REG33_FIX_DA		BIT(1)
-
-#define PHY_REG_34		0x88
-#define  REG34_PHY_READY	BIT(7)
-#define  REG34_PLL_LOCK		BIT(6)
-#define  REG34_PHY_CLK_READY	BIT(5)
-
-#define PHY_REG_35		0x8c
-#define PHY_REG_36		0x90
-#define PHY_REG_37		0x94
-#define PHY_REG_38		0x98
-#define PHY_REG_39		0x9c
-#define PHY_REG_40		0xa0
-#define PHY_REG_41		0xa4
-#define PHY_REG_42		0xa8
-#define PHY_REG_43		0xac
-#define PHY_REG_44		0xb0
-#define PHY_REG_45		0xb4
-#define PHY_REG_46		0xb8
-#define PHY_REG_47		0xbc
+#define REG34_PHY_READY	BIT(7)
+#define REG34_PLL_LOCK		BIT(6)
+#define REG34_PHY_CLK_READY	BIT(5)
 
 #define PHY_PLL_DIV_REGS_NUM 6
 
@@ -369,29 +322,29 @@ struct reg_settings {
 };
 
 static const struct reg_settings common_phy_cfg[] = {
-	{ PHY_REG_00, 0x00 }, { PHY_REG_01, 0xd1 },
-	{ PHY_REG_08, 0x4f }, { PHY_REG_09, 0x30 },
-	{ PHY_REG_10, 0x33 }, { PHY_REG_11, 0x65 },
+	{ PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
+	{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
+	{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
 	/* REG12 pixclk specific */
 	/* REG13 pixclk specific */
 	/* REG14 pixclk specific */
-	{ PHY_REG_15, 0x80 }, { PHY_REG_16, 0x6c },
-	{ PHY_REG_17, 0xf2 }, { PHY_REG_18, 0x67 },
-	{ PHY_REG_19, 0x00 }, { PHY_REG_20, 0x10 },
+	{ PHY_REG(15), 0x80 }, { PHY_REG(16), 0x6c },
+	{ PHY_REG(17), 0xf2 }, { PHY_REG(18), 0x67 },
+	{ PHY_REG(19), 0x00 }, { PHY_REG(20), 0x10 },
 	/* REG21 pixclk specific */
-	{ PHY_REG_22, 0x30 }, { PHY_REG_23, 0x32 },
-	{ PHY_REG_24, 0x60 }, { PHY_REG_25, 0x8f },
-	{ PHY_REG_26, 0x00 }, { PHY_REG_27, 0x00 },
-	{ PHY_REG_28, 0x08 }, { PHY_REG_29, 0x00 },
-	{ PHY_REG_30, 0x00 }, { PHY_REG_31, 0x00 },
-	{ PHY_REG_32, 0x00 }, { PHY_REG_33, 0x80 },
-	{ PHY_REG_34, 0x00 }, { PHY_REG_35, 0x00 },
-	{ PHY_REG_36, 0x00 }, { PHY_REG_37, 0x00 },
-	{ PHY_REG_38, 0x00 }, { PHY_REG_39, 0x00 },
-	{ PHY_REG_40, 0x00 }, { PHY_REG_41, 0xe0 },
-	{ PHY_REG_42, 0x83 }, { PHY_REG_43, 0x0f },
-	{ PHY_REG_44, 0x3E }, { PHY_REG_45, 0xf8 },
-	{ PHY_REG_46, 0x00 }, { PHY_REG_47, 0x00 }
+	{ PHY_REG(22), 0x30 }, { PHY_REG(23), 0x32 },
+	{ PHY_REG(24), 0x60 }, { PHY_REG(25), 0x8f },
+	{ PHY_REG(26), 0x00 }, { PHY_REG(27), 0x00 },
+	{ PHY_REG(28), 0x08 }, { PHY_REG(29), 0x00 },
+	{ PHY_REG(30), 0x00 }, { PHY_REG(31), 0x00 },
+	{ PHY_REG(32), 0x00 }, { PHY_REG(33), 0x80 },
+	{ PHY_REG(34), 0x00 }, { PHY_REG(35), 0x00 },
+	{ PHY_REG(36), 0x00 }, { PHY_REG(37), 0x00 },
+	{ PHY_REG(38), 0x00 }, { PHY_REG(39), 0x00 },
+	{ PHY_REG(40), 0x00 }, { PHY_REG(41), 0xe0 },
+	{ PHY_REG(42), 0x83 }, { PHY_REG(43), 0x0f },
+	{ PHY_REG(44), 0x3E }, { PHY_REG(45), 0xf8 },
+	{ PHY_REG(46), 0x00 }, { PHY_REG(47), 0x00 }
 };
 
 struct fsl_samsung_hdmi_phy {
@@ -442,7 +395,7 @@ fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
 	}
 
 	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
-	       phy->regs + PHY_REG_21);
+	       phy->regs + PHY_REG(21));
 }
 
 static void
@@ -469,7 +422,7 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 		break;
 	}
 
-	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG_12);
+	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG(12));
 
 	/*
 	 * Calculation for the frequency lock detector target code (fld_tg_code)
@@ -489,11 +442,11 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 
 	/* FLD_TOL and FLD_RP_CODE taken from downstream driver */
 	writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),
-	       phy->regs + PHY_REG_13);
+	       phy->regs + PHY_REG(13));
 	writeb(FIELD_PREP(REG14_TOL_MASK, 2) |
 	       FIELD_PREP(REG14_RP_CODE_MASK, 2) |
 	       FIELD_PREP(REG14_TG_CODE_HIGH_MASK, fld_tg_code >> 8),
-	       phy->regs + PHY_REG_14);
+	       phy->regs + PHY_REG(14));
 }
 
 static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
@@ -503,7 +456,7 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	u8 val;
 
 	/* HDMI PHY init */
-	writeb(REG33_FIX_DA, phy->regs + PHY_REG_33);
+	writeb(REG33_FIX_DA, phy->regs + PHY_REG(33));
 
 	/* common PHY registers */
 	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
@@ -511,14 +464,14 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 
 	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
-		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG_02 + i * 4);
+		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
 
 	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
-	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG_33);
+	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));
 
-	ret = readb_poll_timeout(phy->regs + PHY_REG_34, val,
+	ret = readb_poll_timeout(phy->regs + PHY_REG(34), val,
 				 val & REG34_PLL_LOCK, 50, 20000);
 	if (ret)
 		dev_err(phy->dev, "PLL failed to lock\n");
-- 
2.43.0



From aford173 at gmail.com  Tue Sep 10 18:28:08 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 10 Sep 2024 20:28:08 -0500
Subject: [PATCH V7 2/5] phy: freescale: fsl-samsung-hdmi: Simplify REG21_PMS_S_MASK lookup
In-Reply-To: <20240911012838.944630-1-aford173@gmail.com>
References: <20240911012838.944630-1-aford173@gmail.com>
Message-ID: <20240911012838.944630-3-aford173@gmail.com>

The value of 'S' is writen to two places, PHY_REG3[7:4] and
PHY_REG21[3:0].  There is a lookup table which contains
the value of PHY_REG3.  Rather than using a switch statement
based on the pixel clock to search for the value of 'S' again,
just shift the contents of PHY_REG3[7:4] >> 4 and place the value
in PHY_REG21[3:0].  Doing this can eliminate an entire function.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 39 ++------------------
 1 file changed, 4 insertions(+), 35 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index acea7008aefc..4f6874226f9a 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -364,40 +364,6 @@ to_fsl_samsung_hdmi_phy(struct clk_hw *hw)
 	return container_of(hw, struct fsl_samsung_hdmi_phy, hw);
 }
 
-static void
-fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
-				      const struct phy_config *cfg)
-{
-	u8 div = 0x1;
-
-	switch (cfg->pixclk) {
-	case  22250000 ...  33750000:
-		div = 0xf;
-		break;
-	case  35000000 ...  40000000:
-		div = 0xb;
-		break;
-	case  43200000 ...  47500000:
-		div = 0x9;
-		break;
-	case  50349650 ...  63500000:
-		div = 0x7;
-		break;
-	case  67500000 ...  90000000:
-		div = 0x5;
-		break;
-	case  94000000 ... 148500000:
-		div = 0x3;
-		break;
-	case 154000000 ... 297000000:
-		div = 0x1;
-		break;
-	}
-
-	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
-	       phy->regs + PHY_REG(21));
-}
-
 static void
 fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 					    const struct phy_config *cfg)
@@ -466,7 +432,10 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
 		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
 
-	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
+	/* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
+	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
+	       cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
+
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
 	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));
-- 
2.43.0



From aford173 at gmail.com  Tue Sep 10 18:28:09 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 10 Sep 2024 20:28:09 -0500
Subject: [PATCH V7 3/5] xphy: freescale: fsl-samsung-hdmi: Support dynamic integer
In-Reply-To: <20240911012838.944630-1-aford173@gmail.com>
References: <20240911012838.944630-1-aford173@gmail.com>
Message-ID: <20240911012838.944630-4-aford173@gmail.com>

There is currently a look-up table for a variety of resolutions.
Since the phy has the ability to dynamically calculate the values
necessary to use the intger divider which should allow more
resolutions without having to update the look-up-table.

If the lookup table cannot find an exact match, fall back to the
dynamic calculator of the integer divider.

Previously, the value of P was hard-coded to 1, this required an
update to the phy_pll_cfg table to add in the extra value into the
table, so if the value of P is calculated to be something else
by the PMS calculator, the calculated_phy_pll_cfg structure
can be used instead without having to keep track of which method
was used.

Signed-off-by: Adam Ford <aford173 at gmail.com>
---
V7:  Refactored much of the code to create smaller helper functions
     to eliminate redundant code and improve code flow and comment
     readability.   Any t-b and s-o-b tags removed due to the
     extent of the changes.

V6:  Fix comment typos and remove an unnecesary extra calculation
     by using the cached value.
V5:  No Change
V4:  No Change
V3:  Change size of pll_div_regs to include PHY_REG01 (P)
     Create calculated_phy_pll_cfg to containe the values
     Eliminate the PMS calculation from fsl_samsung_hdmi_phy_configure
     Make the LUT primary and fall back to integer calculator in
     phy_clk_round_rate.
     Check the range right away to ensure it's reaonsable rather than
     trying to find a clock only to learn it's outside the range.
     Overall added notes and comments where stuff may not be intuitive.

V2:  Update phy_clk_round_rate and phy_clk_set_rate to both support
     the integer clock PMS calculator.
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 371 +++++++++++++------
 1 file changed, 265 insertions(+), 106 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 4f6874226f9a..49317a96f767 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -16,6 +16,8 @@
 
 #define PHY_REG(reg)		(reg * 4)
 
+#define REG01_PMS_P_MASK	GENMASK(3, 0)
+#define REG03_PMS_S_MASK	GENMASK(7, 4)
 #define REG12_CK_DIV_MASK	GENMASK(5, 4)
 
 #define REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
@@ -38,281 +40,296 @@
 #define REG34_PLL_LOCK		BIT(6)
 #define REG34_PHY_CLK_READY	BIT(5)
 
-#define PHY_PLL_DIV_REGS_NUM 6
+#ifndef MHZ
+#define MHZ	(1000UL * 1000UL)
+#endif
+
+#define PHY_PLL_DIV_REGS_NUM 7
 
 struct phy_config {
 	u32	pixclk;
 	u8	pll_div_regs[PHY_PLL_DIV_REGS_NUM];
 };
 
+/*
+ * The calculated_phy_pll_cfg only handles integer divider for PMS,
+ * meaning the last four entries will be fixed, but the first three will
+ * be calculated by the PMS calculator.
+ */
+static struct phy_config calculated_phy_pll_cfg = {
+	.pixclk = 0,
+	.pll_div_regs = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
+};
+
+/* The lookup table contains values for which the fractional divder is used */
 static const struct phy_config phy_pll_cfg[] = {
 	{
 		.pixclk = 22250000,
-		.pll_div_regs = { 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 23750000,
-		.pll_div_regs = { 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
 	}, {
 		.pixclk = 24000000,
-		.pll_div_regs = { 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 24024000,
-		.pll_div_regs = { 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
 	}, {
 		.pixclk = 25175000,
-		.pll_div_regs = { 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
 	}, {
 		.pixclk = 25200000,
-		.pll_div_regs = { 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 26750000,
-		.pll_div_regs = { 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 27000000,
-		.pll_div_regs = { 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 27027000,
-		.pll_div_regs = { 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 29500000,
-		.pll_div_regs = { 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 30750000,
-		.pll_div_regs = { 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 30888000,
-		.pll_div_regs = { 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
 	}, {
 		.pixclk = 33750000,
-		.pll_div_regs = { 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 35000000,
-		.pll_div_regs = { 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 36000000,
-		.pll_div_regs = { 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 36036000,
-		.pll_div_regs = { 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 40000000,
-		.pll_div_regs = { 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43200000,
-		.pll_div_regs = { 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43243200,
-		.pll_div_regs = { 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 44500000,
-		.pll_div_regs = { 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
 	}, {
 		.pixclk = 47000000,
-		.pll_div_regs = { 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
 	}, {
 		.pixclk = 47500000,
-		.pll_div_regs = { 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
 	}, {
 		.pixclk = 50349650,
-		.pll_div_regs = { 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
 	}, {
 		.pixclk = 50400000,
-		.pll_div_regs = { 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 53250000,
-		.pll_div_regs = { 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 53500000,
-		.pll_div_regs = { 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 54000000,
-		.pll_div_regs = { 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 54054000,
-		.pll_div_regs = { 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 59000000,
-		.pll_div_regs = { 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 59340659,
-		.pll_div_regs = { 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
 	}, {
 		.pixclk = 59400000,
-		.pll_div_regs = { 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 61500000,
-		.pll_div_regs = { 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 63500000,
-		.pll_div_regs = { 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 67500000,
-		.pll_div_regs = { 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
 	}, {
 		.pixclk = 70000000,
-		.pll_div_regs = { 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 72000000,
-		.pll_div_regs = { 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 72072000,
-		.pll_div_regs = { 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 74176000,
-		.pll_div_regs = { 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
 	}, {
 		.pixclk = 74250000,
-		.pll_div_regs = { 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
 	}, {
 		.pixclk = 78500000,
-		.pll_div_regs = { 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 80000000,
-		.pll_div_regs = { 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 82000000,
-		.pll_div_regs = { 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 82500000,
-		.pll_div_regs = { 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
 	}, {
 		.pixclk = 89000000,
-		.pll_div_regs = { 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
 	}, {
 		.pixclk = 90000000,
-		.pll_div_regs = { 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 94000000,
-		.pll_div_regs = { 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
 	}, {
 		.pixclk = 95000000,
-		.pll_div_regs = { 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
 	}, {
 		.pixclk = 98901099,
-		.pll_div_regs = { 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
 	}, {
 		.pixclk = 99000000,
-		.pll_div_regs = { 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
 	}, {
 		.pixclk = 100699300,
-		.pll_div_regs = { 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
 	}, {
 		.pixclk = 100800000,
-		.pll_div_regs = { 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 102500000,
-		.pll_div_regs = { 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
 		.pixclk = 104750000,
-		.pll_div_regs = { 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
 	}, {
 		.pixclk = 106500000,
-		.pll_div_regs = { 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 107000000,
-		.pll_div_regs = { 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 108000000,
-		.pll_div_regs = { 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 108108000,
-		.pll_div_regs = { 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 118000000,
-		.pll_div_regs = { 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 118800000,
-		.pll_div_regs = { 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 123000000,
-		.pll_div_regs = { 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 127000000,
-		.pll_div_regs = { 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 135000000,
-		.pll_div_regs = { 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 135580000,
-		.pll_div_regs = { 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
+		.pll_div_regs = { 0xd1, 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
 	}, {
 		.pixclk = 137520000,
-		.pll_div_regs = { 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
+		.pll_div_regs = { 0xd1, 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
 	}, {
 		.pixclk = 138750000,
-		.pll_div_regs = { 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
+		.pll_div_regs = { 0xd1, 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
 	}, {
 		.pixclk = 140000000,
-		.pll_div_regs = { 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
 	}, {
 		.pixclk = 144000000,
-		.pll_div_regs = { 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 148352000,
-		.pll_div_regs = { 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
 	}, {
 		.pixclk = 148500000,
-		.pll_div_regs = { 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
 	}, {
 		.pixclk = 154000000,
-		.pll_div_regs = { 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
+		.pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
 	}, {
 		.pixclk = 157000000,
-		.pll_div_regs = { 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
 	}, {
 		.pixclk = 160000000,
-		.pll_div_regs = { 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
 	}, {
 		.pixclk = 162000000,
-		.pll_div_regs = { 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
+		.pll_div_regs = { 0xd1, 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
 	}, {
 		.pixclk = 164000000,
-		.pll_div_regs = { 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
 	}, {
 		.pixclk = 165000000,
-		.pll_div_regs = { 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
 	}, {
 		.pixclk = 180000000,
-		.pll_div_regs = { 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 185625000,
-		.pll_div_regs = { 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
 	}, {
 		.pixclk = 188000000,
-		.pll_div_regs = { 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
 	}, {
 		.pixclk = 198000000,
-		.pll_div_regs = { 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
 	}, {
 		.pixclk = 205000000,
-		.pll_div_regs = { 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
 		.pixclk = 209500000,
-		.pll_div_regs = { 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
 	}, {
 		.pixclk = 213000000,
-		.pll_div_regs = { 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 216000000,
-		.pll_div_regs = { 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 216216000,
-		.pll_div_regs = { 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 237600000,
-		.pll_div_regs = { 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 254000000,
-		.pll_div_regs = { 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 277500000,
-		.pll_div_regs = { 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
+		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
 	}, {
 		.pixclk = 288000000,
-		.pll_div_regs = { 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 297000000,
-		.pll_div_regs = { 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
 	},
 };
 
@@ -322,7 +339,8 @@ struct reg_settings {
 };
 
 static const struct reg_settings common_phy_cfg[] = {
-	{ PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
+	{ PHY_REG(0), 0x00 },
+	/* PHY_REG(1-7) pix clk specific */
 	{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
 	{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
 	/* REG12 pixclk specific */
@@ -415,6 +433,83 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 	       phy->regs + PHY_REG(14));
 }
 
+static unsigned long fsl_samsung_hdmi_phy_find_pms(unsigned long fout, u8 *p, u16 *m, u8 *s)
+{
+	unsigned long best_freq = 0;
+	u32 min_delta = 0xffffffff;
+	u8 _p, best_p;
+	u16 _m, best_m;
+	u8 _s, best_s;
+
+	/*
+	 * Figure 13-78 of the reference manual states the PLL should be TMDS x 5
+	 * while the TMDS_CLKO should be the PLL / 5.  So to calculate the PLL,
+	 * take the pix clock x 5, then return the value of the PLL / 5.
+	 */
+	fout *= 5;
+
+	/* The ref manual states the values of 'P' range from 1 to 11 */
+	for (_p = 1; _p <= 11; ++_p) {
+		for (_s = 1; _s <= 16; ++_s) {
+			u64 tmp;
+			u32 delta;
+
+			/* s must be one or even */
+			if (_s > 1 && (_s & 0x01) == 1)
+				_s++;
+
+			/* _s cannot be 14 per the TRM */
+			if (_s == 14)
+				continue;
+
+			/*
+			 * TODO: Ref Manual doesn't state the range of _m
+			 * so this should be further refined if possible.
+			 * This range was set based on the original values
+			 * in the lookup table
+			 */
+			tmp = (u64)fout * (_p * _s);
+			do_div(tmp, 24 * MHZ);
+			_m = tmp;
+			if (_m < 0x30 || _m > 0x7b)
+				continue;
+
+			/*
+			 * Rev 2 of the Ref Manual states the
+			 * VCO can range between 750MHz and
+			 * 3GHz.  The VCO is assumed to be
+			 * is assumed to be (M * f_ref) / P,
+			 * where f_ref is 24MHz.
+			 */
+			tmp = (u64)_m * 24 * MHZ;
+			do_div(tmp, _p);
+			if (tmp < 750 * MHZ ||
+			    tmp > 3000 * MHZ)
+				continue;
+
+			/* Final frequency after post-divider */
+			do_div(tmp, _s);
+
+			delta = abs(fout - tmp);
+			if (delta < min_delta) {
+				best_p = _p;
+				best_s = _s;
+				best_m = _m;
+				min_delta = delta;
+				best_freq = tmp;
+			}
+		}
+	}
+
+	if (best_freq) {
+		*p = best_p;
+		*m = best_m;
+		*s = best_s;
+	}
+
+	return best_freq / 5;
+}
+
 static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 					  const struct phy_config *cfg)
 {
@@ -428,13 +523,13 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
 		writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
 
-	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
+	/* set individual PLL registers PHY_REG1 ... PHY_REG7 */
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
-		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
+		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(1) + i * 4);
 
-	/* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
+	/* High nibble of PHY_REG3 and low nibble of PHY_REG21 both contain 'S' */
 	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
-	       cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
+	       cfg->pll_div_regs[2] >> 4), phy->regs + PHY_REG(21));
 
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
@@ -459,33 +554,97 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
 	return phy->cur_cfg->pixclk;
 }
 
-static long phy_clk_round_rate(struct clk_hw *hw,
-			       unsigned long rate, unsigned long *parent_rate)
+/* Helper function to lookup the available fractional-divider rate */
+static const struct phy_config *fsl_samsung_hdmi_phy_lookup_rate(unsigned long rate)
 {
 	int i;
 
+	/* Search the lookup table */
 	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
 		if (phy_pll_cfg[i].pixclk <= rate)
-			return phy_pll_cfg[i].pixclk;
+			break;
 
-	return -EINVAL;
+	return &phy_pll_cfg[i];
+}
+
+static void fsl_samsung_hdmi_calculate_phy(struct phy_config *cal_phy, unsigned long rate,
+				    u8 p, u16 m, u8 s)
+{
+	cal_phy->pixclk = rate;
+	cal_phy->pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
+	cal_phy->pll_div_regs[1] = m;
+	cal_phy->pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
+	/* pll_div_regs 3-6 are fixed and pre-defined already */
+}
+
+static long phy_clk_round_rate(struct clk_hw *hw,
+			       unsigned long rate, unsigned long *parent_rate)
+{
+	const struct phy_config *fract_div_phy;
+	u32 int_div_clk;
+	u16 m;
+	u8 p, s;
+
+	/* If the clock is out of range return error instead of searching */
+	if (rate > 297000000 || rate < 22250000)
+		return -EINVAL;
+
+	/* Search the fractional divider lookup table */
+	fract_div_phy = fsl_samsung_hdmi_phy_lookup_rate(rate);
+
+	/* If the rate is an exact match, return that value */
+	if (rate == fract_div_phy->pixclk)
+		return fract_div_phy->pixclk;
+
+	/* If the exact match isn't found, calculate the integer divider */
+	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
+
+	/* If the int_div_clk rate is an exact match, return that value */
+	if (int_div_clk == rate)
+		return int_div_clk;
+
+	/* If neither rate is an exact match, use the value from the LUT */
+	return fract_div_phy->pixclk;
 }
 
 static int phy_clk_set_rate(struct clk_hw *hw,
 			    unsigned long rate, unsigned long parent_rate)
 {
 	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
-	int i;
+	const struct phy_config *fract_div_phy;
+	u32 int_div_clk;
+	u16 m;
+	u8 p, s;
 
-	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
-		if (phy_pll_cfg[i].pixclk <= rate)
-			break;
+	/* Search the fractional divider lookup table */
+	fract_div_phy = fsl_samsung_hdmi_phy_lookup_rate(rate);
 
-	if (i < 0)
-		return -EINVAL;
+	/* If the rate is an exact match, use that value */
+	if (fract_div_phy->pixclk == rate)
+		goto use_fract_div;
 
-	phy->cur_cfg = &phy_pll_cfg[i];
+	/*
+	 * If the rate from the fractional divder is not exact, check the integer divider,
+	 * and use it if that value is an exact match.
+	 */
+	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
+	if (int_div_clk == rate) {
+		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n",
+				   int_div_clk);
+
+		fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
+		phy->cur_cfg  = &calculated_phy_pll_cfg;
+		return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
+	}
 
+	/*
+	 * If neither the fractional divder nor the integer divder can find an exact value
+	 * fall back to using the fractional divider
+	 */
+use_fract_div:
+	phy->cur_cfg = fract_div_phy;
+	dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider rate = %u\n",
+			   phy->cur_cfg->pixclk);
 	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
 }
 
-- 
2.43.0



From aford173 at gmail.com  Tue Sep 10 18:28:10 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 10 Sep 2024 20:28:10 -0500
Subject: [PATCH V7 4/5] phy: freescale: fsl-samsung-hdmi: Use closest divider
In-Reply-To: <20240911012838.944630-1-aford173@gmail.com>
References: <20240911012838.944630-1-aford173@gmail.com>
Message-ID: <20240911012838.944630-5-aford173@gmail.com>

Currently, if the clock values cannot be set to the exact rate,
the round_rate and set_rate functions use the closest value found in
the look-up-table.  In preparation of removing values from the LUT
that can be calculated evenly with the integer calculator, it's
necessary to ensure to check both the look-up-table and the integer
divider clock values to get the closest values to the requested
value.  It does this by measuring the difference between the
requested clock value and the closest value in both integer divider
calucator and the fractional clock look-up-table.

Which ever has the smallest difference between them is returned as
the closest rate.

Signed-off-by: Adam Ford <aford173 at gmail.com>
---
V7:  Because of the previous patch refactoring, the flow of this patch
     changed quite a bit to use more help functions and goto statements
     to hopefully make the code flow better and improve comment
     readability.  Because of the change, I removed s-o-b and r-b,
     and t-b tags.

V6:  Simplify the calculation of the closest rate and fix
     a situation where the integer divider values may not be properly
     setup before they are used.
     Fixup some comments
V5:  No Change
V4:  New to series
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 40 ++++++++++++++------
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 49317a96f767..67a28aac9c45 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -577,6 +577,16 @@ static void fsl_samsung_hdmi_calculate_phy(struct phy_config *cal_phy, unsigned
 	/* pll_div_regs 3-6 are fixed and pre-defined already */
 }
 
+static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate,
+						 u32 int_div_clk, u32 frac_div_clk)
+{
+	/* The int_div_clk may be greater than rate, so cast it and use ABS */
+	if (abs((long)rate - (long)int_div_clk) < (rate - frac_div_clk))
+		return int_div_clk;
+
+	return frac_div_clk;
+}
+
 static long phy_clk_round_rate(struct clk_hw *hw,
 			       unsigned long rate, unsigned long *parent_rate)
 {
@@ -624,27 +634,33 @@ static int phy_clk_set_rate(struct clk_hw *hw,
 		goto use_fract_div;
 
 	/*
-	 * If the rate from the fractional divder is not exact, check the integer divider,
+	 * If the rate from the fractional divider is not exact, check the integer divider,
 	 * and use it if that value is an exact match.
 	 */
 	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
+	fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
 	if (int_div_clk == rate) {
-		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n",
-				   int_div_clk);
-
-		fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
-		phy->cur_cfg  = &calculated_phy_pll_cfg;
-		return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
+		goto use_int_div;
 	}
 
 	/*
-	 * If neither the fractional divder nor the integer divder can find an exact value
-	 * fall back to using the fractional divider
+	 * Compare the difference between the integer clock and the fractional clock against
+	 * the desired clock and which whichever is closest,
 	 */
+	if (fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk,
+						  fract_div_phy->pixclk) == fract_div_phy->pixclk)
+		goto use_fract_div;
+
+use_int_div:
+	dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n", int_div_clk);
+	phy->cur_cfg  = &calculated_phy_pll_cfg;
+	goto end;
+
 use_fract_div:
-	phy->cur_cfg = fract_div_phy;
-	dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider rate = %u\n",
-			   phy->cur_cfg->pixclk);
+	 phy->cur_cfg = fract_div_phy;
+	 dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider rate = %u\n",
+		   phy->cur_cfg->pixclk);
+end:
 	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
 }
 
-- 
2.43.0



From aford173 at gmail.com  Tue Sep 10 18:28:11 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 10 Sep 2024 20:28:11 -0500
Subject: [PATCH V7 5/5] phy: freescale: fsl-samsung-hdmi: Remove unnecessary LUT entries
In-Reply-To: <20240911012838.944630-1-aford173@gmail.com>
References: <20240911012838.944630-1-aford173@gmail.com>
Message-ID: <20240911012838.944630-6-aford173@gmail.com>

The lookup table contains entries which use the integer divider
instead of just the fractional divider. Since the set and round
functions check both the integer divider values and the LUT values,
it's no longer necessary to keep the integer divider values in the
lookup table, as can be dynamically calcuated.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
V7: No Change
V6: Fix typos in commit message
V5: No Change
V4:  New to series
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 83 +++-----------------
 1 file changed, 13 insertions(+), 70 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 67a28aac9c45..a5ad51425ee3 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -69,25 +69,16 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 23750000,
 		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
-	}, {
-		.pixclk = 24000000,
-		.pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 24024000,
 		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
 	}, {
 		.pixclk = 25175000,
 		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
-	}, {
-		.pixclk = 25200000,
-		.pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 26750000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 27000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 27027000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -105,18 +96,9 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 35000000,
 		.pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 36000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 36036000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
-	}, {
-		.pixclk = 40000000,
-		.pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
-		.pixclk = 43200000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43243200,
 		.pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
@@ -132,19 +114,13 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 50349650,
 		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
-	}, {
-		.pixclk = 50400000,
-		.pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 53250000,
 		.pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 53500000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 54000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 54054000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -153,10 +129,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 59340659,
 		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
-	}, {
-		.pixclk = 59400000,
-		.pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 61500000,
 		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -168,10 +141,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 70000000,
 		.pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 72000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 72072000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -183,10 +153,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 78500000,
 		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
-	}, {
-		.pixclk = 80000000,
-		.pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 82000000,
 		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -213,10 +180,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 100699300,
 		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
-	}, {
-		.pixclk = 100800000,
-		.pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 102500000,
 		.pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
@@ -228,19 +192,13 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 107000000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 108000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 108108000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 118000000,
 		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
-	}, {
-		.pixclk = 118800000,
-		.pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 123000000,
 		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -261,10 +219,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 140000000,
 		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
-	}, {
-		.pixclk = 144000000,
-		.pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 148352000,
 		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
 	}, {
@@ -288,9 +243,6 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 165000000,
 		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
-	}, {
-		.pixclk = 180000000,
-		.pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 185625000,
 		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
@@ -309,25 +261,16 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 213000000,
 		.pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
-	}, {
-		.pixclk = 216000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 216216000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
-	}, {
-		.pixclk = 237600000,
-		.pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 254000000,
 		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 277500000,
 		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
-	}, {
-		.pixclk = 288000000,
-		.pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 297000000,
 		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
 	},
-- 
2.43.0



From dominique.martinet at atmark-techno.com  Tue Sep 10 22:12:50 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Wed, 11 Sep 2024 14:12:50 +0900
Subject: [PATCH V7 1/5] phy: freescale: fsl-samsung-hdmi: Replace
 register defines with macro
In-Reply-To: <20240911012838.944630-2-aford173@gmail.com>
References: <20240911012838.944630-1-aford173@gmail.com>
 <20240911012838.944630-2-aford173@gmail.com>
Message-ID: <ZuEm0t7HgA5dxe0n@atmark-techno.com>

Adam Ford wrote on Tue, Sep 10, 2024 at 08:28:07PM -0500:
> There are 47 registers defined as PHY_REG_xx were xx goes from 00 to
> 47.  Simplify this by replacing them all with a macro which is passed
> the register number to return the proper register offset.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
> Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
> Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>

Reviewed-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
Tested-by: Dominique Martinet <dominique.martinet at atmark-techno.com>

> ---
>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 133 ++++++-------------
>  1 file changed, 43 insertions(+), 90 deletions(-)
> 
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> index 9048cdc760c2..acea7008aefc 100644
> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -14,76 +14,29 @@
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  
> -#define PHY_REG_00		0x00
> -#define PHY_REG_01		0x04
> -#define PHY_REG_02		0x08
> -#define PHY_REG_08		0x20
> -#define PHY_REG_09		0x24
> -#define PHY_REG_10		0x28
> -#define PHY_REG_11		0x2c
> -
> -#define PHY_REG_12		0x30
> -#define  REG12_CK_DIV_MASK	GENMASK(5, 4)
> -
> -#define PHY_REG_13		0x34
> -#define  REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
> -
> -#define PHY_REG_14		0x38
> -#define  REG14_TOL_MASK		GENMASK(7, 4)
> -#define  REG14_RP_CODE_MASK	GENMASK(3, 1)
> -#define  REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
> -
> -#define PHY_REG_15		0x3c
> -#define PHY_REG_16		0x40
> -#define PHY_REG_17		0x44
> -#define PHY_REG_18		0x48
> -#define PHY_REG_19		0x4c
> -#define PHY_REG_20		0x50
> -
> -#define PHY_REG_21		0x54
> -#define  REG21_SEL_TX_CK_INV	BIT(7)
> -#define  REG21_PMS_S_MASK	GENMASK(3, 0)
> -
> -#define PHY_REG_22		0x58
> -#define PHY_REG_23		0x5c
> -#define PHY_REG_24		0x60
> -#define PHY_REG_25		0x64
> -#define PHY_REG_26		0x68
> -#define PHY_REG_27		0x6c
> -#define PHY_REG_28		0x70
> -#define PHY_REG_29		0x74
> -#define PHY_REG_30		0x78
> -#define PHY_REG_31		0x7c
> -#define PHY_REG_32		0x80
> +#define PHY_REG(reg)		(reg * 4)
>  
> +#define REG12_CK_DIV_MASK	GENMASK(5, 4)
> +
> +#define REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
> +
> +#define REG14_TOL_MASK		GENMASK(7, 4)
> +#define REG14_RP_CODE_MASK	GENMASK(3, 1)
> +#define REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
> +
> +#define REG21_SEL_TX_CK_INV	BIT(7)
> +#define REG21_PMS_S_MASK	GENMASK(3, 0)
>  /*
>   * REG33 does not match the ref manual. According to Sandor Yu from NXP,
>   * "There is a doc issue on the i.MX8MP latest RM"
>   * REG33 is being used per guidance from Sandor
>   */
> +#define REG33_MODE_SET_DONE	BIT(7)
> +#define REG33_FIX_DA		BIT(1)
>  
> -#define PHY_REG_33		0x84
> -#define  REG33_MODE_SET_DONE	BIT(7)
> -#define  REG33_FIX_DA		BIT(1)
> -
> -#define PHY_REG_34		0x88
> -#define  REG34_PHY_READY	BIT(7)
> -#define  REG34_PLL_LOCK		BIT(6)
> -#define  REG34_PHY_CLK_READY	BIT(5)
> -
> -#define PHY_REG_35		0x8c
> -#define PHY_REG_36		0x90
> -#define PHY_REG_37		0x94
> -#define PHY_REG_38		0x98
> -#define PHY_REG_39		0x9c
> -#define PHY_REG_40		0xa0
> -#define PHY_REG_41		0xa4
> -#define PHY_REG_42		0xa8
> -#define PHY_REG_43		0xac
> -#define PHY_REG_44		0xb0
> -#define PHY_REG_45		0xb4
> -#define PHY_REG_46		0xb8
> -#define PHY_REG_47		0xbc
> +#define REG34_PHY_READY	BIT(7)
> +#define REG34_PLL_LOCK		BIT(6)
> +#define REG34_PHY_CLK_READY	BIT(5)
>  
>  #define PHY_PLL_DIV_REGS_NUM 6
>  
> @@ -369,29 +322,29 @@ struct reg_settings {
>  };
>  
>  static const struct reg_settings common_phy_cfg[] = {
> -	{ PHY_REG_00, 0x00 }, { PHY_REG_01, 0xd1 },
> -	{ PHY_REG_08, 0x4f }, { PHY_REG_09, 0x30 },
> -	{ PHY_REG_10, 0x33 }, { PHY_REG_11, 0x65 },
> +	{ PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
> +	{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
> +	{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
>  	/* REG12 pixclk specific */
>  	/* REG13 pixclk specific */
>  	/* REG14 pixclk specific */
> -	{ PHY_REG_15, 0x80 }, { PHY_REG_16, 0x6c },
> -	{ PHY_REG_17, 0xf2 }, { PHY_REG_18, 0x67 },
> -	{ PHY_REG_19, 0x00 }, { PHY_REG_20, 0x10 },
> +	{ PHY_REG(15), 0x80 }, { PHY_REG(16), 0x6c },
> +	{ PHY_REG(17), 0xf2 }, { PHY_REG(18), 0x67 },
> +	{ PHY_REG(19), 0x00 }, { PHY_REG(20), 0x10 },
>  	/* REG21 pixclk specific */
> -	{ PHY_REG_22, 0x30 }, { PHY_REG_23, 0x32 },
> -	{ PHY_REG_24, 0x60 }, { PHY_REG_25, 0x8f },
> -	{ PHY_REG_26, 0x00 }, { PHY_REG_27, 0x00 },
> -	{ PHY_REG_28, 0x08 }, { PHY_REG_29, 0x00 },
> -	{ PHY_REG_30, 0x00 }, { PHY_REG_31, 0x00 },
> -	{ PHY_REG_32, 0x00 }, { PHY_REG_33, 0x80 },
> -	{ PHY_REG_34, 0x00 }, { PHY_REG_35, 0x00 },
> -	{ PHY_REG_36, 0x00 }, { PHY_REG_37, 0x00 },
> -	{ PHY_REG_38, 0x00 }, { PHY_REG_39, 0x00 },
> -	{ PHY_REG_40, 0x00 }, { PHY_REG_41, 0xe0 },
> -	{ PHY_REG_42, 0x83 }, { PHY_REG_43, 0x0f },
> -	{ PHY_REG_44, 0x3E }, { PHY_REG_45, 0xf8 },
> -	{ PHY_REG_46, 0x00 }, { PHY_REG_47, 0x00 }
> +	{ PHY_REG(22), 0x30 }, { PHY_REG(23), 0x32 },
> +	{ PHY_REG(24), 0x60 }, { PHY_REG(25), 0x8f },
> +	{ PHY_REG(26), 0x00 }, { PHY_REG(27), 0x00 },
> +	{ PHY_REG(28), 0x08 }, { PHY_REG(29), 0x00 },
> +	{ PHY_REG(30), 0x00 }, { PHY_REG(31), 0x00 },
> +	{ PHY_REG(32), 0x00 }, { PHY_REG(33), 0x80 },
> +	{ PHY_REG(34), 0x00 }, { PHY_REG(35), 0x00 },
> +	{ PHY_REG(36), 0x00 }, { PHY_REG(37), 0x00 },
> +	{ PHY_REG(38), 0x00 }, { PHY_REG(39), 0x00 },
> +	{ PHY_REG(40), 0x00 }, { PHY_REG(41), 0xe0 },
> +	{ PHY_REG(42), 0x83 }, { PHY_REG(43), 0x0f },
> +	{ PHY_REG(44), 0x3E }, { PHY_REG(45), 0xf8 },
> +	{ PHY_REG(46), 0x00 }, { PHY_REG(47), 0x00 }
>  };
>  
>  struct fsl_samsung_hdmi_phy {
> @@ -442,7 +395,7 @@ fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
>  	}
>  
>  	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
> -	       phy->regs + PHY_REG_21);
> +	       phy->regs + PHY_REG(21));
>  }
>  
>  static void
> @@ -469,7 +422,7 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
>  		break;
>  	}
>  
> -	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG_12);
> +	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG(12));
>  
>  	/*
>  	 * Calculation for the frequency lock detector target code (fld_tg_code)
> @@ -489,11 +442,11 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
>  
>  	/* FLD_TOL and FLD_RP_CODE taken from downstream driver */
>  	writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),
> -	       phy->regs + PHY_REG_13);
> +	       phy->regs + PHY_REG(13));
>  	writeb(FIELD_PREP(REG14_TOL_MASK, 2) |
>  	       FIELD_PREP(REG14_RP_CODE_MASK, 2) |
>  	       FIELD_PREP(REG14_TG_CODE_HIGH_MASK, fld_tg_code >> 8),
> -	       phy->regs + PHY_REG_14);
> +	       phy->regs + PHY_REG(14));
>  }
>  
>  static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
> @@ -503,7 +456,7 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
>  	u8 val;
>  
>  	/* HDMI PHY init */
> -	writeb(REG33_FIX_DA, phy->regs + PHY_REG_33);
> +	writeb(REG33_FIX_DA, phy->regs + PHY_REG(33));
>  
>  	/* common PHY registers */
>  	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
> @@ -511,14 +464,14 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
>  
>  	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
>  	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
> -		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG_02 + i * 4);
> +		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
>  
>  	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
>  	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
>  
> -	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG_33);
> +	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));
>  
> -	ret = readb_poll_timeout(phy->regs + PHY_REG_34, val,
> +	ret = readb_poll_timeout(phy->regs + PHY_REG(34), val,
>  				 val & REG34_PLL_LOCK, 50, 20000);
>  	if (ret)
>  		dev_err(phy->dev, "PLL failed to lock\n");


From dominique.martinet at atmark-techno.com  Tue Sep 10 22:23:12 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Wed, 11 Sep 2024 14:23:12 +0900
Subject: [PATCH V7 2/5] phy: freescale: fsl-samsung-hdmi: Simplify
 REG21_PMS_S_MASK lookup
In-Reply-To: <20240911012838.944630-3-aford173@gmail.com>
References: <20240911012838.944630-1-aford173@gmail.com>
 <20240911012838.944630-3-aford173@gmail.com>
Message-ID: <ZuEpQLcDQ8pgMTUB@atmark-techno.com>

Adam Ford wrote on Tue, Sep 10, 2024 at 08:28:08PM -0500:
> The value of 'S' is writen to two places, PHY_REG3[7:4] and
> PHY_REG21[3:0].  There is a lookup table which contains
> the value of PHY_REG3.  Rather than using a switch statement
> based on the pixel clock to search for the value of 'S' again,
> just shift the contents of PHY_REG3[7:4] >> 4 and place the value
> in PHY_REG21[3:0].  Doing this can eliminate an entire function.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
> Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
> Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>

Reviewed-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
Tested-by: Dominique Martinet <dominique.martinet at atmark-techno.com>

> ---
>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 39 ++------------------
>  1 file changed, 4 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> index acea7008aefc..4f6874226f9a 100644
> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -364,40 +364,6 @@ to_fsl_samsung_hdmi_phy(struct clk_hw *hw)
>  	return container_of(hw, struct fsl_samsung_hdmi_phy, hw);
>  }
>  
> -static void
> -fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
> -				      const struct phy_config *cfg)
> -{
> -	u8 div = 0x1;
> -
> -	switch (cfg->pixclk) {
> -	case  22250000 ...  33750000:
> -		div = 0xf;
> -		break;
> -	case  35000000 ...  40000000:
> -		div = 0xb;
> -		break;
> -	case  43200000 ...  47500000:
> -		div = 0x9;
> -		break;
> -	case  50349650 ...  63500000:
> -		div = 0x7;
> -		break;
> -	case  67500000 ...  90000000:
> -		div = 0x5;
> -		break;
> -	case  94000000 ... 148500000:
> -		div = 0x3;
> -		break;
> -	case 154000000 ... 297000000:
> -		div = 0x1;
> -		break;
> -	}
> -
> -	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
> -	       phy->regs + PHY_REG(21));
> -}
> -
>  static void
>  fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
>  					    const struct phy_config *cfg)
> @@ -466,7 +432,10 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
>  	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
>  		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
>  
> -	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
> +	/* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
> +	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
> +	       cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
> +
>  	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
>  
>  	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));


From dominique.martinet at atmark-techno.com  Tue Sep 10 22:26:17 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Wed, 11 Sep 2024 14:26:17 +0900
Subject: [PATCH V7 3/5] xphy: freescale: fsl-samsung-hdmi: Support
 dynamic integer
In-Reply-To: <20240911012838.944630-4-aford173@gmail.com>
References: <20240911012838.944630-1-aford173@gmail.com>
 <20240911012838.944630-4-aford173@gmail.com>
Message-ID: <ZuEp-QhnlV0byzVa@atmark-techno.com>

Adam Ford wrote on Tue, Sep 10, 2024 at 08:28:09PM -0500:
> Subject: ... xphy: freescale: ...

the 'phy' gained an x

> There is currently a look-up table for a variety of resolutions.
> Since the phy has the ability to dynamically calculate the values
> necessary to use the intger divider which should allow more
> resolutions without having to update the look-up-table.
> 
> If the lookup table cannot find an exact match, fall back to the
> dynamic calculator of the integer divider.
> 
> Previously, the value of P was hard-coded to 1, this required an
> update to the phy_pll_cfg table to add in the extra value into the
> table, so if the value of P is calculated to be something else
> by the PMS calculator, the calculated_phy_pll_cfg structure
> can be used instead without having to keep track of which method
> was used.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Reviewed-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
Tested-by: Dominique Martinet <dominique.martinet at atmark-techno.com>

> ---
> V7:  Refactored much of the code to create smaller helper functions
>      to eliminate redundant code and improve code flow and comment
>      readability.   Any t-b and s-o-b tags removed due to the
>      extent of the changes.
> 
> V6:  Fix comment typos and remove an unnecesary extra calculation
>      by using the cached value.
> V5:  No Change
> V4:  No Change
> V3:  Change size of pll_div_regs to include PHY_REG01 (P)
>      Create calculated_phy_pll_cfg to containe the values
>      Eliminate the PMS calculation from fsl_samsung_hdmi_phy_configure
>      Make the LUT primary and fall back to integer calculator in
>      phy_clk_round_rate.
>      Check the range right away to ensure it's reaonsable rather than
>      trying to find a clock only to learn it's outside the range.
>      Overall added notes and comments where stuff may not be intuitive.
> 
> V2:  Update phy_clk_round_rate and phy_clk_set_rate to both support
>      the integer clock PMS calculator.
> ---
>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 371 +++++++++++++------
>  1 file changed, 265 insertions(+), 106 deletions(-)
> 
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> index 4f6874226f9a..49317a96f767 100644
> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -16,6 +16,8 @@
>  
>  #define PHY_REG(reg)		(reg * 4)
>  
> +#define REG01_PMS_P_MASK	GENMASK(3, 0)
> +#define REG03_PMS_S_MASK	GENMASK(7, 4)
>  #define REG12_CK_DIV_MASK	GENMASK(5, 4)
>  
>  #define REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
> @@ -38,281 +40,296 @@
>  #define REG34_PLL_LOCK		BIT(6)
>  #define REG34_PHY_CLK_READY	BIT(5)
>  
> -#define PHY_PLL_DIV_REGS_NUM 6
> +#ifndef MHZ
> +#define MHZ	(1000UL * 1000UL)
> +#endif
> +
> +#define PHY_PLL_DIV_REGS_NUM 7
>  
>  struct phy_config {
>  	u32	pixclk;
>  	u8	pll_div_regs[PHY_PLL_DIV_REGS_NUM];
>  };
>  
> +/*
> + * The calculated_phy_pll_cfg only handles integer divider for PMS,
> + * meaning the last four entries will be fixed, but the first three will
> + * be calculated by the PMS calculator.
> + */
> +static struct phy_config calculated_phy_pll_cfg = {
> +	.pixclk = 0,
> +	.pll_div_regs = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
> +};
> +
> +/* The lookup table contains values for which the fractional divder is used */
>  static const struct phy_config phy_pll_cfg[] = {
>  	{
>  		.pixclk = 22250000,
> -		.pll_div_regs = { 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 23750000,
> -		.pll_div_regs = { 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 24000000,
> -		.pll_div_regs = { 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 24024000,
> -		.pll_div_regs = { 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 25175000,
> -		.pll_div_regs = { 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 25200000,
> -		.pll_div_regs = { 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 26750000,
> -		.pll_div_regs = { 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 27000000,
> -		.pll_div_regs = { 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 27027000,
> -		.pll_div_regs = { 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 29500000,
> -		.pll_div_regs = { 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 30750000,
> -		.pll_div_regs = { 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
>  	}, {
>  		.pixclk = 30888000,
> -		.pll_div_regs = { 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
>  	}, {
>  		.pixclk = 33750000,
> -		.pll_div_regs = { 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 35000000,
> -		.pll_div_regs = { 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 36000000,
> -		.pll_div_regs = { 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 36036000,
> -		.pll_div_regs = { 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 40000000,
> -		.pll_div_regs = { 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 43200000,
> -		.pll_div_regs = { 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 43243200,
> -		.pll_div_regs = { 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 44500000,
> -		.pll_div_regs = { 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
> +		.pll_div_regs = { 0xd1, 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
>  	}, {
>  		.pixclk = 47000000,
> -		.pll_div_regs = { 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 47500000,
> -		.pll_div_regs = { 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 50349650,
> -		.pll_div_regs = { 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 50400000,
> -		.pll_div_regs = { 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 53250000,
> -		.pll_div_regs = { 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
> +		.pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
>  	}, {
>  		.pixclk = 53500000,
> -		.pll_div_regs = { 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 54000000,
> -		.pll_div_regs = { 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 54054000,
> -		.pll_div_regs = { 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 59000000,
> -		.pll_div_regs = { 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 59340659,
> -		.pll_div_regs = { 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
> +		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
>  	}, {
>  		.pixclk = 59400000,
> -		.pll_div_regs = { 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 61500000,
> -		.pll_div_regs = { 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
>  	}, {
>  		.pixclk = 63500000,
> -		.pll_div_regs = { 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 67500000,
> -		.pll_div_regs = { 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 70000000,
> -		.pll_div_regs = { 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 72000000,
> -		.pll_div_regs = { 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 72072000,
> -		.pll_div_regs = { 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 74176000,
> -		.pll_div_regs = { 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
> +		.pll_div_regs = { 0xd1, 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
>  	}, {
>  		.pixclk = 74250000,
> -		.pll_div_regs = { 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
> +		.pll_div_regs = { 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
>  	}, {
>  		.pixclk = 78500000,
> -		.pll_div_regs = { 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 80000000,
> -		.pll_div_regs = { 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 82000000,
> -		.pll_div_regs = { 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
>  	}, {
>  		.pixclk = 82500000,
> -		.pll_div_regs = { 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
> +		.pll_div_regs = { 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
>  	}, {
>  		.pixclk = 89000000,
> -		.pll_div_regs = { 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 90000000,
> -		.pll_div_regs = { 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 94000000,
> -		.pll_div_regs = { 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 95000000,
> -		.pll_div_regs = { 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 98901099,
> -		.pll_div_regs = { 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
> +		.pll_div_regs = { 0xd1, 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
>  	}, {
>  		.pixclk = 99000000,
> -		.pll_div_regs = { 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
> +		.pll_div_regs = { 0xd1, 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
>  	}, {
>  		.pixclk = 100699300,
> -		.pll_div_regs = { 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 100800000,
> -		.pll_div_regs = { 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 102500000,
> -		.pll_div_regs = { 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
> +		.pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
>  	}, {
>  		.pixclk = 104750000,
> -		.pll_div_regs = { 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
> +		.pll_div_regs = { 0xd1, 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
>  	}, {
>  		.pixclk = 106500000,
> -		.pll_div_regs = { 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
> +		.pll_div_regs = { 0xd1, 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
>  	}, {
>  		.pixclk = 107000000,
> -		.pll_div_regs = { 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 108000000,
> -		.pll_div_regs = { 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 108108000,
> -		.pll_div_regs = { 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 118000000,
> -		.pll_div_regs = { 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 118800000,
> -		.pll_div_regs = { 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 123000000,
> -		.pll_div_regs = { 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
>  	}, {
>  		.pixclk = 127000000,
> -		.pll_div_regs = { 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 135000000,
> -		.pll_div_regs = { 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 135580000,
> -		.pll_div_regs = { 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
> +		.pll_div_regs = { 0xd1, 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
>  	}, {
>  		.pixclk = 137520000,
> -		.pll_div_regs = { 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
> +		.pll_div_regs = { 0xd1, 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
>  	}, {
>  		.pixclk = 138750000,
> -		.pll_div_regs = { 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
> +		.pll_div_regs = { 0xd1, 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
>  	}, {
>  		.pixclk = 140000000,
> -		.pll_div_regs = { 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 144000000,
> -		.pll_div_regs = { 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 148352000,
> -		.pll_div_regs = { 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
>  	}, {
>  		.pixclk = 148500000,
> -		.pll_div_regs = { 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
>  	}, {
>  		.pixclk = 154000000,
> -		.pll_div_regs = { 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
>  	}, {
>  		.pixclk = 157000000,
> -		.pll_div_regs = { 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 160000000,
> -		.pll_div_regs = { 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 162000000,
> -		.pll_div_regs = { 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
> +		.pll_div_regs = { 0xd1, 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
>  	}, {
>  		.pixclk = 164000000,
> -		.pll_div_regs = { 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
> +		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
>  	}, {
>  		.pixclk = 165000000,
> -		.pll_div_regs = { 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
> +		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
>  	}, {
>  		.pixclk = 180000000,
> -		.pll_div_regs = { 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 185625000,
> -		.pll_div_regs = { 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 188000000,
> -		.pll_div_regs = { 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 198000000,
> -		.pll_div_regs = { 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
> +		.pll_div_regs = { 0xd1, 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
>  	}, {
>  		.pixclk = 205000000,
> -		.pll_div_regs = { 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
> +		.pll_div_regs = { 0xd1, 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
>  	}, {
>  		.pixclk = 209500000,
> -		.pll_div_regs = { 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
> +		.pll_div_regs = { 0xd1, 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
>  	}, {
>  		.pixclk = 213000000,
> -		.pll_div_regs = { 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
> +		.pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
>  	}, {
>  		.pixclk = 216000000,
> -		.pll_div_regs = { 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 216216000,
> -		.pll_div_regs = { 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 237600000,
> -		.pll_div_regs = { 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 254000000,
> -		.pll_div_regs = { 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 277500000,
> -		.pll_div_regs = { 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
> +		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
>  	}, {
>  		.pixclk = 288000000,
> -		.pll_div_regs = { 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
> +		.pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 297000000,
> -		.pll_div_regs = { 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
> +		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
>  	},
>  };
>  
> @@ -322,7 +339,8 @@ struct reg_settings {
>  };
>  
>  static const struct reg_settings common_phy_cfg[] = {
> -	{ PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
> +	{ PHY_REG(0), 0x00 },
> +	/* PHY_REG(1-7) pix clk specific */
>  	{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
>  	{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
>  	/* REG12 pixclk specific */
> @@ -415,6 +433,83 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
>  	       phy->regs + PHY_REG(14));
>  }
>  
> +static unsigned long fsl_samsung_hdmi_phy_find_pms(unsigned long fout, u8 *p, u16 *m, u8 *s)
> +{
> +	unsigned long best_freq = 0;
> +	u32 min_delta = 0xffffffff;
> +	u8 _p, best_p;
> +	u16 _m, best_m;
> +	u8 _s, best_s;
> +
> +	/*
> +	 * Figure 13-78 of the reference manual states the PLL should be TMDS x 5
> +	 * while the TMDS_CLKO should be the PLL / 5.  So to calculate the PLL,
> +	 * take the pix clock x 5, then return the value of the PLL / 5.
> +	 */
> +	fout *= 5;
> +
> +	/* The ref manual states the values of 'P' range from 1 to 11 */
> +	for (_p = 1; _p <= 11; ++_p) {
> +		for (_s = 1; _s <= 16; ++_s) {
> +			u64 tmp;
> +			u32 delta;
> +
> +			/* s must be one or even */
> +			if (_s > 1 && (_s & 0x01) == 1)
> +				_s++;
> +
> +			/* _s cannot be 14 per the TRM */
> +			if (_s == 14)
> +				continue;
> +
> +			/*
> +			 * TODO: Ref Manual doesn't state the range of _m
> +			 * so this should be further refined if possible.
> +			 * This range was set based on the original values
> +			 * in the lookup table
> +			 */
> +			tmp = (u64)fout * (_p * _s);
> +			do_div(tmp, 24 * MHZ);
> +			_m = tmp;
> +			if (_m < 0x30 || _m > 0x7b)
> +				continue;
> +
> +			/*
> +			 * Rev 2 of the Ref Manual states the
> +			 * VCO can range between 750MHz and
> +			 * 3GHz.  The VCO is assumed to be
> +			 * is assumed to be (M * f_ref) / P,
> +			 * where f_ref is 24MHz.
> +			 */
> +			tmp = (u64)_m * 24 * MHZ;
> +			do_div(tmp, _p);
> +			if (tmp < 750 * MHZ ||
> +			    tmp > 3000 * MHZ)
> +				continue;
> +
> +			/* Final frequency after post-divider */
> +			do_div(tmp, _s);
> +
> +			delta = abs(fout - tmp);
> +			if (delta < min_delta) {
> +				best_p = _p;
> +				best_s = _s;
> +				best_m = _m;
> +				min_delta = delta;
> +				best_freq = tmp;
> +			}
> +		}
> +	}
> +
> +	if (best_freq) {
> +		*p = best_p;
> +		*m = best_m;
> +		*s = best_s;
> +	}
> +
> +	return best_freq / 5;
> +}
> +
>  static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
>  					  const struct phy_config *cfg)
>  {
> @@ -428,13 +523,13 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
>  	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
>  		writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
>  
> -	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
> +	/* set individual PLL registers PHY_REG1 ... PHY_REG7 */
>  	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
> -		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
> +		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(1) + i * 4);
>  
> -	/* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
> +	/* High nibble of PHY_REG3 and low nibble of PHY_REG21 both contain 'S' */
>  	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
> -	       cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
> +	       cfg->pll_div_regs[2] >> 4), phy->regs + PHY_REG(21));
>  
>  	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
>  
> @@ -459,33 +554,97 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
>  	return phy->cur_cfg->pixclk;
>  }
>  
> -static long phy_clk_round_rate(struct clk_hw *hw,
> -			       unsigned long rate, unsigned long *parent_rate)
> +/* Helper function to lookup the available fractional-divider rate */
> +static const struct phy_config *fsl_samsung_hdmi_phy_lookup_rate(unsigned long rate)
>  {
>  	int i;
>  
> +	/* Search the lookup table */
>  	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
>  		if (phy_pll_cfg[i].pixclk <= rate)
> -			return phy_pll_cfg[i].pixclk;
> +			break;
>  
> -	return -EINVAL;
> +	return &phy_pll_cfg[i];
> +}
> +
> +static void fsl_samsung_hdmi_calculate_phy(struct phy_config *cal_phy, unsigned long rate,
> +				    u8 p, u16 m, u8 s)
> +{
> +	cal_phy->pixclk = rate;
> +	cal_phy->pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
> +	cal_phy->pll_div_regs[1] = m;
> +	cal_phy->pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
> +	/* pll_div_regs 3-6 are fixed and pre-defined already */
> +}
> +
> +static long phy_clk_round_rate(struct clk_hw *hw,
> +			       unsigned long rate, unsigned long *parent_rate)
> +{
> +	const struct phy_config *fract_div_phy;
> +	u32 int_div_clk;
> +	u16 m;
> +	u8 p, s;
> +
> +	/* If the clock is out of range return error instead of searching */
> +	if (rate > 297000000 || rate < 22250000)
> +		return -EINVAL;
> +
> +	/* Search the fractional divider lookup table */
> +	fract_div_phy = fsl_samsung_hdmi_phy_lookup_rate(rate);
> +
> +	/* If the rate is an exact match, return that value */
> +	if (rate == fract_div_phy->pixclk)
> +		return fract_div_phy->pixclk;
> +
> +	/* If the exact match isn't found, calculate the integer divider */
> +	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
> +
> +	/* If the int_div_clk rate is an exact match, return that value */
> +	if (int_div_clk == rate)
> +		return int_div_clk;
> +
> +	/* If neither rate is an exact match, use the value from the LUT */
> +	return fract_div_phy->pixclk;
>  }
>  
>  static int phy_clk_set_rate(struct clk_hw *hw,
>  			    unsigned long rate, unsigned long parent_rate)
>  {
>  	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
> -	int i;
> +	const struct phy_config *fract_div_phy;
> +	u32 int_div_clk;
> +	u16 m;
> +	u8 p, s;
>  
> -	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> -		if (phy_pll_cfg[i].pixclk <= rate)
> -			break;
> +	/* Search the fractional divider lookup table */
> +	fract_div_phy = fsl_samsung_hdmi_phy_lookup_rate(rate);
>  
> -	if (i < 0)
> -		return -EINVAL;
> +	/* If the rate is an exact match, use that value */
> +	if (fract_div_phy->pixclk == rate)
> +		goto use_fract_div;
>  
> -	phy->cur_cfg = &phy_pll_cfg[i];
> +	/*
> +	 * If the rate from the fractional divder is not exact, check the integer divider,
> +	 * and use it if that value is an exact match.
> +	 */
> +	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
> +	if (int_div_clk == rate) {
> +		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n",
> +				   int_div_clk);
> +
> +		fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
> +		phy->cur_cfg  = &calculated_phy_pll_cfg;
> +		return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
> +	}
>  
> +	/*
> +	 * If neither the fractional divder nor the integer divder can find an exact value
> +	 * fall back to using the fractional divider
> +	 */
> +use_fract_div:
> +	phy->cur_cfg = fract_div_phy;
> +	dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider rate = %u\n",
> +			   phy->cur_cfg->pixclk);
>  	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
>  }
>  


From dominique.martinet at atmark-techno.com  Tue Sep 10 22:27:17 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Wed, 11 Sep 2024 14:27:17 +0900
Subject: [PATCH V7 4/5] phy: freescale: fsl-samsung-hdmi: Use closest
 divider
In-Reply-To: <20240911012838.944630-5-aford173@gmail.com>
References: <20240911012838.944630-1-aford173@gmail.com>
 <20240911012838.944630-5-aford173@gmail.com>
Message-ID: <ZuEqNVWSPXXR1YHM@atmark-techno.com>

Adam Ford wrote on Tue, Sep 10, 2024 at 08:28:10PM -0500:
> Currently, if the clock values cannot be set to the exact rate,
> the round_rate and set_rate functions use the closest value found in
> the look-up-table.  In preparation of removing values from the LUT
> that can be calculated evenly with the integer calculator, it's
> necessary to ensure to check both the look-up-table and the integer
> divider clock values to get the closest values to the requested
> value.  It does this by measuring the difference between the
> requested clock value and the closest value in both integer divider
> calucator and the fractional clock look-up-table.
> 
> Which ever has the smallest difference between them is returned as
> the closest rate.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Thank you for the rework,

Reviewed-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
Tested-by: Dominique Martinet <dominique.martinet at atmark-techno.com>

> ---
> V7:  Because of the previous patch refactoring, the flow of this patch
>      changed quite a bit to use more help functions and goto statements
>      to hopefully make the code flow better and improve comment
>      readability.  Because of the change, I removed s-o-b and r-b,
>      and t-b tags.
> 
> V6:  Simplify the calculation of the closest rate and fix
>      a situation where the integer divider values may not be properly
>      setup before they are used.
>      Fixup some comments
> V5:  No Change
> V4:  New to series
> ---
>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 40 ++++++++++++++------
>  1 file changed, 28 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> index 49317a96f767..67a28aac9c45 100644
> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -577,6 +577,16 @@ static void fsl_samsung_hdmi_calculate_phy(struct phy_config *cal_phy, unsigned
>  	/* pll_div_regs 3-6 are fixed and pre-defined already */
>  }
>  
> +static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate,
> +						 u32 int_div_clk, u32 frac_div_clk)
> +{
> +	/* The int_div_clk may be greater than rate, so cast it and use ABS */
> +	if (abs((long)rate - (long)int_div_clk) < (rate - frac_div_clk))
> +		return int_div_clk;
> +
> +	return frac_div_clk;
> +}
> +
>  static long phy_clk_round_rate(struct clk_hw *hw,
>  			       unsigned long rate, unsigned long *parent_rate)
>  {
> @@ -624,27 +634,33 @@ static int phy_clk_set_rate(struct clk_hw *hw,
>  		goto use_fract_div;
>  
>  	/*
> -	 * If the rate from the fractional divder is not exact, check the integer divider,
> +	 * If the rate from the fractional divider is not exact, check the integer divider,
>  	 * and use it if that value is an exact match.
>  	 */
>  	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
> +	fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
>  	if (int_div_clk == rate) {
> -		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n",
> -				   int_div_clk);
> -
> -		fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
> -		phy->cur_cfg  = &calculated_phy_pll_cfg;
> -		return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
> +		goto use_int_div;
>  	}
>  
>  	/*
> -	 * If neither the fractional divder nor the integer divder can find an exact value
> -	 * fall back to using the fractional divider
> +	 * Compare the difference between the integer clock and the fractional clock against
> +	 * the desired clock and which whichever is closest,
>  	 */
> +	if (fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk,
> +						  fract_div_phy->pixclk) == fract_div_phy->pixclk)
> +		goto use_fract_div;
> +
> +use_int_div:
> +	dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n", int_div_clk);
> +	phy->cur_cfg  = &calculated_phy_pll_cfg;
> +	goto end;
> +
>  use_fract_div:
> -	phy->cur_cfg = fract_div_phy;
> -	dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider rate = %u\n",
> -			   phy->cur_cfg->pixclk);
> +	 phy->cur_cfg = fract_div_phy;
> +	 dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider rate = %u\n",
> +		   phy->cur_cfg->pixclk);
> +end:
>  	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
>  }
>  


From dominique.martinet at atmark-techno.com  Tue Sep 10 22:47:25 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Wed, 11 Sep 2024 14:47:25 +0900
Subject: [PATCH V7 5/5] phy: freescale: fsl-samsung-hdmi: Remove
 unnecessary LUT entries
In-Reply-To: <20240911012838.944630-6-aford173@gmail.com>
References: <20240911012838.944630-1-aford173@gmail.com>
 <20240911012838.944630-6-aford173@gmail.com>
Message-ID: <ZuEu7Qf3WkU8NnJA@atmark-techno.com>

Adam Ford wrote on Tue, Sep 10, 2024 at 08:28:11PM -0500:
> The lookup table contains entries which use the integer divider
> instead of just the fractional divider. Since the set and round
> functions check both the integer divider values and the LUT values,
> it's no longer necessary to keep the integer divider values in the
> lookup table, as can be dynamically calcuated.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
> Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>


not that we'd have done anything different if there was something
incoherent, but FWIW I checked re-computing values for these regs match
and there was no problem.

Reviewed-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
Tested-by: Dominique Martinet <dominique.martinet at atmark-techno.com>


> ---
> V7: No Change
> V6: Fix typos in commit message
> V5: No Change
> V4:  New to series
> ---
>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 83 +++-----------------
>  1 file changed, 13 insertions(+), 70 deletions(-)
> 
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> index 67a28aac9c45..a5ad51425ee3 100644
> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -69,25 +69,16 @@ static const struct phy_config phy_pll_cfg[] = {
>  	}, {
>  		.pixclk = 23750000,
>  		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
> -	}, {
> -		.pixclk = 24000000,
> -		.pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 24024000,
>  		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 25175000,
>  		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
> -	}, {
> -		.pixclk = 25200000,
> -		.pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> -	}, {
> +	},  {
>  		.pixclk = 26750000,
>  		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
> -	}, {
> -		.pixclk = 27000000,
> -		.pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> -	}, {
> +	},  {
>  		.pixclk = 27027000,
>  		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
> @@ -105,18 +96,9 @@ static const struct phy_config phy_pll_cfg[] = {
>  	}, {
>  		.pixclk = 35000000,
>  		.pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
> -	}, {
> -		.pixclk = 36000000,
> -		.pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> -	}, {
> +	},  {
>  		.pixclk = 36036000,
>  		.pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
> -	}, {
> -		.pixclk = 40000000,
> -		.pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> -	}, {
> -		.pixclk = 43200000,
> -		.pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 43243200,
>  		.pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
> @@ -132,19 +114,13 @@ static const struct phy_config phy_pll_cfg[] = {
>  	}, {
>  		.pixclk = 50349650,
>  		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
> -	}, {
> -		.pixclk = 50400000,
> -		.pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 53250000,
>  		.pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
>  	}, {
>  		.pixclk = 53500000,
>  		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
> -	}, {
> -		.pixclk = 54000000,
> -		.pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
> -	}, {
> +	},  {
>  		.pixclk = 54054000,
>  		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
> @@ -153,10 +129,7 @@ static const struct phy_config phy_pll_cfg[] = {
>  	}, {
>  		.pixclk = 59340659,
>  		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
> -	}, {
> -		.pixclk = 59400000,
> -		.pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
> -	}, {
> +	},  {
>  		.pixclk = 61500000,
>  		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
>  	}, {
> @@ -168,10 +141,7 @@ static const struct phy_config phy_pll_cfg[] = {
>  	}, {
>  		.pixclk = 70000000,
>  		.pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
> -	}, {
> -		.pixclk = 72000000,
> -		.pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
> -	}, {
> +	},  {
>  		.pixclk = 72072000,
>  		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
> @@ -183,10 +153,7 @@ static const struct phy_config phy_pll_cfg[] = {
>  	}, {
>  		.pixclk = 78500000,
>  		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
> -	}, {
> -		.pixclk = 80000000,
> -		.pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
> -	}, {
> +	},  {
>  		.pixclk = 82000000,
>  		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
>  	}, {
> @@ -213,10 +180,7 @@ static const struct phy_config phy_pll_cfg[] = {
>  	}, {
>  		.pixclk = 100699300,
>  		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
> -	}, {
> -		.pixclk = 100800000,
> -		.pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
> -	}, {
> +	},  {
>  		.pixclk = 102500000,
>  		.pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
>  	}, {
> @@ -228,19 +192,13 @@ static const struct phy_config phy_pll_cfg[] = {
>  	}, {
>  		.pixclk = 107000000,
>  		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
> -	}, {
> -		.pixclk = 108000000,
> -		.pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
> -	}, {
> +	},  {
>  		.pixclk = 108108000,
>  		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 118000000,
>  		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
> -	}, {
> -		.pixclk = 118800000,
> -		.pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
> -	}, {
> +	},  {
>  		.pixclk = 123000000,
>  		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
>  	}, {
> @@ -261,10 +219,7 @@ static const struct phy_config phy_pll_cfg[] = {
>  	}, {
>  		.pixclk = 140000000,
>  		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
> -	}, {
> -		.pixclk = 144000000,
> -		.pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
> -	}, {
> +	},  {
>  		.pixclk = 148352000,
>  		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
>  	}, {
> @@ -288,9 +243,6 @@ static const struct phy_config phy_pll_cfg[] = {
>  	}, {
>  		.pixclk = 165000000,
>  		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
> -	}, {
> -		.pixclk = 180000000,
> -		.pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 185625000,
>  		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
> @@ -309,25 +261,16 @@ static const struct phy_config phy_pll_cfg[] = {
>  	}, {
>  		.pixclk = 213000000,
>  		.pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
> -	}, {
> -		.pixclk = 216000000,
> -		.pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
>  	}, {
>  		.pixclk = 216216000,
>  		.pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
> -	}, {
> -		.pixclk = 237600000,
> -		.pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
> -	}, {
> +	},  {
>  		.pixclk = 254000000,
>  		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
>  	}, {
>  		.pixclk = 277500000,
>  		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
> -	}, {
> -		.pixclk = 288000000,
> -		.pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
> -	}, {
> +	},  {
>  		.pixclk = 297000000,
>  		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
>  	},


From dominique.martinet at atmark-techno.com  Tue Sep 10 23:08:07 2024
From: dominique.martinet at atmark-techno.com (Dominique Martinet)
Date: Wed, 11 Sep 2024 15:08:07 +0900
Subject: [PATCH 0/2] Extending PLL LUT for i.MX8MP Samsung HDMI PHY
In-Reply-To: <ZuDjAwPxHeJTvXAp@atmark-techno.com>
References: <20240910181544.214797-1-frieder@fris.de>
 <ZuDjAwPxHeJTvXAp@atmark-techno.com>
Message-ID: <ZuEzxw96vRlYJ321@atmark-techno.com>

Dominique Martinet wrote on Wed, Sep 11, 2024 at 09:23:31AM +0900:
> so if I find some time I'll whip some loop to check all other values...

There were more differences than I thought there'd be (see diff below)

they're all minor enough to probably not care, but your script finds
exact values for them so it might be worth updating the regs if we keep
the table...
(OTOH these seem to work, and "if it works don't touch it" -- I have no
further opinion now I've checked, curiosity is sated)

Might want to just check 154000000 though, reg6's 0x80 was not set so
SDC was disabled? and it'd get the integer fraction (153600000) instead
if I understand this correctly

---------
diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index a5ad51425ee3..72facc7bd045 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -73,7 +73,7 @@ static const struct phy_config phy_pll_cfg[] = {
 		.pixclk = 24024000,
 		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
 	}, {
-		.pixclk = 25175000,
+		.pixclk = 25177981,
 		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
 	},  {
 		.pixclk = 26750000,
@@ -82,16 +82,16 @@ static const struct phy_config phy_pll_cfg[] = {
 		.pixclk = 27027000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
-		.pixclk = 29500000,
+		.pixclk = 29487500,
 		.pll_div_regs = { 0xd1, 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
 	}, {
-		.pixclk = 30750000,
+		.pixclk = 30729661,
 		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
 	}, {
-		.pixclk = 30888000,
+		.pixclk = 30848949,
 		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
 	}, {
-		.pixclk = 33750000,
+		.pixclk = 33731250,
 		.pll_div_regs = { 0xd1, 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 35000000,
@@ -106,13 +106,13 @@ static const struct phy_config phy_pll_cfg[] = {
 		.pixclk = 44500000,
 		.pll_div_regs = { 0xd1, 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
 	}, {
-		.pixclk = 47000000,
+		.pixclk = 47005000,
 		.pll_div_regs = { 0xd1, 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
 	}, {
-		.pixclk = 47500000,
+		.pixclk = 47502000,
 		.pll_div_regs = { 0xd1, 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
 	}, {
-		.pixclk = 50349650,
+		.pixclk = 50355924,
 		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
 	}, {
 		.pixclk = 53250000,
@@ -124,16 +124,16 @@ static const struct phy_config phy_pll_cfg[] = {
 		.pixclk = 54054000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
-		.pixclk = 59000000,
+		.pixclk = 58975000,
 		.pll_div_regs = { 0xd1, 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
 	}, {
-		.pixclk = 59340659,
+		.pixclk = 59264777,
 		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
 	},  {
-		.pixclk = 61500000,
+		.pixclk = 61459322,
 		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
 	}, {
-		.pixclk = 63500000,
+		.pixclk = 63437500,
 		.pll_div_regs = { 0xd1, 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 67500000,
@@ -145,25 +145,25 @@ static const struct phy_config phy_pll_cfg[] = {
 		.pixclk = 72072000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
-		.pixclk = 74176000,
+		.pixclk = 74175824,
 		.pll_div_regs = { 0xd1, 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
 	}, {
 		.pixclk = 74250000,
 		.pll_div_regs = { 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
 	}, {
-		.pixclk = 78500000,
+		.pixclk = 78487500,
 		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
 	},  {
-		.pixclk = 82000000,
+		.pixclk = 81945763,
 		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
 	}, {
-		.pixclk = 82500000,
+		.pixclk = 82486555,
 		.pll_div_regs = { 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
 	}, {
-		.pixclk = 89000000,
+		.pixclk = 89075000,
 		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
 	}, {
-		.pixclk = 90000000,
+		.pixclk = 89950000,
 		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 94000000,
@@ -178,7 +178,7 @@ static const struct phy_config phy_pll_cfg[] = {
 		.pixclk = 99000000,
 		.pll_div_regs = { 0xd1, 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
 	}, {
-		.pixclk = 100699300,
+		.pixclk = 100711847,
 		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
 	},  {
 		.pixclk = 102500000,
@@ -196,16 +196,16 @@ static const struct phy_config phy_pll_cfg[] = {
 		.pixclk = 108108000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
-		.pixclk = 118000000,
+		.pixclk = 117950000,
 		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
 	},  {
-		.pixclk = 123000000,
+		.pixclk = 122918644,
 		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
 	}, {
-		.pixclk = 127000000,
+		.pixclk = 126875000,
 		.pll_div_regs = { 0xd1, 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
 	}, {
-		.pixclk = 135000000,
+		.pixclk = 134925000,
 		.pll_div_regs = { 0xd1, 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 135580000,
@@ -214,20 +214,20 @@ static const struct phy_config phy_pll_cfg[] = {
 		.pixclk = 137520000,
 		.pll_div_regs = { 0xd1, 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
 	}, {
-		.pixclk = 138750000,
+		.pixclk = 138658397,
 		.pll_div_regs = { 0xd1, 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
 	}, {
-		.pixclk = 140000000,
+		.pixclk = 140040000,
 		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
 	},  {
-		.pixclk = 148352000,
+		.pixclk = 148265128,
 		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
 	}, {
-		.pixclk = 148500000,
+		.pixclk = 148396403,
 		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
 	}, {
 		.pixclk = 154000000,
-		.pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
+		.pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 157000000,
 		.pll_div_regs = { 0xd1, 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
@@ -268,10 +268,10 @@ static const struct phy_config phy_pll_cfg[] = {
 		.pixclk = 254000000,
 		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
 	}, {
-		.pixclk = 277500000,
+		.pixclk = 277316794,
 		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
 	},  {
-		.pixclk = 297000000,
+		.pixclk = 296792806,
 		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
 	},
 };
-------------
-- 
Dominique


From xu.yang_2 at nxp.com  Tue Sep 10 23:09:02 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 11 Sep 2024 14:09:02 +0800
Subject: [PATCH v4 5/5] arm64: dts: imx95-19x19-evk: add typec nodes and
 enable usb3 node
In-Reply-To: <ZuCaquGr+ocHmD6x@lizhi-Precision-Tower-5810>
References: <20240910070339.4150883-1-xu.yang_2@nxp.com>
 <20240910070339.4150883-5-xu.yang_2@nxp.com>
 <ZuCaquGr+ocHmD6x@lizhi-Precision-Tower-5810>
Message-ID: <20240911060902.pjfrkjbyuvcqso45@hippo>

On Tue, Sep 10, 2024 at 03:14:50PM -0400, Frank Li wrote:
> On Tue, Sep 10, 2024 at 03:03:39PM +0800, Xu Yang wrote:
> > This board has one Type-C port which has USB3 capability. This will
> > add typec nodes and enable usb3 node.
> >
> > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> >
> > ---
> > Changes in v2:
> >  - no changes
> > Changes in v3:
> >  - no changes
> > Changes in v4:
> >  - no changes
> > ---
> >  .../boot/dts/freescale/imx95-19x19-evk.dts    | 81 +++++++++++++++++++
> >  1 file changed, 81 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
> > index d14a54ab4fd4..46a9cd3d4403 100644
> > --- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
> > +++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
> > @@ -5,6 +5,7 @@
> >
> >  /dts-v1/;
> >
> > +#include <dt-bindings/usb/pd.h>
> >  #include "imx95.dtsi"
> >
> >  / {
> > @@ -99,6 +100,48 @@ i2c7_pcal6524: i2c7-gpio at 22 {
> >  		interrupt-parent = <&gpio5>;
> >  		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
> >  	};
> > +
> > +	ptn5110: tcpc at 50 {
> > +		compatible = "nxp,ptn5110", "tcpci";
> > +		reg = <0x50>;
> > +		pinctrl-names = "default";
> > +		pinctrl-0 = <&pinctrl_typec>;
> > +		interrupt-parent = <&gpio5>;
> > +		interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
> > +
> > +		typec_con: connector {
> > +			compatible = "usb-c-connector";
> > +			label = "USB-C";
> > +			power-role = "dual";
> > +			data-role = "dual";
> > +			try-power-role = "sink";
> > +			source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
> > +			sink-pdos = <PDO_FIXED(5000, 0, PDO_FIXED_USB_COMM)>;
> > +			op-sink-microwatt = <0>;
> > +			self-powered;
> > +
> > +			ports {
> > +				#address-cells = <1>;
> > +				#size-cells = <0>;
> > +
> > +				port at 0 {
> > +					reg = <0>;
> > +
> > +					typec_con_hs: endpoint {
> > +						remote-endpoint = <&usb3_data_hs>;
> > +					};
> > +				};
> > +
> > +				port at 1 {
> > +					reg = <1>;
> > +
> > +					typec_con_ss: endpoint {
> > +						remote-endpoint = <&usb3_data_ss>;
> > +					};
> > +				};
> > +			};
> > +		};
> > +	};
> >  };
> >
> >  &lpuart1 {
> > @@ -128,6 +171,38 @@ &pcie1 {
> >  	status = "okay";
> >  };
> >
> > +&usb3 {
> > +	status = "okay";
> > +};
> > +
> > +&usb3_phy {
> > +	status = "okay";
> > +
> > +	port {
> > +		usb3_data_ss: endpoint {
> > +			remote-endpoint = <&typec_con_ss>;
> > +		};
> > +	};
> > +};
> 
> Please keep node name alphabet order
> usb3_phy should be after usb3_dwc3.

Okay. Will fix the order.

Thanks,
Xu Yang



From xu.yang_2 at nxp.com  Tue Sep 10 23:17:16 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 11 Sep 2024 14:17:16 +0800
Subject: [PATCH v5 1/5] dt-bindings: phy: imx8mq-usb: add compatible "fsl,imx95-usb-phy"
Message-ID: <20240911061720.495606-1-xu.yang_2@nxp.com>

The usb phy in i.MX95 is compatible with i.MX8MP's, this will add a
compatible "fsl,imx95-usb-phy" for i.MX95. Also change reg maxItems
to 2 since i.MX95 needs another regmap to control Type-C Assist (TCA)
block. Since i.MX95 usb phy is able to switch SS lanes, this will also
add orientation-switch and port property to the file.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - replace minItems with description in reg property
 - remove orientation-switch and port
 - refer to usb-switch.yaml
 - use unevaluatedProperties
Changes in v3:
 - add Rb tag
Changes in v4:
 - no changes
Changes in v5:
 - no changes
---
 .../bindings/phy/fsl,imx8mq-usb-phy.yaml      | 42 ++++++++++++++++---
 1 file changed, 37 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
index dc3a3f709fea..6d6d211883ae 100644
--- a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
@@ -11,12 +11,17 @@ maintainers:
 
 properties:
   compatible:
-    enum:
-      - fsl,imx8mq-usb-phy
-      - fsl,imx8mp-usb-phy
+    oneOf:
+      - enum:
+          - fsl,imx8mq-usb-phy
+          - fsl,imx8mp-usb-phy
+      - items:
+          - const: fsl,imx95-usb-phy
+          - const: fsl,imx8mp-usb-phy
 
   reg:
-    maxItems: 1
+    minItems: 1
+    maxItems: 2
 
   "#phy-cells":
     const: 0
@@ -89,7 +94,34 @@ required:
   - clocks
   - clock-names
 
-additionalProperties: false
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx95-usb-phy
+    then:
+      properties:
+        reg:
+          items:
+            - description: USB PHY Control range
+            - description: USB PHY TCA Block range
+    else:
+      properties:
+        reg:
+          maxItems: 1
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx95-usb-phy
+    then:
+      $ref: /schemas/usb/usb-switch.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
-- 
2.34.1



From xu.yang_2 at nxp.com  Tue Sep 10 23:17:17 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 11 Sep 2024 14:17:17 +0800
Subject: [PATCH v5 2/5] dt-bindings: usb: dwc3-imx8mp: add compatible string for imx95
In-Reply-To: <20240911061720.495606-1-xu.yang_2@nxp.com>
References: <20240911061720.495606-1-xu.yang_2@nxp.com>
Message-ID: <20240911061720.495606-2-xu.yang_2@nxp.com>

The i.MX95 is compatible with i.MX8MP's usb controller. This will add a
compatible string "fsl,imx95-dwc3" for i.MX95.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - add Ack-by tag
Changes in v3:
 - no changes
Changes in v4:
 - no changes
Changes in v5:
 - no changes
---
 Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
index 9ea1e4cd0709..baf130669c38 100644
--- a/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
@@ -12,7 +12,11 @@ maintainers:
 
 properties:
   compatible:
-    const: fsl,imx8mp-dwc3
+    oneOf:
+      - items:
+          - const: fsl,imx95-dwc3
+          - const: fsl,imx8mp-dwc3
+      - const: fsl,imx8mp-dwc3
 
   reg:
     items:
-- 
2.34.1



From xu.yang_2 at nxp.com  Tue Sep 10 23:17:18 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 11 Sep 2024 14:17:18 +0800
Subject: [PATCH v5 3/5] phy: fsl-imx8mq-usb: add tca function driver for imx95
In-Reply-To: <20240911061720.495606-1-xu.yang_2@nxp.com>
References: <20240911061720.495606-1-xu.yang_2@nxp.com>
Message-ID: <20240911061720.495606-3-xu.yang_2@nxp.com>

The i.MX95 USB3 phy has a Type-C Assist block (TCA). This block consists
two functional blocks (XBar assist and VBus assist) and one system
access interface using APB.

The primary functionality of XBar assist is:
 - switching lane for flip
 - moving unused lanes into lower power states.

This info can be get from:
i.MX95 RM Chapter 163.3.8 Type-C assist (TCA) block.

This will add support for TCA block to achieve lane switching and tca
lower power functionality.

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

---
Changes in v2:
 - return the value of imx95_usb_phy_get_tca()
Changes in v3:
 - no changes
Changes in v4:
 - remove compatible check for imx95
 - check whether tca register region exist or not, yes means has tca,
   otherwise skip tca setup
Changes in v5:
 - no changes
---
 drivers/phy/freescale/Kconfig              |   1 +
 drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 243 +++++++++++++++++++++
 2 files changed, 244 insertions(+)

diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index dcd9acff6d01..81f53564ee15 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -5,6 +5,7 @@ if (ARCH_MXC && ARM64) || COMPILE_TEST
 config PHY_FSL_IMX8MQ_USB
 	tristate "Freescale i.MX8M USB3 PHY"
 	depends on OF && HAS_IOMEM
+	depends on TYPEC || TYPEC=n
 	select GENERIC_PHY
 	default ARCH_MXC && ARM64
 
diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
index adc6394626ce..f97f86644b2c 100644
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
@@ -10,6 +10,7 @@
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/usb/typec_mux.h>
 
 #define PHY_CTRL0			0x0
 #define PHY_CTRL0_REF_SSP_EN		BIT(2)
@@ -50,11 +51,66 @@
 
 #define PHY_TUNE_DEFAULT		0xffffffff
 
+#define TCA_CLK_RST			0x00
+#define TCA_CLK_RST_SW			BIT(9)
+#define TCA_CLK_RST_REF_CLK_EN		BIT(1)
+#define TCA_CLK_RST_SUSPEND_CLK_EN	BIT(0)
+
+#define TCA_INTR_EN			0x04
+#define TCA_INTR_STS			0x08
+
+#define TCA_GCFG			0x10
+#define TCA_GCFG_ROLE_HSTDEV		BIT(4)
+#define TCA_GCFG_OP_MODE		GENMASK(1, 0)
+#define TCA_GCFG_OP_MODE_SYSMODE	0
+#define TCA_GCFG_OP_MODE_SYNCMODE	1
+
+#define TCA_TCPC			0x14
+#define TCA_TCPC_VALID			BIT(4)
+#define TCA_TCPC_LOW_POWER_EN		BIT(3)
+#define TCA_TCPC_ORIENTATION_NORMAL	BIT(2)
+#define TCA_TCPC_MUX_CONTRL		GENMASK(1, 0)
+#define TCA_TCPC_MUX_CONTRL_NO_CONN	0
+#define TCA_TCPC_MUX_CONTRL_USB_CONN	1
+
+#define TCA_SYSMODE_CFG			0x18
+#define TCA_SYSMODE_TCPC_DISABLE	BIT(3)
+#define TCA_SYSMODE_TCPC_FLIP		BIT(2)
+
+#define TCA_CTRLSYNCMODE_CFG0		0x20
+#define TCA_CTRLSYNCMODE_CFG1           0x20
+
+#define TCA_PSTATE			0x30
+#define TCA_PSTATE_CM_STS		BIT(4)
+#define TCA_PSTATE_TX_STS		BIT(3)
+#define TCA_PSTATE_RX_PLL_STS		BIT(2)
+#define TCA_PSTATE_PIPE0_POWER_DOWN	GENMASK(1, 0)
+
+#define TCA_GEN_STATUS			0x34
+#define TCA_GEN_DEV_POR			BIT(12)
+#define TCA_GEN_REF_CLK_SEL		BIT(8)
+#define TCA_GEN_TYPEC_FLIP_INVERT	BIT(4)
+#define TCA_GEN_PHY_TYPEC_DISABLE	BIT(3)
+#define TCA_GEN_PHY_TYPEC_FLIP		BIT(2)
+
+#define TCA_VBUS_CTRL			0x40
+#define TCA_VBUS_STATUS			0x44
+
+#define TCA_INFO			0xFC
+
+struct tca_blk {
+	struct typec_switch_dev *sw;
+	void __iomem *base;
+	struct mutex mutex;
+	enum typec_orientation orientation;
+};
+
 struct imx8mq_usb_phy {
 	struct phy *phy;
 	struct clk *clk;
 	void __iomem *base;
 	struct regulator *vbus;
+	struct tca_blk *tca;
 	u32 pcs_tx_swing_full;
 	u32 pcs_tx_deemph_3p5db;
 	u32 tx_vref_tune;
@@ -64,6 +120,175 @@ struct imx8mq_usb_phy {
 	u32 comp_dis_tune;
 };
 
+
+static void tca_blk_orientation_set(struct tca_blk *tca,
+				enum typec_orientation orientation);
+
+#ifdef CONFIG_TYPEC
+
+static int tca_blk_typec_switch_set(struct typec_switch_dev *sw,
+				enum typec_orientation orientation)
+{
+	struct imx8mq_usb_phy *imx_phy = typec_switch_get_drvdata(sw);
+	struct tca_blk *tca = imx_phy->tca;
+	int ret;
+
+	if (tca->orientation == orientation)
+		return 0;
+
+	ret = clk_prepare_enable(imx_phy->clk);
+	if (ret)
+		return ret;
+
+	tca_blk_orientation_set(tca, orientation);
+	clk_disable_unprepare(imx_phy->clk);
+
+	return 0;
+}
+
+static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device *pdev,
+					struct imx8mq_usb_phy *imx_phy)
+{
+	struct device *dev = &pdev->dev;
+	struct typec_switch_dev *sw;
+	struct typec_switch_desc sw_desc = { };
+
+	sw_desc.drvdata = imx_phy;
+	sw_desc.fwnode = dev->fwnode;
+	sw_desc.set = tca_blk_typec_switch_set;
+	sw_desc.name = NULL;
+
+	sw = typec_switch_register(dev, &sw_desc);
+	if (IS_ERR(sw)) {
+		dev_err(dev, "Error register tca orientation switch: %ld",
+				PTR_ERR(sw));
+		return NULL;
+	}
+
+	return sw;
+}
+
+static void tca_blk_put_typec_switch(struct typec_switch_dev *sw)
+{
+	typec_switch_unregister(sw);
+}
+
+#else
+
+static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device *pdev,
+			struct imx8mq_usb_phy *imx_phy)
+{
+	return NULL;
+}
+
+static void tca_blk_put_typec_switch(struct typec_switch_dev *sw) {}
+
+#endif /* CONFIG_TYPEC */
+
+static void tca_blk_orientation_set(struct tca_blk *tca,
+				enum typec_orientation orientation)
+{
+	u32 val;
+
+	mutex_lock(&tca->mutex);
+
+	if (orientation == TYPEC_ORIENTATION_NONE) {
+		/*
+		 * use Controller Synced Mode for TCA low power enable and
+		 * put PHY to USB safe state.
+		 */
+		val = readl(tca->base + TCA_GCFG);
+		val = FIELD_PREP(TCA_GCFG_OP_MODE, TCA_GCFG_OP_MODE_SYNCMODE);
+		writel(val, tca->base + TCA_GCFG);
+
+		val = readl(tca->base + TCA_TCPC);
+		val = TCA_TCPC_VALID | TCA_TCPC_LOW_POWER_EN;
+		writel(val, tca->base + TCA_TCPC);
+
+		goto out;
+	}
+
+	/* use System Configuration Mode for TCA mux control. */
+	val = readl(tca->base + TCA_GCFG);
+	val = FIELD_PREP(TCA_GCFG_OP_MODE, TCA_GCFG_OP_MODE_SYSMODE);
+	writel(val, tca->base + TCA_GCFG);
+
+	/* Disable TCA module */
+	val = readl(tca->base + TCA_SYSMODE_CFG);
+	val |= TCA_SYSMODE_TCPC_DISABLE;
+	writel(val, tca->base + TCA_SYSMODE_CFG);
+
+	if (orientation == TYPEC_ORIENTATION_REVERSE)
+		val |= TCA_SYSMODE_TCPC_FLIP;
+	else if (orientation == TYPEC_ORIENTATION_NORMAL)
+		val &= ~TCA_SYSMODE_TCPC_FLIP;
+
+	writel(val, tca->base + TCA_SYSMODE_CFG);
+
+	/* Enable TCA module */
+	val &= ~TCA_SYSMODE_TCPC_DISABLE;
+	writel(val, tca->base + TCA_SYSMODE_CFG);
+
+out:
+	tca->orientation = orientation;
+	mutex_unlock(&tca->mutex);
+}
+
+static void tca_blk_init(struct tca_blk *tca)
+{
+	u32 val;
+
+	/* reset XBar block */
+	val = readl(tca->base + TCA_CLK_RST);
+	val &= ~TCA_CLK_RST_SW;
+	writel(val, tca->base + TCA_CLK_RST);
+
+	udelay(100);
+
+	/* clear reset */
+	val |= TCA_CLK_RST_SW;
+	writel(val, tca->base + TCA_CLK_RST);
+
+	tca_blk_orientation_set(tca, tca->orientation);
+}
+
+static struct tca_blk *imx95_usb_phy_get_tca(struct platform_device *pdev,
+				struct imx8mq_usb_phy *imx_phy)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct tca_blk *tca;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res)
+		return 0;
+
+	tca = devm_kzalloc(dev, sizeof(*tca), GFP_KERNEL);
+	if (!tca)
+		return ERR_PTR(-ENOMEM);
+
+	tca->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(tca->base))
+		return tca->base;
+
+	mutex_init(&tca->mutex);
+
+	tca->orientation = TYPEC_ORIENTATION_NORMAL;
+	tca->sw = tca_blk_get_typec_switch(pdev, imx_phy);
+
+	return tca;
+}
+
+static void imx95_usb_phy_put_tca(struct imx8mq_usb_phy *imx_phy)
+{
+	struct tca_blk *tca = imx_phy->tca;
+
+	if (!tca)
+		return;
+
+	tca_blk_put_typec_switch(tca->sw);
+}
+
 static u32 phy_tx_vref_tune_from_property(u32 percent)
 {
 	percent = clamp(percent, 94U, 124U);
@@ -315,6 +540,9 @@ static int imx8mp_usb_phy_init(struct phy *phy)
 
 	imx8m_phy_tune(imx_phy);
 
+	if (imx_phy->tca)
+		tca_blk_init(imx_phy->tca);
+
 	return 0;
 }
 
@@ -359,6 +587,8 @@ static const struct of_device_id imx8mq_usb_phy_of_match[] = {
 	 .data = &imx8mq_usb_phy_ops,},
 	{.compatible = "fsl,imx8mp-usb-phy",
 	 .data = &imx8mp_usb_phy_ops,},
+	{.compatible = "fsl,imx95-usb-phy",
+	 .data = &imx8mp_usb_phy_ops,},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, imx8mq_usb_phy_of_match);
@@ -398,6 +628,11 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 
 	phy_set_drvdata(imx_phy->phy, imx_phy);
 
+	imx_phy->tca = imx95_usb_phy_get_tca(pdev, imx_phy);
+	if (IS_ERR(imx_phy->tca))
+		return dev_err_probe(dev, PTR_ERR(imx_phy->tca),
+					"failed to get tca\n");
+
 	imx8m_get_phy_tuning_data(imx_phy);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
@@ -405,8 +640,16 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 	return PTR_ERR_OR_ZERO(phy_provider);
 }
 
+static void imx8mq_usb_phy_remove(struct platform_device *pdev)
+{
+	struct imx8mq_usb_phy *imx_phy = platform_get_drvdata(pdev);
+
+	imx95_usb_phy_put_tca(imx_phy);
+}
+
 static struct platform_driver imx8mq_usb_phy_driver = {
 	.probe	= imx8mq_usb_phy_probe,
+	.remove = imx8mq_usb_phy_remove,
 	.driver = {
 		.name	= "imx8mq-usb-phy",
 		.of_match_table	= imx8mq_usb_phy_of_match,
-- 
2.34.1



From xu.yang_2 at nxp.com  Tue Sep 10 23:17:19 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 11 Sep 2024 14:17:19 +0800
Subject: [PATCH v5 4/5] arm64: dts: imx95: add usb3 related nodes
In-Reply-To: <20240911061720.495606-1-xu.yang_2@nxp.com>
References: <20240911061720.495606-1-xu.yang_2@nxp.com>
Message-ID: <20240911061720.495606-4-xu.yang_2@nxp.com>

Add usb3 phy and controller nodes for imx95.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - no changes
Changes in v3:
 - no changes
Changes in v4:
 - reorder nodes
Changes in v5:
 - no changes
---
 arch/arm64/boot/dts/freescale/imx95.dtsi | 43 ++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
index 425272aa5a81..2377b3ade95a 100644
--- a/arch/arm64/boot/dts/freescale/imx95.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
@@ -1188,5 +1188,48 @@ pcie1_ep: pcie-ep at 4c380000 {
 			power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
 			status = "disabled";
 		};
+
+		usb3: usb at 4c010010 {
+			compatible = "fsl,imx95-dwc3", "fsl,imx8mp-dwc3";
+			reg = <0x0 0x4c010010 0x0 0x04>,
+			      <0x0 0x4c1f0000 0x0 0x20>;
+			clocks = <&scmi_clk IMX95_CLK_HSIO>,
+				 <&scmi_clk IMX95_CLK_32K>;
+			clock-names = "hsio", "suspend";
+			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
+			dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
+			status = "disabled";
+
+			usb3_dwc3: usb at 4c100000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x4c100000 0x0 0x10000>;
+				clocks = <&scmi_clk IMX95_CLK_HSIO>,
+					 <&scmi_clk IMX95_CLK_24M>,
+					 <&scmi_clk IMX95_CLK_32K>;
+				clock-names = "bus_early", "ref", "suspend";
+				interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+				phys = <&usb3_phy>, <&usb3_phy>;
+				phy-names = "usb2-phy", "usb3-phy";
+				snps,gfladj-refclk-lpm-sel-quirk;
+				snps,parkmode-disable-ss-quirk;
+				iommus = <&smmu 0xe>;
+			};
+		};
+
+		usb3_phy: phy at 4c1f0040 {
+			compatible = "fsl,imx95-usb-phy", "fsl,imx8mp-usb-phy";
+			reg = <0x0 0x4c1f0040 0x0 0x40>,
+			      <0x0 0x4c1fc000 0x0 0x100>;
+			clocks = <&scmi_clk IMX95_CLK_HSIO>;
+			clock-names = "phy";
+			#phy-cells = <0>;
+			power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
+			orientation-switch;
+			status = "disabled";
+		};
 	};
 };
-- 
2.34.1



From xu.yang_2 at nxp.com  Tue Sep 10 23:17:20 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 11 Sep 2024 14:17:20 +0800
Subject: [PATCH v5 5/5] arm64: dts: imx95-19x19-evk: add typec nodes and enable usb3 node
In-Reply-To: <20240911061720.495606-1-xu.yang_2@nxp.com>
References: <20240911061720.495606-1-xu.yang_2@nxp.com>
Message-ID: <20240911061720.495606-5-xu.yang_2@nxp.com>

This board has one Type-C port which has USB3 capability. This will
add typec nodes and enable usb3 node.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - no changes
Changes in v3:
 - no changes
Changes in v4:
 - no changes
Changes in v5:
 - correct nodes order
---
 .../boot/dts/freescale/imx95-19x19-evk.dts    | 81 +++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
index d14a54ab4fd4..a6888fdb6c0a 100644
--- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/usb/pd.h>
 #include "imx95.dtsi"
 
 / {
@@ -99,6 +100,48 @@ i2c7_pcal6524: i2c7-gpio at 22 {
 		interrupt-parent = <&gpio5>;
 		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
 	};
+
+	ptn5110: tcpc at 50 {
+		compatible = "nxp,ptn5110", "tcpci";
+		reg = <0x50>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_typec>;
+		interrupt-parent = <&gpio5>;
+		interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
+
+		typec_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			power-role = "dual";
+			data-role = "dual";
+			try-power-role = "sink";
+			source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+			sink-pdos = <PDO_FIXED(5000, 0, PDO_FIXED_USB_COMM)>;
+			op-sink-microwatt = <0>;
+			self-powered;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					typec_con_hs: endpoint {
+						remote-endpoint = <&usb3_data_hs>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					typec_con_ss: endpoint {
+						remote-endpoint = <&usb3_data_ss>;
+					};
+				};
+			};
+		};
+	};
 };
 
 &lpuart1 {
@@ -128,6 +171,38 @@ &pcie1 {
 	status = "okay";
 };
 
+&usb3 {
+	status = "okay";
+};
+
+&usb3_dwc3 {
+	dr_mode = "otg";
+	hnp-disable;
+	srp-disable;
+	adp-disable;
+	usb-role-switch;
+	role-switch-default-mode = "peripheral";
+	snps,dis-u1-entry-quirk;
+	snps,dis-u2-entry-quirk;
+	status = "okay";
+
+	port {
+		usb3_data_hs: endpoint {
+			remote-endpoint = <&typec_con_hs>;
+		};
+	};
+};
+
+&usb3_phy {
+	status = "okay";
+
+	port {
+		usb3_data_ss: endpoint {
+			remote-endpoint = <&typec_con_ss>;
+		};
+	};
+};
+
 &usdhc1 {
 	pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
 	pinctrl-0 = <&pinctrl_usdhc1>;
@@ -245,6 +320,12 @@ IMX95_PAD_SD2_RESET_B__GPIO3_IO_BIT7		0x31e
 		>;
 	};
 
+	pinctrl_typec: typecgrp {
+		fsl,pins = <
+			IMX95_PAD_GPIO_IO34__GPIO5_IO_BIT14			0x31e
+		>;
+	};
+
 	pinctrl_usdhc2_gpio: usdhc2gpiogrp {
 		fsl,pins = <
 			IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0		0x31e
-- 
2.34.1



From quic_jingyw at quicinc.com  Tue Sep 10 23:56:16 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 11 Sep 2024 14:56:16 +0800
Subject: [PATCH v2] dt-bindings: phy: Add QMP UFS PHY comptible for QCS8300
Message-ID: <20240911-qcs8300_ufs_phy_binding-v2-1-c801a2d27a84@quicinc.com>

From: Xin Liu <quic_liuxin at quicinc.com>

Document the QMP UFS PHY compatible for Qualcomm QCS8300 to support
physical layer functionality for UFS found on the SoC. Use fallback to
indicate the compatibility of the QMP UFS PHY on the QCS8300 with that
on the SA8775P.

Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
Changes in v2:
- decoupled from the original series.
- Use fallback to indicate compatibility with SA8775P.
- typo fixup
- Link to v1: https://lore.kernel.org/r/20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007 at quicinc.com
---
 .../bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml    | 46 ++++++++++++----------
 1 file changed, 26 insertions(+), 20 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
index f9cfbd0b2de6..626a2039e177 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
@@ -15,26 +15,31 @@ description:
 
 properties:
   compatible:
-    enum:
-      - qcom,msm8996-qmp-ufs-phy
-      - qcom,msm8998-qmp-ufs-phy
-      - qcom,sa8775p-qmp-ufs-phy
-      - qcom,sc7180-qmp-ufs-phy
-      - qcom,sc7280-qmp-ufs-phy
-      - qcom,sc8180x-qmp-ufs-phy
-      - qcom,sc8280xp-qmp-ufs-phy
-      - qcom,sdm845-qmp-ufs-phy
-      - qcom,sm6115-qmp-ufs-phy
-      - qcom,sm6125-qmp-ufs-phy
-      - qcom,sm6350-qmp-ufs-phy
-      - qcom,sm7150-qmp-ufs-phy
-      - qcom,sm8150-qmp-ufs-phy
-      - qcom,sm8250-qmp-ufs-phy
-      - qcom,sm8350-qmp-ufs-phy
-      - qcom,sm8450-qmp-ufs-phy
-      - qcom,sm8475-qmp-ufs-phy
-      - qcom,sm8550-qmp-ufs-phy
-      - qcom,sm8650-qmp-ufs-phy
+    oneOf:
+      - items:
+          - enum:
+              - qcom,qcs8300-qmp-ufs-phy
+          - const: qcom,sa8775p-qmp-ufs-phy
+      - enum:
+          - qcom,msm8996-qmp-ufs-phy
+          - qcom,msm8998-qmp-ufs-phy
+          - qcom,sa8775p-qmp-ufs-phy
+          - qcom,sc7180-qmp-ufs-phy
+          - qcom,sc7280-qmp-ufs-phy
+          - qcom,sc8180x-qmp-ufs-phy
+          - qcom,sc8280xp-qmp-ufs-phy
+          - qcom,sdm845-qmp-ufs-phy
+          - qcom,sm6115-qmp-ufs-phy
+          - qcom,sm6125-qmp-ufs-phy
+          - qcom,sm6350-qmp-ufs-phy
+          - qcom,sm7150-qmp-ufs-phy
+          - qcom,sm8150-qmp-ufs-phy
+          - qcom,sm8250-qmp-ufs-phy
+          - qcom,sm8350-qmp-ufs-phy
+          - qcom,sm8450-qmp-ufs-phy
+          - qcom,sm8475-qmp-ufs-phy
+          - qcom,sm8550-qmp-ufs-phy
+          - qcom,sm8650-qmp-ufs-phy
 
   reg:
     maxItems: 1
@@ -85,6 +90,7 @@ allOf:
           contains:
             enum:
               - qcom,msm8998-qmp-ufs-phy
+              - qcom,qcs8300-qmp-ufs-phy
               - qcom,sa8775p-qmp-ufs-phy
               - qcom,sc7180-qmp-ufs-phy
               - qcom,sc7280-qmp-ufs-phy

---
base-commit: 100cc857359b5d731407d1038f7e76cd0e871d94
change-id: 20240911-qcs8300_ufs_phy_binding-84640e3e7bb7

Best regards,
-- 
Jingyi Wang <quic_jingyw at quicinc.com>



From frieder.schrempf at kontron.de  Wed Sep 11 00:01:13 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Wed, 11 Sep 2024 09:01:13 +0200
Subject: [PATCH V7 3/5] xphy: freescale: fsl-samsung-hdmi: Support dynamic
 integer
In-Reply-To: <20240911012838.944630-4-aford173@gmail.com>
References: <20240911012838.944630-1-aford173@gmail.com>
 <20240911012838.944630-4-aford173@gmail.com>
Message-ID: <bbf4ec7e-ef77-485b-b748-4bb3a6baba59@kontron.de>

On 11.09.24 3:28 AM, Adam Ford wrote:
> There is currently a look-up table for a variety of resolutions.
> Since the phy has the ability to dynamically calculate the values
> necessary to use the intger divider which should allow more

                       ^ integer

> resolutions without having to update the look-up-table.
> 
> If the lookup table cannot find an exact match, fall back to the
> dynamic calculator of the integer divider.
> 
> Previously, the value of P was hard-coded to 1, this required an
> update to the phy_pll_cfg table to add in the extra value into the
> table, so if the value of P is calculated to be something else
> by the PMS calculator, the calculated_phy_pll_cfg structure
> can be used instead without having to keep track of which method
> was used.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> ---
> V7:  Refactored much of the code to create smaller helper functions
>      to eliminate redundant code and improve code flow and comment
>      readability.   Any t-b and s-o-b tags removed due to the
>      extent of the changes.
> 
> V6:  Fix comment typos and remove an unnecesary extra calculation
>      by using the cached value.
> V5:  No Change
> V4:  No Change
> V3:  Change size of pll_div_regs to include PHY_REG01 (P)
>      Create calculated_phy_pll_cfg to containe the values
>      Eliminate the PMS calculation from fsl_samsung_hdmi_phy_configure
>      Make the LUT primary and fall back to integer calculator in
>      phy_clk_round_rate.
>      Check the range right away to ensure it's reaonsable rather than
>      trying to find a clock only to learn it's outside the range.
>      Overall added notes and comments where stuff may not be intuitive.
> 
> V2:  Update phy_clk_round_rate and phy_clk_set_rate to both support
>      the integer clock PMS calculator.
> ---
>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 371 +++++++++++++------
>  1 file changed, 265 insertions(+), 106 deletions(-)
> 
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> index 4f6874226f9a..49317a96f767 100644
[...]
> +
> +	/* The ref manual states the values of 'P' range from 1 to 11 */
> +	for (_p = 1; _p <= 11; ++_p) {
> +		for (_s = 1; _s <= 16; ++_s) {
> +			u64 tmp;
> +			u32 delta;
> +
> +			/* s must be one or even */
> +			if (_s > 1 && (_s & 0x01) == 1)
> +				_s++;
> +
> +			/* _s cannot be 14 per the TRM */
> +			if (_s == 14)
> +				continue;
> +
> +			/*
> +			 * TODO: Ref Manual doesn't state the range of _m
> +			 * so this should be further refined if possible.
> +			 * This range was set based on the original values
> +			 * in the lookup table
> +			 */
> +			tmp = (u64)fout * (_p * _s);
> +			do_div(tmp, 24 * MHZ);
> +			_m = tmp;
> +			if (_m < 0x30 || _m > 0x7b)
> +				continue;
> +
> +			/*
> +			 * Rev 2 of the Ref Manual states the
> +			 * VCO can range between 750MHz and
> +			 * 3GHz.  The VCO is assumed to be

                                ^ whitespace

> +			 * is assumed to be (M * f_ref) / P,

                           ^ duplicate "is assumed to be"

> +			 * where f_ref is 24MHz.
> +			 */
> +			tmp = (u64)_m * 24 * MHZ;
> +			do_div(tmp, _p);
> +			if (tmp < 750 * MHZ ||
> +			    tmp > 3000 * MHZ)
> +				continue;
> +
> +			/* Final frequency after post-divider */
> +			do_div(tmp, _s);
> +
> +			delta = abs(fout - tmp);
> +			if (delta < min_delta) {
> +				best_p = _p;
> +				best_s = _s;
> +				best_m = _m;
> +				min_delta = delta;
> +				best_freq = tmp;
> +			}
> +		}
> +	}
> +
> +	if (best_freq) {
> +		*p = best_p;
> +		*m = best_m;
> +		*s = best_s;
> +	}
> +
> +	return best_freq / 5;
> +}
> +
[...]
>  
>  static int phy_clk_set_rate(struct clk_hw *hw,
>  			    unsigned long rate, unsigned long parent_rate)
>  {
>  	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
> -	int i;
> +	const struct phy_config *fract_div_phy;
> +	u32 int_div_clk;
> +	u16 m;
> +	u8 p, s;
>  
> -	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> -		if (phy_pll_cfg[i].pixclk <= rate)
> -			break;
> +	/* Search the fractional divider lookup table */
> +	fract_div_phy = fsl_samsung_hdmi_phy_lookup_rate(rate);
>  
> -	if (i < 0)
> -		return -EINVAL;
> +	/* If the rate is an exact match, use that value */
> +	if (fract_div_phy->pixclk == rate)
> +		goto use_fract_div;

Actually I don't really like the jump here and the even more extensive
jumping in the next patch.

Why not simply create another function and do "return use_fract_div()"
here and below at the end of phy_clk_set_rate().

>  
> -	phy->cur_cfg = &phy_pll_cfg[i];
> +	/*
> +	 * If the rate from the fractional divder is not exact, check the integer divider,
> +	 * and use it if that value is an exact match.
> +	 */
> +	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
> +	if (int_div_clk == rate) {
> +		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n",
> +				   int_div_clk);
> +
> +		fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
> +		phy->cur_cfg  = &calculated_phy_pll_cfg;
> +		return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
> +	}
>  
> +	/*
> +	 * If neither the fractional divder nor the integer divder can find an exact value

                                     ^ divider              ^ divider

> +	 * fall back to using the fractional divider
> +	 */
> +use_fract_div:
> +	phy->cur_cfg = fract_div_phy;
> +	dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider rate = %u\n",
> +			   phy->cur_cfg->pixclk);
>  	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
>  }
>  


From frieder.schrempf at kontron.de  Wed Sep 11 00:07:14 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Wed, 11 Sep 2024 09:07:14 +0200
Subject: [PATCH V7 4/5] phy: freescale: fsl-samsung-hdmi: Use closest
 divider
In-Reply-To: <20240911012838.944630-5-aford173@gmail.com>
References: <20240911012838.944630-1-aford173@gmail.com>
 <20240911012838.944630-5-aford173@gmail.com>
Message-ID: <f2c8b5de-5a51-4b03-8809-d396e99584f6@kontron.de>

On 11.09.24 3:28 AM, Adam Ford wrote:
> Currently, if the clock values cannot be set to the exact rate,
> the round_rate and set_rate functions use the closest value found in
> the look-up-table.  In preparation of removing values from the LUT
> that can be calculated evenly with the integer calculator, it's
> necessary to ensure to check both the look-up-table and the integer
> divider clock values to get the closest values to the requested
> value.  It does this by measuring the difference between the
> requested clock value and the closest value in both integer divider
> calucator and the fractional clock look-up-table.

  ^ calculator

> 
> Which ever has the smallest difference between them is returned as
> the closest rate.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> ---
> V7:  Because of the previous patch refactoring, the flow of this patch
>      changed quite a bit to use more help functions and goto statements
>      to hopefully make the code flow better and improve comment
>      readability.  Because of the change, I removed s-o-b and r-b,
>      and t-b tags.
> 
> V6:  Simplify the calculation of the closest rate and fix
>      a situation where the integer divider values may not be properly
>      setup before they are used.
>      Fixup some comments
> V5:  No Change
> V4:  New to series
> ---
>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 40 ++++++++++++++------
>  1 file changed, 28 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> index 49317a96f767..67a28aac9c45 100644
> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -577,6 +577,16 @@ static void fsl_samsung_hdmi_calculate_phy(struct phy_config *cal_phy, unsigned
>  	/* pll_div_regs 3-6 are fixed and pre-defined already */
>  }
>  
> +static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate,
> +						 u32 int_div_clk, u32 frac_div_clk)
> +{
> +	/* The int_div_clk may be greater than rate, so cast it and use ABS */
> +	if (abs((long)rate - (long)int_div_clk) < (rate - frac_div_clk))
> +		return int_div_clk;
> +
> +	return frac_div_clk;
> +}
> +
>  static long phy_clk_round_rate(struct clk_hw *hw,
>  			       unsigned long rate, unsigned long *parent_rate)
>  {
> @@ -624,27 +634,33 @@ static int phy_clk_set_rate(struct clk_hw *hw,
>  		goto use_fract_div;
>  
>  	/*
> -	 * If the rate from the fractional divder is not exact, check the integer divider,
> +	 * If the rate from the fractional divider is not exact, check the integer divider,
>  	 * and use it if that value is an exact match.
>  	 */
>  	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
> +	fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
>  	if (int_div_clk == rate) {
> -		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n",
> -				   int_div_clk);
> -
> -		fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
> -		phy->cur_cfg  = &calculated_phy_pll_cfg;
> -		return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
> +		goto use_int_div;
>  	}
>  
>  	/*
> -	 * If neither the fractional divder nor the integer divder can find an exact value
> -	 * fall back to using the fractional divider
> +	 * Compare the difference between the integer clock and the fractional clock against
> +	 * the desired clock and which whichever is closest,
>  	 */
> +	if (fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk,
> +						  fract_div_phy->pixclk) == fract_div_phy->pixclk)
> +		goto use_fract_div;
> +
> +use_int_div:
> +	dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n", int_div_clk);
> +	phy->cur_cfg  = &calculated_phy_pll_cfg;
> +	goto end;

You are jumping into this part of the code and then back out again to
the end of the function. In my opinion this is beyond what is generally
considered "good" use of goto. It makes the code hard to read.

Can we rewrite/rearrange this to avoid goto in this function? Just
creating additional functions as necessary and calling them in the right
places should do the job without having duplicated code, no?

> +
>  use_fract_div:
> -	phy->cur_cfg = fract_div_phy;
> -	dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider rate = %u\n",
> -			   phy->cur_cfg->pixclk);
> +	 phy->cur_cfg = fract_div_phy;
> +	 dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider rate = %u\n",
> +		   phy->cur_cfg->pixclk);
> +end:
>  	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
>  }
>  


From quic_qianyu at quicinc.com  Wed Sep 11 01:17:41 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Wed, 11 Sep 2024 16:17:41 +0800
Subject: [PATCH 8/8] PCI: qcom: Add support to PCIe slot power supplies
In-Reply-To: <20240827165826.moe6cnemeheos6jn@thinkpad>
References: <20240827063631.3932971-1-quic_qianyu@quicinc.com>
 <20240827063631.3932971-9-quic_qianyu@quicinc.com>
 <CAA8EJpq5KergZ8czg4F=EYMLANoOeBsiSVoO-zAgfG0ezQrKCQ@mail.gmail.com>
 <20240827165826.moe6cnemeheos6jn@thinkpad>
Message-ID: <26f2845f-2e29-4887-9f33-0b5b2a06adb6@quicinc.com>


On 8/28/2024 12:58 AM, Manivannan Sadhasivam wrote:
> On Tue, Aug 27, 2024 at 02:44:09PM +0300, Dmitry Baryshkov wrote:
>> On Tue, 27 Aug 2024 at 09:36, Qiang Yu <quic_qianyu at quicinc.com> wrote:
>>> On platform x1e80100 QCP, PCIe3 is a standard x8 form factor. Hence, add
>>> support to use 3.3v, 3.3v aux and 12v regulators.
>> First of all, I don't see corresponding bindings change.
>>
>> Second, these supplies power up the slot, not the host controller
>> itself. As such these supplies do not belong to the host controller
>> entry. Please consider using the pwrseq framework instead.
>>
> Indeed. For legacy reasons, slot power supplies were populated in the host
> bridge node itself until recently Rob started objecting it [1]. And it makes
> real sense to put these supplies in the root port node and handle them in the
> relevant driver.
>
> I'm still evaluating whether the handling should be done in the portdrv or
> pwrctl driver, but haven't reached the conclusion. Pwrctl seems to be the ideal
> choice, but I see a few issues related to handling the OF node for the root
> port.
>
> Hope I'll come to a conclusion in the next few days and will update this thread.
>
> - Mani
>
> [1] https://lore.kernel.org/lkml/20240604235806.GA1903493-robh at kernel.org/
Hi Mani, do you have any updates?

Thanks,
Qiang
>
>>> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
>>> ---
>>>   drivers/pci/controller/dwc/pcie-qcom.c | 52 +++++++++++++++++++++++++-
>>>   1 file changed, 50 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
>>> index 6f953e32d990..59fb415dfeeb 100644
>>> --- a/drivers/pci/controller/dwc/pcie-qcom.c
>>> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
>>> @@ -248,6 +248,8 @@ struct qcom_pcie_cfg {
>>>          bool no_l0s;
>>>   };
>>>
>>> +#define QCOM_PCIE_SLOT_MAX_SUPPLIES                    3
>>> +
>>>   struct qcom_pcie {
>>>          struct dw_pcie *pci;
>>>          void __iomem *parf;                     /* DT parf */
>>> @@ -260,6 +262,7 @@ struct qcom_pcie {
>>>          struct icc_path *icc_cpu;
>>>          const struct qcom_pcie_cfg *cfg;
>>>          struct dentry *debugfs;
>>> +       struct regulator_bulk_data slot_supplies[QCOM_PCIE_SLOT_MAX_SUPPLIES];
>>>          bool suspended;
>>>          bool use_pm_opp;
>>>   };
>>> @@ -1174,6 +1177,41 @@ static int qcom_pcie_link_up(struct dw_pcie *pci)
>>>          return !!(val & PCI_EXP_LNKSTA_DLLLA);
>>>   }
>>>
>>> +static int qcom_pcie_enable_slot_supplies(struct qcom_pcie *pcie)
>>> +{
>>> +       struct dw_pcie *pci = pcie->pci;
>>> +       int ret;
>>> +
>>> +       ret = regulator_bulk_enable(ARRAY_SIZE(pcie->slot_supplies),
>>> +                                   pcie->slot_supplies);
>>> +       if (ret < 0)
>>> +               dev_err(pci->dev, "Failed to enable slot regulators\n");
>>> +
>>> +       return ret;
>>> +}
>>> +
>>> +static void qcom_pcie_disable_slot_supplies(struct qcom_pcie *pcie)
>>> +{
>>> +       regulator_bulk_disable(ARRAY_SIZE(pcie->slot_supplies),
>>> +                              pcie->slot_supplies);
>>> +}
>>> +
>>> +static int qcom_pcie_get_slot_supplies(struct qcom_pcie *pcie)
>>> +{
>>> +       struct dw_pcie *pci = pcie->pci;
>>> +       int ret;
>>> +
>>> +       pcie->slot_supplies[0].supply = "vpcie12v";
>>> +       pcie->slot_supplies[1].supply = "vpcie3v3";
>>> +       pcie->slot_supplies[2].supply = "vpcie3v3aux";
>>> +       ret = devm_regulator_bulk_get(pci->dev, ARRAY_SIZE(pcie->slot_supplies),
>>> +                                     pcie->slot_supplies);
>>> +       if (ret < 0)
>>> +               dev_err(pci->dev, "Failed to get slot regulators\n");
>>> +
>>> +       return ret;
>>> +}
>>> +
>>>   static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
>>>   {
>>>          struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>>> @@ -1182,10 +1220,14 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
>>>
>>>          qcom_ep_reset_assert(pcie);
>>>
>>> -       ret = pcie->cfg->ops->init(pcie);
>>> +       ret = qcom_pcie_enable_slot_supplies(pcie);
>>>          if (ret)
>>>                  return ret;
>>>
>>> +       ret = pcie->cfg->ops->init(pcie);
>>> +       if (ret)
>>> +               goto err_disable_slot;
>>> +
>>>          ret = phy_set_mode_ext(pcie->phy, PHY_MODE_PCIE, PHY_MODE_PCIE_RC);
>>>          if (ret)
>>>                  goto err_deinit;
>>> @@ -1216,7 +1258,8 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
>>>          phy_power_off(pcie->phy);
>>>   err_deinit:
>>>          pcie->cfg->ops->deinit(pcie);
>>> -
>>> +err_disable_slot:
>>> +       qcom_pcie_disable_slot_supplies(pcie);
>>>          return ret;
>>>   }
>>>
>>> @@ -1228,6 +1271,7 @@ static void qcom_pcie_host_deinit(struct dw_pcie_rp *pp)
>>>          qcom_ep_reset_assert(pcie);
>>>          phy_power_off(pcie->phy);
>>>          pcie->cfg->ops->deinit(pcie);
>>> +       qcom_pcie_disable_slot_supplies(pcie);
>>>   }
>>>
>>>   static void qcom_pcie_host_post_init(struct dw_pcie_rp *pp)
>>> @@ -1602,6 +1646,10 @@ static int qcom_pcie_probe(struct platform_device *pdev)
>>>                          goto err_pm_runtime_put;
>>>          }
>>>
>>> +       ret = qcom_pcie_get_slot_supplies(pcie);
>>> +       if (ret)
>>> +               goto err_pm_runtime_put;
>>> +
>>>          ret = pcie->cfg->ops->get_resources(pcie);
>>>          if (ret)
>>>                  goto err_pm_runtime_put;
>>> --
>>> 2.34.1
>>>
>>
>> -- 
>> With best wishes
>> Dmitry


From quic_qianyu at quicinc.com  Wed Sep 11 01:22:34 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Wed, 11 Sep 2024 16:22:34 +0800
Subject: [PATCH 4/8] arm64: dts: qcom: x1e80100: Add support for PCIe3 on
 x1e80100
In-Reply-To: <ffbeb834-c56a-40b2-b9d6-f03149a1a37b@quicinc.com>
References: <20240827063631.3932971-1-quic_qianyu@quicinc.com>
 <20240827063631.3932971-5-quic_qianyu@quicinc.com>
 <41d4bc67-e47c-4b6e-a620-b83f48f43103@kernel.org>
 <ffbeb834-c56a-40b2-b9d6-f03149a1a37b@quicinc.com>
Message-ID: <cc9df490-dca9-4771-91cb-e8e1b5d2d48e@quicinc.com>


On 8/28/2024 9:36 PM, Qiang Yu wrote:
>
> On 8/27/2024 6:42 PM, Konrad Dybcio wrote:
>> On 27.08.2024 8:36 AM, Qiang Yu wrote:
>>> Describe PCIe3 controller and PHY. Also add required system 
>>> resources like
>>> regulators, clocks, interrupts and registers configuration for PCIe3.
>>>
>>> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
>>> ---
>>> ? arch/arm64/boot/dts/qcom/x1e80100.dtsi | 205 
>>> ++++++++++++++++++++++++-
>>> ? 1 file changed, 204 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi 
>>> b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
>>> index 74b694e74705..55b81e7de1c7 100644
>>> --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
>>> +++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
>>> @@ -744,7 +744,7 @@ gcc: clock-controller at 100000 {
>>> ? ????????????? clocks = <&bi_tcxo_div2>,
>>> ?????????????????? <&sleep_clk>,
>>> -???????????????? <0>,
>>> +???????????????? <&pcie3_phy>,
>>> ?????????????????? <&pcie4_phy>,
>>> ?????????????????? <&pcie5_phy>,
>>> ?????????????????? <&pcie6a_phy>,
>>> @@ -2879,6 +2879,209 @@ mmss_noc: interconnect at 1780000 {
>>> ????????????? #interconnect-cells = <2>;
>>> ????????? };
>>> ? +??????? pcie3: pci at 1bd0000 {
>>> +??????????? device_type = "pci";
>>> +??????????? compatible = "qcom,pcie-x1e80100";
>>> +??????????? reg = <0 0x01bd0000 0 0x3000>,
>>> +????????????????? <0 0x78000000 0 0xf1d>,
>>> +????????????????? <0 0x78000f40 0 0xa8>,
>>> +????????????????? <0 0x78001000 0 0x1000>,
>>> +????????????????? <0 0x78100000 0 0x100000>;
>>> +??????????? reg-names = "parf",
>>> +??????????????????? "dbi",
>>> +??????????????????? "elbi",
>>> +??????????????????? "atu",
>>> +??????????????????? "config";
>> There's a "mhi" region at 0x01bd3000, 0x1000-wide too, please add it
>>
>>> +??????????? #address-cells = <3>;
>>> +??????????? #size-cells = <2>;
>>> +??????????? ranges = <0x01000000 0 0x00000000 0 0x78200000 0 
>>> 0x100000>,
>>> +???????????????? <0x02000000 0 0x78300000 0 0x78300000 0 0x3d00000>;
>> There's 64bit BAR space as well:
>>
>> <0x03000000 0x7 0x40000000 0x7 0x40000000 0x0 0x40000000>;
>>
>>> +??????????? bus-range = <0 0xff>;
>> 0x00 please
>>
>>> +
>>> +??????????? dma-coherent;
>>> +
>>> +??????????? linux,pci-domain = <3>;
>>> +??????????? num-lanes = <8>;
>>> +
>>> +??????????? interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
>>> +???????????????????? <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
>>> +???????????????????? <GIC_SPI 769 IRQ_TYPE_LEVEL_HIGH>,
>>> +???????????????????? <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>,
>>> +???????????????????? <GIC_SPI 671 IRQ_TYPE_LEVEL_HIGH>,
>>> +???????????????????? <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
>>> +???????????????????? <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
>>> +???????????????????? <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
>>> +??????????? interrupt-names = "msi0",
>>> +????????????????????? "msi1",
>>> +????????????????????? "msi2",
>>> +????????????????????? "msi3",
>>> +????????????????????? "msi4",
>>> +????????????????????? "msi5",
>>> +????????????????????? "msi6",
>>> +????????????????????? "msi7";
>>> +
>>> +??????????? #interrupt-cells = <1>;
>>> +??????????? interrupt-map-mask = <0 0 0 0x7>;
>>> +??????????? interrupt-map = <0 0 0 1 &intc 0 0 0 220 
>>> IRQ_TYPE_LEVEL_HIGH>,
>>> +??????????????????? <0 0 0 2 &intc 0 0 0 221 IRQ_TYPE_LEVEL_HIGH>,
>>> +??????????????????? <0 0 0 3 &intc 0 0 0 237 IRQ_TYPE_LEVEL_HIGH>,
>>> +??????????????????? <0 0 0 4 &intc 0 0 0 238 IRQ_TYPE_LEVEL_HIGH>;
>>> +
>>> +??????????? clocks = <&gcc GCC_PCIE_3_PIPE_CLK_SRC>,
>> We don't toggle source clocks from dt, this is upstream of the pipe
>> div clocks and is taken care of by the common clock framework,
>> please drop.
> GCC_PCIE_3_PIPE_CLK_SRC is a clk mux. The enable and disable callback
> provided in clk driver is used to switch between pipe_clk and XO,
> respectively. If we drop GCC_PCIE_3_PIPE_CLK_SRC here, that means
> the mux will be XO until pipediv2 clk is enabled. I need to do some
> experiment to check this. Will update in thread.
>
> Thanks,
> Qiang
After removing GCC_PCIE_3_PIPE_CLK_SRC, I tested it and link was up.

Thanks,
Qiang
>>> +???????????????? <&gcc GCC_PCIE_3_AUX_CLK>,
>>> +???????????????? <&gcc GCC_PCIE_3_CFG_AHB_CLK>,
>>> +???????????????? <&gcc GCC_PCIE_3_MSTR_AXI_CLK>,
>>> +???????????????? <&gcc GCC_PCIE_3_SLV_AXI_CLK>,
>>> +???????????????? <&gcc GCC_PCIE_3_SLV_Q2A_AXI_CLK>,
>>> +???????????????? <&gcc GCC_CFG_NOC_PCIE_ANOC_SOUTH_AHB_CLK>,
>> GCC_CFG_NOC_PCIE_ANOC_NORTH_AHB_CLK
>>
>>> +???????????????? <&gcc GCC_CNOC_PCIE_NORTH_SF_AXI_CLK>;
>>> +??????????? clock-names = "pipe_clk_src",
>>> +????????????????????? "aux",
>>> +????????????????????? "cfg",
>>> +????????????????????? "bus_master",
>>> +????????????????????? "bus_slave",
>>> +????????????????????? "slave_q2a",
>>> +????????????????????? "noc_aggr",
>>> +????????????????????? "cnoc_sf_axi";
>>> +
>>> +??????????? assigned-clocks = <&gcc GCC_PCIE_3_AUX_CLK>;
>>> +??????????? assigned-clock-rates = <19200000>;
>>> +
>>> +??????????? interconnects = <&pcie_south_anoc MASTER_PCIE_3 
>>> QCOM_ICC_TAG_ALWAYS
>>> +???????????????????? &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
>>> +??????????????????? <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
>>> +???????????????????? &cnoc_main SLAVE_PCIE_3 QCOM_ICC_TAG_ALWAYS>;
>>> +??????????? interconnect-names = "pcie-mem",
>>> +???????????????????????? "cpu-pcie";
>>> +
>>> +??????????? resets = <&gcc GCC_PCIE_3_BCR>,
>>> +???????????????? <&gcc GCC_PCIE_3_LINK_DOWN_BCR>;
>>> +??????????? reset-names = "pci",
>>> +????????????????????? "link_down";
>>> +
>>> +??????????? power-domains = <&gcc GCC_PCIE_3_GDSC>;
>>> +
>>> +??????????? phys = <&pcie3_phy>;
>>> +??????????? phy-names = "pciephy";
>>> +
>>> +??????????? operating-points-v2 = <&pcie3_opp_table>;
>>> +
>>> +??????????? status = "disabled";
>>> +
>>> +??????????? pcie3_opp_table: opp-table {
>>> +??????????????? compatible = "operating-points-v2";
>>> +
>>> +??????????????? /* GEN 1 x1 */
>>> +??????????????? opp-2500000 {
>>> +??????????????????? opp-hz = /bits/ 64 <2500000>;
>>> +??????????????????? required-opps = <&rpmhpd_opp_low_svs>;
>>> +??????????????????? opp-peak-kBps = <250000 1>;
>>> +??????????????? };
>>> +
>>> +??????????????? /* GEN 1 x2 and GEN 2 x1 */
>>> +??????????????? opp-5000000 {
>>> +??????????????????? opp-hz = /bits/ 64 <5000000>;
>>> +??????????????????? required-opps = <&rpmhpd_opp_low_svs>;
>>> +??????????????????? opp-peak-kBps = <500000 1>;
>>> +??????????????? };
>>> +
>>> +??????????????? /* GEN 1 x4 and GEN 2 x2*/
>> Missing ' '
>>
>>> +??????????????? opp-10000000 {
>>> +??????????????????? opp-hz = /bits/ 64 <10000000>;
>>> +??????????????????? required-opps = <&rpmhpd_opp_low_svs>;
>>> +??????????????????? opp-peak-kBps = <1000000 1>;
>>> +??????????????? };
>>> +
>>> +??????????????? /* GEN 1 x8 and GEN 2 X4 */
>> Inconsistent capitalization, please use lowercase 'x'
>>
>> [...]
>>
>>> +??????? pcie3_phy: phy at 1be0000 {
>>> +??????????? compatible = "qcom,x1e80100-qmp-gen4x8-pcie-phy";
>>> +??????????? reg = <0 0x01be0000 0 0x10000>;
>>> +
>>> +??????????? clocks = <&gcc GCC_PCIE_3_AUX_CLK>,
>> This clock doesn't belong here, the PHY is clocked by PHY_AUX
>>
>>> +???????????????? <&gcc GCC_PCIE_3_CFG_AHB_CLK>,
>>> +???????????????? <&rpmhcc RPMH_CXO_CLK>,
>> This is unnecessary as commented before
>>
>>> +???????????????? <&gcc GCC_PCIE_3_PHY_RCHNG_CLK>,
>>> +???????????????? <&gcc GCC_PCIE_3_PHY_AUX_CLK>,
>>> +???????????????? <&gcc GCC_PCIE_3_PIPE_CLK>,
>>> +???????????????? <&gcc GCC_PCIE_3_PIPEDIV2_CLK>,
>>> +???????????????? <&tcsr TCSR_PCIE_8L_CLKREF_EN>;
>> This should be the 'ref' here
>>
>> Konrad


From christian.bruel at foss.st.com  Wed Sep 11 01:25:25 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 10:25:25 +0200
Subject: [PATCH v6 0/5] Add STM32MP25 USB3/PCIE COMBOPHY driver 
Message-ID: <20240911082530.2978336-1-christian.bruel@foss.st.com>

Changes in v6:
   - stm32_combophy_pll_init: merge combophy_cr1 accesses and error path.
   - Use devm_reset_control_get_exclusive

Changes in v5:
   - Drop syscfg phandle and change driver to use lookup_by_compatible
   - Use clk_bulk API and drop stm32_combophy_enable/disable_clocks
   - Reorder required: list.
   - Fix access-controllers maxItems
   
Changes in v4:
   - "#phy-cells": Drop type item description since it is specified
     by user node phandle.
   - Rename stm32-combophy.yaml to match compatible
   - Drop wakeup-source from bindings (should be generic)
   - Alphabetically reorder required: list.
   - Drop "Reviewed-by" since those previous changes

Changes in v3:
   - Reorder MAINTAINERS patch

Changes in v2:
   - Reorder entries
   - Rename clock_names and reset_names bindings
   - Rename and clarify rx-equalizer binding 

Christian Bruel (5):
  dt-bindings: phy: Add STM32MP25 COMBOPHY bindings
  phy: stm32: Add support for STM32MP25 COMBOPHY.
  MAINTAINERS: add entry for ST STM32MP25 COMBOPHY driver
  arm64: dts: st: Add combophy node on stm32mp251
  arm64: dts: st: Enable COMBOPHY on the stm32mp257f-ev1 board

 .../bindings/phy/st,stm32mp25-combophy.yaml   | 119 ++++
 MAINTAINERS                                   |   6 +
 arch/arm64/boot/dts/st/stm32mp251.dtsi        |  16 +
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts    |  14 +
 drivers/phy/st/Kconfig                        |  11 +
 drivers/phy/st/Makefile                       |   1 +
 drivers/phy/st/phy-stm32-combophy.c           | 596 ++++++++++++++++++
 7 files changed, 763 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
 create mode 100644 drivers/phy/st/phy-stm32-combophy.c

-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 01:25:26 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 10:25:26 +0200
Subject: [PATCH v6 1/5] dt-bindings: phy: Add STM32MP25 COMBOPHY bindings
In-Reply-To: <20240911082530.2978336-1-christian.bruel@foss.st.com>
References: <20240911082530.2978336-1-christian.bruel@foss.st.com>
Message-ID: <20240911082530.2978336-2-christian.bruel@foss.st.com>

Document the bindings for STM32 COMBOPHY interface, used to support
the PCIe and USB3 stm32mp25 drivers.
Following entries can be used to tune caracterisation parameters
 - st,output-micro-ohms and st,output-vswing-microvolt bindings entries
to tune the impedance and voltage swing using discrete simulation results
 - st,rx-equalizer register to set the internal rx equalizer filter value.

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 .../bindings/phy/st,stm32mp25-combophy.yaml   | 119 ++++++++++++++++++
 1 file changed, 119 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml

diff --git a/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml b/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
new file mode 100644
index 000000000000..a2e82c0bb56b
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/st,stm32mp25-combophy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32MP25 USB3/PCIe COMBOPHY
+
+maintainers:
+  - Christian Bruel <christian.bruel at foss.st.com>
+
+description:
+  Single lane PHY shared (exclusive) between the USB3 and PCIe controllers.
+  Supports 5Gbit/s for USB3 and PCIe gen2 or 2.5Gbit/s for PCIe gen1.
+
+properties:
+  compatible:
+    const: st,stm32mp25-combophy
+
+  reg:
+    maxItems: 1
+
+  "#phy-cells":
+    const: 1
+
+  clocks:
+    minItems: 2
+    items:
+      - description: apb Bus clock mandatory to access registers.
+      - description: ker Internal RCC reference clock for USB3 or PCIe
+      - description: pad Optional on board clock input for PCIe only. Typically an
+                     external 100Mhz oscillator wired on dedicated CLKIN pad. Used as reference
+                     clock input instead of the ker
+
+  clock-names:
+    minItems: 2
+    items:
+      - const: apb
+      - const: ker
+      - const: pad
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    const: phy
+
+  power-domains:
+    maxItems: 1
+
+  wakeup-source: true
+
+  interrupts:
+    maxItems: 1
+    description: interrupt used for wakeup
+
+  access-controllers:
+    maxItems: 1
+    description: Phandle to the rifsc device to check access right.
+
+  st,ssc-on:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      A property whose presence indicates that the Spread Spectrum Clocking is active.
+
+  st,rx-equalizer:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 7
+    default: 2
+    description:
+      A 3 bit value to tune the RX fixed equalizer setting for optimal eye compliance
+
+  st,output-micro-ohms:
+    minimum: 3999000
+    maximum: 6090000
+    default: 4968000
+    description:
+      A value property to tune the Single Ended Output Impedance, simulations results
+      at 25C for a VDDP=0.8V. The hardware accepts discrete values in this range.
+
+  st,output-vswing-microvolt:
+    minimum: 442000
+    maximum: 803000
+    default: 803000
+    description:
+      A value property in microvolt to tune the Single Ended Output Voltage Swing to change the
+      Vlo, Vhi for a VDDP = 0.8V. The hardware accepts discrete values in this range.
+
+required:
+  - compatible
+  - reg
+  - "#phy-cells"
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/reset/st,stm32mp25-rcc.h>
+
+    phy at 480c0000 {
+        compatible = "st,stm32mp25-combophy";
+        reg = <0x480c0000 0x1000>;
+        #phy-cells = <1>;
+        clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>;
+        clock-names = "apb", "ker";
+        resets = <&rcc USB3PCIEPHY_R>;
+        reset-names = "phy";
+        access-controllers = <&rifsc 67>;
+        power-domains = <&CLUSTER_PD>;
+        wakeup-source;
+        interrupts-extended = <&exti1 45 IRQ_TYPE_EDGE_FALLING>;
+    };
-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 01:25:27 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 10:25:27 +0200
Subject: [PATCH v6 2/5] phy: stm32: Add support for STM32MP25 COMBOPHY.
In-Reply-To: <20240911082530.2978336-1-christian.bruel@foss.st.com>
References: <20240911082530.2978336-1-christian.bruel@foss.st.com>
Message-ID: <20240911082530.2978336-3-christian.bruel@foss.st.com>

Addition of the COMBOPHY driver found on STM32MP25 platforms

This single lane PHY is shared (exclusive) between the USB3 and PCIE
controllers.
Supports 5Gbit/s for PCIE gen2 or 2.5Gbit/s for PCIE gen1.

Supports wakeup-source capability to wakeup system using remote-wakeup
capable USB device

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 drivers/phy/st/Kconfig              |  11 +
 drivers/phy/st/Makefile             |   1 +
 drivers/phy/st/phy-stm32-combophy.c | 596 ++++++++++++++++++++++++++++
 3 files changed, 608 insertions(+)
 create mode 100644 drivers/phy/st/phy-stm32-combophy.c

diff --git a/drivers/phy/st/Kconfig b/drivers/phy/st/Kconfig
index 3fc3d0781fb8..304614b6dabf 100644
--- a/drivers/phy/st/Kconfig
+++ b/drivers/phy/st/Kconfig
@@ -33,6 +33,17 @@ config PHY_STIH407_USB
 	  Enable this support to enable the picoPHY device used by USB2
 	  and USB3 controllers on STMicroelectronics STiH407 SoC families.
 
+config PHY_STM32_COMBOPHY
+	tristate "STMicroelectronics COMBOPHY driver for STM32MP25"
+	depends on ARCH_STM32 || COMPILE_TEST
+	select GENERIC_PHY
+	help
+	  Enable this to support the COMBOPHY device used by USB3 or PCIe
+	  controllers on STMicroelectronics STM32MP25 SoC.
+	  This driver controls the COMBOPHY block to generate the PCIe 100Mhz
+	  reference clock from either the external clock generator or HSE
+	  internal SoC clock source.
+
 config PHY_STM32_USBPHYC
 	tristate "STMicroelectronics STM32 USB HS PHY Controller driver"
 	depends on ARCH_STM32 || COMPILE_TEST
diff --git a/drivers/phy/st/Makefile b/drivers/phy/st/Makefile
index c862dd937b64..cb80e954ea9f 100644
--- a/drivers/phy/st/Makefile
+++ b/drivers/phy/st/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_PHY_MIPHY28LP) 		+= phy-miphy28lp.o
 obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)	+= phy-spear1310-miphy.o
 obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)	+= phy-spear1340-miphy.o
 obj-$(CONFIG_PHY_STIH407_USB)		+= phy-stih407-usb.o
+obj-$(CONFIG_PHY_STM32_COMBOPHY)	+= phy-stm32-combophy.o
 obj-$(CONFIG_PHY_STM32_USBPHYC) 	+= phy-stm32-usbphyc.o
diff --git a/drivers/phy/st/phy-stm32-combophy.c b/drivers/phy/st/phy-stm32-combophy.c
new file mode 100644
index 000000000000..37ae6b28c7fa
--- /dev/null
+++ b/drivers/phy/st/phy-stm32-combophy.c
@@ -0,0 +1,596 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * STMicroelectronics COMBOPHY STM32MP25 Controller driver.
+ *
+ * Copyright (C) 2024 STMicroelectronics
+ * Author: Christian Bruel <christian.bruel at foss.st.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <dt-bindings/phy/phy.h>
+
+#define SYSCFG_COMBOPHY_CR1 0x4c00
+#define SYSCFG_COMBOPHY_CR2 0x4c04
+#define SYSCFG_COMBOPHY_CR4 0x4c0c
+#define SYSCFG_COMBOPHY_CR5 0x4c10
+#define SYSCFG_COMBOPHY_SR  0x4c14
+#define SYSCFG_PCIEPRGCR    0x6080
+
+/* SYSCFG PCIEPRGCR */
+#define STM32MP25_PCIEPRGCR_EN	  BIT(0)
+#define STM32MP25_PCIEPRG_IMPCTRL_OHM     GENMASK(3, 1)
+#define STM32MP25_PCIEPRG_IMPCTRL_VSWING  GENMASK(5, 4)
+
+/* SYSCFG SYSCFG_COMBOPHY_SR */
+#define STM32MP25_PIPE0_PHYSTATUS BIT(1)
+
+/* SYSCFG CR1 */
+#define SYSCFG_COMBOPHY_CR1_REFUSEPAD BIT(0)
+#define SYSCFG_COMBOPHY_CR1_MPLLMULT GENMASK(7, 1)
+#define SYSCFG_COMBOPHY_CR1_REFCLKSEL GENMASK(16, 8)
+#define SYSCFG_COMBOPHY_CR1_REFCLKDIV2 BIT(17)
+#define SYSCFG_COMBOPHY_CR1_REFSSPEN BIT(18)
+#define SYSCFG_COMBOPHY_CR1_SSCEN BIT(19)
+
+/* SYSCFG CR4 */
+#define SYSCFG_COMBOPHY_CR4_RX0_EQ GENMASK(2, 0)
+
+#define MPLLMULT_19_2 (0x02u << 1)
+#define MPLLMULT_20   (0x7du << 1)
+#define MPLLMULT_24   (0x68u << 1)
+#define MPLLMULT_25   (0x64u << 1)
+#define MPLLMULT_26   (0x60u << 1)
+#define MPLLMULT_38_4 (0x41u << 1)
+#define MPLLMULT_48   (0x6cu << 1)
+#define MPLLMULT_50   (0x32u << 1)
+#define MPLLMULT_52   (0x30u << 1)
+#define MPLLMULT_100  (0x19u << 1)
+
+#define REFCLKSEL_0   0
+#define REFCLKSEL_1   (0x108u << 8)
+
+#define REFCLDIV_0    0
+
+/* SYSCFG CR2 */
+#define SYSCFG_COMBOPHY_CR2_MODESEL GENMASK(1, 0)
+#define SYSCFG_COMBOPHY_CR2_ISO_DIS BIT(15)
+
+#define COMBOPHY_MODESEL_PCIE 0
+#define COMBOPHY_MODESEL_USB  3
+
+/* SYSCFG CR5 */
+#define SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS BIT(12)
+
+#define COMBOPHY_SUP_ANA_MPLL_LOOP_CTL 0xc0
+#define COMBOPHY_PROP_CNTRL GENMASK(7, 4)
+
+/* Required apb/ker clocks first, optional pad last. */
+static const char * const combophy_clks[] = {"apb", "ker", "pad"};
+#define APB_CLK 0
+#define KER_CLK 1
+#define PAD_CLK 2
+
+struct stm32_combophy {
+	struct phy *phy;
+	struct regmap *regmap;
+	struct device *dev;
+	void __iomem *base;
+	struct reset_control *phy_reset;
+	struct clk_bulk_data clks[ARRAY_SIZE(combophy_clks)];
+	int num_clks;
+	bool have_pad_clk;
+	unsigned int type;
+	bool is_init;
+	int irq_wakeup;
+};
+
+struct clk_impedance  {
+	u32 microohm;
+	u32 vswing[4];
+};
+
+/*
+ * lookup table to hold the settings needed for a ref clock frequency
+ * impedance, the offset is used to set the IMP_CTL and DE_EMP bit of the
+ * PRG_IMP_CTRL register. Use ordered discrete values in the table
+ */
+static const struct clk_impedance imp_lookup[] = {
+	{ 6090000, { 442000, 564000, 684000, 802000 } },
+	{ 5662000, { 528000, 621000, 712000, 803000 } },
+	{ 5292000, { 491000, 596000, 700000, 802000 } },
+	{ 4968000, { 558000, 640000, 722000, 803000 } },
+	{ 4684000, { 468000, 581000, 692000, 802000 } },
+	{ 4429000, { 554000, 613000, 717000, 803000 } },
+	{ 4204000, { 511000, 609000, 706000, 802000 } },
+	{ 3999000, { 571000, 648000, 726000, 803000 } }
+};
+
+static int stm32_impedance_tune(struct stm32_combophy *combophy)
+{
+	u8 imp_size = ARRAY_SIZE(imp_lookup);
+	u8 vswing_size = ARRAY_SIZE(imp_lookup[0].vswing);
+	u8 imp_of, vswing_of;
+	u32 max_imp = imp_lookup[0].microohm;
+	u32 min_imp = imp_lookup[imp_size - 1].microohm;
+	u32 max_vswing = imp_lookup[imp_size - 1].vswing[vswing_size - 1];
+	u32 min_vswing = imp_lookup[0].vswing[0];
+	u32 val;
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,output-micro-ohms", &val)) {
+		if (val < min_imp || val > max_imp) {
+			dev_err(combophy->dev, "Invalid value %u for output ohm\n", val);
+			return -EINVAL;
+		}
+
+		for (imp_of = 0; imp_of < ARRAY_SIZE(imp_lookup); imp_of++)
+			if (imp_lookup[imp_of].microohm <= val)
+				break;
+
+		dev_dbg(combophy->dev, "Set %u micro-ohms output impedance\n",
+			imp_lookup[imp_of].microohm);
+
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRG_IMPCTRL_OHM,
+				   FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_OHM, imp_of));
+	} else {
+		regmap_read(combophy->regmap, SYSCFG_PCIEPRGCR, &val);
+		imp_of = FIELD_GET(STM32MP25_PCIEPRG_IMPCTRL_OHM, val);
+	}
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,output-vswing-microvolt", &val)) {
+		if (val < min_vswing || val > max_vswing) {
+			dev_err(combophy->dev, "Invalid value %u for output vswing\n", val);
+			return -EINVAL;
+		}
+
+		for (vswing_of = 0; vswing_of < ARRAY_SIZE(imp_lookup[imp_of].vswing); vswing_of++)
+			if (imp_lookup[imp_of].vswing[vswing_of] >= val)
+				break;
+
+		dev_dbg(combophy->dev, "Set %u microvolt swing\n",
+			 imp_lookup[imp_of].vswing[vswing_of]);
+
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRG_IMPCTRL_VSWING,
+				   FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of));
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_pll_init(struct stm32_combophy *combophy)
+{
+	int ret;
+	u32 refclksel, pllmult, propcntrl, val;
+	u32 clk_rate;
+	struct clk *clk;
+	u32 cr1_val = 0, cr1_mask = 0;
+
+	if (combophy->have_pad_clk)
+		clk = combophy->clks[PAD_CLK].clk;
+	else
+		clk = combophy->clks[KER_CLK].clk;
+
+	clk_rate = clk_get_rate(clk);
+
+	dev_dbg(combophy->dev, "%s pll init rate %d\n",
+		combophy->have_pad_clk ? "External" : "Ker", clk_rate);
+
+	if (combophy->type != PHY_TYPE_PCIE) {
+		cr1_mask |= SYSCFG_COMBOPHY_CR1_REFSSPEN;
+		cr1_val |= SYSCFG_COMBOPHY_CR1_REFSSPEN;
+	}
+
+	if (of_property_present(combophy->dev->of_node, "st,ssc-on")) {
+		dev_dbg(combophy->dev, "Enabling clock with SSC\n");
+		cr1_mask |= SYSCFG_COMBOPHY_CR1_SSCEN;
+		cr1_val |= SYSCFG_COMBOPHY_CR1_SSCEN;
+	}
+
+	switch (clk_rate) {
+	case 100000000:
+		pllmult = MPLLMULT_100;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0x8u << 4;
+		break;
+	case 19200000:
+		pllmult = MPLLMULT_19_2;
+		refclksel = REFCLKSEL_1;
+		propcntrl = 0x8u << 4;
+		break;
+	case 25000000:
+		pllmult = MPLLMULT_25;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0xeu << 4;
+		break;
+	case 24000000:
+		pllmult = MPLLMULT_24;
+		refclksel = REFCLKSEL_1;
+		propcntrl = 0xeu << 4;
+		break;
+	case 20000000:
+		pllmult = MPLLMULT_20;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0xeu << 4;
+		break;
+	default:
+		dev_err(combophy->dev, "Invalid rate 0x%x\n", clk_rate);
+		return -EINVAL;
+	};
+
+	cr1_mask |= SYSCFG_COMBOPHY_CR1_REFCLKDIV2;
+	cr1_val |= REFCLDIV_0;
+
+	cr1_mask |= SYSCFG_COMBOPHY_CR1_REFCLKSEL;
+	cr1_val |= refclksel;
+
+	cr1_mask |= SYSCFG_COMBOPHY_CR1_MPLLMULT;
+	cr1_val |= pllmult;
+
+	/*
+	 * vddcombophy is interconnected with vddcore. Isolation bit should be unset
+	 * before using the ComboPHY.
+	 */
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, SYSCFG_COMBOPHY_CR2_ISO_DIS);
+
+	reset_control_assert(combophy->phy_reset);
+
+	if (combophy->type == PHY_TYPE_PCIE) {
+		ret = stm32_impedance_tune(combophy);
+		if (ret)
+			goto out_iso;
+
+		cr1_mask |= SYSCFG_COMBOPHY_CR1_REFUSEPAD;
+		cr1_val |= combophy->have_pad_clk ? SYSCFG_COMBOPHY_CR1_REFUSEPAD : 0;
+	}
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,rx-equalizer", &val)) {
+		dev_dbg(combophy->dev, "Set RX equalizer %u\n", val);
+		if (val > SYSCFG_COMBOPHY_CR4_RX0_EQ) {
+			dev_err(combophy->dev, "Invalid value %u for rx0 equalizer\n", val);
+			ret = -EINVAL;
+			goto out_iso;
+		}
+
+		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR4,
+			   SYSCFG_COMBOPHY_CR4_RX0_EQ, val);
+	}
+
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1, cr1_mask, cr1_val);
+
+	/*
+	 * Force elasticity buffer to be tuned for the reference clock as
+	 * the separated clock model is not supported
+	 */
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR5,
+			   SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS, SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS);
+
+	reset_control_deassert(combophy->phy_reset);
+
+	ret = regmap_read_poll_timeout(combophy->regmap, SYSCFG_COMBOPHY_SR, val,
+				       !(val & STM32MP25_PIPE0_PHYSTATUS),
+				       10, 1000);
+	if (ret) {
+		dev_err(combophy->dev, "timeout, cannot lock PLL\n");
+		if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
+			regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+					   STM32MP25_PCIEPRGCR_EN, 0);
+
+		if (combophy->type != PHY_TYPE_PCIE)
+			regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+					   SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
+
+		goto out;
+	}
+
+
+	if (combophy->type == PHY_TYPE_PCIE) {
+		if (!combophy->have_pad_clk)
+			regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+					   STM32MP25_PCIEPRGCR_EN, STM32MP25_PCIEPRGCR_EN);
+
+		val = readl_relaxed(combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
+		val &= ~COMBOPHY_PROP_CNTRL;
+		val |= propcntrl;
+		writel_relaxed(val, combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
+	}
+
+	return 0;
+
+out_iso:
+	reset_control_deassert(combophy->phy_reset);
+
+out:
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
+
+	return ret;
+}
+
+static struct phy *stm32_combophy_xlate(struct device *dev,
+					const struct of_phandle_args *args)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+	unsigned int type;
+
+	if (args->args_count != 1) {
+		dev_err(dev, "invalid number of cells in 'phy' property\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	type = args->args[0];
+	if (type != PHY_TYPE_USB3 && type != PHY_TYPE_PCIE) {
+		dev_err(dev, "unsupported device type: %d\n", type);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (combophy->have_pad_clk && type != PHY_TYPE_PCIE) {
+		dev_err(dev, "Invalid use of clk_pad for USB3 mode\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	combophy->type = type;
+
+	return combophy->phy;
+}
+
+static int stm32_combophy_set_mode(struct stm32_combophy *combophy)
+{
+	int type = combophy->type;
+	u32 val;
+
+	switch (type) {
+	case PHY_TYPE_PCIE:
+		dev_dbg(combophy->dev, "setting PCIe ComboPHY\n");
+		val = COMBOPHY_MODESEL_PCIE;
+		break;
+	case PHY_TYPE_USB3:
+		dev_dbg(combophy->dev, "setting USB3 ComboPHY\n");
+		val = COMBOPHY_MODESEL_USB;
+		break;
+	default:
+		dev_err(combophy->dev, "Invalid PHY mode %d\n", type);
+		return -EINVAL;
+	}
+
+	return regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+				  SYSCFG_COMBOPHY_CR2_MODESEL, val);
+}
+
+static int stm32_combophy_suspend_noirq(struct device *dev)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+
+	/*
+	 * Clocks should be turned off since it is not needed for
+	 * wakeup capability. In case usb-remote wakeup is not enabled,
+	 * combo-phy is already turned off by HCD driver using exit callback
+	 */
+	if (combophy->is_init) {
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+
+		/* since wakeup is enabled for ctrl */
+		enable_irq_wake(combophy->irq_wakeup);
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_resume_noirq(struct device *dev)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+	int ret;
+
+	/*
+	 * If clocks was turned off by suspend call for wakeup then needs
+	 * to be turned back ON in resume. In case usb-remote wakeup is not
+	 * enabled, clocks already turned ON by HCD driver using init callback
+	 */
+	if (combophy->is_init) {
+		/* since wakeup was enabled for ctrl */
+		disable_irq_wake(combophy->irq_wakeup);
+
+		ret = clk_bulk_prepare_enable(combophy->num_clks, combophy->clks);
+		if (ret) {
+			dev_err(dev, "can't enable clocks (%d)\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_exit(struct phy *phy)
+{
+	struct stm32_combophy *combophy = phy_get_drvdata(phy);
+	struct device *dev = combophy->dev;
+
+	combophy->is_init = false;
+
+	if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRGCR_EN, 0);
+
+	if (combophy->type != PHY_TYPE_PCIE)
+		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+				   SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
+
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
+
+	clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+
+	pm_runtime_put_noidle(dev);
+
+	return 0;
+}
+
+static int stm32_combophy_init(struct phy *phy)
+{
+	struct stm32_combophy *combophy = phy_get_drvdata(phy);
+	struct device *dev = combophy->dev;
+	int ret;
+
+	pm_runtime_get_noresume(dev);
+
+	ret = clk_bulk_prepare_enable(combophy->num_clks, combophy->clks);
+	if (ret) {
+		dev_err(dev, "can't enable clocks (%d)\n", ret);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	ret = stm32_combophy_set_mode(combophy);
+	if (ret) {
+		dev_err(dev, "combophy mode not set\n");
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	ret = stm32_combophy_pll_init(combophy);
+	if (ret) {
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	pm_runtime_disable(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+
+	combophy->is_init = true;
+
+	return ret;
+}
+
+static const struct phy_ops stm32_combophy_phy_data = {
+	.init = stm32_combophy_init,
+	.exit = stm32_combophy_exit,
+	.owner = THIS_MODULE
+};
+
+static irqreturn_t stm32_combophy_irq_wakeup_handler(int irq, void *dev_id)
+{
+	return IRQ_HANDLED;
+}
+
+static int stm32_combophy_get_clocks(struct stm32_combophy *combophy)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(combophy_clks); i++)
+		combophy->clks[i].id = combophy_clks[i];
+
+	combophy->num_clks = ARRAY_SIZE(combophy_clks) - 1;
+
+	ret = devm_clk_bulk_get(combophy->dev, combophy->num_clks, combophy->clks);
+	if (ret)
+		return ret;
+
+	ret = devm_clk_bulk_get_optional(combophy->dev, 1, combophy->clks + combophy->num_clks);
+	if (ret)
+		return ret;
+
+	if (combophy->clks[combophy->num_clks].clk != NULL) {
+		combophy->have_pad_clk = true;
+		combophy->num_clks++;
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_probe(struct platform_device *pdev)
+{
+	struct stm32_combophy *combophy;
+	struct device *dev = &pdev->dev;
+	struct phy_provider *phy_provider;
+	int ret, irq;
+
+	combophy = devm_kzalloc(dev, sizeof(*combophy), GFP_KERNEL);
+	if (!combophy)
+		return -ENOMEM;
+
+	combophy->dev = dev;
+
+	dev_set_drvdata(dev, combophy);
+
+	combophy->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(combophy->base))
+		return PTR_ERR(combophy->base);
+
+	if (stm32_combophy_get_clocks(combophy))
+		return ret;
+
+	combophy->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
+	if (IS_ERR(combophy->phy_reset))
+		return dev_err_probe(dev, PTR_ERR(combophy->phy_reset),
+				     "Failed to get PHY reset\n");
+
+	combophy->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg");
+	if (IS_ERR(combophy->regmap))
+		return dev_err_probe(dev, PTR_ERR(combophy->regmap),
+				     "No syscfg specified\n");
+
+	combophy->phy = devm_phy_create(dev, NULL, &stm32_combophy_phy_data);
+	if (IS_ERR(combophy->phy))
+		return dev_err_probe(dev, PTR_ERR(combophy->phy),
+				     "failed to create PCIe/USB3 ComboPHY\n");
+
+	if (device_property_read_bool(dev, "wakeup-source")) {
+		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return dev_err_probe(dev, irq, "failed to get IRQ\n");
+		combophy->irq_wakeup = irq;
+
+		ret = devm_request_threaded_irq(dev, combophy->irq_wakeup, NULL,
+						stm32_combophy_irq_wakeup_handler, IRQF_ONESHOT,
+						NULL, NULL);
+		if (ret)
+			return dev_err_probe(dev, ret, "unable to request wake IRQ %d\n",
+						 combophy->irq_wakeup);
+	}
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to enable pm runtime\n");
+
+	phy_set_drvdata(combophy->phy, combophy);
+
+	phy_provider = devm_of_phy_provider_register(dev, stm32_combophy_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct dev_pm_ops stm32_combophy_pm_ops = {
+	NOIRQ_SYSTEM_SLEEP_PM_OPS(stm32_combophy_suspend_noirq,
+				  stm32_combophy_resume_noirq)
+};
+
+static const struct of_device_id stm32_combophy_of_match[] = {
+	{ .compatible = "st,stm32mp25-combophy", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, stm32_combophy_of_match);
+
+static struct platform_driver stm32_combophy_driver = {
+	.probe = stm32_combophy_probe,
+	.driver = {
+		   .name = "stm32-combophy",
+		   .of_match_table = stm32_combophy_of_match,
+		   .pm = pm_sleep_ptr(&stm32_combophy_pm_ops)
+	}
+};
+
+module_platform_driver(stm32_combophy_driver);
+
+MODULE_AUTHOR("Christian Bruel <christian.bruel at foss.st.com>");
+MODULE_DESCRIPTION("STM32MP25 Combophy USB3/PCIe controller driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 01:25:29 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 10:25:29 +0200
Subject: [PATCH v6 4/5] arm64: dts: st: Add combophy node on stm32mp251
In-Reply-To: <20240911082530.2978336-1-christian.bruel@foss.st.com>
References: <20240911082530.2978336-1-christian.bruel@foss.st.com>
Message-ID: <20240911082530.2978336-5-christian.bruel@foss.st.com>

Add support for COMBOPHY which is used either by the USB3 and PCIe
controller.
USB3 or PCIe mode is done with phy_set_mode().
PCIe internal reference clock can be generated from the internal clock
source or optionnaly from an external 100Mhz pad.

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp251.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 1167cf63d7e8..b596afec1b6e 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -7,6 +7,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset/st,stm32mp25-rcc.h>
 #include <dt-bindings/regulator/st,stm32mp25-regulator.h>
+#include <dt-bindings/phy/phy.h>
 
 / {
 	#address-cells = <2>;
@@ -518,6 +519,21 @@ i2c8: i2c at 46040000 {
 				status = "disabled";
 			};
 
+			combophy: phy at 480c0000 {
+				compatible = "st,stm32mp25-combophy";
+				reg = <0x480c0000 0x1000>;
+				#phy-cells = <1>;
+				clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>;
+				clock-names = "apb", "ker";
+				resets = <&rcc USB3PCIEPHY_R>;
+				reset-names = "phy";
+				access-controllers = <&rifsc 67>;
+				power-domains = <&CLUSTER_PD>;
+				wakeup-source;
+				interrupts-extended = <&exti1 45 IRQ_TYPE_EDGE_FALLING>;
+				status = "disabled";
+			};
+
 			sdmmc1: mmc at 48220000 {
 				compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell";
 				arm,primecell-periphid = <0x00353180>;
-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 01:25:28 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 10:25:28 +0200
Subject: [PATCH v6 3/5] MAINTAINERS: add entry for ST STM32MP25 COMBOPHY driver
In-Reply-To: <20240911082530.2978336-1-christian.bruel@foss.st.com>
References: <20240911082530.2978336-1-christian.bruel@foss.st.com>
Message-ID: <20240911082530.2978336-4-christian.bruel@foss.st.com>

Add myself as STM32MP25 COMBOPHY maintainer

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index a70b7c9c3533..b922a5637b16 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21931,6 +21931,12 @@ F:	arch/m68k/kernel/*sun3*
 F:	arch/m68k/sun3*/
 F:	drivers/net/ethernet/i825xx/sun3*
 
+STMICROELECTRONICS STMP32MP25 USB3/PCIE COMBOPHY DRIVER
+M:	Christian Bruel <christian.bruel at foss.st.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
+F:	drivers/phy/st/phy-stm32-combophy.c
+
 SUN4I LOW RES ADC ATTACHED TABLET KEYS DRIVER
 M:	Hans de Goede <hdegoede at redhat.com>
 L:	linux-input at vger.kernel.org
-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 01:25:30 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 10:25:30 +0200
Subject: [PATCH v6 5/5] arm64: dts: st: Enable COMBOPHY on the stm32mp257f-ev1 board
In-Reply-To: <20240911082530.2978336-1-christian.bruel@foss.st.com>
References: <20240911082530.2978336-1-christian.bruel@foss.st.com>
Message-ID: <20240911082530.2978336-6-christian.bruel@foss.st.com>

Enable the COMBOPHY with external pad clock on stm32mp257f-ev1
board, to be used for the PCIe clock provider.

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
index 214191a8322b..bcf84d533cb2 100644
--- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
+++ b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
@@ -27,6 +27,14 @@ chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
+	clocks {
+		pad_clk: pad-clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+		};
+	};
+
 	memory at 80000000 {
 		device_type = "memory";
 		reg = <0x0 0x80000000 0x1 0x0>;
@@ -50,6 +58,12 @@ &arm_wdt {
 	status = "okay";
 };
 
+&combophy {
+	clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>, <&pad_clk>;
+	clock-names = "apb", "ker", "pad";
+	status = "okay";
+};
+
 &ethernet2 {
 	pinctrl-names = "default", "sleep";
 	pinctrl-0 = <&eth2_rgmii_pins_a>;
-- 
2.34.1



From quic_mukhopad at quicinc.com  Wed Sep 11 03:08:09 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Wed, 11 Sep 2024 15:38:09 +0530
Subject: [PATCH 1/5] dt-bindings: phy: Add eDP PHY compatible for sa8775p
In-Reply-To: <20240911100813.338-1-quic_mukhopad@quicinc.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com>
Message-ID: <20240911100813.338-2-quic_mukhopad@quicinc.com>

Add compatible string for the supported eDP PHY on sa8775p platform.

Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
 Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
index 4e15d90d08b0..293fb6a9b1c3 100644
--- a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
@@ -17,6 +17,7 @@ description:
 properties:
   compatible:
     enum:
+      - qcom,sa8775p-edp-phy
       - qcom,sc7280-edp-phy
       - qcom,sc8180x-edp-phy
       - qcom,sc8280xp-dp-phy
-- 
2.17.1



From quic_mukhopad at quicinc.com  Wed Sep 11 03:08:08 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Wed, 11 Sep 2024 15:38:08 +0530
Subject: [PATCH 0/5] Add support for DisplayPort on SA8775P platform
Message-ID: <20240911100813.338-1-quic_mukhopad@quicinc.com>

This series adds support for the DisplayPort controller
and eDP PHY v5 found on the Qualcomm SA8775P platform.

Soutrik Mukhopadhyay (5):
  dt-bindings: phy: Add eDP PHY compatible for sa8775p
  phy: qcom: edp: Introduce aux_cfg array for version specific aux
    settings
  phy: qcom: edp: Add support for eDP PHY on SA8775P
  dt-bindings: display: msm: dp-controller: document SA8775P compatible
  drm/msm/dp: Add DisplayPort controller for SA8775P

 .../bindings/display/msm/dp-controller.yaml   |  1 +
 .../devicetree/bindings/phy/qcom,edp-phy.yaml |  1 +
 drivers/gpu/drm/msm/dp/dp_display.c           |  7 ++
 drivers/phy/qualcomm/phy-qcom-edp.c           | 81 +++++++++++++++----
 4 files changed, 76 insertions(+), 14 deletions(-)

-- 
2.17.1



From quic_mukhopad at quicinc.com  Wed Sep 11 03:08:13 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Wed, 11 Sep 2024 15:38:13 +0530
Subject: [PATCH 5/5] drm/msm/dp: Add DisplayPort controller for SA8775P
In-Reply-To: <20240911100813.338-1-quic_mukhopad@quicinc.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com>
Message-ID: <20240911100813.338-6-quic_mukhopad@quicinc.com>

The Qualcomm SA8775P platform comes with a DisplayPort controller
with a different base offset than the previous SoCs,
add support for this in the DisplayPort driver.

Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
 drivers/gpu/drm/msm/dp/dp_display.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index e1228fb093ee..e4954fd99eb0 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -118,6 +118,12 @@ struct msm_dp_desc {
 	bool wide_bus_supported;
 };
 
+static const struct msm_dp_desc sa8775p_dp_descs[] = {
+	{ .io_start = 0xaf54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{ .io_start = 0xaf5c000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
+	{}
+};
+
 static const struct msm_dp_desc sc7180_dp_descs[] = {
 	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
 	{}
@@ -162,6 +168,7 @@ static const struct msm_dp_desc x1e80100_dp_descs[] = {
 };
 
 static const struct of_device_id dp_dt_match[] = {
+	{ .compatible = "qcom,sa8775p-dp", .data = &sa8775p_dp_descs },
 	{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
 	{ .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
 	{ .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_descs },
-- 
2.17.1



From quic_mukhopad at quicinc.com  Wed Sep 11 03:08:10 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Wed, 11 Sep 2024 15:38:10 +0530
Subject: [PATCH 2/5] phy: qcom: edp: Introduce aux_cfg array for version specific aux settings
In-Reply-To: <20240911100813.338-1-quic_mukhopad@quicinc.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com>
Message-ID: <20240911100813.338-3-quic_mukhopad@quicinc.com>

In order to support different HW versions, introduce aux_cfg array
to move v4 specific aux configuration settings.

Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
 drivers/phy/qualcomm/phy-qcom-edp.c | 34 +++++++++++++++++------------
 1 file changed, 20 insertions(+), 14 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
index da2b32fb5b45..0f860a807d1b 100644
--- a/drivers/phy/qualcomm/phy-qcom-edp.c
+++ b/drivers/phy/qualcomm/phy-qcom-edp.c
@@ -90,6 +90,7 @@ struct phy_ver_ops {
 
 struct qcom_edp_phy_cfg {
 	bool is_edp;
+	u8 *aux_cfg;
 	const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
 	const struct phy_ver_ops *ver_ops;
 };
@@ -186,11 +187,14 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
 	.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
 };
 
+static u8 edp_phy_aux_cfg_v4[10] = {
+	0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
+};
+
 static int qcom_edp_phy_init(struct phy *phy)
 {
 	struct qcom_edp *edp = phy_get_drvdata(phy);
 	int ret;
-	u8 cfg8;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
 	if (ret)
@@ -222,22 +226,20 @@ static int qcom_edp_phy_init(struct phy *phy)
 	 * even needed.
 	 */
 	if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
-		cfg8 = 0xb7;
-	else
-		cfg8 = 0x37;
+		edp->cfg->aux_cfg[8] = 0xb7;
 
 	writel(0xfc, edp->edp + DP_PHY_MODE);
 
-	writel(0x00, edp->edp + DP_PHY_AUX_CFG0);
-	writel(0x13, edp->edp + DP_PHY_AUX_CFG1);
-	writel(0x24, edp->edp + DP_PHY_AUX_CFG2);
-	writel(0x00, edp->edp + DP_PHY_AUX_CFG3);
-	writel(0x0a, edp->edp + DP_PHY_AUX_CFG4);
-	writel(0x26, edp->edp + DP_PHY_AUX_CFG5);
-	writel(0x0a, edp->edp + DP_PHY_AUX_CFG6);
-	writel(0x03, edp->edp + DP_PHY_AUX_CFG7);
-	writel(cfg8, edp->edp + DP_PHY_AUX_CFG8);
-	writel(0x03, edp->edp + DP_PHY_AUX_CFG9);
+	writel(edp->cfg->aux_cfg[0], edp->edp + DP_PHY_AUX_CFG0);
+	writel(edp->cfg->aux_cfg[1], edp->edp + DP_PHY_AUX_CFG1);
+	writel(edp->cfg->aux_cfg[2], edp->edp + DP_PHY_AUX_CFG2);
+	writel(edp->cfg->aux_cfg[3], edp->edp + DP_PHY_AUX_CFG3);
+	writel(edp->cfg->aux_cfg[4], edp->edp + DP_PHY_AUX_CFG4);
+	writel(edp->cfg->aux_cfg[5], edp->edp + DP_PHY_AUX_CFG5);
+	writel(edp->cfg->aux_cfg[6], edp->edp + DP_PHY_AUX_CFG6);
+	writel(edp->cfg->aux_cfg[7], edp->edp + DP_PHY_AUX_CFG7);
+	writel(edp->cfg->aux_cfg[8], edp->edp + DP_PHY_AUX_CFG8);
+	writel(edp->cfg->aux_cfg[9], edp->edp + DP_PHY_AUX_CFG9);
 
 	writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
 	       PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
@@ -519,16 +521,19 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
 };
 
 static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
+	.aux_cfg = edp_phy_aux_cfg_v4,
 	.ver_ops = &qcom_edp_phy_ops_v4,
 };
 
 static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
+	.aux_cfg = edp_phy_aux_cfg_v4,
 	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
 	.ver_ops = &qcom_edp_phy_ops_v4,
 };
 
 static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
 	.is_edp = true,
+	.aux_cfg = edp_phy_aux_cfg_v4,
 	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
 	.ver_ops = &qcom_edp_phy_ops_v4,
 };
@@ -707,6 +712,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
 };
 
 static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
+	.aux_cfg = edp_phy_aux_cfg_v4,
 	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
 	.ver_ops = &qcom_edp_phy_ops_v6,
 };
-- 
2.17.1



From quic_mukhopad at quicinc.com  Wed Sep 11 03:08:11 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Wed, 11 Sep 2024 15:38:11 +0530
Subject: [PATCH 3/5] phy: qcom: edp: Add support for eDP PHY on SA8775P
In-Reply-To: <20240911100813.338-1-quic_mukhopad@quicinc.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com>
Message-ID: <20240911100813.338-4-quic_mukhopad@quicinc.com>

Add support for eDP PHY v5 found on the Qualcomm SA8775P platform.

Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
 drivers/phy/qualcomm/phy-qcom-edp.c | 47 +++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
index 0f860a807d1b..34a47cd2919d 100644
--- a/drivers/phy/qualcomm/phy-qcom-edp.c
+++ b/drivers/phy/qualcomm/phy-qcom-edp.c
@@ -191,6 +191,45 @@ static u8 edp_phy_aux_cfg_v4[10] = {
 	0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
 };
 
+static const u8 edp_swing_hbr_rbr_v5[4][4] = {
+	{ 0x07, 0x0f, 0x16, 0x1f },
+	{ 0x0d, 0x16, 0x1e, 0xff },
+	{ 0x11, 0x1b, 0xff, 0xff },
+	{ 0x16, 0xff, 0xff, 0xff }
+};
+
+static const u8 edp_pre_emp_hbr_rbr_v5[4][4] = {
+	{ 0x05, 0x11, 0x17, 0x1d },
+	{ 0x05, 0x11, 0x18, 0xff },
+	{ 0x06, 0x11, 0xff, 0xff },
+	{ 0x00, 0xff, 0xff, 0xff }
+};
+
+static const u8 edp_swing_hbr2_hbr3_v5[4][4] = {
+	{ 0x0b, 0x11, 0x17, 0x1c },
+	{ 0x10, 0x19, 0x1f, 0xff },
+	{ 0x19, 0x1f, 0xff, 0xff },
+	{ 0x1f, 0xff, 0xff, 0xff }
+};
+
+static const u8 edp_pre_emp_hbr2_hbr3_v5[4][4] = {
+	{ 0x0c, 0x15, 0x19, 0x1e },
+	{ 0x0b, 0x15, 0x19, 0xff },
+	{ 0x0e, 0x14, 0xff, 0xff },
+	{ 0x0d, 0xff, 0xff, 0xff }
+};
+
+static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v5 = {
+	.swing_hbr_rbr = &edp_swing_hbr_rbr_v5,
+	.swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3_v5,
+	.pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr_v5,
+	.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v5,
+};
+
+static u8 edp_phy_aux_cfg_v5[10] = {
+	0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
+};
+
 static int qcom_edp_phy_init(struct phy *phy)
 {
 	struct qcom_edp *edp = phy_get_drvdata(phy);
@@ -520,6 +559,13 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
 	.com_configure_ssc	= qcom_edp_com_configure_ssc_v4,
 };
 
+static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
+	.is_edp = false,
+	.aux_cfg = edp_phy_aux_cfg_v5,
+	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5,
+	.ver_ops = &qcom_edp_phy_ops_v4,
+};
+
 static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
 	.aux_cfg = edp_phy_aux_cfg_v4,
 	.ver_ops = &qcom_edp_phy_ops_v4,
@@ -1114,6 +1160,7 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id qcom_edp_phy_match_table[] = {
+	{ .compatible = "qcom,sa8775p-edp-phy", .data = &sa8775p_dp_phy_cfg, },
 	{ .compatible = "qcom,sc7280-edp-phy", .data = &sc7280_dp_phy_cfg, },
 	{ .compatible = "qcom,sc8180x-edp-phy", .data = &sc7280_dp_phy_cfg, },
 	{ .compatible = "qcom,sc8280xp-dp-phy", .data = &sc8280xp_dp_phy_cfg, },
-- 
2.17.1



From quic_mukhopad at quicinc.com  Wed Sep 11 03:08:12 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Wed, 11 Sep 2024 15:38:12 +0530
Subject: [PATCH 4/5] dt-bindings: display: msm: dp-controller: document SA8775P compatible
In-Reply-To: <20240911100813.338-1-quic_mukhopad@quicinc.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com>
Message-ID: <20240911100813.338-5-quic_mukhopad@quicinc.com>

Add compatible string for the DisplayPort controller found on the
Qualcomm SA8775P platform.

Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
 Documentation/devicetree/bindings/display/msm/dp-controller.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index 97993feda193..a212f335d5ff 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -17,6 +17,7 @@ properties:
   compatible:
     oneOf:
       - enum:
+          - qcom,sa8775p-dp
           - qcom,sc7180-dp
           - qcom,sc7280-dp
           - qcom,sc7280-edp
-- 
2.17.1



From dmitry.baryshkov at linaro.org  Wed Sep 11 03:34:53 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 11 Sep 2024 13:34:53 +0300
Subject: [PATCH 2/5] phy: qcom: edp: Introduce aux_cfg array for version
 specific aux settings
In-Reply-To: <20240911100813.338-3-quic_mukhopad@quicinc.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com> <20240911100813.338-3-quic_mukhopad@quicinc.com>
Message-ID: <CAA8EJppLFWpf0QSmzAo5nqu=iMALyKzxEvy7sD5R0LDYSbA_7w@mail.gmail.com>

On Wed, 11 Sept 2024 at 13:08, Soutrik Mukhopadhyay
<quic_mukhopad at quicinc.com> wrote:
>
> In order to support different HW versions, introduce aux_cfg array
> to move v4 specific aux configuration settings.
>
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-edp.c | 34 +++++++++++++++++------------
>  1 file changed, 20 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> index da2b32fb5b45..0f860a807d1b 100644
> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> @@ -90,6 +90,7 @@ struct phy_ver_ops {
>
>  struct qcom_edp_phy_cfg {
>         bool is_edp;
> +       u8 *aux_cfg;
>         const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
>         const struct phy_ver_ops *ver_ops;
>  };
> @@ -186,11 +187,14 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
>         .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
>  };
>
> +static u8 edp_phy_aux_cfg_v4[10] = {

static const u8, please.


> +       0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
> +};
> +
>  static int qcom_edp_phy_init(struct phy *phy)
>  {
>         struct qcom_edp *edp = phy_get_drvdata(phy);
>         int ret;
> -       u8 cfg8;
>
>         ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
>         if (ret)
> @@ -222,22 +226,20 @@ static int qcom_edp_phy_init(struct phy *phy)
>          * even needed.
>          */
>         if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
> -               cfg8 = 0xb7;
> -       else
> -               cfg8 = 0x37;
> +               edp->cfg->aux_cfg[8] = 0xb7;
>
>         writel(0xfc, edp->edp + DP_PHY_MODE);
>
> -       writel(0x00, edp->edp + DP_PHY_AUX_CFG0);
> -       writel(0x13, edp->edp + DP_PHY_AUX_CFG1);
> -       writel(0x24, edp->edp + DP_PHY_AUX_CFG2);
> -       writel(0x00, edp->edp + DP_PHY_AUX_CFG3);
> -       writel(0x0a, edp->edp + DP_PHY_AUX_CFG4);
> -       writel(0x26, edp->edp + DP_PHY_AUX_CFG5);
> -       writel(0x0a, edp->edp + DP_PHY_AUX_CFG6);
> -       writel(0x03, edp->edp + DP_PHY_AUX_CFG7);
> -       writel(cfg8, edp->edp + DP_PHY_AUX_CFG8);
> -       writel(0x03, edp->edp + DP_PHY_AUX_CFG9);
> +       writel(edp->cfg->aux_cfg[0], edp->edp + DP_PHY_AUX_CFG0);
> +       writel(edp->cfg->aux_cfg[1], edp->edp + DP_PHY_AUX_CFG1);
> +       writel(edp->cfg->aux_cfg[2], edp->edp + DP_PHY_AUX_CFG2);
> +       writel(edp->cfg->aux_cfg[3], edp->edp + DP_PHY_AUX_CFG3);
> +       writel(edp->cfg->aux_cfg[4], edp->edp + DP_PHY_AUX_CFG4);
> +       writel(edp->cfg->aux_cfg[5], edp->edp + DP_PHY_AUX_CFG5);
> +       writel(edp->cfg->aux_cfg[6], edp->edp + DP_PHY_AUX_CFG6);
> +       writel(edp->cfg->aux_cfg[7], edp->edp + DP_PHY_AUX_CFG7);
> +       writel(edp->cfg->aux_cfg[8], edp->edp + DP_PHY_AUX_CFG8);
> +       writel(edp->cfg->aux_cfg[9], edp->edp + DP_PHY_AUX_CFG9);
>
>         writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
>                PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
> @@ -519,16 +521,19 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
>  };
>
>  static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
> +       .aux_cfg = edp_phy_aux_cfg_v4,
>         .ver_ops = &qcom_edp_phy_ops_v4,
>  };
>
>  static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
> +       .aux_cfg = edp_phy_aux_cfg_v4,
>         .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
>         .ver_ops = &qcom_edp_phy_ops_v4,
>  };
>
>  static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
>         .is_edp = true,
> +       .aux_cfg = edp_phy_aux_cfg_v4,
>         .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
>         .ver_ops = &qcom_edp_phy_ops_v4,
>  };
> @@ -707,6 +712,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
>  };
>
>  static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
> +       .aux_cfg = edp_phy_aux_cfg_v4,

Is this correct? Judging by ver_ops, X Elite uses v6 of the PHY, so
maybe it should also use v5 AUX tables?

>         .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
>         .ver_ops = &qcom_edp_phy_ops_v6,
>  };
> --
> 2.17.1
>


--
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Wed Sep 11 03:40:02 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 11 Sep 2024 13:40:02 +0300
Subject: [PATCH 3/5] phy: qcom: edp: Add support for eDP PHY on SA8775P
In-Reply-To: <20240911100813.338-4-quic_mukhopad@quicinc.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com> <20240911100813.338-4-quic_mukhopad@quicinc.com>
Message-ID: <CAA8EJpqurbPKjmRH8zdqPkMuze4zwJVu+=W0nP=Ldc6o_4Tu4w@mail.gmail.com>

On Wed, 11 Sept 2024 at 13:08, Soutrik Mukhopadhyay
<quic_mukhopad at quicinc.com> wrote:
>
> Add support for eDP PHY v5 found on the Qualcomm SA8775P platform.
>
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-edp.c | 47 +++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> index 0f860a807d1b..34a47cd2919d 100644
> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> @@ -191,6 +191,45 @@ static u8 edp_phy_aux_cfg_v4[10] = {
>         0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
>  };
>
> +static const u8 edp_swing_hbr_rbr_v5[4][4] = {
> +       { 0x07, 0x0f, 0x16, 0x1f },
> +       { 0x0d, 0x16, 0x1e, 0xff },
> +       { 0x11, 0x1b, 0xff, 0xff },
> +       { 0x16, 0xff, 0xff, 0xff }
> +};

Same as v4

> +
> +static const u8 edp_pre_emp_hbr_rbr_v5[4][4] = {
> +       { 0x05, 0x11, 0x17, 0x1d },
> +       { 0x05, 0x11, 0x18, 0xff },
> +       { 0x06, 0x11, 0xff, 0xff },
> +       { 0x00, 0xff, 0xff, 0xff }
> +};

Could you please confirm that there is a single value difference?

> +
> +static const u8 edp_swing_hbr2_hbr3_v5[4][4] = {
> +       { 0x0b, 0x11, 0x17, 0x1c },
> +       { 0x10, 0x19, 0x1f, 0xff },
> +       { 0x19, 0x1f, 0xff, 0xff },
> +       { 0x1f, 0xff, 0xff, 0xff }
> +};

Same as v4

> +
> +static const u8 edp_pre_emp_hbr2_hbr3_v5[4][4] = {
> +       { 0x0c, 0x15, 0x19, 0x1e },
> +       { 0x0b, 0x15, 0x19, 0xff },
> +       { 0x0e, 0x14, 0xff, 0xff },
> +       { 0x0d, 0xff, 0xff, 0xff }
> +};

This one looks fine

> +
> +static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v5 = {
> +       .swing_hbr_rbr = &edp_swing_hbr_rbr_v5,
> +       .swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3_v5,
> +       .pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr_v5,
> +       .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v5,
> +};
> +
> +static u8 edp_phy_aux_cfg_v5[10] = {
> +       0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
> +};
> +
>  static int qcom_edp_phy_init(struct phy *phy)
>  {
>         struct qcom_edp *edp = phy_get_drvdata(phy);
> @@ -520,6 +559,13 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
>         .com_configure_ssc      = qcom_edp_com_configure_ssc_v4,
>  };
>
> +static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
> +       .is_edp = false,
> +       .aux_cfg = edp_phy_aux_cfg_v5,
> +       .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5,
> +       .ver_ops = &qcom_edp_phy_ops_v4,
> +};
> +
>  static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
>         .aux_cfg = edp_phy_aux_cfg_v4,
>         .ver_ops = &qcom_edp_phy_ops_v4,
> @@ -1114,6 +1160,7 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
>  }
>
>  static const struct of_device_id qcom_edp_phy_match_table[] = {
> +       { .compatible = "qcom,sa8775p-edp-phy", .data = &sa8775p_dp_phy_cfg, },
>         { .compatible = "qcom,sc7280-edp-phy", .data = &sc7280_dp_phy_cfg, },
>         { .compatible = "qcom,sc8180x-edp-phy", .data = &sc7280_dp_phy_cfg, },
>         { .compatible = "qcom,sc8280xp-dp-phy", .data = &sc8280xp_dp_phy_cfg, },
> --
> 2.17.1
>


-- 
With best wishes
Dmitry


From christian.bruel at foss.st.com  Wed Sep 11 03:37:27 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 12:37:27 +0200
Subject: [PATCH v7 3/5] MAINTAINERS: add entry for ST STM32MP25 COMBOPHY driver
In-Reply-To: <20240911103729.2980431-1-christian.bruel@foss.st.com>
References: <20240911103729.2980431-1-christian.bruel@foss.st.com>
Message-ID: <20240911103729.2980431-4-christian.bruel@foss.st.com>

Add myself as STM32MP25 COMBOPHY maintainer

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index a70b7c9c3533..abcb5e4c5324 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21908,6 +21908,12 @@ F:	drivers/*/stm32-*timer*
 F:	drivers/pwm/pwm-stm32*
 F:	include/linux/*/stm32-*tim*
 
+STMP32MP25 USB3/PCIE COMBOPHY DRIVER
+M:	Christian Bruel <christian.bruel at foss.st.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
+F:	drivers/phy/st/phy-stm32-combophy.c
+
 STMMAC ETHERNET DRIVER
 M:	Alexandre Torgue <alexandre.torgue at foss.st.com>
 M:	Jose Abreu <joabreu at synopsys.com>
-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 03:37:25 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 12:37:25 +0200
Subject: [PATCH v7 1/5] dt-bindings: phy: Add STM32MP25 COMBOPHY bindings
In-Reply-To: <20240911103729.2980431-1-christian.bruel@foss.st.com>
References: <20240911103729.2980431-1-christian.bruel@foss.st.com>
Message-ID: <20240911103729.2980431-2-christian.bruel@foss.st.com>

Document the bindings for STM32 COMBOPHY interface, used to support
the PCIe and USB3 stm32mp25 drivers.
Following entries can be used to tune caracterisation parameters
 - st,output-micro-ohms and st,output-vswing-microvolt bindings entries
to tune the impedance and voltage swing using discrete simulation results
 - st,rx-equalizer register to set the internal rx equalizer filter value.

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 .../bindings/phy/st,stm32mp25-combophy.yaml   | 119 ++++++++++++++++++
 1 file changed, 119 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml

diff --git a/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml b/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
new file mode 100644
index 000000000000..a2e82c0bb56b
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/st,stm32mp25-combophy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32MP25 USB3/PCIe COMBOPHY
+
+maintainers:
+  - Christian Bruel <christian.bruel at foss.st.com>
+
+description:
+  Single lane PHY shared (exclusive) between the USB3 and PCIe controllers.
+  Supports 5Gbit/s for USB3 and PCIe gen2 or 2.5Gbit/s for PCIe gen1.
+
+properties:
+  compatible:
+    const: st,stm32mp25-combophy
+
+  reg:
+    maxItems: 1
+
+  "#phy-cells":
+    const: 1
+
+  clocks:
+    minItems: 2
+    items:
+      - description: apb Bus clock mandatory to access registers.
+      - description: ker Internal RCC reference clock for USB3 or PCIe
+      - description: pad Optional on board clock input for PCIe only. Typically an
+                     external 100Mhz oscillator wired on dedicated CLKIN pad. Used as reference
+                     clock input instead of the ker
+
+  clock-names:
+    minItems: 2
+    items:
+      - const: apb
+      - const: ker
+      - const: pad
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    const: phy
+
+  power-domains:
+    maxItems: 1
+
+  wakeup-source: true
+
+  interrupts:
+    maxItems: 1
+    description: interrupt used for wakeup
+
+  access-controllers:
+    maxItems: 1
+    description: Phandle to the rifsc device to check access right.
+
+  st,ssc-on:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      A property whose presence indicates that the Spread Spectrum Clocking is active.
+
+  st,rx-equalizer:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 7
+    default: 2
+    description:
+      A 3 bit value to tune the RX fixed equalizer setting for optimal eye compliance
+
+  st,output-micro-ohms:
+    minimum: 3999000
+    maximum: 6090000
+    default: 4968000
+    description:
+      A value property to tune the Single Ended Output Impedance, simulations results
+      at 25C for a VDDP=0.8V. The hardware accepts discrete values in this range.
+
+  st,output-vswing-microvolt:
+    minimum: 442000
+    maximum: 803000
+    default: 803000
+    description:
+      A value property in microvolt to tune the Single Ended Output Voltage Swing to change the
+      Vlo, Vhi for a VDDP = 0.8V. The hardware accepts discrete values in this range.
+
+required:
+  - compatible
+  - reg
+  - "#phy-cells"
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/reset/st,stm32mp25-rcc.h>
+
+    phy at 480c0000 {
+        compatible = "st,stm32mp25-combophy";
+        reg = <0x480c0000 0x1000>;
+        #phy-cells = <1>;
+        clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>;
+        clock-names = "apb", "ker";
+        resets = <&rcc USB3PCIEPHY_R>;
+        reset-names = "phy";
+        access-controllers = <&rifsc 67>;
+        power-domains = <&CLUSTER_PD>;
+        wakeup-source;
+        interrupts-extended = <&exti1 45 IRQ_TYPE_EDGE_FALLING>;
+    };
-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 03:37:24 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 12:37:24 +0200
Subject: [PATCH v7 0/5] Add STM32MP25 USB3/PCIE COMBOPHY driver 
Message-ID: <20240911103729.2980431-1-christian.bruel@foss.st.com>

Changes in v7:
   - MAINTAINERS: Reorder STMP32MP25 DRIVER entry

Changes in v6:
   - stm32_combophy_pll_init: merge combophy_cr1 accesses and error path.
   - Use devm_reset_control_get_exclusive

Changes in v5:
   - Drop syscfg phandle and change driver to use lookup_by_compatible
   - Use clk_bulk API and drop stm32_combophy_enable/disable_clocks
   - Reorder required: list.
   - Fix access-controllers maxItems

Changes in v4:
   - "#phy-cells": Drop type item description since it is specified
     by user node phandle.
   - Rename stm32-combophy.yaml to match compatible
   - Drop wakeup-source from bindings (should be generic)
   - Alphabetically reorder required: list.
   - Drop "Reviewed-by" since those previous changes

Changes in v3:
   - Reorder MAINTAINERS patch

Changes in v2:
   - Reorder entries
   - Rename clock_names and reset_names bindings
   - Rename and clarify rx-equalizer binding 

Christian Bruel (5):
  dt-bindings: phy: Add STM32MP25 COMBOPHY bindings
  phy: stm32: Add support for STM32MP25 COMBOPHY.
  MAINTAINERS: add entry for ST STM32MP25 COMBOPHY driver
  arm64: dts: st: Add combophy node on stm32mp251
  arm64: dts: st: Enable COMBOPHY on the stm32mp257f-ev1 board

 .../bindings/phy/st,stm32mp25-combophy.yaml   | 119 ++++
 MAINTAINERS                                   |   6 +
 arch/arm64/boot/dts/st/stm32mp251.dtsi        |  16 +
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts    |  14 +
 drivers/phy/st/Kconfig                        |  11 +
 drivers/phy/st/Makefile                       |   1 +
 drivers/phy/st/phy-stm32-combophy.c           | 596 ++++++++++++++++++
 7 files changed, 763 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
 create mode 100644 drivers/phy/st/phy-stm32-combophy.c

-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 03:37:26 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 12:37:26 +0200
Subject: [PATCH v7 2/5] phy: stm32: Add support for STM32MP25 COMBOPHY.
In-Reply-To: <20240911103729.2980431-1-christian.bruel@foss.st.com>
References: <20240911103729.2980431-1-christian.bruel@foss.st.com>
Message-ID: <20240911103729.2980431-3-christian.bruel@foss.st.com>

Addition of the COMBOPHY driver found on STM32MP25 platforms

This single lane PHY is shared (exclusive) between the USB3 and PCIE
controllers.
Supports 5Gbit/s for PCIE gen2 or 2.5Gbit/s for PCIE gen1.

Supports wakeup-source capability to wakeup system using remote-wakeup
capable USB device

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 drivers/phy/st/Kconfig              |  11 +
 drivers/phy/st/Makefile             |   1 +
 drivers/phy/st/phy-stm32-combophy.c | 596 ++++++++++++++++++++++++++++
 3 files changed, 608 insertions(+)
 create mode 100644 drivers/phy/st/phy-stm32-combophy.c

diff --git a/drivers/phy/st/Kconfig b/drivers/phy/st/Kconfig
index 3fc3d0781fb8..304614b6dabf 100644
--- a/drivers/phy/st/Kconfig
+++ b/drivers/phy/st/Kconfig
@@ -33,6 +33,17 @@ config PHY_STIH407_USB
 	  Enable this support to enable the picoPHY device used by USB2
 	  and USB3 controllers on STMicroelectronics STiH407 SoC families.
 
+config PHY_STM32_COMBOPHY
+	tristate "STMicroelectronics COMBOPHY driver for STM32MP25"
+	depends on ARCH_STM32 || COMPILE_TEST
+	select GENERIC_PHY
+	help
+	  Enable this to support the COMBOPHY device used by USB3 or PCIe
+	  controllers on STMicroelectronics STM32MP25 SoC.
+	  This driver controls the COMBOPHY block to generate the PCIe 100Mhz
+	  reference clock from either the external clock generator or HSE
+	  internal SoC clock source.
+
 config PHY_STM32_USBPHYC
 	tristate "STMicroelectronics STM32 USB HS PHY Controller driver"
 	depends on ARCH_STM32 || COMPILE_TEST
diff --git a/drivers/phy/st/Makefile b/drivers/phy/st/Makefile
index c862dd937b64..cb80e954ea9f 100644
--- a/drivers/phy/st/Makefile
+++ b/drivers/phy/st/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_PHY_MIPHY28LP) 		+= phy-miphy28lp.o
 obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)	+= phy-spear1310-miphy.o
 obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)	+= phy-spear1340-miphy.o
 obj-$(CONFIG_PHY_STIH407_USB)		+= phy-stih407-usb.o
+obj-$(CONFIG_PHY_STM32_COMBOPHY)	+= phy-stm32-combophy.o
 obj-$(CONFIG_PHY_STM32_USBPHYC) 	+= phy-stm32-usbphyc.o
diff --git a/drivers/phy/st/phy-stm32-combophy.c b/drivers/phy/st/phy-stm32-combophy.c
new file mode 100644
index 000000000000..37ae6b28c7fa
--- /dev/null
+++ b/drivers/phy/st/phy-stm32-combophy.c
@@ -0,0 +1,596 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * STMicroelectronics COMBOPHY STM32MP25 Controller driver.
+ *
+ * Copyright (C) 2024 STMicroelectronics
+ * Author: Christian Bruel <christian.bruel at foss.st.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <dt-bindings/phy/phy.h>
+
+#define SYSCFG_COMBOPHY_CR1 0x4c00
+#define SYSCFG_COMBOPHY_CR2 0x4c04
+#define SYSCFG_COMBOPHY_CR4 0x4c0c
+#define SYSCFG_COMBOPHY_CR5 0x4c10
+#define SYSCFG_COMBOPHY_SR  0x4c14
+#define SYSCFG_PCIEPRGCR    0x6080
+
+/* SYSCFG PCIEPRGCR */
+#define STM32MP25_PCIEPRGCR_EN	  BIT(0)
+#define STM32MP25_PCIEPRG_IMPCTRL_OHM     GENMASK(3, 1)
+#define STM32MP25_PCIEPRG_IMPCTRL_VSWING  GENMASK(5, 4)
+
+/* SYSCFG SYSCFG_COMBOPHY_SR */
+#define STM32MP25_PIPE0_PHYSTATUS BIT(1)
+
+/* SYSCFG CR1 */
+#define SYSCFG_COMBOPHY_CR1_REFUSEPAD BIT(0)
+#define SYSCFG_COMBOPHY_CR1_MPLLMULT GENMASK(7, 1)
+#define SYSCFG_COMBOPHY_CR1_REFCLKSEL GENMASK(16, 8)
+#define SYSCFG_COMBOPHY_CR1_REFCLKDIV2 BIT(17)
+#define SYSCFG_COMBOPHY_CR1_REFSSPEN BIT(18)
+#define SYSCFG_COMBOPHY_CR1_SSCEN BIT(19)
+
+/* SYSCFG CR4 */
+#define SYSCFG_COMBOPHY_CR4_RX0_EQ GENMASK(2, 0)
+
+#define MPLLMULT_19_2 (0x02u << 1)
+#define MPLLMULT_20   (0x7du << 1)
+#define MPLLMULT_24   (0x68u << 1)
+#define MPLLMULT_25   (0x64u << 1)
+#define MPLLMULT_26   (0x60u << 1)
+#define MPLLMULT_38_4 (0x41u << 1)
+#define MPLLMULT_48   (0x6cu << 1)
+#define MPLLMULT_50   (0x32u << 1)
+#define MPLLMULT_52   (0x30u << 1)
+#define MPLLMULT_100  (0x19u << 1)
+
+#define REFCLKSEL_0   0
+#define REFCLKSEL_1   (0x108u << 8)
+
+#define REFCLDIV_0    0
+
+/* SYSCFG CR2 */
+#define SYSCFG_COMBOPHY_CR2_MODESEL GENMASK(1, 0)
+#define SYSCFG_COMBOPHY_CR2_ISO_DIS BIT(15)
+
+#define COMBOPHY_MODESEL_PCIE 0
+#define COMBOPHY_MODESEL_USB  3
+
+/* SYSCFG CR5 */
+#define SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS BIT(12)
+
+#define COMBOPHY_SUP_ANA_MPLL_LOOP_CTL 0xc0
+#define COMBOPHY_PROP_CNTRL GENMASK(7, 4)
+
+/* Required apb/ker clocks first, optional pad last. */
+static const char * const combophy_clks[] = {"apb", "ker", "pad"};
+#define APB_CLK 0
+#define KER_CLK 1
+#define PAD_CLK 2
+
+struct stm32_combophy {
+	struct phy *phy;
+	struct regmap *regmap;
+	struct device *dev;
+	void __iomem *base;
+	struct reset_control *phy_reset;
+	struct clk_bulk_data clks[ARRAY_SIZE(combophy_clks)];
+	int num_clks;
+	bool have_pad_clk;
+	unsigned int type;
+	bool is_init;
+	int irq_wakeup;
+};
+
+struct clk_impedance  {
+	u32 microohm;
+	u32 vswing[4];
+};
+
+/*
+ * lookup table to hold the settings needed for a ref clock frequency
+ * impedance, the offset is used to set the IMP_CTL and DE_EMP bit of the
+ * PRG_IMP_CTRL register. Use ordered discrete values in the table
+ */
+static const struct clk_impedance imp_lookup[] = {
+	{ 6090000, { 442000, 564000, 684000, 802000 } },
+	{ 5662000, { 528000, 621000, 712000, 803000 } },
+	{ 5292000, { 491000, 596000, 700000, 802000 } },
+	{ 4968000, { 558000, 640000, 722000, 803000 } },
+	{ 4684000, { 468000, 581000, 692000, 802000 } },
+	{ 4429000, { 554000, 613000, 717000, 803000 } },
+	{ 4204000, { 511000, 609000, 706000, 802000 } },
+	{ 3999000, { 571000, 648000, 726000, 803000 } }
+};
+
+static int stm32_impedance_tune(struct stm32_combophy *combophy)
+{
+	u8 imp_size = ARRAY_SIZE(imp_lookup);
+	u8 vswing_size = ARRAY_SIZE(imp_lookup[0].vswing);
+	u8 imp_of, vswing_of;
+	u32 max_imp = imp_lookup[0].microohm;
+	u32 min_imp = imp_lookup[imp_size - 1].microohm;
+	u32 max_vswing = imp_lookup[imp_size - 1].vswing[vswing_size - 1];
+	u32 min_vswing = imp_lookup[0].vswing[0];
+	u32 val;
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,output-micro-ohms", &val)) {
+		if (val < min_imp || val > max_imp) {
+			dev_err(combophy->dev, "Invalid value %u for output ohm\n", val);
+			return -EINVAL;
+		}
+
+		for (imp_of = 0; imp_of < ARRAY_SIZE(imp_lookup); imp_of++)
+			if (imp_lookup[imp_of].microohm <= val)
+				break;
+
+		dev_dbg(combophy->dev, "Set %u micro-ohms output impedance\n",
+			imp_lookup[imp_of].microohm);
+
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRG_IMPCTRL_OHM,
+				   FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_OHM, imp_of));
+	} else {
+		regmap_read(combophy->regmap, SYSCFG_PCIEPRGCR, &val);
+		imp_of = FIELD_GET(STM32MP25_PCIEPRG_IMPCTRL_OHM, val);
+	}
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,output-vswing-microvolt", &val)) {
+		if (val < min_vswing || val > max_vswing) {
+			dev_err(combophy->dev, "Invalid value %u for output vswing\n", val);
+			return -EINVAL;
+		}
+
+		for (vswing_of = 0; vswing_of < ARRAY_SIZE(imp_lookup[imp_of].vswing); vswing_of++)
+			if (imp_lookup[imp_of].vswing[vswing_of] >= val)
+				break;
+
+		dev_dbg(combophy->dev, "Set %u microvolt swing\n",
+			 imp_lookup[imp_of].vswing[vswing_of]);
+
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRG_IMPCTRL_VSWING,
+				   FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of));
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_pll_init(struct stm32_combophy *combophy)
+{
+	int ret;
+	u32 refclksel, pllmult, propcntrl, val;
+	u32 clk_rate;
+	struct clk *clk;
+	u32 cr1_val = 0, cr1_mask = 0;
+
+	if (combophy->have_pad_clk)
+		clk = combophy->clks[PAD_CLK].clk;
+	else
+		clk = combophy->clks[KER_CLK].clk;
+
+	clk_rate = clk_get_rate(clk);
+
+	dev_dbg(combophy->dev, "%s pll init rate %d\n",
+		combophy->have_pad_clk ? "External" : "Ker", clk_rate);
+
+	if (combophy->type != PHY_TYPE_PCIE) {
+		cr1_mask |= SYSCFG_COMBOPHY_CR1_REFSSPEN;
+		cr1_val |= SYSCFG_COMBOPHY_CR1_REFSSPEN;
+	}
+
+	if (of_property_present(combophy->dev->of_node, "st,ssc-on")) {
+		dev_dbg(combophy->dev, "Enabling clock with SSC\n");
+		cr1_mask |= SYSCFG_COMBOPHY_CR1_SSCEN;
+		cr1_val |= SYSCFG_COMBOPHY_CR1_SSCEN;
+	}
+
+	switch (clk_rate) {
+	case 100000000:
+		pllmult = MPLLMULT_100;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0x8u << 4;
+		break;
+	case 19200000:
+		pllmult = MPLLMULT_19_2;
+		refclksel = REFCLKSEL_1;
+		propcntrl = 0x8u << 4;
+		break;
+	case 25000000:
+		pllmult = MPLLMULT_25;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0xeu << 4;
+		break;
+	case 24000000:
+		pllmult = MPLLMULT_24;
+		refclksel = REFCLKSEL_1;
+		propcntrl = 0xeu << 4;
+		break;
+	case 20000000:
+		pllmult = MPLLMULT_20;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0xeu << 4;
+		break;
+	default:
+		dev_err(combophy->dev, "Invalid rate 0x%x\n", clk_rate);
+		return -EINVAL;
+	};
+
+	cr1_mask |= SYSCFG_COMBOPHY_CR1_REFCLKDIV2;
+	cr1_val |= REFCLDIV_0;
+
+	cr1_mask |= SYSCFG_COMBOPHY_CR1_REFCLKSEL;
+	cr1_val |= refclksel;
+
+	cr1_mask |= SYSCFG_COMBOPHY_CR1_MPLLMULT;
+	cr1_val |= pllmult;
+
+	/*
+	 * vddcombophy is interconnected with vddcore. Isolation bit should be unset
+	 * before using the ComboPHY.
+	 */
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, SYSCFG_COMBOPHY_CR2_ISO_DIS);
+
+	reset_control_assert(combophy->phy_reset);
+
+	if (combophy->type == PHY_TYPE_PCIE) {
+		ret = stm32_impedance_tune(combophy);
+		if (ret)
+			goto out_iso;
+
+		cr1_mask |= SYSCFG_COMBOPHY_CR1_REFUSEPAD;
+		cr1_val |= combophy->have_pad_clk ? SYSCFG_COMBOPHY_CR1_REFUSEPAD : 0;
+	}
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,rx-equalizer", &val)) {
+		dev_dbg(combophy->dev, "Set RX equalizer %u\n", val);
+		if (val > SYSCFG_COMBOPHY_CR4_RX0_EQ) {
+			dev_err(combophy->dev, "Invalid value %u for rx0 equalizer\n", val);
+			ret = -EINVAL;
+			goto out_iso;
+		}
+
+		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR4,
+			   SYSCFG_COMBOPHY_CR4_RX0_EQ, val);
+	}
+
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1, cr1_mask, cr1_val);
+
+	/*
+	 * Force elasticity buffer to be tuned for the reference clock as
+	 * the separated clock model is not supported
+	 */
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR5,
+			   SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS, SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS);
+
+	reset_control_deassert(combophy->phy_reset);
+
+	ret = regmap_read_poll_timeout(combophy->regmap, SYSCFG_COMBOPHY_SR, val,
+				       !(val & STM32MP25_PIPE0_PHYSTATUS),
+				       10, 1000);
+	if (ret) {
+		dev_err(combophy->dev, "timeout, cannot lock PLL\n");
+		if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
+			regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+					   STM32MP25_PCIEPRGCR_EN, 0);
+
+		if (combophy->type != PHY_TYPE_PCIE)
+			regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+					   SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
+
+		goto out;
+	}
+
+
+	if (combophy->type == PHY_TYPE_PCIE) {
+		if (!combophy->have_pad_clk)
+			regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+					   STM32MP25_PCIEPRGCR_EN, STM32MP25_PCIEPRGCR_EN);
+
+		val = readl_relaxed(combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
+		val &= ~COMBOPHY_PROP_CNTRL;
+		val |= propcntrl;
+		writel_relaxed(val, combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
+	}
+
+	return 0;
+
+out_iso:
+	reset_control_deassert(combophy->phy_reset);
+
+out:
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
+
+	return ret;
+}
+
+static struct phy *stm32_combophy_xlate(struct device *dev,
+					const struct of_phandle_args *args)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+	unsigned int type;
+
+	if (args->args_count != 1) {
+		dev_err(dev, "invalid number of cells in 'phy' property\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	type = args->args[0];
+	if (type != PHY_TYPE_USB3 && type != PHY_TYPE_PCIE) {
+		dev_err(dev, "unsupported device type: %d\n", type);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (combophy->have_pad_clk && type != PHY_TYPE_PCIE) {
+		dev_err(dev, "Invalid use of clk_pad for USB3 mode\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	combophy->type = type;
+
+	return combophy->phy;
+}
+
+static int stm32_combophy_set_mode(struct stm32_combophy *combophy)
+{
+	int type = combophy->type;
+	u32 val;
+
+	switch (type) {
+	case PHY_TYPE_PCIE:
+		dev_dbg(combophy->dev, "setting PCIe ComboPHY\n");
+		val = COMBOPHY_MODESEL_PCIE;
+		break;
+	case PHY_TYPE_USB3:
+		dev_dbg(combophy->dev, "setting USB3 ComboPHY\n");
+		val = COMBOPHY_MODESEL_USB;
+		break;
+	default:
+		dev_err(combophy->dev, "Invalid PHY mode %d\n", type);
+		return -EINVAL;
+	}
+
+	return regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+				  SYSCFG_COMBOPHY_CR2_MODESEL, val);
+}
+
+static int stm32_combophy_suspend_noirq(struct device *dev)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+
+	/*
+	 * Clocks should be turned off since it is not needed for
+	 * wakeup capability. In case usb-remote wakeup is not enabled,
+	 * combo-phy is already turned off by HCD driver using exit callback
+	 */
+	if (combophy->is_init) {
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+
+		/* since wakeup is enabled for ctrl */
+		enable_irq_wake(combophy->irq_wakeup);
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_resume_noirq(struct device *dev)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+	int ret;
+
+	/*
+	 * If clocks was turned off by suspend call for wakeup then needs
+	 * to be turned back ON in resume. In case usb-remote wakeup is not
+	 * enabled, clocks already turned ON by HCD driver using init callback
+	 */
+	if (combophy->is_init) {
+		/* since wakeup was enabled for ctrl */
+		disable_irq_wake(combophy->irq_wakeup);
+
+		ret = clk_bulk_prepare_enable(combophy->num_clks, combophy->clks);
+		if (ret) {
+			dev_err(dev, "can't enable clocks (%d)\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_exit(struct phy *phy)
+{
+	struct stm32_combophy *combophy = phy_get_drvdata(phy);
+	struct device *dev = combophy->dev;
+
+	combophy->is_init = false;
+
+	if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRGCR_EN, 0);
+
+	if (combophy->type != PHY_TYPE_PCIE)
+		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+				   SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
+
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
+
+	clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+
+	pm_runtime_put_noidle(dev);
+
+	return 0;
+}
+
+static int stm32_combophy_init(struct phy *phy)
+{
+	struct stm32_combophy *combophy = phy_get_drvdata(phy);
+	struct device *dev = combophy->dev;
+	int ret;
+
+	pm_runtime_get_noresume(dev);
+
+	ret = clk_bulk_prepare_enable(combophy->num_clks, combophy->clks);
+	if (ret) {
+		dev_err(dev, "can't enable clocks (%d)\n", ret);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	ret = stm32_combophy_set_mode(combophy);
+	if (ret) {
+		dev_err(dev, "combophy mode not set\n");
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	ret = stm32_combophy_pll_init(combophy);
+	if (ret) {
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	pm_runtime_disable(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+
+	combophy->is_init = true;
+
+	return ret;
+}
+
+static const struct phy_ops stm32_combophy_phy_data = {
+	.init = stm32_combophy_init,
+	.exit = stm32_combophy_exit,
+	.owner = THIS_MODULE
+};
+
+static irqreturn_t stm32_combophy_irq_wakeup_handler(int irq, void *dev_id)
+{
+	return IRQ_HANDLED;
+}
+
+static int stm32_combophy_get_clocks(struct stm32_combophy *combophy)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(combophy_clks); i++)
+		combophy->clks[i].id = combophy_clks[i];
+
+	combophy->num_clks = ARRAY_SIZE(combophy_clks) - 1;
+
+	ret = devm_clk_bulk_get(combophy->dev, combophy->num_clks, combophy->clks);
+	if (ret)
+		return ret;
+
+	ret = devm_clk_bulk_get_optional(combophy->dev, 1, combophy->clks + combophy->num_clks);
+	if (ret)
+		return ret;
+
+	if (combophy->clks[combophy->num_clks].clk != NULL) {
+		combophy->have_pad_clk = true;
+		combophy->num_clks++;
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_probe(struct platform_device *pdev)
+{
+	struct stm32_combophy *combophy;
+	struct device *dev = &pdev->dev;
+	struct phy_provider *phy_provider;
+	int ret, irq;
+
+	combophy = devm_kzalloc(dev, sizeof(*combophy), GFP_KERNEL);
+	if (!combophy)
+		return -ENOMEM;
+
+	combophy->dev = dev;
+
+	dev_set_drvdata(dev, combophy);
+
+	combophy->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(combophy->base))
+		return PTR_ERR(combophy->base);
+
+	if (stm32_combophy_get_clocks(combophy))
+		return ret;
+
+	combophy->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
+	if (IS_ERR(combophy->phy_reset))
+		return dev_err_probe(dev, PTR_ERR(combophy->phy_reset),
+				     "Failed to get PHY reset\n");
+
+	combophy->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg");
+	if (IS_ERR(combophy->regmap))
+		return dev_err_probe(dev, PTR_ERR(combophy->regmap),
+				     "No syscfg specified\n");
+
+	combophy->phy = devm_phy_create(dev, NULL, &stm32_combophy_phy_data);
+	if (IS_ERR(combophy->phy))
+		return dev_err_probe(dev, PTR_ERR(combophy->phy),
+				     "failed to create PCIe/USB3 ComboPHY\n");
+
+	if (device_property_read_bool(dev, "wakeup-source")) {
+		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return dev_err_probe(dev, irq, "failed to get IRQ\n");
+		combophy->irq_wakeup = irq;
+
+		ret = devm_request_threaded_irq(dev, combophy->irq_wakeup, NULL,
+						stm32_combophy_irq_wakeup_handler, IRQF_ONESHOT,
+						NULL, NULL);
+		if (ret)
+			return dev_err_probe(dev, ret, "unable to request wake IRQ %d\n",
+						 combophy->irq_wakeup);
+	}
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to enable pm runtime\n");
+
+	phy_set_drvdata(combophy->phy, combophy);
+
+	phy_provider = devm_of_phy_provider_register(dev, stm32_combophy_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct dev_pm_ops stm32_combophy_pm_ops = {
+	NOIRQ_SYSTEM_SLEEP_PM_OPS(stm32_combophy_suspend_noirq,
+				  stm32_combophy_resume_noirq)
+};
+
+static const struct of_device_id stm32_combophy_of_match[] = {
+	{ .compatible = "st,stm32mp25-combophy", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, stm32_combophy_of_match);
+
+static struct platform_driver stm32_combophy_driver = {
+	.probe = stm32_combophy_probe,
+	.driver = {
+		   .name = "stm32-combophy",
+		   .of_match_table = stm32_combophy_of_match,
+		   .pm = pm_sleep_ptr(&stm32_combophy_pm_ops)
+	}
+};
+
+module_platform_driver(stm32_combophy_driver);
+
+MODULE_AUTHOR("Christian Bruel <christian.bruel at foss.st.com>");
+MODULE_DESCRIPTION("STM32MP25 Combophy USB3/PCIe controller driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 03:37:28 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 12:37:28 +0200
Subject: [PATCH v7 4/5] arm64: dts: st: Add combophy node on stm32mp251
In-Reply-To: <20240911103729.2980431-1-christian.bruel@foss.st.com>
References: <20240911103729.2980431-1-christian.bruel@foss.st.com>
Message-ID: <20240911103729.2980431-5-christian.bruel@foss.st.com>

Add support for COMBOPHY which is used either by the USB3 and PCIe
controller.
USB3 or PCIe mode is done with phy_set_mode().
PCIe internal reference clock can be generated from the internal clock
source or optionnaly from an external 100Mhz pad.

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp251.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 1167cf63d7e8..b596afec1b6e 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -7,6 +7,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset/st,stm32mp25-rcc.h>
 #include <dt-bindings/regulator/st,stm32mp25-regulator.h>
+#include <dt-bindings/phy/phy.h>
 
 / {
 	#address-cells = <2>;
@@ -518,6 +519,21 @@ i2c8: i2c at 46040000 {
 				status = "disabled";
 			};
 
+			combophy: phy at 480c0000 {
+				compatible = "st,stm32mp25-combophy";
+				reg = <0x480c0000 0x1000>;
+				#phy-cells = <1>;
+				clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>;
+				clock-names = "apb", "ker";
+				resets = <&rcc USB3PCIEPHY_R>;
+				reset-names = "phy";
+				access-controllers = <&rifsc 67>;
+				power-domains = <&CLUSTER_PD>;
+				wakeup-source;
+				interrupts-extended = <&exti1 45 IRQ_TYPE_EDGE_FALLING>;
+				status = "disabled";
+			};
+
 			sdmmc1: mmc at 48220000 {
 				compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell";
 				arm,primecell-periphid = <0x00353180>;
-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 03:46:45 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 12:46:45 +0200
Subject: [PATCH v8 4/5] arm64: dts: st: Add combophy node on stm32mp251
In-Reply-To: <20240911104646.2980821-1-christian.bruel@foss.st.com>
References: <20240911104646.2980821-1-christian.bruel@foss.st.com>
Message-ID: <20240911104646.2980821-5-christian.bruel@foss.st.com>

Add support for COMBOPHY which is used either by the USB3 and PCIe
controller.
USB3 or PCIe mode is done with phy_set_mode().
PCIe internal reference clock can be generated from the internal clock
source or optionnaly from an external 100Mhz pad.

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp251.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 1167cf63d7e8..b596afec1b6e 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -7,6 +7,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset/st,stm32mp25-rcc.h>
 #include <dt-bindings/regulator/st,stm32mp25-regulator.h>
+#include <dt-bindings/phy/phy.h>
 
 / {
 	#address-cells = <2>;
@@ -518,6 +519,21 @@ i2c8: i2c at 46040000 {
 				status = "disabled";
 			};
 
+			combophy: phy at 480c0000 {
+				compatible = "st,stm32mp25-combophy";
+				reg = <0x480c0000 0x1000>;
+				#phy-cells = <1>;
+				clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>;
+				clock-names = "apb", "ker";
+				resets = <&rcc USB3PCIEPHY_R>;
+				reset-names = "phy";
+				access-controllers = <&rifsc 67>;
+				power-domains = <&CLUSTER_PD>;
+				wakeup-source;
+				interrupts-extended = <&exti1 45 IRQ_TYPE_EDGE_FALLING>;
+				status = "disabled";
+			};
+
 			sdmmc1: mmc at 48220000 {
 				compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell";
 				arm,primecell-periphid = <0x00353180>;
-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 03:46:44 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 12:46:44 +0200
Subject: [PATCH v8 3/5] MAINTAINERS: add entry for ST STM32MP25 COMBOPHY driver
In-Reply-To: <20240911104646.2980821-1-christian.bruel@foss.st.com>
References: <20240911104646.2980821-1-christian.bruel@foss.st.com>
Message-ID: <20240911104646.2980821-4-christian.bruel@foss.st.com>

Add myself as STM32MP25 COMBOPHY maintainer

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index a70b7c9c3533..73fd76dab699 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21908,6 +21908,12 @@ F:	drivers/*/stm32-*timer*
 F:	drivers/pwm/pwm-stm32*
 F:	include/linux/*/stm32-*tim*
 
+STM32MP25 USB3/PCIE COMBOPHY DRIVER
+M:	Christian Bruel <christian.bruel at foss.st.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
+F:	drivers/phy/st/phy-stm32-combophy.c
+
 STMMAC ETHERNET DRIVER
 M:	Alexandre Torgue <alexandre.torgue at foss.st.com>
 M:	Jose Abreu <joabreu at synopsys.com>
-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 03:46:41 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 12:46:41 +0200
Subject: [PATCH v8 0/5] Add STM32MP25 USB3/PCIE COMBOPHY driver 
Message-ID: <20240911104646.2980821-1-christian.bruel@foss.st.com>

Changes in v7/v8:
   - MAINTAINERS: Reorder STM32MP25 DRIVER entry

Changes in v6:
   - stm32_combophy_pll_init: merge combophy_cr1 accesses and error path.
   - Use devm_reset_control_get_exclusive

Changes in v5:
   - Drop syscfg phandle and change driver to use lookup_by_compatible
   - Use clk_bulk API and drop stm32_combophy_enable/disable_clocks
   - Reorder required: list.
   - Fix access-controllers maxItems

Changes in v4:
   - "#phy-cells": Drop type item description since it is specified
     by user node phandle.
   - Rename stm32-combophy.yaml to match compatible
   - Drop wakeup-source from bindings (should be generic)
   - Alphabetically reorder required: list.
   - Drop "Reviewed-by" since those previous changes

Changes in v3:
   - Reorder MAINTAINERS patch

Changes in v2:
   - Reorder entries
   - Rename clock_names and reset_names bindings
   - Rename and clarify rx-equalizer binding 

Christian Bruel (5):
  dt-bindings: phy: Add STM32MP25 COMBOPHY bindings
  phy: stm32: Add support for STM32MP25 COMBOPHY.
  MAINTAINERS: add entry for ST STM32MP25 COMBOPHY driver
  arm64: dts: st: Add combophy node on stm32mp251
  arm64: dts: st: Enable COMBOPHY on the stm32mp257f-ev1 board

 .../bindings/phy/st,stm32mp25-combophy.yaml   | 119 ++++
 MAINTAINERS                                   |   6 +
 arch/arm64/boot/dts/st/stm32mp251.dtsi        |  16 +
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts    |  14 +
 drivers/phy/st/Kconfig                        |  11 +
 drivers/phy/st/Makefile                       |   1 +
 drivers/phy/st/phy-stm32-combophy.c           | 596 ++++++++++++++++++
 7 files changed, 763 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
 create mode 100644 drivers/phy/st/phy-stm32-combophy.c

-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 03:46:42 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 12:46:42 +0200
Subject: [PATCH v8 1/5] dt-bindings: phy: Add STM32MP25 COMBOPHY bindings
In-Reply-To: <20240911104646.2980821-1-christian.bruel@foss.st.com>
References: <20240911104646.2980821-1-christian.bruel@foss.st.com>
Message-ID: <20240911104646.2980821-2-christian.bruel@foss.st.com>

Document the bindings for STM32 COMBOPHY interface, used to support
the PCIe and USB3 stm32mp25 drivers.
Following entries can be used to tune caracterisation parameters
 - st,output-micro-ohms and st,output-vswing-microvolt bindings entries
to tune the impedance and voltage swing using discrete simulation results
 - st,rx-equalizer register to set the internal rx equalizer filter value.

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 .../bindings/phy/st,stm32mp25-combophy.yaml   | 119 ++++++++++++++++++
 1 file changed, 119 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml

diff --git a/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml b/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
new file mode 100644
index 000000000000..a2e82c0bb56b
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/st,stm32mp25-combophy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32MP25 USB3/PCIe COMBOPHY
+
+maintainers:
+  - Christian Bruel <christian.bruel at foss.st.com>
+
+description:
+  Single lane PHY shared (exclusive) between the USB3 and PCIe controllers.
+  Supports 5Gbit/s for USB3 and PCIe gen2 or 2.5Gbit/s for PCIe gen1.
+
+properties:
+  compatible:
+    const: st,stm32mp25-combophy
+
+  reg:
+    maxItems: 1
+
+  "#phy-cells":
+    const: 1
+
+  clocks:
+    minItems: 2
+    items:
+      - description: apb Bus clock mandatory to access registers.
+      - description: ker Internal RCC reference clock for USB3 or PCIe
+      - description: pad Optional on board clock input for PCIe only. Typically an
+                     external 100Mhz oscillator wired on dedicated CLKIN pad. Used as reference
+                     clock input instead of the ker
+
+  clock-names:
+    minItems: 2
+    items:
+      - const: apb
+      - const: ker
+      - const: pad
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    const: phy
+
+  power-domains:
+    maxItems: 1
+
+  wakeup-source: true
+
+  interrupts:
+    maxItems: 1
+    description: interrupt used for wakeup
+
+  access-controllers:
+    maxItems: 1
+    description: Phandle to the rifsc device to check access right.
+
+  st,ssc-on:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      A property whose presence indicates that the Spread Spectrum Clocking is active.
+
+  st,rx-equalizer:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 7
+    default: 2
+    description:
+      A 3 bit value to tune the RX fixed equalizer setting for optimal eye compliance
+
+  st,output-micro-ohms:
+    minimum: 3999000
+    maximum: 6090000
+    default: 4968000
+    description:
+      A value property to tune the Single Ended Output Impedance, simulations results
+      at 25C for a VDDP=0.8V. The hardware accepts discrete values in this range.
+
+  st,output-vswing-microvolt:
+    minimum: 442000
+    maximum: 803000
+    default: 803000
+    description:
+      A value property in microvolt to tune the Single Ended Output Voltage Swing to change the
+      Vlo, Vhi for a VDDP = 0.8V. The hardware accepts discrete values in this range.
+
+required:
+  - compatible
+  - reg
+  - "#phy-cells"
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/reset/st,stm32mp25-rcc.h>
+
+    phy at 480c0000 {
+        compatible = "st,stm32mp25-combophy";
+        reg = <0x480c0000 0x1000>;
+        #phy-cells = <1>;
+        clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>;
+        clock-names = "apb", "ker";
+        resets = <&rcc USB3PCIEPHY_R>;
+        reset-names = "phy";
+        access-controllers = <&rifsc 67>;
+        power-domains = <&CLUSTER_PD>;
+        wakeup-source;
+        interrupts-extended = <&exti1 45 IRQ_TYPE_EDGE_FALLING>;
+    };
-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 03:46:43 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 12:46:43 +0200
Subject: [PATCH v8 2/5] phy: stm32: Add support for STM32MP25 COMBOPHY.
In-Reply-To: <20240911104646.2980821-1-christian.bruel@foss.st.com>
References: <20240911104646.2980821-1-christian.bruel@foss.st.com>
Message-ID: <20240911104646.2980821-3-christian.bruel@foss.st.com>

Addition of the COMBOPHY driver found on STM32MP25 platforms

This single lane PHY is shared (exclusive) between the USB3 and PCIE
controllers.
Supports 5Gbit/s for PCIE gen2 or 2.5Gbit/s for PCIE gen1.

Supports wakeup-source capability to wakeup system using remote-wakeup
capable USB device

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 drivers/phy/st/Kconfig              |  11 +
 drivers/phy/st/Makefile             |   1 +
 drivers/phy/st/phy-stm32-combophy.c | 596 ++++++++++++++++++++++++++++
 3 files changed, 608 insertions(+)
 create mode 100644 drivers/phy/st/phy-stm32-combophy.c

diff --git a/drivers/phy/st/Kconfig b/drivers/phy/st/Kconfig
index 3fc3d0781fb8..304614b6dabf 100644
--- a/drivers/phy/st/Kconfig
+++ b/drivers/phy/st/Kconfig
@@ -33,6 +33,17 @@ config PHY_STIH407_USB
 	  Enable this support to enable the picoPHY device used by USB2
 	  and USB3 controllers on STMicroelectronics STiH407 SoC families.
 
+config PHY_STM32_COMBOPHY
+	tristate "STMicroelectronics COMBOPHY driver for STM32MP25"
+	depends on ARCH_STM32 || COMPILE_TEST
+	select GENERIC_PHY
+	help
+	  Enable this to support the COMBOPHY device used by USB3 or PCIe
+	  controllers on STMicroelectronics STM32MP25 SoC.
+	  This driver controls the COMBOPHY block to generate the PCIe 100Mhz
+	  reference clock from either the external clock generator or HSE
+	  internal SoC clock source.
+
 config PHY_STM32_USBPHYC
 	tristate "STMicroelectronics STM32 USB HS PHY Controller driver"
 	depends on ARCH_STM32 || COMPILE_TEST
diff --git a/drivers/phy/st/Makefile b/drivers/phy/st/Makefile
index c862dd937b64..cb80e954ea9f 100644
--- a/drivers/phy/st/Makefile
+++ b/drivers/phy/st/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_PHY_MIPHY28LP) 		+= phy-miphy28lp.o
 obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)	+= phy-spear1310-miphy.o
 obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)	+= phy-spear1340-miphy.o
 obj-$(CONFIG_PHY_STIH407_USB)		+= phy-stih407-usb.o
+obj-$(CONFIG_PHY_STM32_COMBOPHY)	+= phy-stm32-combophy.o
 obj-$(CONFIG_PHY_STM32_USBPHYC) 	+= phy-stm32-usbphyc.o
diff --git a/drivers/phy/st/phy-stm32-combophy.c b/drivers/phy/st/phy-stm32-combophy.c
new file mode 100644
index 000000000000..37ae6b28c7fa
--- /dev/null
+++ b/drivers/phy/st/phy-stm32-combophy.c
@@ -0,0 +1,596 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * STMicroelectronics COMBOPHY STM32MP25 Controller driver.
+ *
+ * Copyright (C) 2024 STMicroelectronics
+ * Author: Christian Bruel <christian.bruel at foss.st.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <dt-bindings/phy/phy.h>
+
+#define SYSCFG_COMBOPHY_CR1 0x4c00
+#define SYSCFG_COMBOPHY_CR2 0x4c04
+#define SYSCFG_COMBOPHY_CR4 0x4c0c
+#define SYSCFG_COMBOPHY_CR5 0x4c10
+#define SYSCFG_COMBOPHY_SR  0x4c14
+#define SYSCFG_PCIEPRGCR    0x6080
+
+/* SYSCFG PCIEPRGCR */
+#define STM32MP25_PCIEPRGCR_EN	  BIT(0)
+#define STM32MP25_PCIEPRG_IMPCTRL_OHM     GENMASK(3, 1)
+#define STM32MP25_PCIEPRG_IMPCTRL_VSWING  GENMASK(5, 4)
+
+/* SYSCFG SYSCFG_COMBOPHY_SR */
+#define STM32MP25_PIPE0_PHYSTATUS BIT(1)
+
+/* SYSCFG CR1 */
+#define SYSCFG_COMBOPHY_CR1_REFUSEPAD BIT(0)
+#define SYSCFG_COMBOPHY_CR1_MPLLMULT GENMASK(7, 1)
+#define SYSCFG_COMBOPHY_CR1_REFCLKSEL GENMASK(16, 8)
+#define SYSCFG_COMBOPHY_CR1_REFCLKDIV2 BIT(17)
+#define SYSCFG_COMBOPHY_CR1_REFSSPEN BIT(18)
+#define SYSCFG_COMBOPHY_CR1_SSCEN BIT(19)
+
+/* SYSCFG CR4 */
+#define SYSCFG_COMBOPHY_CR4_RX0_EQ GENMASK(2, 0)
+
+#define MPLLMULT_19_2 (0x02u << 1)
+#define MPLLMULT_20   (0x7du << 1)
+#define MPLLMULT_24   (0x68u << 1)
+#define MPLLMULT_25   (0x64u << 1)
+#define MPLLMULT_26   (0x60u << 1)
+#define MPLLMULT_38_4 (0x41u << 1)
+#define MPLLMULT_48   (0x6cu << 1)
+#define MPLLMULT_50   (0x32u << 1)
+#define MPLLMULT_52   (0x30u << 1)
+#define MPLLMULT_100  (0x19u << 1)
+
+#define REFCLKSEL_0   0
+#define REFCLKSEL_1   (0x108u << 8)
+
+#define REFCLDIV_0    0
+
+/* SYSCFG CR2 */
+#define SYSCFG_COMBOPHY_CR2_MODESEL GENMASK(1, 0)
+#define SYSCFG_COMBOPHY_CR2_ISO_DIS BIT(15)
+
+#define COMBOPHY_MODESEL_PCIE 0
+#define COMBOPHY_MODESEL_USB  3
+
+/* SYSCFG CR5 */
+#define SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS BIT(12)
+
+#define COMBOPHY_SUP_ANA_MPLL_LOOP_CTL 0xc0
+#define COMBOPHY_PROP_CNTRL GENMASK(7, 4)
+
+/* Required apb/ker clocks first, optional pad last. */
+static const char * const combophy_clks[] = {"apb", "ker", "pad"};
+#define APB_CLK 0
+#define KER_CLK 1
+#define PAD_CLK 2
+
+struct stm32_combophy {
+	struct phy *phy;
+	struct regmap *regmap;
+	struct device *dev;
+	void __iomem *base;
+	struct reset_control *phy_reset;
+	struct clk_bulk_data clks[ARRAY_SIZE(combophy_clks)];
+	int num_clks;
+	bool have_pad_clk;
+	unsigned int type;
+	bool is_init;
+	int irq_wakeup;
+};
+
+struct clk_impedance  {
+	u32 microohm;
+	u32 vswing[4];
+};
+
+/*
+ * lookup table to hold the settings needed for a ref clock frequency
+ * impedance, the offset is used to set the IMP_CTL and DE_EMP bit of the
+ * PRG_IMP_CTRL register. Use ordered discrete values in the table
+ */
+static const struct clk_impedance imp_lookup[] = {
+	{ 6090000, { 442000, 564000, 684000, 802000 } },
+	{ 5662000, { 528000, 621000, 712000, 803000 } },
+	{ 5292000, { 491000, 596000, 700000, 802000 } },
+	{ 4968000, { 558000, 640000, 722000, 803000 } },
+	{ 4684000, { 468000, 581000, 692000, 802000 } },
+	{ 4429000, { 554000, 613000, 717000, 803000 } },
+	{ 4204000, { 511000, 609000, 706000, 802000 } },
+	{ 3999000, { 571000, 648000, 726000, 803000 } }
+};
+
+static int stm32_impedance_tune(struct stm32_combophy *combophy)
+{
+	u8 imp_size = ARRAY_SIZE(imp_lookup);
+	u8 vswing_size = ARRAY_SIZE(imp_lookup[0].vswing);
+	u8 imp_of, vswing_of;
+	u32 max_imp = imp_lookup[0].microohm;
+	u32 min_imp = imp_lookup[imp_size - 1].microohm;
+	u32 max_vswing = imp_lookup[imp_size - 1].vswing[vswing_size - 1];
+	u32 min_vswing = imp_lookup[0].vswing[0];
+	u32 val;
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,output-micro-ohms", &val)) {
+		if (val < min_imp || val > max_imp) {
+			dev_err(combophy->dev, "Invalid value %u for output ohm\n", val);
+			return -EINVAL;
+		}
+
+		for (imp_of = 0; imp_of < ARRAY_SIZE(imp_lookup); imp_of++)
+			if (imp_lookup[imp_of].microohm <= val)
+				break;
+
+		dev_dbg(combophy->dev, "Set %u micro-ohms output impedance\n",
+			imp_lookup[imp_of].microohm);
+
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRG_IMPCTRL_OHM,
+				   FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_OHM, imp_of));
+	} else {
+		regmap_read(combophy->regmap, SYSCFG_PCIEPRGCR, &val);
+		imp_of = FIELD_GET(STM32MP25_PCIEPRG_IMPCTRL_OHM, val);
+	}
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,output-vswing-microvolt", &val)) {
+		if (val < min_vswing || val > max_vswing) {
+			dev_err(combophy->dev, "Invalid value %u for output vswing\n", val);
+			return -EINVAL;
+		}
+
+		for (vswing_of = 0; vswing_of < ARRAY_SIZE(imp_lookup[imp_of].vswing); vswing_of++)
+			if (imp_lookup[imp_of].vswing[vswing_of] >= val)
+				break;
+
+		dev_dbg(combophy->dev, "Set %u microvolt swing\n",
+			 imp_lookup[imp_of].vswing[vswing_of]);
+
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRG_IMPCTRL_VSWING,
+				   FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of));
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_pll_init(struct stm32_combophy *combophy)
+{
+	int ret;
+	u32 refclksel, pllmult, propcntrl, val;
+	u32 clk_rate;
+	struct clk *clk;
+	u32 cr1_val = 0, cr1_mask = 0;
+
+	if (combophy->have_pad_clk)
+		clk = combophy->clks[PAD_CLK].clk;
+	else
+		clk = combophy->clks[KER_CLK].clk;
+
+	clk_rate = clk_get_rate(clk);
+
+	dev_dbg(combophy->dev, "%s pll init rate %d\n",
+		combophy->have_pad_clk ? "External" : "Ker", clk_rate);
+
+	if (combophy->type != PHY_TYPE_PCIE) {
+		cr1_mask |= SYSCFG_COMBOPHY_CR1_REFSSPEN;
+		cr1_val |= SYSCFG_COMBOPHY_CR1_REFSSPEN;
+	}
+
+	if (of_property_present(combophy->dev->of_node, "st,ssc-on")) {
+		dev_dbg(combophy->dev, "Enabling clock with SSC\n");
+		cr1_mask |= SYSCFG_COMBOPHY_CR1_SSCEN;
+		cr1_val |= SYSCFG_COMBOPHY_CR1_SSCEN;
+	}
+
+	switch (clk_rate) {
+	case 100000000:
+		pllmult = MPLLMULT_100;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0x8u << 4;
+		break;
+	case 19200000:
+		pllmult = MPLLMULT_19_2;
+		refclksel = REFCLKSEL_1;
+		propcntrl = 0x8u << 4;
+		break;
+	case 25000000:
+		pllmult = MPLLMULT_25;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0xeu << 4;
+		break;
+	case 24000000:
+		pllmult = MPLLMULT_24;
+		refclksel = REFCLKSEL_1;
+		propcntrl = 0xeu << 4;
+		break;
+	case 20000000:
+		pllmult = MPLLMULT_20;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0xeu << 4;
+		break;
+	default:
+		dev_err(combophy->dev, "Invalid rate 0x%x\n", clk_rate);
+		return -EINVAL;
+	};
+
+	cr1_mask |= SYSCFG_COMBOPHY_CR1_REFCLKDIV2;
+	cr1_val |= REFCLDIV_0;
+
+	cr1_mask |= SYSCFG_COMBOPHY_CR1_REFCLKSEL;
+	cr1_val |= refclksel;
+
+	cr1_mask |= SYSCFG_COMBOPHY_CR1_MPLLMULT;
+	cr1_val |= pllmult;
+
+	/*
+	 * vddcombophy is interconnected with vddcore. Isolation bit should be unset
+	 * before using the ComboPHY.
+	 */
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, SYSCFG_COMBOPHY_CR2_ISO_DIS);
+
+	reset_control_assert(combophy->phy_reset);
+
+	if (combophy->type == PHY_TYPE_PCIE) {
+		ret = stm32_impedance_tune(combophy);
+		if (ret)
+			goto out_iso;
+
+		cr1_mask |= SYSCFG_COMBOPHY_CR1_REFUSEPAD;
+		cr1_val |= combophy->have_pad_clk ? SYSCFG_COMBOPHY_CR1_REFUSEPAD : 0;
+	}
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,rx-equalizer", &val)) {
+		dev_dbg(combophy->dev, "Set RX equalizer %u\n", val);
+		if (val > SYSCFG_COMBOPHY_CR4_RX0_EQ) {
+			dev_err(combophy->dev, "Invalid value %u for rx0 equalizer\n", val);
+			ret = -EINVAL;
+			goto out_iso;
+		}
+
+		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR4,
+			   SYSCFG_COMBOPHY_CR4_RX0_EQ, val);
+	}
+
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1, cr1_mask, cr1_val);
+
+	/*
+	 * Force elasticity buffer to be tuned for the reference clock as
+	 * the separated clock model is not supported
+	 */
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR5,
+			   SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS, SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS);
+
+	reset_control_deassert(combophy->phy_reset);
+
+	ret = regmap_read_poll_timeout(combophy->regmap, SYSCFG_COMBOPHY_SR, val,
+				       !(val & STM32MP25_PIPE0_PHYSTATUS),
+				       10, 1000);
+	if (ret) {
+		dev_err(combophy->dev, "timeout, cannot lock PLL\n");
+		if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
+			regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+					   STM32MP25_PCIEPRGCR_EN, 0);
+
+		if (combophy->type != PHY_TYPE_PCIE)
+			regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+					   SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
+
+		goto out;
+	}
+
+
+	if (combophy->type == PHY_TYPE_PCIE) {
+		if (!combophy->have_pad_clk)
+			regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+					   STM32MP25_PCIEPRGCR_EN, STM32MP25_PCIEPRGCR_EN);
+
+		val = readl_relaxed(combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
+		val &= ~COMBOPHY_PROP_CNTRL;
+		val |= propcntrl;
+		writel_relaxed(val, combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
+	}
+
+	return 0;
+
+out_iso:
+	reset_control_deassert(combophy->phy_reset);
+
+out:
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
+
+	return ret;
+}
+
+static struct phy *stm32_combophy_xlate(struct device *dev,
+					const struct of_phandle_args *args)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+	unsigned int type;
+
+	if (args->args_count != 1) {
+		dev_err(dev, "invalid number of cells in 'phy' property\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	type = args->args[0];
+	if (type != PHY_TYPE_USB3 && type != PHY_TYPE_PCIE) {
+		dev_err(dev, "unsupported device type: %d\n", type);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (combophy->have_pad_clk && type != PHY_TYPE_PCIE) {
+		dev_err(dev, "Invalid use of clk_pad for USB3 mode\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	combophy->type = type;
+
+	return combophy->phy;
+}
+
+static int stm32_combophy_set_mode(struct stm32_combophy *combophy)
+{
+	int type = combophy->type;
+	u32 val;
+
+	switch (type) {
+	case PHY_TYPE_PCIE:
+		dev_dbg(combophy->dev, "setting PCIe ComboPHY\n");
+		val = COMBOPHY_MODESEL_PCIE;
+		break;
+	case PHY_TYPE_USB3:
+		dev_dbg(combophy->dev, "setting USB3 ComboPHY\n");
+		val = COMBOPHY_MODESEL_USB;
+		break;
+	default:
+		dev_err(combophy->dev, "Invalid PHY mode %d\n", type);
+		return -EINVAL;
+	}
+
+	return regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+				  SYSCFG_COMBOPHY_CR2_MODESEL, val);
+}
+
+static int stm32_combophy_suspend_noirq(struct device *dev)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+
+	/*
+	 * Clocks should be turned off since it is not needed for
+	 * wakeup capability. In case usb-remote wakeup is not enabled,
+	 * combo-phy is already turned off by HCD driver using exit callback
+	 */
+	if (combophy->is_init) {
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+
+		/* since wakeup is enabled for ctrl */
+		enable_irq_wake(combophy->irq_wakeup);
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_resume_noirq(struct device *dev)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+	int ret;
+
+	/*
+	 * If clocks was turned off by suspend call for wakeup then needs
+	 * to be turned back ON in resume. In case usb-remote wakeup is not
+	 * enabled, clocks already turned ON by HCD driver using init callback
+	 */
+	if (combophy->is_init) {
+		/* since wakeup was enabled for ctrl */
+		disable_irq_wake(combophy->irq_wakeup);
+
+		ret = clk_bulk_prepare_enable(combophy->num_clks, combophy->clks);
+		if (ret) {
+			dev_err(dev, "can't enable clocks (%d)\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_exit(struct phy *phy)
+{
+	struct stm32_combophy *combophy = phy_get_drvdata(phy);
+	struct device *dev = combophy->dev;
+
+	combophy->is_init = false;
+
+	if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRGCR_EN, 0);
+
+	if (combophy->type != PHY_TYPE_PCIE)
+		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+				   SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
+
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
+
+	clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+
+	pm_runtime_put_noidle(dev);
+
+	return 0;
+}
+
+static int stm32_combophy_init(struct phy *phy)
+{
+	struct stm32_combophy *combophy = phy_get_drvdata(phy);
+	struct device *dev = combophy->dev;
+	int ret;
+
+	pm_runtime_get_noresume(dev);
+
+	ret = clk_bulk_prepare_enable(combophy->num_clks, combophy->clks);
+	if (ret) {
+		dev_err(dev, "can't enable clocks (%d)\n", ret);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	ret = stm32_combophy_set_mode(combophy);
+	if (ret) {
+		dev_err(dev, "combophy mode not set\n");
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	ret = stm32_combophy_pll_init(combophy);
+	if (ret) {
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	pm_runtime_disable(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+
+	combophy->is_init = true;
+
+	return ret;
+}
+
+static const struct phy_ops stm32_combophy_phy_data = {
+	.init = stm32_combophy_init,
+	.exit = stm32_combophy_exit,
+	.owner = THIS_MODULE
+};
+
+static irqreturn_t stm32_combophy_irq_wakeup_handler(int irq, void *dev_id)
+{
+	return IRQ_HANDLED;
+}
+
+static int stm32_combophy_get_clocks(struct stm32_combophy *combophy)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(combophy_clks); i++)
+		combophy->clks[i].id = combophy_clks[i];
+
+	combophy->num_clks = ARRAY_SIZE(combophy_clks) - 1;
+
+	ret = devm_clk_bulk_get(combophy->dev, combophy->num_clks, combophy->clks);
+	if (ret)
+		return ret;
+
+	ret = devm_clk_bulk_get_optional(combophy->dev, 1, combophy->clks + combophy->num_clks);
+	if (ret)
+		return ret;
+
+	if (combophy->clks[combophy->num_clks].clk != NULL) {
+		combophy->have_pad_clk = true;
+		combophy->num_clks++;
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_probe(struct platform_device *pdev)
+{
+	struct stm32_combophy *combophy;
+	struct device *dev = &pdev->dev;
+	struct phy_provider *phy_provider;
+	int ret, irq;
+
+	combophy = devm_kzalloc(dev, sizeof(*combophy), GFP_KERNEL);
+	if (!combophy)
+		return -ENOMEM;
+
+	combophy->dev = dev;
+
+	dev_set_drvdata(dev, combophy);
+
+	combophy->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(combophy->base))
+		return PTR_ERR(combophy->base);
+
+	if (stm32_combophy_get_clocks(combophy))
+		return ret;
+
+	combophy->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
+	if (IS_ERR(combophy->phy_reset))
+		return dev_err_probe(dev, PTR_ERR(combophy->phy_reset),
+				     "Failed to get PHY reset\n");
+
+	combophy->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg");
+	if (IS_ERR(combophy->regmap))
+		return dev_err_probe(dev, PTR_ERR(combophy->regmap),
+				     "No syscfg specified\n");
+
+	combophy->phy = devm_phy_create(dev, NULL, &stm32_combophy_phy_data);
+	if (IS_ERR(combophy->phy))
+		return dev_err_probe(dev, PTR_ERR(combophy->phy),
+				     "failed to create PCIe/USB3 ComboPHY\n");
+
+	if (device_property_read_bool(dev, "wakeup-source")) {
+		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return dev_err_probe(dev, irq, "failed to get IRQ\n");
+		combophy->irq_wakeup = irq;
+
+		ret = devm_request_threaded_irq(dev, combophy->irq_wakeup, NULL,
+						stm32_combophy_irq_wakeup_handler, IRQF_ONESHOT,
+						NULL, NULL);
+		if (ret)
+			return dev_err_probe(dev, ret, "unable to request wake IRQ %d\n",
+						 combophy->irq_wakeup);
+	}
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to enable pm runtime\n");
+
+	phy_set_drvdata(combophy->phy, combophy);
+
+	phy_provider = devm_of_phy_provider_register(dev, stm32_combophy_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct dev_pm_ops stm32_combophy_pm_ops = {
+	NOIRQ_SYSTEM_SLEEP_PM_OPS(stm32_combophy_suspend_noirq,
+				  stm32_combophy_resume_noirq)
+};
+
+static const struct of_device_id stm32_combophy_of_match[] = {
+	{ .compatible = "st,stm32mp25-combophy", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, stm32_combophy_of_match);
+
+static struct platform_driver stm32_combophy_driver = {
+	.probe = stm32_combophy_probe,
+	.driver = {
+		   .name = "stm32-combophy",
+		   .of_match_table = stm32_combophy_of_match,
+		   .pm = pm_sleep_ptr(&stm32_combophy_pm_ops)
+	}
+};
+
+module_platform_driver(stm32_combophy_driver);
+
+MODULE_AUTHOR("Christian Bruel <christian.bruel at foss.st.com>");
+MODULE_DESCRIPTION("STM32MP25 Combophy USB3/PCIe controller driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From christian.bruel at foss.st.com  Wed Sep 11 03:46:46 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 11 Sep 2024 12:46:46 +0200
Subject: [PATCH v8 5/5] arm64: dts: st: Enable COMBOPHY on the stm32mp257f-ev1 board
In-Reply-To: <20240911104646.2980821-1-christian.bruel@foss.st.com>
References: <20240911104646.2980821-1-christian.bruel@foss.st.com>
Message-ID: <20240911104646.2980821-6-christian.bruel@foss.st.com>

Enable the COMBOPHY with external pad clock on stm32mp257f-ev1
board, to be used for the PCIe clock provider.

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
index 214191a8322b..bcf84d533cb2 100644
--- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
+++ b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
@@ -27,6 +27,14 @@ chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
+	clocks {
+		pad_clk: pad-clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+		};
+	};
+
 	memory at 80000000 {
 		device_type = "memory";
 		reg = <0x0 0x80000000 0x1 0x0>;
@@ -50,6 +58,12 @@ &arm_wdt {
 	status = "okay";
 };
 
+&combophy {
+	clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>, <&pad_clk>;
+	clock-names = "apb", "ker", "pad";
+	status = "okay";
+};
+
 &ethernet2 {
 	pinctrl-names = "default", "sleep";
 	pinctrl-0 = <&eth2_rgmii_pins_a>;
-- 
2.34.1



From johan+linaro at kernel.org  Wed Sep 11 04:52:50 2024
From: johan+linaro at kernel.org (Johan Hovold)
Date: Wed, 11 Sep 2024 13:52:50 +0200
Subject: [PATCH 1/4] phy: qcom: qmp-usb: fix NULL-deref on runtime suspend
In-Reply-To: <20240911115253.10920-1-johan+linaro@kernel.org>
References: <20240911115253.10920-1-johan+linaro@kernel.org>
Message-ID: <20240911115253.10920-2-johan+linaro@kernel.org>

Commit 413db06c05e7 ("phy: qcom-qmp-usb: clean up probe initialisation")
removed most users of the platform device driver data, but mistakenly
also removed the initialisation despite the data still being used in the
runtime PM callbacks.

Restore the driver data initialisation at probe to avoid a NULL-pointer
dereference on runtime suspend.

Apparently no one uses runtime PM, which currently needs to be enabled
manually through sysfs, with this driver.

Fixes: 413db06c05e7 ("phy: qcom-qmp-usb: clean up probe initialisation")
Cc: stable at vger.kernel.org	# 6.2
Signed-off-by: Johan Hovold <johan+linaro at kernel.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
index 49f4a53f9b2c..76068393e4ba 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
@@ -2191,6 +2191,7 @@ static int qmp_usb_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	qmp->dev = dev;
+	dev_set_drvdata(dev, qmp);
 
 	qmp->cfg = of_device_get_match_data(dev);
 	if (!qmp->cfg)
-- 
2.44.2



From johan+linaro at kernel.org  Wed Sep 11 04:52:53 2024
From: johan+linaro at kernel.org (Johan Hovold)
Date: Wed, 11 Sep 2024 13:52:53 +0200
Subject: [PATCH 4/4] phy: qcom: qmp-usb: move driver data initialisation earlier
In-Reply-To: <20240911115253.10920-1-johan+linaro@kernel.org>
References: <20240911115253.10920-1-johan+linaro@kernel.org>
Message-ID: <20240911115253.10920-5-johan+linaro@kernel.org>

Commit 44aff8e31080 ("phy: qcom-qmp-combo: clean up probe
initialisation") removed most users of the platform device driver data,
but mistakenly also removed the initialisation despite the data still
being used in the runtime PM callbacks.

The initialisation was soon after restored by commit 83a0bbe39b17 ("phy:
qcom-qmp-combo: add support for updated sc8280xp binding") but now
happens slightly later during probe. This should not cause any trouble
currently as runtime PM needs to be enabled manually through sysfs and
the platform device would not be suspended before the PHY has been
registered anyway.

Move the driver data initialisation to avoid a NULL-pointer dereference
on runtime suspend if runtime PM is ever enabled by default in this
driver.

Fixes: 44aff8e31080 ("phy: qcom-qmp-combo: clean up probe initialisation")
Signed-off-by: Johan Hovold <johan+linaro at kernel.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index c478bf74817a..ddecf34968fd 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -3649,6 +3649,7 @@ static int qmp_combo_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	qmp->dev = dev;
+	dev_set_drvdata(dev, qmp);
 
 	qmp->orientation = TYPEC_ORIENTATION_NORMAL;
 
@@ -3725,8 +3726,6 @@ static int qmp_combo_probe(struct platform_device *pdev)
 
 	phy_set_drvdata(qmp->dp_phy, qmp);
 
-	dev_set_drvdata(dev, qmp);
-
 	if (usb_np == dev->of_node)
 		phy_provider = devm_of_phy_provider_register(dev, qmp_combo_phy_xlate);
 	else
-- 
2.44.2



From johan+linaro at kernel.org  Wed Sep 11 04:52:51 2024
From: johan+linaro at kernel.org (Johan Hovold)
Date: Wed, 11 Sep 2024 13:52:51 +0200
Subject: [PATCH 2/4] phy: qcom: qmp-usb-legacy: fix NULL-deref on runtime suspend
In-Reply-To: <20240911115253.10920-1-johan+linaro@kernel.org>
References: <20240911115253.10920-1-johan+linaro@kernel.org>
Message-ID: <20240911115253.10920-3-johan+linaro@kernel.org>

Commit 413db06c05e7 ("phy: qcom-qmp-usb: clean up probe initialisation")
removed most users of the platform device driver data from the
qcom-qmp-usb driver, but mistakenly also removed the initialisation
despite the data still being used in the runtime PM callbacks. This bug
was later reproduced when the driver was copied to create the
qmp-usb-legacy driver.

Restore the driver data initialisation at probe to avoid a NULL-pointer
dereference on runtime suspend.

Apparently no one uses runtime PM, which currently needs to be enabled
manually through sysfs, with these drivers.

Fixes: e464a3180a43 ("phy: qcom-qmp-usb: split off the legacy USB+dp_com support")
Cc: stable at vger.kernel.org	# 6.6
Signed-off-by: Johan Hovold <johan+linaro at kernel.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
index 6d0ba39c1943..8bf951b0490c 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
@@ -1248,6 +1248,7 @@ static int qmp_usb_legacy_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	qmp->dev = dev;
+	dev_set_drvdata(dev, qmp);
 
 	qmp->cfg = of_device_get_match_data(dev);
 	if (!qmp->cfg)
-- 
2.44.2



From johan+linaro at kernel.org  Wed Sep 11 04:52:52 2024
From: johan+linaro at kernel.org (Johan Hovold)
Date: Wed, 11 Sep 2024 13:52:52 +0200
Subject: [PATCH 3/4] phy: qcom: qmp-usbc: fix NULL-deref on runtime suspend
In-Reply-To: <20240911115253.10920-1-johan+linaro@kernel.org>
References: <20240911115253.10920-1-johan+linaro@kernel.org>
Message-ID: <20240911115253.10920-4-johan+linaro@kernel.org>

Commit 413db06c05e7 ("phy: qcom-qmp-usb: clean up probe initialisation")
removed most users of the platform device driver data from the
qcom-qmp-usb driver, but mistakenly also removed the initialisation
despite the data still being used in the runtime PM callbacks. This bug
was later reproduced when the driver was copied to create the qmp-usbc
driver.

Restore the driver data initialisation at probe to avoid a NULL-pointer
dereference on runtime suspend.

Apparently no one uses runtime PM, which currently needs to be enabled
manually through sysfs, with these drivers.

Fixes: 19281571a4d5 ("phy: qcom: qmp-usb: split USB-C PHY driver")
Cc: stable at vger.kernel.org	# 6.9
Signed-off-by: Johan Hovold <johan+linaro at kernel.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index 5cbc5fd529eb..dea3456f88b1 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -1049,6 +1049,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	qmp->dev = dev;
+	dev_set_drvdata(dev, qmp);
 
 	qmp->orientation = TYPEC_ORIENTATION_NORMAL;
 
-- 
2.44.2



From johan+linaro at kernel.org  Wed Sep 11 04:52:49 2024
From: johan+linaro at kernel.org (Johan Hovold)
Date: Wed, 11 Sep 2024 13:52:49 +0200
Subject: [PATCH 0/4] phy: qcom: qmp-usb: fix NULL-deref on runtime suspend
Message-ID: <20240911115253.10920-1-johan+linaro@kernel.org>

When working on suspend support for Qualcomm platforms like x1e80100, I
ran into a NULL-pointer dereference in one of the QMP drivers. Turns out
this issue has since been reproduced in two more drivers.

Johan


Johan Hovold (4):
  phy: qcom: qmp-usb: fix NULL-deref on runtime suspend
  phy: qcom: qmp-usb-legacy: fix NULL-deref on runtime suspend
  phy: qcom: qmp-usbc: fix NULL-deref on runtime suspend
  phy: qcom: qmp-usb: move driver data initialisation earlier

 drivers/phy/qualcomm/phy-qcom-qmp-combo.c      | 3 +--
 drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c | 1 +
 drivers/phy/qualcomm/phy-qcom-qmp-usb.c        | 1 +
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c       | 1 +
 4 files changed, 4 insertions(+), 2 deletions(-)

-- 
2.44.2



From johan at kernel.org  Wed Sep 11 04:57:27 2024
From: johan at kernel.org (Johan Hovold)
Date: Wed, 11 Sep 2024 13:57:27 +0200
Subject: [PATCH 4/4] phy: qcom: qmp-usb: move driver data initialisation
 earlier
In-Reply-To: <20240911115253.10920-5-johan+linaro@kernel.org>
References: <20240911115253.10920-1-johan+linaro@kernel.org>
 <20240911115253.10920-5-johan+linaro@kernel.org>
Message-ID: <ZuGFpx3VZOGP-6Ii@hovoldconsulting.com>

On Wed, Sep 11, 2024 at 01:52:53PM +0200, Johan Hovold wrote:
> Commit 44aff8e31080 ("phy: qcom-qmp-combo: clean up probe
> initialisation") removed most users of the platform device driver data,
> but mistakenly also removed the initialisation despite the data still
> being used in the runtime PM callbacks.

Perhaps the copy/paste error in Subject can be fixed when applying. The
summary was supposed to say:

	phy: qcom: qmp-combo: move driver data initialisation earlier

and nothing else.

Johan


From manivannan.sadhasivam at linaro.org  Wed Sep 11 08:32:28 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Wed, 11 Sep 2024 21:02:28 +0530
Subject: [PATCH 8/8] PCI: qcom: Add support to PCIe slot power supplies
In-Reply-To: <26f2845f-2e29-4887-9f33-0b5b2a06adb6@quicinc.com>
References: <20240827063631.3932971-1-quic_qianyu@quicinc.com>
 <20240827063631.3932971-9-quic_qianyu@quicinc.com>
 <CAA8EJpq5KergZ8czg4F=EYMLANoOeBsiSVoO-zAgfG0ezQrKCQ@mail.gmail.com>
 <20240827165826.moe6cnemeheos6jn@thinkpad>
 <26f2845f-2e29-4887-9f33-0b5b2a06adb6@quicinc.com>
Message-ID: <20240911153228.7ajcqicxnu2afhbp@thinkpad>

On Wed, Sep 11, 2024 at 04:17:41PM +0800, Qiang Yu wrote:
> 
> On 8/28/2024 12:58 AM, Manivannan Sadhasivam wrote:
> > On Tue, Aug 27, 2024 at 02:44:09PM +0300, Dmitry Baryshkov wrote:
> > > On Tue, 27 Aug 2024 at 09:36, Qiang Yu <quic_qianyu at quicinc.com> wrote:
> > > > On platform x1e80100 QCP, PCIe3 is a standard x8 form factor. Hence, add
> > > > support to use 3.3v, 3.3v aux and 12v regulators.
> > > First of all, I don't see corresponding bindings change.
> > > 
> > > Second, these supplies power up the slot, not the host controller
> > > itself. As such these supplies do not belong to the host controller
> > > entry. Please consider using the pwrseq framework instead.
> > > 
> > Indeed. For legacy reasons, slot power supplies were populated in the host
> > bridge node itself until recently Rob started objecting it [1]. And it makes
> > real sense to put these supplies in the root port node and handle them in the
> > relevant driver.
> > 
> > I'm still evaluating whether the handling should be done in the portdrv or
> > pwrctl driver, but haven't reached the conclusion. Pwrctl seems to be the ideal
> > choice, but I see a few issues related to handling the OF node for the root
> > port.
> > 
> > Hope I'll come to a conclusion in the next few days and will update this thread.
> > 
> > - Mani
> > 
> > [1] https://lore.kernel.org/lkml/20240604235806.GA1903493-robh at kernel.org/
> Hi Mani, do you have any updates?
> 

I'm working with Bartosz to add a new pwrctl driver for rootports. And we are
debugging an issue currently. Unfortunately, the progress is very slow as I'm on
vacation still.

Will post the patches once it got resolved.

- Mani

> Thanks,
> Qiang
> > 
> > > > Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> > > > ---
> > > >   drivers/pci/controller/dwc/pcie-qcom.c | 52 +++++++++++++++++++++++++-
> > > >   1 file changed, 50 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> > > > index 6f953e32d990..59fb415dfeeb 100644
> > > > --- a/drivers/pci/controller/dwc/pcie-qcom.c
> > > > +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> > > > @@ -248,6 +248,8 @@ struct qcom_pcie_cfg {
> > > >          bool no_l0s;
> > > >   };
> > > > 
> > > > +#define QCOM_PCIE_SLOT_MAX_SUPPLIES                    3
> > > > +
> > > >   struct qcom_pcie {
> > > >          struct dw_pcie *pci;
> > > >          void __iomem *parf;                     /* DT parf */
> > > > @@ -260,6 +262,7 @@ struct qcom_pcie {
> > > >          struct icc_path *icc_cpu;
> > > >          const struct qcom_pcie_cfg *cfg;
> > > >          struct dentry *debugfs;
> > > > +       struct regulator_bulk_data slot_supplies[QCOM_PCIE_SLOT_MAX_SUPPLIES];
> > > >          bool suspended;
> > > >          bool use_pm_opp;
> > > >   };
> > > > @@ -1174,6 +1177,41 @@ static int qcom_pcie_link_up(struct dw_pcie *pci)
> > > >          return !!(val & PCI_EXP_LNKSTA_DLLLA);
> > > >   }
> > > > 
> > > > +static int qcom_pcie_enable_slot_supplies(struct qcom_pcie *pcie)
> > > > +{
> > > > +       struct dw_pcie *pci = pcie->pci;
> > > > +       int ret;
> > > > +
> > > > +       ret = regulator_bulk_enable(ARRAY_SIZE(pcie->slot_supplies),
> > > > +                                   pcie->slot_supplies);
> > > > +       if (ret < 0)
> > > > +               dev_err(pci->dev, "Failed to enable slot regulators\n");
> > > > +
> > > > +       return ret;
> > > > +}
> > > > +
> > > > +static void qcom_pcie_disable_slot_supplies(struct qcom_pcie *pcie)
> > > > +{
> > > > +       regulator_bulk_disable(ARRAY_SIZE(pcie->slot_supplies),
> > > > +                              pcie->slot_supplies);
> > > > +}
> > > > +
> > > > +static int qcom_pcie_get_slot_supplies(struct qcom_pcie *pcie)
> > > > +{
> > > > +       struct dw_pcie *pci = pcie->pci;
> > > > +       int ret;
> > > > +
> > > > +       pcie->slot_supplies[0].supply = "vpcie12v";
> > > > +       pcie->slot_supplies[1].supply = "vpcie3v3";
> > > > +       pcie->slot_supplies[2].supply = "vpcie3v3aux";
> > > > +       ret = devm_regulator_bulk_get(pci->dev, ARRAY_SIZE(pcie->slot_supplies),
> > > > +                                     pcie->slot_supplies);
> > > > +       if (ret < 0)
> > > > +               dev_err(pci->dev, "Failed to get slot regulators\n");
> > > > +
> > > > +       return ret;
> > > > +}
> > > > +
> > > >   static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
> > > >   {
> > > >          struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > > > @@ -1182,10 +1220,14 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
> > > > 
> > > >          qcom_ep_reset_assert(pcie);
> > > > 
> > > > -       ret = pcie->cfg->ops->init(pcie);
> > > > +       ret = qcom_pcie_enable_slot_supplies(pcie);
> > > >          if (ret)
> > > >                  return ret;
> > > > 
> > > > +       ret = pcie->cfg->ops->init(pcie);
> > > > +       if (ret)
> > > > +               goto err_disable_slot;
> > > > +
> > > >          ret = phy_set_mode_ext(pcie->phy, PHY_MODE_PCIE, PHY_MODE_PCIE_RC);
> > > >          if (ret)
> > > >                  goto err_deinit;
> > > > @@ -1216,7 +1258,8 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
> > > >          phy_power_off(pcie->phy);
> > > >   err_deinit:
> > > >          pcie->cfg->ops->deinit(pcie);
> > > > -
> > > > +err_disable_slot:
> > > > +       qcom_pcie_disable_slot_supplies(pcie);
> > > >          return ret;
> > > >   }
> > > > 
> > > > @@ -1228,6 +1271,7 @@ static void qcom_pcie_host_deinit(struct dw_pcie_rp *pp)
> > > >          qcom_ep_reset_assert(pcie);
> > > >          phy_power_off(pcie->phy);
> > > >          pcie->cfg->ops->deinit(pcie);
> > > > +       qcom_pcie_disable_slot_supplies(pcie);
> > > >   }
> > > > 
> > > >   static void qcom_pcie_host_post_init(struct dw_pcie_rp *pp)
> > > > @@ -1602,6 +1646,10 @@ static int qcom_pcie_probe(struct platform_device *pdev)
> > > >                          goto err_pm_runtime_put;
> > > >          }
> > > > 
> > > > +       ret = qcom_pcie_get_slot_supplies(pcie);
> > > > +       if (ret)
> > > > +               goto err_pm_runtime_put;
> > > > +
> > > >          ret = pcie->cfg->ops->get_resources(pcie);
> > > >          if (ret)
> > > >                  goto err_pm_runtime_put;
> > > > --
> > > > 2.34.1
> > > > 
> > > 
> > > -- 
> > > With best wishes
> > > Dmitry

-- 
????????? ????????


From frieder at fris.de  Wed Sep 11 11:24:01 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Wed, 11 Sep 2024 20:24:01 +0200
Subject: [PATCH 0/2] Extending PLL LUT for i.MX8MP Samsung HDMI PHY
In-Reply-To: <ZuDjAwPxHeJTvXAp@atmark-techno.com>
References: <20240910181544.214797-1-frieder@fris.de>
 <ZuDjAwPxHeJTvXAp@atmark-techno.com>
Message-ID: <074fc86c-6e6e-4dbc-857a-21e9abf965ac@fris.de>

On 11.09.24 02:23, Dominique Martinet wrote:
> Frieder Schrempf wrote on Tue, Sep 10, 2024 at 08:14:51PM +0200:
>> [2] https://codeberg.org/fschrempf/samsung-hdmi-phy-pll-calculator/src/branch/main/pll.py
> 
> Great work! Thanks!
> 
> I was curious about the existing table entries, recomputing existing
> values doesn't yield the same values. For example, the first entry is
> {
>          .pixclk = 22250000,
>          .pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
> }
> but computing it yields
> {
>      .pixclk = 22250000,
>      .pll_div_regs = { 0xd1, 0x4a, 0xf0, 0xef, 0x10, 0x81, 0x40 },
> }
> 
> I assume there just are multiple ways to generate the same frequencies,
> which is fine in itself, but it'd be great to be able to "back-compute"
> the entries as a sanity check.
> 
> I've played a bit with your script and spent more time on it than I'd
> like to admit, but something like this seems to do the trick, plugging
> in the regs from the kernel:

Thanks for the feedback and the additional code. Yes, the script yields 
different results for the existing table entries.

For the reverse operation I used the spreadsheet (pll.ods, also in the 
repo). Actually I wrote that before the Python code and used it for 
verification.

> 
> ---
> pll = FractionalNPLL(freq_ref)
> 
> regs = [0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40]
> # assume fractional
> if not regs[0] & 0xD0:
>      print("reg[0] missing 0xD0")
>      sys.exit(1)
> pll.freq_frac = True
> pll.params["p"] = regs[0] & 0x2f
> pll.params["m"] = regs[1]
> pll.params["s"] = (regs[2] >> 4) + 1
> pll.params["n2"] = ((regs[2] >> 3) & 0x1) + 1
> pll.params["n"] = (regs[2] & 0x7) + 4
> pll.params["lc"] = regs[3] & 0x7f
> if regs[4] & 0x80:
>      pll.params["lc"] = - pll.params["lc"]
> pll.params["k"] = regs[4] & 0x7f
> pll.params["lc_s"] = regs[5] & 0x7f
> pll.params["k_s"] = regs[6] & 0xbf
> 
> 
> f_vco = int(pll.params["m"] * pll.f_ref / pll.params["p"])
> if f_vco < 750000000 or f_vco > 3000000000:
>      print(f"f_vco {f_vco} out of range")
>      sys.exit(1)
> f_calc = f_vco / pll.params["s"] / 5
> pll.freq_int = round(f_calc)
> print(f_calc)
> sdc = pll.calc_sdc(pll.params)
> frac = pll.calc_f_frac(sdc, pll.params)
> print(frac)
> freq = pll.freq_int + frac
> print(freq)
> pll.print_reg_driver_data(freq)
> exit(0);
> ---
> yields this back (comments added manually)
> ---
> 22500000.0 (integer part)
> -250000.0 (fractional part)
> 22250000.0 (summed)
> 
> PHY Driver Table Entry:
> {
>      .pixclk = 22250000.0,
>      .pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x81, 0x40 },
> }
> ---
> 
> so if I find some time I'll whip some loop to check all other values...

If you look at the second sheet in the pll.ods file, you can see that I 
already started to create a table for verifying the existing values. I 
gave up at some point when I saw my calculations were giving reasonable 
results and continued with writing the script. But it's easy to extend 
the first columns with the values from the driver and copy the other 
columns to provide the calculations.

> 
> That aside, I see no problem with this, just one meta-comment about
> adding a link to the script in an external repo: I see some other
> drivers have python scripts in their trees e.g.
> drivers/comedi/drivers/ni_routing/tools/*py
> drivers/gpu/drm/ci/xfails/update-xfails.py
> drivers/gpu/drm/msm/registers/gen_header.py
> 
> would it make sense to commit the script here instead of linking to a
> repo that might be lost in the future?
> 
> I'm not quite sure what policy the linux repo has here, so leaving that
> as an open question.

I was thinking about this as well and I really have no idea what is 
preferred by the maintainers. So I will just wait for some feedback here.


From frieder at fris.de  Wed Sep 11 11:26:48 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Wed, 11 Sep 2024 20:26:48 +0200
Subject: [PATCH 0/2] Extending PLL LUT for i.MX8MP Samsung HDMI PHY
In-Reply-To: <ZuDyBQ1I2vcGzAqX@atmark-techno.com>
References: <20240910181544.214797-1-frieder@fris.de>
 <ZuDjAwPxHeJTvXAp@atmark-techno.com>
 <CAHCN7xJD8jsqyZX1JkWxrA84XkZ8YYN19hXW6KVe+jkOFugqrw@mail.gmail.com>
 <ZuDyBQ1I2vcGzAqX@atmark-techno.com>
Message-ID: <440cf92a-052f-4a03-91a8-2405c902aa3e@fris.de>

On 11.09.24 03:27, Dominique Martinet wrote:
> Adam Ford wrote on Tue, Sep 10, 2024 at 08:16:04PM -0500:
>>> That aside, I see no problem with this, just one meta-comment about
>>> adding a link to the script in an external repo: I see some other
>>> drivers have python scripts in their trees e.g.
>>> drivers/comedi/drivers/ni_routing/tools/*py
>>> drivers/gpu/drm/ci/xfails/update-xfails.py
>>> drivers/gpu/drm/msm/registers/gen_header.py
>>>
>>> would it make sense to commit the script here instead of linking to a
>>> repo that might be lost in the future?
>>>
>>> I'm not quite sure what policy the linux repo has here, so leaving that
>>> as an open question.
>>
>> Is there a reason this couldn't be coded in C and used to expand my
>> integer calculator series?  With that, we could drop the lookup table.
> 
> Quoting a previous mail from Frieder:
>> I will clean things up a bit and then share what I have. I hope that this
>> allows anyone to calculate parameters for their non-standard displays if
>> required.
>>
>> If someone feels extra motivated they could try to calculate the fractional
>> parameters at runtime. However I'm not sure that this is feasible. The
>> numerical computation of a large number of parameters is quite heavy and it's
>> probably not easy to strip the algorithm down to something that can be run on
>> the target without too much overhead.
> 
> Trying a random frequency with the algorithm he has implemented it
> easily takes 10 seconds to run on my imx8mp board, so even if we asssume
> C is 3-4 times faster I think the current algorithm is too slow for
> runtime and it makes more sense to extended the LUT to me (as long as
> the values can be & are checked at least once, which we now can)
> 
> The current algorithm brute-forces its way through so there could be a
> better way of computing the fractional part of the divider, but I'm not
> sure it's worth the effort at this point; I guess it's a good
> intellectual challenge though so someone might do it in the future.

Second this. My algorithm is far from optimal and there might be more 
elegant solutions. If anyone feels like creating something that can be 
added to the driver that would be interesting and welcome for sure.


From dmitry.baryshkov at linaro.org  Wed Sep 11 12:01:34 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 11 Sep 2024 22:01:34 +0300
Subject: [PATCH 0/4] phy: qcom: qmp-usb: fix NULL-deref on runtime suspend
In-Reply-To: <20240911115253.10920-1-johan+linaro@kernel.org>
References: <20240911115253.10920-1-johan+linaro@kernel.org>
Message-ID: <zvy3mvgvkhrey3qcj4m3mgfs7apinsr6t2zo5afjjxpijhs7ig@tzv7fe47bodk>

On Wed, Sep 11, 2024 at 01:52:49PM GMT, Johan Hovold wrote:
> When working on suspend support for Qualcomm platforms like x1e80100, I
> ran into a NULL-pointer dereference in one of the QMP drivers. Turns out
> this issue has since been reproduced in two more drivers.
> 
> Johan

For the series:


Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>


-- 
With best wishes
Dmitry


From frieder at fris.de  Wed Sep 11 12:03:19 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Wed, 11 Sep 2024 21:03:19 +0200
Subject: [PATCH 0/2] Extending PLL LUT for i.MX8MP Samsung HDMI PHY
In-Reply-To: <ZuEzxw96vRlYJ321@atmark-techno.com>
References: <20240910181544.214797-1-frieder@fris.de>
 <ZuDjAwPxHeJTvXAp@atmark-techno.com> <ZuEzxw96vRlYJ321@atmark-techno.com>
Message-ID: <eb648c15-6cb5-43c5-93d6-f91157e542e6@fris.de>

On 11.09.24 08:08, Dominique Martinet wrote:
> Dominique Martinet wrote on Wed, Sep 11, 2024 at 09:23:31AM +0900:
>> so if I find some time I'll whip some loop to check all other values...
> 
> There were more differences than I thought there'd be (see diff below)
> 
> they're all minor enough to probably not care, but your script finds
> exact values for them so it might be worth updating the regs if we keep
> the table...
> (OTOH these seem to work, and "if it works don't touch it" -- I have no
> further opinion now I've checked, curiosity is sated)

Yeah, that's interesting. A lot of those values seem to be a little off. 
Or my calculation has some problem, but it's unlikely as everything else 
seems to add up so nicely.

The deviations seem very minor, only in the per mill ballpark or even 
lower. I wonder how they got these values initially.

It would still be nice to verify the clocks with some real measurements 
on the hardware level before we change the existing values.

On a side note, there is drivers/gpu/drm/exynos/exynos_hdmi.c which is 
basically for the same kind of PHY, probably an older version of the IP 
core. It also has some LUTs for the PLL registers. But I didn't compare 
them so far.

> 
> Might want to just check 154000000 though, reg6's 0x80 was not set so
> SDC was disabled? and it'd get the integer fraction (153600000) instead
> if I understand this correctly

I think there are two switches. The fractional-N part can be enabled but 
the sigma-delta-part can still be disabled. That's different than having 
the fractional-N completely turned off.

My script doesn't cover this case. It assumes the SDC is always enabled 
if the fractional-N is enabled.

The problem is that I don't know what part of the calculation is the SDC 
value exactly. The reference manual is confusing and probably defective 
in some way in regard to this. So I don't really know when to 
enable/disable the SDC part.

For the 154 MHz this means even with SDC turned off the fractional-N 
part will provide the 400 kHZ to be added to the integer part. At least 
that's how I understand it. I might be wrong.

> 
> ---------
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> index a5ad51425ee3..72facc7bd045 100644
> --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -73,7 +73,7 @@ static const struct phy_config phy_pll_cfg[] = {
>   		.pixclk = 24024000,
>   		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
>   	}, {
> -		.pixclk = 25175000,
> +		.pixclk = 25177981,
>   		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
>   	},  {
>   		.pixclk = 26750000,
> @@ -82,16 +82,16 @@ static const struct phy_config phy_pll_cfg[] = {
>   		.pixclk = 27027000,
>   		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
>   	}, {
> -		.pixclk = 29500000,
> +		.pixclk = 29487500,
>   		.pll_div_regs = { 0xd1, 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
>   	}, {
> -		.pixclk = 30750000,
> +		.pixclk = 30729661,
>   		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
>   	}, {
> -		.pixclk = 30888000,
> +		.pixclk = 30848949,
>   		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
>   	}, {
> -		.pixclk = 33750000,
> +		.pixclk = 33731250,
>   		.pll_div_regs = { 0xd1, 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
>   	}, {
>   		.pixclk = 35000000,
> @@ -106,13 +106,13 @@ static const struct phy_config phy_pll_cfg[] = {
>   		.pixclk = 44500000,
>   		.pll_div_regs = { 0xd1, 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
>   	}, {
> -		.pixclk = 47000000,
> +		.pixclk = 47005000,
>   		.pll_div_regs = { 0xd1, 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
>   	}, {
> -		.pixclk = 47500000,
> +		.pixclk = 47502000,
>   		.pll_div_regs = { 0xd1, 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
>   	}, {
> -		.pixclk = 50349650,
> +		.pixclk = 50355924,
>   		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
>   	}, {
>   		.pixclk = 53250000,
> @@ -124,16 +124,16 @@ static const struct phy_config phy_pll_cfg[] = {
>   		.pixclk = 54054000,
>   		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
>   	}, {
> -		.pixclk = 59000000,
> +		.pixclk = 58975000,
>   		.pll_div_regs = { 0xd1, 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
>   	}, {
> -		.pixclk = 59340659,
> +		.pixclk = 59264777,
>   		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
>   	},  {
> -		.pixclk = 61500000,
> +		.pixclk = 61459322,
>   		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
>   	}, {
> -		.pixclk = 63500000,
> +		.pixclk = 63437500,
>   		.pll_div_regs = { 0xd1, 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
>   	}, {
>   		.pixclk = 67500000,
> @@ -145,25 +145,25 @@ static const struct phy_config phy_pll_cfg[] = {
>   		.pixclk = 72072000,
>   		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
>   	}, {
> -		.pixclk = 74176000,
> +		.pixclk = 74175824,
>   		.pll_div_regs = { 0xd1, 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
>   	}, {
>   		.pixclk = 74250000,
>   		.pll_div_regs = { 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
>   	}, {
> -		.pixclk = 78500000,
> +		.pixclk = 78487500,
>   		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
>   	},  {
> -		.pixclk = 82000000,
> +		.pixclk = 81945763,
>   		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
>   	}, {
> -		.pixclk = 82500000,
> +		.pixclk = 82486555,
>   		.pll_div_regs = { 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
>   	}, {
> -		.pixclk = 89000000,
> +		.pixclk = 89075000,
>   		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
>   	}, {
> -		.pixclk = 90000000,
> +		.pixclk = 89950000,
>   		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
>   	}, {
>   		.pixclk = 94000000,
> @@ -178,7 +178,7 @@ static const struct phy_config phy_pll_cfg[] = {
>   		.pixclk = 99000000,
>   		.pll_div_regs = { 0xd1, 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
>   	}, {
> -		.pixclk = 100699300,
> +		.pixclk = 100711847,
>   		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
>   	},  {
>   		.pixclk = 102500000,
> @@ -196,16 +196,16 @@ static const struct phy_config phy_pll_cfg[] = {
>   		.pixclk = 108108000,
>   		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
>   	}, {
> -		.pixclk = 118000000,
> +		.pixclk = 117950000,
>   		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
>   	},  {
> -		.pixclk = 123000000,
> +		.pixclk = 122918644,
>   		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
>   	}, {
> -		.pixclk = 127000000,
> +		.pixclk = 126875000,
>   		.pll_div_regs = { 0xd1, 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
>   	}, {
> -		.pixclk = 135000000,
> +		.pixclk = 134925000,
>   		.pll_div_regs = { 0xd1, 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
>   	}, {
>   		.pixclk = 135580000,
> @@ -214,20 +214,20 @@ static const struct phy_config phy_pll_cfg[] = {
>   		.pixclk = 137520000,
>   		.pll_div_regs = { 0xd1, 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
>   	}, {
> -		.pixclk = 138750000,
> +		.pixclk = 138658397,
>   		.pll_div_regs = { 0xd1, 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
>   	}, {
> -		.pixclk = 140000000,
> +		.pixclk = 140040000,
>   		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
>   	},  {
> -		.pixclk = 148352000,
> +		.pixclk = 148265128,
>   		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
>   	}, {
> -		.pixclk = 148500000,
> +		.pixclk = 148396403,
>   		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
>   	}, {
>   		.pixclk = 154000000,
> -		.pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
> +		.pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x80, 0x40 },
>   	}, {
>   		.pixclk = 157000000,
>   		.pll_div_regs = { 0xd1, 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
> @@ -268,10 +268,10 @@ static const struct phy_config phy_pll_cfg[] = {
>   		.pixclk = 254000000,
>   		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
>   	}, {
> -		.pixclk = 277500000,
> +		.pixclk = 277316794,
>   		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
>   	},  {
> -		.pixclk = 297000000,
> +		.pixclk = 296792806,
>   		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
>   	},
>   };
> -------------


From quic_bjorande at quicinc.com  Wed Sep 11 13:02:34 2024
From: quic_bjorande at quicinc.com (Bjorn Andersson)
Date: Wed, 11 Sep 2024 13:02:34 -0700
Subject: [PATCH 5/5] drm/msm/dp: Add DisplayPort controller for SA8775P
In-Reply-To: <20240911100813.338-6-quic_mukhopad@quicinc.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com>
 <20240911100813.338-6-quic_mukhopad@quicinc.com>
Message-ID: <ZuH3WqMwn7fl3nhh@hu-bjorande-lv.qualcomm.com>

On Wed, Sep 11, 2024 at 03:38:13PM +0530, Soutrik Mukhopadhyay wrote:
> The Qualcomm SA8775P platform comes with a DisplayPort controller
> with a different base offset than the previous SoCs,
> add support for this in the DisplayPort driver.
> 
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
>  drivers/gpu/drm/msm/dp/dp_display.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> index e1228fb093ee..e4954fd99eb0 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -118,6 +118,12 @@ struct msm_dp_desc {
>  	bool wide_bus_supported;
>  };
>  
> +static const struct msm_dp_desc sa8775p_dp_descs[] = {
> +	{ .io_start = 0xaf54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
> +	{ .io_start = 0xaf5c000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },

Why is this list incomplete?

Regards,
Bjorn

> +	{}
> +};
> +
>  static const struct msm_dp_desc sc7180_dp_descs[] = {
>  	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
>  	{}
> @@ -162,6 +168,7 @@ static const struct msm_dp_desc x1e80100_dp_descs[] = {
>  };
>  
>  static const struct of_device_id dp_dt_match[] = {
> +	{ .compatible = "qcom,sa8775p-dp", .data = &sa8775p_dp_descs },
>  	{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
>  	{ .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
>  	{ .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_descs },
> -- 
> 2.17.1
> 


From quic_bjorande at quicinc.com  Wed Sep 11 18:45:25 2024
From: quic_bjorande at quicinc.com (Bjorn Andersson)
Date: Wed, 11 Sep 2024 18:45:25 -0700
Subject: [PATCH 2/5] phy: qcom: edp: Introduce aux_cfg array for version
 specific aux settings
In-Reply-To: <20240911100813.338-3-quic_mukhopad@quicinc.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com>
 <20240911100813.338-3-quic_mukhopad@quicinc.com>
Message-ID: <ZuJHtXrZIRDd7Kyg@hu-bjorande-lv.qualcomm.com>

On Wed, Sep 11, 2024 at 03:38:10PM +0530, Soutrik Mukhopadhyay wrote:
> In order to support different HW versions, introduce aux_cfg array
> to move v4 specific aux configuration settings.
> 
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-edp.c | 34 +++++++++++++++++------------
>  1 file changed, 20 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> index da2b32fb5b45..0f860a807d1b 100644
> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> @@ -90,6 +90,7 @@ struct phy_ver_ops {
>  
>  struct qcom_edp_phy_cfg {
>  	bool is_edp;
> +	u8 *aux_cfg;
>  	const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
>  	const struct phy_ver_ops *ver_ops;
>  };
> @@ -186,11 +187,14 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
>  	.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
>  };
>  
> +static u8 edp_phy_aux_cfg_v4[10] = {
> +	0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
> +};
> +
>  static int qcom_edp_phy_init(struct phy *phy)
>  {
>  	struct qcom_edp *edp = phy_get_drvdata(phy);
>  	int ret;
> -	u8 cfg8;
>  
>  	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
>  	if (ret)
> @@ -222,22 +226,20 @@ static int qcom_edp_phy_init(struct phy *phy)
>  	 * even needed.
>  	 */
>  	if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
> -		cfg8 = 0xb7;
> -	else
> -		cfg8 = 0x37;
> +		edp->cfg->aux_cfg[8] = 0xb7;

If you have multiple instances of the eDP PHY they will all point to the
same edp_phy_aux_cfg_v4[], so making instance-specific modifications
to that array will not be okay.


Make edp_phy_aux_cfg_v4[] const to reduce the likelihood for someone
else to make this mistake in the future and make a local copy of the
array on the stack so that you can modify it.

Regards,
Bjorn

>  
>  	writel(0xfc, edp->edp + DP_PHY_MODE);
>  
> -	writel(0x00, edp->edp + DP_PHY_AUX_CFG0);
> -	writel(0x13, edp->edp + DP_PHY_AUX_CFG1);
> -	writel(0x24, edp->edp + DP_PHY_AUX_CFG2);
> -	writel(0x00, edp->edp + DP_PHY_AUX_CFG3);
> -	writel(0x0a, edp->edp + DP_PHY_AUX_CFG4);
> -	writel(0x26, edp->edp + DP_PHY_AUX_CFG5);
> -	writel(0x0a, edp->edp + DP_PHY_AUX_CFG6);
> -	writel(0x03, edp->edp + DP_PHY_AUX_CFG7);
> -	writel(cfg8, edp->edp + DP_PHY_AUX_CFG8);
> -	writel(0x03, edp->edp + DP_PHY_AUX_CFG9);
> +	writel(edp->cfg->aux_cfg[0], edp->edp + DP_PHY_AUX_CFG0);
> +	writel(edp->cfg->aux_cfg[1], edp->edp + DP_PHY_AUX_CFG1);
> +	writel(edp->cfg->aux_cfg[2], edp->edp + DP_PHY_AUX_CFG2);
> +	writel(edp->cfg->aux_cfg[3], edp->edp + DP_PHY_AUX_CFG3);
> +	writel(edp->cfg->aux_cfg[4], edp->edp + DP_PHY_AUX_CFG4);
> +	writel(edp->cfg->aux_cfg[5], edp->edp + DP_PHY_AUX_CFG5);
> +	writel(edp->cfg->aux_cfg[6], edp->edp + DP_PHY_AUX_CFG6);
> +	writel(edp->cfg->aux_cfg[7], edp->edp + DP_PHY_AUX_CFG7);
> +	writel(edp->cfg->aux_cfg[8], edp->edp + DP_PHY_AUX_CFG8);
> +	writel(edp->cfg->aux_cfg[9], edp->edp + DP_PHY_AUX_CFG9);
>  
>  	writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
>  	       PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
> @@ -519,16 +521,19 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
>  };
>  
>  static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
> +	.aux_cfg = edp_phy_aux_cfg_v4,
>  	.ver_ops = &qcom_edp_phy_ops_v4,
>  };
>  
>  static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
> +	.aux_cfg = edp_phy_aux_cfg_v4,
>  	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
>  	.ver_ops = &qcom_edp_phy_ops_v4,
>  };
>  
>  static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
>  	.is_edp = true,
> +	.aux_cfg = edp_phy_aux_cfg_v4,
>  	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
>  	.ver_ops = &qcom_edp_phy_ops_v4,
>  };
> @@ -707,6 +712,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
>  };
>  
>  static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
> +	.aux_cfg = edp_phy_aux_cfg_v4,
>  	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
>  	.ver_ops = &qcom_edp_phy_ops_v6,
>  };
> -- 
> 2.17.1
> 


From quic_mukhopad at quicinc.com  Thu Sep 12 02:36:22 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Thu, 12 Sep 2024 15:06:22 +0530
Subject: [PATCH 2/5] phy: qcom: edp: Introduce aux_cfg array for version
 specific aux settings
In-Reply-To: <CAA8EJppLFWpf0QSmzAo5nqu=iMALyKzxEvy7sD5R0LDYSbA_7w@mail.gmail.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com>
 <20240911100813.338-3-quic_mukhopad@quicinc.com>
 <CAA8EJppLFWpf0QSmzAo5nqu=iMALyKzxEvy7sD5R0LDYSbA_7w@mail.gmail.com>
Message-ID: <274c267f-f3d4-42cf-915e-44a7c76f2489@quicinc.com>


On 9/11/2024 4:04 PM, Dmitry Baryshkov wrote:
> On Wed, 11 Sept 2024 at 13:08, Soutrik Mukhopadhyay
> <quic_mukhopad at quicinc.com> wrote:
>> In order to support different HW versions, introduce aux_cfg array
>> to move v4 specific aux configuration settings.
>>
>> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
>> ---
>>   drivers/phy/qualcomm/phy-qcom-edp.c | 34 +++++++++++++++++------------
>>   1 file changed, 20 insertions(+), 14 deletions(-)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
>> index da2b32fb5b45..0f860a807d1b 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
>> @@ -90,6 +90,7 @@ struct phy_ver_ops {
>>
>>   struct qcom_edp_phy_cfg {
>>          bool is_edp;
>> +       u8 *aux_cfg;
>>          const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
>>          const struct phy_ver_ops *ver_ops;
>>   };
>> @@ -186,11 +187,14 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
>>          .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
>>   };
>>
>> +static u8 edp_phy_aux_cfg_v4[10] = {
> static const u8, please.


Sure, we will change this to "static const u8" in next version patch.


>
>
>> +       0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
>> +};
>> +
>>   static int qcom_edp_phy_init(struct phy *phy)
>>   {
>>          struct qcom_edp *edp = phy_get_drvdata(phy);
>>          int ret;
>> -       u8 cfg8;
>>
>>          ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
>>          if (ret)
>> @@ -222,22 +226,20 @@ static int qcom_edp_phy_init(struct phy *phy)
>>           * even needed.
>>           */
>>          if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
>> -               cfg8 = 0xb7;
>> -       else
>> -               cfg8 = 0x37;
>> +               edp->cfg->aux_cfg[8] = 0xb7;
>>
>>          writel(0xfc, edp->edp + DP_PHY_MODE);
>>
>> -       writel(0x00, edp->edp + DP_PHY_AUX_CFG0);
>> -       writel(0x13, edp->edp + DP_PHY_AUX_CFG1);
>> -       writel(0x24, edp->edp + DP_PHY_AUX_CFG2);
>> -       writel(0x00, edp->edp + DP_PHY_AUX_CFG3);
>> -       writel(0x0a, edp->edp + DP_PHY_AUX_CFG4);
>> -       writel(0x26, edp->edp + DP_PHY_AUX_CFG5);
>> -       writel(0x0a, edp->edp + DP_PHY_AUX_CFG6);
>> -       writel(0x03, edp->edp + DP_PHY_AUX_CFG7);
>> -       writel(cfg8, edp->edp + DP_PHY_AUX_CFG8);
>> -       writel(0x03, edp->edp + DP_PHY_AUX_CFG9);
>> +       writel(edp->cfg->aux_cfg[0], edp->edp + DP_PHY_AUX_CFG0);
>> +       writel(edp->cfg->aux_cfg[1], edp->edp + DP_PHY_AUX_CFG1);
>> +       writel(edp->cfg->aux_cfg[2], edp->edp + DP_PHY_AUX_CFG2);
>> +       writel(edp->cfg->aux_cfg[3], edp->edp + DP_PHY_AUX_CFG3);
>> +       writel(edp->cfg->aux_cfg[4], edp->edp + DP_PHY_AUX_CFG4);
>> +       writel(edp->cfg->aux_cfg[5], edp->edp + DP_PHY_AUX_CFG5);
>> +       writel(edp->cfg->aux_cfg[6], edp->edp + DP_PHY_AUX_CFG6);
>> +       writel(edp->cfg->aux_cfg[7], edp->edp + DP_PHY_AUX_CFG7);
>> +       writel(edp->cfg->aux_cfg[8], edp->edp + DP_PHY_AUX_CFG8);
>> +       writel(edp->cfg->aux_cfg[9], edp->edp + DP_PHY_AUX_CFG9);
>>
>>          writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
>>                 PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
>> @@ -519,16 +521,19 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
>>   };
>>
>>   static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
>> +       .aux_cfg = edp_phy_aux_cfg_v4,
>>          .ver_ops = &qcom_edp_phy_ops_v4,
>>   };
>>
>>   static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
>> +       .aux_cfg = edp_phy_aux_cfg_v4,
>>          .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
>>          .ver_ops = &qcom_edp_phy_ops_v4,
>>   };
>>
>>   static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
>>          .is_edp = true,
>> +       .aux_cfg = edp_phy_aux_cfg_v4,
>>          .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
>>          .ver_ops = &qcom_edp_phy_ops_v4,
>>   };
>> @@ -707,6 +712,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
>>   };
>>
>>   static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
>> +       .aux_cfg = edp_phy_aux_cfg_v4,
> Is this correct? Judging by ver_ops, X Elite uses v6 of the PHY, so
> maybe it should also use v5 AUX tables?


As per the current implementation, v6 uses v4 aux configuration, so we 
updated it to v4.


>
>>          .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
>>          .ver_ops = &qcom_edp_phy_ops_v6,
>>   };
>> --
>> 2.17.1
>>
>
> --
> With best wishes
> Dmitry


From quic_mukhopad at quicinc.com  Thu Sep 12 02:39:29 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Thu, 12 Sep 2024 15:09:29 +0530
Subject: [PATCH 2/5] phy: qcom: edp: Introduce aux_cfg array for version
 specific aux settings
In-Reply-To: <ZuJHtXrZIRDd7Kyg@hu-bjorande-lv.qualcomm.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com>
 <20240911100813.338-3-quic_mukhopad@quicinc.com>
 <ZuJHtXrZIRDd7Kyg@hu-bjorande-lv.qualcomm.com>
Message-ID: <3bf16fae-60ae-4bd2-b631-3cd8bfef0609@quicinc.com>


On 9/12/2024 7:15 AM, Bjorn Andersson wrote:
> On Wed, Sep 11, 2024 at 03:38:10PM +0530, Soutrik Mukhopadhyay wrote:
>> In order to support different HW versions, introduce aux_cfg array
>> to move v4 specific aux configuration settings.
>>
>> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
>> ---
>>   drivers/phy/qualcomm/phy-qcom-edp.c | 34 +++++++++++++++++------------
>>   1 file changed, 20 insertions(+), 14 deletions(-)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
>> index da2b32fb5b45..0f860a807d1b 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
>> @@ -90,6 +90,7 @@ struct phy_ver_ops {
>>   
>>   struct qcom_edp_phy_cfg {
>>   	bool is_edp;
>> +	u8 *aux_cfg;
>>   	const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
>>   	const struct phy_ver_ops *ver_ops;
>>   };
>> @@ -186,11 +187,14 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
>>   	.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
>>   };
>>   
>> +static u8 edp_phy_aux_cfg_v4[10] = {
>> +	0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
>> +};
>> +
>>   static int qcom_edp_phy_init(struct phy *phy)
>>   {
>>   	struct qcom_edp *edp = phy_get_drvdata(phy);
>>   	int ret;
>> -	u8 cfg8;
>>   
>>   	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
>>   	if (ret)
>> @@ -222,22 +226,20 @@ static int qcom_edp_phy_init(struct phy *phy)
>>   	 * even needed.
>>   	 */
>>   	if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
>> -		cfg8 = 0xb7;
>> -	else
>> -		cfg8 = 0x37;
>> +		edp->cfg->aux_cfg[8] = 0xb7;
> If you have multiple instances of the eDP PHY they will all point to the
> same edp_phy_aux_cfg_v4[], so making instance-specific modifications
> to that array will not be okay.
>
>
> Make edp_phy_aux_cfg_v4[] const to reduce the likelihood for someone
> else to make this mistake in the future and make a local copy of the
> array on the stack so that you can modify it.
>
> Regards,
> Bjorn


Sure, we will change edp_phy_aux_cfg_v4[] to const and use local copy to 
modify it.


>
>>   
>>   	writel(0xfc, edp->edp + DP_PHY_MODE);
>>   
>> -	writel(0x00, edp->edp + DP_PHY_AUX_CFG0);
>> -	writel(0x13, edp->edp + DP_PHY_AUX_CFG1);
>> -	writel(0x24, edp->edp + DP_PHY_AUX_CFG2);
>> -	writel(0x00, edp->edp + DP_PHY_AUX_CFG3);
>> -	writel(0x0a, edp->edp + DP_PHY_AUX_CFG4);
>> -	writel(0x26, edp->edp + DP_PHY_AUX_CFG5);
>> -	writel(0x0a, edp->edp + DP_PHY_AUX_CFG6);
>> -	writel(0x03, edp->edp + DP_PHY_AUX_CFG7);
>> -	writel(cfg8, edp->edp + DP_PHY_AUX_CFG8);
>> -	writel(0x03, edp->edp + DP_PHY_AUX_CFG9);
>> +	writel(edp->cfg->aux_cfg[0], edp->edp + DP_PHY_AUX_CFG0);
>> +	writel(edp->cfg->aux_cfg[1], edp->edp + DP_PHY_AUX_CFG1);
>> +	writel(edp->cfg->aux_cfg[2], edp->edp + DP_PHY_AUX_CFG2);
>> +	writel(edp->cfg->aux_cfg[3], edp->edp + DP_PHY_AUX_CFG3);
>> +	writel(edp->cfg->aux_cfg[4], edp->edp + DP_PHY_AUX_CFG4);
>> +	writel(edp->cfg->aux_cfg[5], edp->edp + DP_PHY_AUX_CFG5);
>> +	writel(edp->cfg->aux_cfg[6], edp->edp + DP_PHY_AUX_CFG6);
>> +	writel(edp->cfg->aux_cfg[7], edp->edp + DP_PHY_AUX_CFG7);
>> +	writel(edp->cfg->aux_cfg[8], edp->edp + DP_PHY_AUX_CFG8);
>> +	writel(edp->cfg->aux_cfg[9], edp->edp + DP_PHY_AUX_CFG9);
>>   
>>   	writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
>>   	       PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
>> @@ -519,16 +521,19 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
>>   };
>>   
>>   static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
>> +	.aux_cfg = edp_phy_aux_cfg_v4,
>>   	.ver_ops = &qcom_edp_phy_ops_v4,
>>   };
>>   
>>   static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
>> +	.aux_cfg = edp_phy_aux_cfg_v4,
>>   	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
>>   	.ver_ops = &qcom_edp_phy_ops_v4,
>>   };
>>   
>>   static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
>>   	.is_edp = true,
>> +	.aux_cfg = edp_phy_aux_cfg_v4,
>>   	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
>>   	.ver_ops = &qcom_edp_phy_ops_v4,
>>   };
>> @@ -707,6 +712,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
>>   };
>>   
>>   static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
>> +	.aux_cfg = edp_phy_aux_cfg_v4,
>>   	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
>>   	.ver_ops = &qcom_edp_phy_ops_v6,
>>   };
>> -- 
>> 2.17.1
>>


From quic_mukhopad at quicinc.com  Thu Sep 12 02:56:59 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Thu, 12 Sep 2024 15:26:59 +0530
Subject: [PATCH 3/5] phy: qcom: edp: Add support for eDP PHY on SA8775P
In-Reply-To: <CAA8EJpqurbPKjmRH8zdqPkMuze4zwJVu+=W0nP=Ldc6o_4Tu4w@mail.gmail.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com>
 <20240911100813.338-4-quic_mukhopad@quicinc.com>
 <CAA8EJpqurbPKjmRH8zdqPkMuze4zwJVu+=W0nP=Ldc6o_4Tu4w@mail.gmail.com>
Message-ID: <9cf67bc8-d567-4fbe-af77-bdc79f74fc0a@quicinc.com>


On 9/11/2024 4:10 PM, Dmitry Baryshkov wrote:
> On Wed, 11 Sept 2024 at 13:08, Soutrik Mukhopadhyay
> <quic_mukhopad at quicinc.com> wrote:
>> Add support for eDP PHY v5 found on the Qualcomm SA8775P platform.
>>
>> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
>> ---
>>   drivers/phy/qualcomm/phy-qcom-edp.c | 47 +++++++++++++++++++++++++++++
>>   1 file changed, 47 insertions(+)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
>> index 0f860a807d1b..34a47cd2919d 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
>> @@ -191,6 +191,45 @@ static u8 edp_phy_aux_cfg_v4[10] = {
>>          0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
>>   };
>>
>> +static const u8 edp_swing_hbr_rbr_v5[4][4] = {
>> +       { 0x07, 0x0f, 0x16, 0x1f },
>> +       { 0x0d, 0x16, 0x1e, 0xff },
>> +       { 0x11, 0x1b, 0xff, 0xff },
>> +       { 0x16, 0xff, 0xff, 0xff }
>> +};
> Same as v4


Yes, we will reuse edp_swing_hbr_rbr for v5.


>
>> +
>> +static const u8 edp_pre_emp_hbr_rbr_v5[4][4] = {
>> +       { 0x05, 0x11, 0x17, 0x1d },
>> +       { 0x05, 0x11, 0x18, 0xff },
>> +       { 0x06, 0x11, 0xff, 0xff },
>> +       { 0x00, 0xff, 0xff, 0xff }
>> +};
> Could you please confirm that there is a single value difference?


Yes, there is a single value difference.


>
>> +
>> +static const u8 edp_swing_hbr2_hbr3_v5[4][4] = {
>> +       { 0x0b, 0x11, 0x17, 0x1c },
>> +       { 0x10, 0x19, 0x1f, 0xff },
>> +       { 0x19, 0x1f, 0xff, 0xff },
>> +       { 0x1f, 0xff, 0xff, 0xff }
>> +};
> Same as v4


Yes, we will reuse edp_swing_hbr2_hbr3 for v5.


>
>> +
>> +static const u8 edp_pre_emp_hbr2_hbr3_v5[4][4] = {
>> +       { 0x0c, 0x15, 0x19, 0x1e },
>> +       { 0x0b, 0x15, 0x19, 0xff },
>> +       { 0x0e, 0x14, 0xff, 0xff },
>> +       { 0x0d, 0xff, 0xff, 0xff }
>> +};
> This one looks fine
>
>> +
>> +static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v5 = {
>> +       .swing_hbr_rbr = &edp_swing_hbr_rbr_v5,
>> +       .swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3_v5,
>> +       .pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr_v5,
>> +       .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v5,
>> +};
>> +
>> +static u8 edp_phy_aux_cfg_v5[10] = {
>> +       0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
>> +};
>> +
>>   static int qcom_edp_phy_init(struct phy *phy)
>>   {
>>          struct qcom_edp *edp = phy_get_drvdata(phy);
>> @@ -520,6 +559,13 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
>>          .com_configure_ssc      = qcom_edp_com_configure_ssc_v4,
>>   };
>>
>> +static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
>> +       .is_edp = false,
>> +       .aux_cfg = edp_phy_aux_cfg_v5,
>> +       .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5,
>> +       .ver_ops = &qcom_edp_phy_ops_v4,
>> +};
>> +
>>   static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
>>          .aux_cfg = edp_phy_aux_cfg_v4,
>>          .ver_ops = &qcom_edp_phy_ops_v4,
>> @@ -1114,6 +1160,7 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
>>   }
>>
>>   static const struct of_device_id qcom_edp_phy_match_table[] = {
>> +       { .compatible = "qcom,sa8775p-edp-phy", .data = &sa8775p_dp_phy_cfg, },
>>          { .compatible = "qcom,sc7280-edp-phy", .data = &sc7280_dp_phy_cfg, },
>>          { .compatible = "qcom,sc8180x-edp-phy", .data = &sc7280_dp_phy_cfg, },
>>          { .compatible = "qcom,sc8280xp-dp-phy", .data = &sc8280xp_dp_phy_cfg, },
>> --
>> 2.17.1
>>
>


From quic_mukhopad at quicinc.com  Thu Sep 12 03:04:05 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Thu, 12 Sep 2024 15:34:05 +0530
Subject: [PATCH 5/5] drm/msm/dp: Add DisplayPort controller for SA8775P
In-Reply-To: <ZuH3WqMwn7fl3nhh@hu-bjorande-lv.qualcomm.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com>
 <20240911100813.338-6-quic_mukhopad@quicinc.com>
 <ZuH3WqMwn7fl3nhh@hu-bjorande-lv.qualcomm.com>
Message-ID: <a44a6f08-1f4a-4e5c-a4e4-30ab65c467f7@quicinc.com>


On 9/12/2024 1:32 AM, Bjorn Andersson wrote:
> On Wed, Sep 11, 2024 at 03:38:13PM +0530, Soutrik Mukhopadhyay wrote:
>> The Qualcomm SA8775P platform comes with a DisplayPort controller
>> with a different base offset than the previous SoCs,
>> add support for this in the DisplayPort driver.
>>
>> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
>> ---
>>   drivers/gpu/drm/msm/dp/dp_display.c | 7 +++++++
>>   1 file changed, 7 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
>> index e1228fb093ee..e4954fd99eb0 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_display.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
>> @@ -118,6 +118,12 @@ struct msm_dp_desc {
>>   	bool wide_bus_supported;
>>   };
>>   
>> +static const struct msm_dp_desc sa8775p_dp_descs[] = {
>> +	{ .io_start = 0xaf54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
>> +	{ .io_start = 0xaf5c000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
> Why is this list incomplete?
>
> Regards,
> Bjorn


Do you mean to add for mdss_1 as well?

We only added dp controllers for mdss_0 as we plan to validate and 
enable only these.


>
>> +	{}
>> +};
>> +
>>   static const struct msm_dp_desc sc7180_dp_descs[] = {
>>   	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
>>   	{}
>> @@ -162,6 +168,7 @@ static const struct msm_dp_desc x1e80100_dp_descs[] = {
>>   };
>>   
>>   static const struct of_device_id dp_dt_match[] = {
>> +	{ .compatible = "qcom,sa8775p-dp", .data = &sa8775p_dp_descs },
>>   	{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
>>   	{ .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
>>   	{ .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_descs },
>> -- 
>> 2.17.1
>>


From mripard at kernel.org  Thu Sep 12 05:30:01 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 12 Sep 2024 14:30:01 +0200
Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501
 DP/HDMI driver
In-Reply-To: <PAXPR04MB9448EF507CB5C18A43239A80F49E2@PAXPR04MB9448.eurprd04.prod.outlook.com>
References: <cover.1719903904.git.Sandor.yu@nxp.com>
 <359914108b879e995d4a39de32a33310009f0fab.1719903904.git.Sandor.yu@nxp.com>
 <20240702-quartz-salamander-of-culture-eec264@houat>
 <PAXPR04MB94480AB0490BBF00D2BA17BBF4932@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <20240903-gay-capable-hound-3cbef2@houat>
 <PAXPR04MB9448EF507CB5C18A43239A80F49E2@PAXPR04MB9448.eurprd04.prod.outlook.com>
Message-ID: <20240912-zippy-mongoose-of-domination-2ebc1d@houat>

On Fri, Sep 06, 2024 at 02:50:08AM GMT, Sandor Yu wrote:
> > On Tue, Sep 03, 2024 at 06:07:25AM GMT, Sandor Yu wrote:
> > > > -----Original Message-----
> > > > From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On Behalf
> > > > Of Maxime Ripard
> > > > Sent: 2024?7?2? 21:25
> > > > To: Sandor Yu <sandor.yu at nxp.com>
> > > > Cc: dmitry.baryshkov at linaro.org; andrzej.hajda at intel.com;
> > > > neil.armstrong at linaro.org; Laurent Pinchart
> > > > <laurent.pinchart at ideasonboard.com>; jonas at kwiboo.se;
> > > > jernej.skrabec at gmail.com; airlied at gmail.com; daniel at ffwll.ch;
> > > > robh+dt at kernel.org; krzysztof.kozlowski+dt at linaro.org;
> > > > shawnguo at kernel.org; s.hauer at pengutronix.de; festevam at gmail.com;
> > > > vkoul at kernel.org; dri-devel at lists.freedesktop.org;
> > > > devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > > > linux-kernel at vger.kernel.org; linux-phy at lists.infradead.org;
> > > > kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>; Oliver
> > > > Brown <oliver.brown at nxp.com>; alexander.stein at ew.tq-group.com;
> > > > sam at ravnborg.org
> > > > Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add
> > > > MHDP8501 DP/HDMI driver
> > > >
> > > > Hi,
> > > >
> > > > There's still the scrambler issue we discussed on v15, but I have
> > > > some more comments.
> > > >
> > > > On Tue, Jul 02, 2024 at 08:22:36PM GMT, Sandor Yu wrote:
> > > > > +enum drm_connector_status cdns_mhdp8501_detect(struct
> > > > > +cdns_mhdp8501_device *mhdp) {
> > > > > +	u8 hpd = 0xf;
> > > > > +
> > > > > +	hpd = cdns_mhdp8501_read_hpd(mhdp);
> > > > > +	if (hpd == 1)
> > > > > +		return connector_status_connected;
> > > > > +	else if (hpd == 0)
> > > > > +		return connector_status_disconnected;
> > > > > +
> > > > > +	dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n", hpd);
> > > > > +	return connector_status_unknown; }
> > > > > +
> > > > > +static void hotplug_work_func(struct work_struct *work) {
> > > > > +	struct cdns_mhdp8501_device *mhdp = container_of(work,
> > > > > +						     struct cdns_mhdp8501_device,
> > > > > +						     hotplug_work.work);
> > > > > +	enum drm_connector_status status =
> > cdns_mhdp8501_detect(mhdp);
> > > > > +
> > > > > +	drm_bridge_hpd_notify(&mhdp->bridge, status);
> > > > > +
> > > > > +	if (status == connector_status_connected) {
> > > > > +		/* Cable connected  */
> > > > > +		DRM_INFO("HDMI/DP Cable Plug In\n");
> > > > > +		enable_irq(mhdp->irq[IRQ_OUT]);
> > > > > +	} else if (status == connector_status_disconnected) {
> > > > > +		/* Cable Disconnected  */
> > > > > +		DRM_INFO("HDMI/DP Cable Plug Out\n");
> > > > > +		enable_irq(mhdp->irq[IRQ_IN]);
> > > > > +	}
> > > > > +}
> > > >
> > > > You shouldn't play with the interrupt being enabled here: hotplug
> > > > interrupts should always enabled.
> > > >
> > > > If you can't for some reason, the reason should be documented in your
> > driver.
> > >
> > > iMX8MQ have two HPD interrupters, one for plugout and the other for
> > > plugin, because they could not be masked, so we have to enable one and
> > disable the other.
> > > I will add more comments here.
> > 
> > Right, but why do you need to enable and disable them? Do you get spurious
> > interrupts?
> 
> They don't have status registers and cannot be masked. If they are not disabled, 
> they will continuously generate interrupts. Therefore, I have to disable one and enable the other.

Sorry, I still don't get it. How can it be useful to detect hotplug
interrupts if it constantly sends spurious interrupts when it's enabled?

> > > > > +	/* Mailbox protect for HDMI PHY access */
> > > > > +	mutex_lock(&mhdp->mbox_mutex);
> > > > > +	ret = phy_init(mhdp->phy);
> > > > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > > > +	if (ret) {
> > > > > +		dev_err(dev, "Failed to initialize PHY: %d\n", ret);
> > > > > +		goto clk_disable;
> > > > > +	}
> > > > > +
> > > > > +	/* Mailbox protect for HDMI PHY access */
> > > > > +	mutex_lock(&mhdp->mbox_mutex);
> > > > > +	ret = phy_set_mode(mhdp->phy, phy_mode);
> > > > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > > > +	if (ret) {
> > > > > +		dev_err(dev, "Failed to configure PHY: %d\n", ret);
> > > > > +		goto clk_disable;
> > > > > +	}
> > > >
> > > > Why do you need a shared mutex between the phy and HDMI controller?
> > >
> > > Both PHY and HDMI controller could access to the HDMI firmware by
> > > mailbox, So add mutex to avoid race condition.
> > 
> > That should be handled at either the phy or mailbox level, not in your hdmi
> > driver.
>
> In both HDMI driver and PHY driver, every mailbox access had protected
> by its owns mutex. However, this mutex can only protect each mailbox
> access within their respective drivers, and it cannot provide
> protection for access between the HDMI and PHY drivers.
> 
> The PHY driver only provides two API functions, and these functions
> are only called in the HDMI driver. Therefore, when accessing these
> functions, we use a mutex to protect them. This ensures that mailbox
> access is protected across different PHY and HDMI drivers.

It's really about abstraction. You're using a publicly defined API, and
change the semantics for your driver only, and that's not ok.

Why can't the mailbox driver itself serialize the accesses from any
user, HDMI and PHY drivers included?

> > > >
> > > > > +static enum drm_mode_status
> > > > > +cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
> > > > > +			       const struct drm_display_mode *mode,
> > > > > +			       unsigned long long tmds_rate) {
> > > > > +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > > > > +	union phy_configure_opts phy_cfg;
> > > > > +	int ret;
> > > > > +
> > > > > +	phy_cfg.hdmi.tmds_char_rate = tmds_rate;
> > > > > +
> > > > > +	/* Mailbox protect for HDMI PHY access */
> > > > > +	mutex_lock(&mhdp->mbox_mutex);
> > > > > +	ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
> > > > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > > > +	if (ret < 0)
> > > > > +		return MODE_CLOCK_RANGE;
> > > > > +
> > > > > +	return MODE_OK;
> > > > > +}
> > > > > +
> > > > > +static enum drm_mode_status
> > > > > +cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
> > > > > +			    const struct drm_display_info *info,
> > > > > +			    const struct drm_display_mode *mode) {
> > > > > +	unsigned long long tmds_rate;
> > > > > +
> > > > > +	/* We don't support double-clocked and Interlaced modes */
> > > > > +	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
> > > > > +	    mode->flags & DRM_MODE_FLAG_INTERLACE)
> > > > > +		return MODE_BAD;
> > > > > +
> > > > > +	/* MAX support pixel clock rate 594MHz */
> > > > > +	if (mode->clock > 594000)
> > > > > +		return MODE_CLOCK_HIGH;
> > > >
> > > > This needs to be in the tmds_char_rate_valid function
> > > This clock rate check is covered by function tmds_char_rate_valid() It
> > > could be removed if keep function tmds_char_rate_valid() be called by
> > mode_valid.
> > 
> > Yeah, it's not something you should have to duplicate.
> > 
> > > >
> > > > > +	if (mode->hdisplay > 3840)
> > > > > +		return MODE_BAD_HVALUE;
> > > > > +
> > > > > +	if (mode->vdisplay > 2160)
> > > > > +		return MODE_BAD_VVALUE;
> > > > > +
> > > > > +	tmds_rate = mode->clock * 1000ULL;
> > > > > +	return cdns_hdmi_tmds_char_rate_valid(bridge, mode, tmds_rate);
> > > >
> > > > It will already be called by the core so this is redundant.
> > >
> > > mode_valid function is use to filter the mode list in
> > > drm_helper_probe_single_connector_modes(),
> > > if function cdns_hdmi_tmds_char_rate_valid() is not called, unsupported
> > modes will in mode list.
> > 
> > It's probably something we should deal with in the core somehow. I'm not
> > entirely sure how to reconcile drm_bridge_connector and the hdmi
> > framework there, but we should at the very least provide a mode_valid
> > helper for bridges.
>
> I agree with that. In fact, I'm a bit confused about the current
> mode_valid and tmds_char_rate_valid functions. Ideally, we should find
> a way to make tmds_char_rate_valid also work for filtering out the
> mode list, rather than just during atomic_check.

Yeah, definitely. The way we did so on vc4 for example was to compute
the rate for a 8bpc, RGB, output and try to validate that. I think it
would be reasonable to start with that.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 273 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20240912/739fba20/attachment.sig>

From quic_qianyu at quicinc.com  Thu Sep 12 06:39:44 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Thu, 12 Sep 2024 21:39:44 +0800
Subject: [PATCH 8/8] PCI: qcom: Add support to PCIe slot power supplies
In-Reply-To: <20240911153228.7ajcqicxnu2afhbp@thinkpad>
References: <20240827063631.3932971-1-quic_qianyu@quicinc.com>
 <20240827063631.3932971-9-quic_qianyu@quicinc.com>
 <CAA8EJpq5KergZ8czg4F=EYMLANoOeBsiSVoO-zAgfG0ezQrKCQ@mail.gmail.com>
 <20240827165826.moe6cnemeheos6jn@thinkpad>
 <26f2845f-2e29-4887-9f33-0b5b2a06adb6@quicinc.com>
 <20240911153228.7ajcqicxnu2afhbp@thinkpad>
Message-ID: <9222ef18-2eef-4ba3-95aa-fae540c06925@quicinc.com>


On 9/11/2024 11:32 PM, Manivannan Sadhasivam wrote:
> On Wed, Sep 11, 2024 at 04:17:41PM +0800, Qiang Yu wrote:
>> On 8/28/2024 12:58 AM, Manivannan Sadhasivam wrote:
>>> On Tue, Aug 27, 2024 at 02:44:09PM +0300, Dmitry Baryshkov wrote:
>>>> On Tue, 27 Aug 2024 at 09:36, Qiang Yu <quic_qianyu at quicinc.com> wrote:
>>>>> On platform x1e80100 QCP, PCIe3 is a standard x8 form factor. Hence, add
>>>>> support to use 3.3v, 3.3v aux and 12v regulators.
>>>> First of all, I don't see corresponding bindings change.
>>>>
>>>> Second, these supplies power up the slot, not the host controller
>>>> itself. As such these supplies do not belong to the host controller
>>>> entry. Please consider using the pwrseq framework instead.
>>>>
>>> Indeed. For legacy reasons, slot power supplies were populated in the host
>>> bridge node itself until recently Rob started objecting it [1]. And it makes
>>> real sense to put these supplies in the root port node and handle them in the
>>> relevant driver.
>>>
>>> I'm still evaluating whether the handling should be done in the portdrv or
>>> pwrctl driver, but haven't reached the conclusion. Pwrctl seems to be the ideal
>>> choice, but I see a few issues related to handling the OF node for the root
>>> port.
>>>
>>> Hope I'll come to a conclusion in the next few days and will update this thread.
>>>
>>> - Mani
>>>
>>> [1] https://lore.kernel.org/lkml/20240604235806.GA1903493-robh at kernel.org/
>> Hi Mani, do you have any updates?
>>
> I'm working with Bartosz to add a new pwrctl driver for rootports. And we are
> debugging an issue currently. Unfortunately, the progress is very slow as I'm on
> vacation still.
>
> Will post the patches once it got resolved.
>
> - Mani
OK, thanks for your update.

Thanks,
Qiang
>> Thanks,
>> Qiang
>>>>> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
>>>>> ---
>>>>>    drivers/pci/controller/dwc/pcie-qcom.c | 52 +++++++++++++++++++++++++-
>>>>>    1 file changed, 50 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
>>>>> index 6f953e32d990..59fb415dfeeb 100644
>>>>> --- a/drivers/pci/controller/dwc/pcie-qcom.c
>>>>> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
>>>>> @@ -248,6 +248,8 @@ struct qcom_pcie_cfg {
>>>>>           bool no_l0s;
>>>>>    };
>>>>>
>>>>> +#define QCOM_PCIE_SLOT_MAX_SUPPLIES                    3
>>>>> +
>>>>>    struct qcom_pcie {
>>>>>           struct dw_pcie *pci;
>>>>>           void __iomem *parf;                     /* DT parf */
>>>>> @@ -260,6 +262,7 @@ struct qcom_pcie {
>>>>>           struct icc_path *icc_cpu;
>>>>>           const struct qcom_pcie_cfg *cfg;
>>>>>           struct dentry *debugfs;
>>>>> +       struct regulator_bulk_data slot_supplies[QCOM_PCIE_SLOT_MAX_SUPPLIES];
>>>>>           bool suspended;
>>>>>           bool use_pm_opp;
>>>>>    };
>>>>> @@ -1174,6 +1177,41 @@ static int qcom_pcie_link_up(struct dw_pcie *pci)
>>>>>           return !!(val & PCI_EXP_LNKSTA_DLLLA);
>>>>>    }
>>>>>
>>>>> +static int qcom_pcie_enable_slot_supplies(struct qcom_pcie *pcie)
>>>>> +{
>>>>> +       struct dw_pcie *pci = pcie->pci;
>>>>> +       int ret;
>>>>> +
>>>>> +       ret = regulator_bulk_enable(ARRAY_SIZE(pcie->slot_supplies),
>>>>> +                                   pcie->slot_supplies);
>>>>> +       if (ret < 0)
>>>>> +               dev_err(pci->dev, "Failed to enable slot regulators\n");
>>>>> +
>>>>> +       return ret;
>>>>> +}
>>>>> +
>>>>> +static void qcom_pcie_disable_slot_supplies(struct qcom_pcie *pcie)
>>>>> +{
>>>>> +       regulator_bulk_disable(ARRAY_SIZE(pcie->slot_supplies),
>>>>> +                              pcie->slot_supplies);
>>>>> +}
>>>>> +
>>>>> +static int qcom_pcie_get_slot_supplies(struct qcom_pcie *pcie)
>>>>> +{
>>>>> +       struct dw_pcie *pci = pcie->pci;
>>>>> +       int ret;
>>>>> +
>>>>> +       pcie->slot_supplies[0].supply = "vpcie12v";
>>>>> +       pcie->slot_supplies[1].supply = "vpcie3v3";
>>>>> +       pcie->slot_supplies[2].supply = "vpcie3v3aux";
>>>>> +       ret = devm_regulator_bulk_get(pci->dev, ARRAY_SIZE(pcie->slot_supplies),
>>>>> +                                     pcie->slot_supplies);
>>>>> +       if (ret < 0)
>>>>> +               dev_err(pci->dev, "Failed to get slot regulators\n");
>>>>> +
>>>>> +       return ret;
>>>>> +}
>>>>> +
>>>>>    static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
>>>>>    {
>>>>>           struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>>>>> @@ -1182,10 +1220,14 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
>>>>>
>>>>>           qcom_ep_reset_assert(pcie);
>>>>>
>>>>> -       ret = pcie->cfg->ops->init(pcie);
>>>>> +       ret = qcom_pcie_enable_slot_supplies(pcie);
>>>>>           if (ret)
>>>>>                   return ret;
>>>>>
>>>>> +       ret = pcie->cfg->ops->init(pcie);
>>>>> +       if (ret)
>>>>> +               goto err_disable_slot;
>>>>> +
>>>>>           ret = phy_set_mode_ext(pcie->phy, PHY_MODE_PCIE, PHY_MODE_PCIE_RC);
>>>>>           if (ret)
>>>>>                   goto err_deinit;
>>>>> @@ -1216,7 +1258,8 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
>>>>>           phy_power_off(pcie->phy);
>>>>>    err_deinit:
>>>>>           pcie->cfg->ops->deinit(pcie);
>>>>> -
>>>>> +err_disable_slot:
>>>>> +       qcom_pcie_disable_slot_supplies(pcie);
>>>>>           return ret;
>>>>>    }
>>>>>
>>>>> @@ -1228,6 +1271,7 @@ static void qcom_pcie_host_deinit(struct dw_pcie_rp *pp)
>>>>>           qcom_ep_reset_assert(pcie);
>>>>>           phy_power_off(pcie->phy);
>>>>>           pcie->cfg->ops->deinit(pcie);
>>>>> +       qcom_pcie_disable_slot_supplies(pcie);
>>>>>    }
>>>>>
>>>>>    static void qcom_pcie_host_post_init(struct dw_pcie_rp *pp)
>>>>> @@ -1602,6 +1646,10 @@ static int qcom_pcie_probe(struct platform_device *pdev)
>>>>>                           goto err_pm_runtime_put;
>>>>>           }
>>>>>
>>>>> +       ret = qcom_pcie_get_slot_supplies(pcie);
>>>>> +       if (ret)
>>>>> +               goto err_pm_runtime_put;
>>>>> +
>>>>>           ret = pcie->cfg->ops->get_resources(pcie);
>>>>>           if (ret)
>>>>>                   goto err_pm_runtime_put;
>>>>> --
>>>>> 2.34.1
>>>>>
>>>> -- 
>>>> With best wishes
>>>> Dmitry


From konradybcio at kernel.org  Thu Sep 12 07:15:56 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Thu, 12 Sep 2024 16:15:56 +0200
Subject: [PATCH 8/8] PCI: qcom: Add support to PCIe slot power supplies
In-Reply-To: <9222ef18-2eef-4ba3-95aa-fae540c06925@quicinc.com>
References: <20240827063631.3932971-1-quic_qianyu@quicinc.com>
 <20240827063631.3932971-9-quic_qianyu@quicinc.com>
 <CAA8EJpq5KergZ8czg4F=EYMLANoOeBsiSVoO-zAgfG0ezQrKCQ@mail.gmail.com>
 <20240827165826.moe6cnemeheos6jn@thinkpad>
 <26f2845f-2e29-4887-9f33-0b5b2a06adb6@quicinc.com>
 <20240911153228.7ajcqicxnu2afhbp@thinkpad>
 <9222ef18-2eef-4ba3-95aa-fae540c06925@quicinc.com>
Message-ID: <d5468dd2-0f81-4d89-a3bd-a546b2395ca6@kernel.org>

On 12.09.2024 3:39 PM, Qiang Yu wrote:
> 
> On 9/11/2024 11:32 PM, Manivannan Sadhasivam wrote:
>> On Wed, Sep 11, 2024 at 04:17:41PM +0800, Qiang Yu wrote:
>>> On 8/28/2024 12:58 AM, Manivannan Sadhasivam wrote:
>>>> On Tue, Aug 27, 2024 at 02:44:09PM +0300, Dmitry Baryshkov wrote:
>>>>> On Tue, 27 Aug 2024 at 09:36, Qiang Yu <quic_qianyu at quicinc.com> wrote:
>>>>>> On platform x1e80100 QCP, PCIe3 is a standard x8 form factor. Hence, add
>>>>>> support to use 3.3v, 3.3v aux and 12v regulators.
>>>>> First of all, I don't see corresponding bindings change.
>>>>>
>>>>> Second, these supplies power up the slot, not the host controller
>>>>> itself. As such these supplies do not belong to the host controller
>>>>> entry. Please consider using the pwrseq framework instead.
>>>>>
>>>> Indeed. For legacy reasons, slot power supplies were populated in the host
>>>> bridge node itself until recently Rob started objecting it [1]. And it makes
>>>> real sense to put these supplies in the root port node and handle them in the
>>>> relevant driver.
>>>>
>>>> I'm still evaluating whether the handling should be done in the portdrv or
>>>> pwrctl driver, but haven't reached the conclusion. Pwrctl seems to be the ideal
>>>> choice, but I see a few issues related to handling the OF node for the root
>>>> port.
>>>>
>>>> Hope I'll come to a conclusion in the next few days and will update this thread.
>>>>
>>>> - Mani
>>>>
>>>> [1] https://lore.kernel.org/lkml/20240604235806.GA1903493-robh at kernel.org/
>>> Hi Mani, do you have any updates?
>>>
>> I'm working with Bartosz to add a new pwrctl driver for rootports. And we are
>> debugging an issue currently. Unfortunately, the progress is very slow as I'm on
>> vacation still.
>>
>> Will post the patches once it got resolved.
>>
>> - Mani
> OK, thanks for your update.

Qiang, you can still resubmit the rest of the patches without having
to wait on that to be resolved

Konrad


From manivannan.sadhasivam at linaro.org  Thu Sep 12 07:44:39 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Thu, 12 Sep 2024 20:14:39 +0530
Subject: [PATCH 8/8] PCI: qcom: Add support to PCIe slot power supplies
In-Reply-To: <d5468dd2-0f81-4d89-a3bd-a546b2395ca6@kernel.org>
References: <20240827063631.3932971-1-quic_qianyu@quicinc.com>
 <20240827063631.3932971-9-quic_qianyu@quicinc.com>
 <CAA8EJpq5KergZ8czg4F=EYMLANoOeBsiSVoO-zAgfG0ezQrKCQ@mail.gmail.com>
 <20240827165826.moe6cnemeheos6jn@thinkpad>
 <26f2845f-2e29-4887-9f33-0b5b2a06adb6@quicinc.com>
 <20240911153228.7ajcqicxnu2afhbp@thinkpad>
 <9222ef18-2eef-4ba3-95aa-fae540c06925@quicinc.com>
 <d5468dd2-0f81-4d89-a3bd-a546b2395ca6@kernel.org>
Message-ID: <20240912144439.fnne4x7qvggveve2@thinkpad>

On Thu, Sep 12, 2024 at 04:15:56PM +0200, Konrad Dybcio wrote:
> On 12.09.2024 3:39 PM, Qiang Yu wrote:
> > 
> > On 9/11/2024 11:32 PM, Manivannan Sadhasivam wrote:
> >> On Wed, Sep 11, 2024 at 04:17:41PM +0800, Qiang Yu wrote:
> >>> On 8/28/2024 12:58 AM, Manivannan Sadhasivam wrote:
> >>>> On Tue, Aug 27, 2024 at 02:44:09PM +0300, Dmitry Baryshkov wrote:
> >>>>> On Tue, 27 Aug 2024 at 09:36, Qiang Yu <quic_qianyu at quicinc.com> wrote:
> >>>>>> On platform x1e80100 QCP, PCIe3 is a standard x8 form factor. Hence, add
> >>>>>> support to use 3.3v, 3.3v aux and 12v regulators.
> >>>>> First of all, I don't see corresponding bindings change.
> >>>>>
> >>>>> Second, these supplies power up the slot, not the host controller
> >>>>> itself. As such these supplies do not belong to the host controller
> >>>>> entry. Please consider using the pwrseq framework instead.
> >>>>>
> >>>> Indeed. For legacy reasons, slot power supplies were populated in the host
> >>>> bridge node itself until recently Rob started objecting it [1]. And it makes
> >>>> real sense to put these supplies in the root port node and handle them in the
> >>>> relevant driver.
> >>>>
> >>>> I'm still evaluating whether the handling should be done in the portdrv or
> >>>> pwrctl driver, but haven't reached the conclusion. Pwrctl seems to be the ideal
> >>>> choice, but I see a few issues related to handling the OF node for the root
> >>>> port.
> >>>>
> >>>> Hope I'll come to a conclusion in the next few days and will update this thread.
> >>>>
> >>>> - Mani
> >>>>
> >>>> [1] https://lore.kernel.org/lkml/20240604235806.GA1903493-robh at kernel.org/
> >>> Hi Mani, do you have any updates?
> >>>
> >> I'm working with Bartosz to add a new pwrctl driver for rootports. And we are
> >> debugging an issue currently. Unfortunately, the progress is very slow as I'm on
> >> vacation still.
> >>
> >> Will post the patches once it got resolved.
> >>
> >> - Mani
> > OK, thanks for your update.
> 
> Qiang, you can still resubmit the rest of the patches without having
> to wait on that to be resolved
> 

In that case, the slot supplies should be described in the PCIe bridge.

- Mani

> Konrad

-- 
????????? ????????


From dmitry.baryshkov at linaro.org  Thu Sep 12 07:49:31 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 12 Sep 2024 17:49:31 +0300
Subject: [PATCH 8/8] PCI: qcom: Add support to PCIe slot power supplies
In-Reply-To: <20240912144439.fnne4x7qvggveve2@thinkpad>
References: <20240827063631.3932971-1-quic_qianyu@quicinc.com>
 <20240827063631.3932971-9-quic_qianyu@quicinc.com> <CAA8EJpq5KergZ8czg4F=EYMLANoOeBsiSVoO-zAgfG0ezQrKCQ@mail.gmail.com>
 <20240827165826.moe6cnemeheos6jn@thinkpad> <26f2845f-2e29-4887-9f33-0b5b2a06adb6@quicinc.com>
 <20240911153228.7ajcqicxnu2afhbp@thinkpad> <9222ef18-2eef-4ba3-95aa-fae540c06925@quicinc.com>
 <d5468dd2-0f81-4d89-a3bd-a546b2395ca6@kernel.org> <20240912144439.fnne4x7qvggveve2@thinkpad>
Message-ID: <CAA8EJppSFb+Me6w5vUpmbogQ4DS2=15FmHu4nzGz2POWQPouwA@mail.gmail.com>

On Thu, 12 Sept 2024 at 17:45, Manivannan Sadhasivam
<manivannan.sadhasivam at linaro.org> wrote:
>
> On Thu, Sep 12, 2024 at 04:15:56PM +0200, Konrad Dybcio wrote:
> > On 12.09.2024 3:39 PM, Qiang Yu wrote:
> > >
> > > On 9/11/2024 11:32 PM, Manivannan Sadhasivam wrote:
> > >> On Wed, Sep 11, 2024 at 04:17:41PM +0800, Qiang Yu wrote:
> > >>> On 8/28/2024 12:58 AM, Manivannan Sadhasivam wrote:
> > >>>> On Tue, Aug 27, 2024 at 02:44:09PM +0300, Dmitry Baryshkov wrote:
> > >>>>> On Tue, 27 Aug 2024 at 09:36, Qiang Yu <quic_qianyu at quicinc.com> wrote:
> > >>>>>> On platform x1e80100 QCP, PCIe3 is a standard x8 form factor. Hence, add
> > >>>>>> support to use 3.3v, 3.3v aux and 12v regulators.
> > >>>>> First of all, I don't see corresponding bindings change.
> > >>>>>
> > >>>>> Second, these supplies power up the slot, not the host controller
> > >>>>> itself. As such these supplies do not belong to the host controller
> > >>>>> entry. Please consider using the pwrseq framework instead.
> > >>>>>
> > >>>> Indeed. For legacy reasons, slot power supplies were populated in the host
> > >>>> bridge node itself until recently Rob started objecting it [1]. And it makes
> > >>>> real sense to put these supplies in the root port node and handle them in the
> > >>>> relevant driver.
> > >>>>
> > >>>> I'm still evaluating whether the handling should be done in the portdrv or
> > >>>> pwrctl driver, but haven't reached the conclusion. Pwrctl seems to be the ideal
> > >>>> choice, but I see a few issues related to handling the OF node for the root
> > >>>> port.
> > >>>>
> > >>>> Hope I'll come to a conclusion in the next few days and will update this thread.
> > >>>>
> > >>>> - Mani
> > >>>>
> > >>>> [1] https://lore.kernel.org/lkml/20240604235806.GA1903493-robh at kernel.org/
> > >>> Hi Mani, do you have any updates?
> > >>>
> > >> I'm working with Bartosz to add a new pwrctl driver for rootports. And we are
> > >> debugging an issue currently. Unfortunately, the progress is very slow as I'm on
> > >> vacation still.
> > >>
> > >> Will post the patches once it got resolved.
> > >>
> > >> - Mani
> > > OK, thanks for your update.
> >
> > Qiang, you can still resubmit the rest of the patches without having
> > to wait on that to be resolved
> >
>
> In that case, the slot supplies should be described in the PCIe bridge.

Patches 1-6 don't seem to depend on slot supplies, so they can be
submitted separately.

>
> - Mani
>
> > Konrad
>
> --
> ????????? ????????



-- 
With best wishes
Dmitry


From zajec5 at gmail.com  Thu Sep 12 21:45:57 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri, 13 Sep 2024 06:45:57 +0200
Subject: [PATCH 2/2] phy: bcm-ns-usb2: drop support for old binding variant
In-Reply-To: <20240913044557.28315-1-zajec5@gmail.com>
References: <20240913044557.28315-1-zajec5@gmail.com>
Message-ID: <20240913044557.28315-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

The old binding was incorrectly designed and ended up being deprecated 3
years ago. Finally it has been dropped so relevant code it not needed
anymore.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 drivers/phy/broadcom/phy-bcm-ns-usb2.c | 54 +++++++-------------------
 1 file changed, 15 insertions(+), 39 deletions(-)

diff --git a/drivers/phy/broadcom/phy-bcm-ns-usb2.c b/drivers/phy/broadcom/phy-bcm-ns-usb2.c
index 5213c75b6da6..c5d35031b398 100644
--- a/drivers/phy/broadcom/phy-bcm-ns-usb2.c
+++ b/drivers/phy/broadcom/phy-bcm-ns-usb2.c
@@ -24,9 +24,6 @@ struct bcm_ns_usb2 {
 	struct phy *phy;
 	struct regmap *clkset;
 	void __iomem *base;
-
-	/* Deprecated binding */
-	void __iomem *dmu;
 };
 
 static int bcm_ns_usb2_phy_init(struct phy *phy)
@@ -49,10 +46,7 @@ static int bcm_ns_usb2_phy_init(struct phy *phy)
 		goto err_clk_off;
 	}
 
-	if (usb2->base)
-		usb2ctl = readl(usb2->base);
-	else
-		usb2ctl = readl(usb2->dmu + BCMA_DMU_CRU_USB2_CONTROL);
+	usb2ctl = readl(usb2->base);
 
 	if (usb2ctl & BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_MASK) {
 		usb_pll_pdiv = usb2ctl;
@@ -66,24 +60,16 @@ static int bcm_ns_usb2_phy_init(struct phy *phy)
 	usb_pll_ndiv = (1920000000 * usb_pll_pdiv) / ref_clk_rate;
 
 	/* Unlock DMU PLL settings with some magic value */
-	if (usb2->clkset)
-		regmap_write(usb2->clkset, 0, 0x0000ea68);
-	else
-		writel(0x0000ea68, usb2->dmu + BCMA_DMU_CRU_CLKSET_KEY);
+	regmap_write(usb2->clkset, 0, 0x0000ea68);
 
 	/* Write USB 2.0 PLL control setting */
 	usb2ctl &= ~BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_MASK;
 	usb2ctl |= usb_pll_ndiv << BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_SHIFT;
-	if (usb2->base)
-		writel(usb2ctl, usb2->base);
-	else
-		writel(usb2ctl, usb2->dmu + BCMA_DMU_CRU_USB2_CONTROL);
+
+	writel(usb2ctl, usb2->base);
 
 	/* Lock DMU PLL settings */
-	if (usb2->clkset)
-		regmap_write(usb2->clkset, 0, 0x00000000);
-	else
-		writel(0x00000000, usb2->dmu + BCMA_DMU_CRU_CLKSET_KEY);
+	regmap_write(usb2->clkset, 0, 0x00000000);
 
 err_clk_off:
 	clk_disable_unprepare(usb2->ref_clk);
@@ -107,27 +93,17 @@ static int bcm_ns_usb2_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	usb2->dev = dev;
 
-	if (of_property_present(dev->of_node, "brcm,syscon-clkset")) {
-		usb2->base = devm_platform_ioremap_resource(pdev, 0);
-		if (IS_ERR(usb2->base)) {
-			dev_err(dev, "Failed to map control reg\n");
-			return PTR_ERR(usb2->base);
-		}
-
-		usb2->clkset = syscon_regmap_lookup_by_phandle(dev->of_node,
-							       "brcm,syscon-clkset");
-		if (IS_ERR(usb2->clkset)) {
-			dev_err(dev, "Failed to lookup clkset regmap\n");
-			return PTR_ERR(usb2->clkset);
-		}
-	} else {
-		usb2->dmu = devm_platform_ioremap_resource_byname(pdev, "dmu");
-		if (IS_ERR(usb2->dmu)) {
-			dev_err(dev, "Failed to map DMU regs\n");
-			return PTR_ERR(usb2->dmu);
-		}
+	usb2->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(usb2->base)) {
+		dev_err(dev, "Failed to map control reg\n");
+		return PTR_ERR(usb2->base);
+	}
 
-		dev_warn(dev, "using deprecated DT binding\n");
+	usb2->clkset = syscon_regmap_lookup_by_phandle(dev->of_node,
+						       "brcm,syscon-clkset");
+	if (IS_ERR(usb2->clkset)) {
+		dev_err(dev, "Failed to lookup clkset regmap\n");
+		return PTR_ERR(usb2->clkset);
 	}
 
 	usb2->ref_clk = devm_clk_get(dev, "phy-ref-clk");
-- 
2.35.3



From zajec5 at gmail.com  Thu Sep 12 21:45:56 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri, 13 Sep 2024 06:45:56 +0200
Subject: [PATCH 1/2] dt-bindings: phy: bcm-ns-usb2-phy: drop deprecated variant
Message-ID: <20240913044557.28315-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

The old binding variant (the one covering whole DMU block) was
deprecated 3 years ago. Linux kernel was warning when using it for
similar amount of time.

There aren't any known Northstar devices with bootloader providing DT to
operating system. Actually OpenWrt seems to be the only project using
this binding and it always appends DTB to kernel. It has switched to the
non-deprecated binding years ago.

Given there is close to zero chance this breaks anyone's setup it should
more than safe to drop this binding variant after 3 years.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 .../bindings/phy/bcm-ns-usb2-phy.yaml         | 19 +++----------------
 1 file changed, 3 insertions(+), 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.yaml b/Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.yaml
index 426101530a21..d72c02ab55ae 100644
--- a/Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.yaml
@@ -18,16 +18,8 @@ properties:
     const: brcm,ns-usb2-phy
 
   reg:
-    anyOf:
-      - maxItems: 1
-        description: PHY control register
-      - maxItems: 1
-        description: iomem address range of DMU (Device Management Unit)
-        deprecated: true
-
-  reg-names:
-    items:
-      - const: dmu
+    maxItems: 1
+    description: PHY control register
 
   brcm,syscon-clkset:
     description: phandle to syscon for clkset register
@@ -50,12 +42,7 @@ required:
   - clocks
   - clock-names
   - "#phy-cells"
-
-oneOf:
-  - required:
-      - brcm,syscon-clkset
-  - required:
-      - reg-names
+  - brcm,syscon-clkset
 
 additionalProperties: false
 
-- 
2.35.3



From quic_qianyu at quicinc.com  Fri Sep 13 01:37:20 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Fri, 13 Sep 2024 01:37:20 -0700
Subject: [PATCH v2 1/5] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the X1E80100 QMP PCIe PHY Gen4 x8
In-Reply-To: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
Message-ID: <20240913083724.1217691-2-quic_qianyu@quicinc.com>

PCIe 3rd instance of X1E80100 support Gen 4x8 which needs different 8 lane
capable QMP PCIe PHY. Document Gen 4x8 PHY as separate module.

Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
---
 .../devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml    | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
index dcf4fa55fbba..680ec3113c2b 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -41,6 +41,7 @@ properties:
       - qcom,x1e80100-qmp-gen3x2-pcie-phy
       - qcom,x1e80100-qmp-gen4x2-pcie-phy
       - qcom,x1e80100-qmp-gen4x4-pcie-phy
+      - qcom,x1e80100-qmp-gen4x8-pcie-phy
 
   reg:
     minItems: 1
@@ -172,6 +173,7 @@ allOf:
               - qcom,sc8280xp-qmp-gen3x2-pcie-phy
               - qcom,sc8280xp-qmp-gen3x4-pcie-phy
               - qcom,x1e80100-qmp-gen4x4-pcie-phy
+              - qcom,x1e80100-qmp-gen4x8-pcie-phy
     then:
       properties:
         clocks:
@@ -201,6 +203,7 @@ allOf:
               - qcom,sm8550-qmp-gen4x2-pcie-phy
               - qcom,sm8650-qmp-gen4x2-pcie-phy
               - qcom,x1e80100-qmp-gen4x2-pcie-phy
+              - qcom,x1e80100-qmp-gen4x8-pcie-phy
     then:
       properties:
         resets:
-- 
2.34.1



From quic_qianyu at quicinc.com  Fri Sep 13 01:37:21 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Fri, 13 Sep 2024 01:37:21 -0700
Subject: [PATCH v2 2/5] dt-bindings: PCI: qcom: Add OPP table for X1E80100
In-Reply-To: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
Message-ID: <20240913083724.1217691-3-quic_qianyu@quicinc.com>

Add OPP table so that PCIe is able to adjust power domain performance
state and ICC peak bw according to PCIe gen speed and link width.

Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
---
 Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
index a9db0a231563..e2d6719ca54d 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
@@ -70,6 +70,10 @@ properties:
       - const: pci # PCIe core reset
       - const: link_down # PCIe link down reset
 
+  operating-points-v2: true
+  opp-table:
+    type: object
+
 allOf:
   - $ref: qcom,pcie-common.yaml#
 
-- 
2.34.1



From quic_qianyu at quicinc.com  Fri Sep 13 01:37:22 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Fri, 13 Sep 2024 01:37:22 -0700
Subject: [PATCH v2 3/5] phy: qcom: qmp: Add phy register and clk setting for x1e80100 PCIe3
In-Reply-To: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
Message-ID: <20240913083724.1217691-4-quic_qianyu@quicinc.com>

Currently driver supports only x4 lane based functionality using tx/rx and
tx2/rx2 pair of register sets. To support 8 lane functionality with PCIe3,
PCIe3 related QMP PHY provides additional programming which are available
as txz and rxz based register set. Hence adds txz and rxz based registers
usage and programming sequences. Phy register setting for txz and rxz will
be applied to all 8 lanes. Some lanes may have different settings on
several registers than txz/rxz, these registers should be programmed after
txz/rxz programming sequences completing.

Besides, x1e80100 SoC uses QMP phy with version v6.30 for PCIe Gen4 x8.
Add the new register offsets in a dedicated header file.

Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c      | 211 ++++++++++++++++++
 .../qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h    |  25 +++
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h |  19 ++
 3 files changed, 255 insertions(+)
 create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
 create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index f71787fb4d7e..d7bbd9df11d7 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -34,6 +34,8 @@
 #include "phy-qcom-qmp-pcs-pcie-v5_20.h"
 #include "phy-qcom-qmp-pcs-pcie-v6.h"
 #include "phy-qcom-qmp-pcs-pcie-v6_20.h"
+#include "phy-qcom-qmp-pcs-pcie-v6_30.h"
+#include "phy-qcom-qmp-pcs-v6_30.h"
 #include "phy-qcom-qmp-pcie-qhp.h"
 
 #define PHY_INIT_COMPLETE_TIMEOUT		10000
@@ -1344,6 +1346,155 @@ static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
 	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_FOM_EQ_CONFIG5, 0x8a),
 };
 
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_txz_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_TX, 0x1a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_RX, 0x05),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_1, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_2, 0x10),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_3, 0x51),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_TRAN_DRVR_EMP_EN, 0x34),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_rxz_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_2, 0x0c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_GAIN_RATE_2, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_3, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_PI_CONTROLS, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_ACC_DEFAULT_VAL_RATE3, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_CAL_CTRL2, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_POSTCAL_OFFSET, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_BKUP_CTRL1, 0x15),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_3, 0x45),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_VGA_CAL_MAN_VAL, 0x0c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_VGA_CAL_CNTRL1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_GM_CAL, 0x0d),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_EQU_ADAPTOR_CNTRL4, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_SIGDET_ENABLES, 0x1c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_PHPRE_CTRL, 0x20),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_Q_PI_INTRINSIC_BIAS_RATE32, 0x39),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B0, 0xd4),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B1, 0x23),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B2, 0x58),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B3, 0x9a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B4, 0x38),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B5, 0xb6),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B6, 0xee),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B0, 0x1c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B1, 0xe4),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B2, 0x60),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B3, 0xdf),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B4, 0x69),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B5, 0x76),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B6, 0xff),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_TX_ADPT_CTRL, 0x10),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_rx_tbl[] = {
+	QMP_PHY_INIT_CFG_LANE(QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x3a, BIT(0)),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RXCLK_DIV2_CTRL, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_SUMMER_CAL_SPD_MODE, 0x5b),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_DFE_DAC_ENABLE1, 0x88),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH1, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH2, 0x0d),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B0, 0x12),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B1, 0x12),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B2, 0xdb),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B3, 0x9a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B4, 0x38),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B5, 0xb6),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B6, 0x64),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE210, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE210, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE210, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH4_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH5_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH6_RATE3, 0x1f),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_serdes_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0x26),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x03),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x0d),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x68),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0xab),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0xaa),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x12),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0xf8),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0d),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0xab),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xaa),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x62),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_POST_DIV_MUX, 0x40),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 0x1c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x90),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x82),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x46),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_CFG, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x34),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x20),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MISC_1, 0x88),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MODE, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_VCO_DC_LEVEL_CTRL, 0x0f),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_pcs_tbl[] = {
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_LOCK_DETECT_CONFIG2, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_G3S2_PRE_GAIN, 0x2e),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_RX_SIGDET_LVL, 0x99),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_ALIGN_DETECT_CONFIG7, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_EQ_CONFIG4, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_EQ_CONFIG5, 0x22),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_TX_RX_CONFIG, 0x04),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_TX_RX_CONFIG2, 0x02),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl[] = {
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_OSC_DTCT_ACTIONS, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_EQ_CONFIG1, 0x16),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_EQ_CONFIG5, 0x02),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_PRE_GAIN, 0x2e),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG1, 0x03),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG3, 0x28),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG5, 0x18),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G3_FOM_EQ_CONFIG5, 0x7a),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_FOM_EQ_CONFIG5, 0x8a),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G3_RXEQEVAL_TIME, 0x27),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_RXEQEVAL_TIME, 0x27),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_TX_RX_CONFIG, 0xc0),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_POWER_STATE_CONFIG2, 0x1d),
+
+};
+
 static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
@@ -2582,6 +2733,8 @@ struct qmp_pcie_offsets {
 	u16 rx;
 	u16 tx2;
 	u16 rx2;
+	u16 txz;
+	u16 rxz;
 	u16 ln_shrd;
 };
 
@@ -2592,6 +2745,10 @@ struct qmp_phy_cfg_tbls {
 	int tx_num;
 	const struct qmp_phy_init_tbl *rx;
 	int rx_num;
+	const struct qmp_phy_init_tbl *txz;
+	int txz_num;
+	const struct qmp_phy_init_tbl *rxz;
+	int rxz_num;
 	const struct qmp_phy_init_tbl *pcs;
 	int pcs_num;
 	const struct qmp_phy_init_tbl *pcs_misc;
@@ -2659,6 +2816,8 @@ struct qmp_pcie {
 	void __iomem *rx;
 	void __iomem *tx2;
 	void __iomem *rx2;
+	void __iomem *txz;
+	void __iomem *rxz;
 	void __iomem *ln_shrd;
 
 	void __iomem *port_b;
@@ -2826,6 +2985,17 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_20 = {
 	.ln_shrd	= 0x0e00,
 };
 
+static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_30 = {
+	.serdes		= 0x8800,
+	.pcs		= 0x9000,
+	.pcs_misc	= 0x9800,
+	.tx		= 0x0000,
+	.rx		= 0x0200,
+	.txz		= 0xe000,
+	.rxz		= 0xe200,
+	.ln_shrd	= 0x8000,
+};
+
 static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
 	.lanes			= 1,
 
@@ -3704,6 +3874,38 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x4_pciephy_cfg = {
 	.has_nocsr_reset	= true,
 };
 
+static const struct qmp_phy_cfg x1e80100_qmp_gen4x8_pciephy_cfg = {
+	.lanes = 8,
+
+	.offsets		= &qmp_pcie_offsets_v6_30,
+	.tbls = {
+		.serdes			= x1e80100_qmp_gen4x8_pcie_serdes_tbl,
+		.serdes_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_serdes_tbl),
+		.rx			= x1e80100_qmp_gen4x8_pcie_rx_tbl,
+		.rx_num			= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_rx_tbl),
+		.pcs			= x1e80100_qmp_gen4x8_pcie_pcs_tbl,
+		.pcs_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_pcs_tbl),
+		.pcs_misc		= x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl,
+		.pcs_misc_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl),
+		.ln_shrd		= x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl,
+		.ln_shrd_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl),
+		.txz			= x1e80100_qmp_gen4x8_pcie_txz_tbl,
+		.txz_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_txz_tbl),
+		.rxz			= x1e80100_qmp_gen4x8_pcie_rxz_tbl,
+		.rxz_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_rxz_tbl),
+	},
+
+	.reset_list		= sdm845_pciephy_reset_l,
+	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.vreg_list		= sm8550_qmp_phy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm8550_qmp_phy_vreg_l),
+	.regs			= pciephy_v6_regs_layout,
+
+	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,
+	.phy_status		= PHYSTATUS_4_20,
+	.has_nocsr_reset	= true,
+};
+
 static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
 {
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -3751,6 +3953,9 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
 
 	qmp_configure(qmp->dev, serdes, tbls->serdes, tbls->serdes_num);
 
+	qmp_configure(qmp->dev, qmp->txz, tbls->txz, tbls->txz_num);
+	qmp_configure(qmp->dev, qmp->rxz, tbls->rxz, tbls->rxz_num);
+
 	qmp_configure_lane(qmp->dev, tx, tbls->tx, tbls->tx_num, 1);
 	qmp_configure_lane(qmp->dev, rx, tbls->rx, tbls->rx_num, 1);
 
@@ -4293,6 +4498,9 @@ static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
 			return PTR_ERR(qmp->port_b);
 	}
 
+	qmp->txz = base + offs->txz;
+	qmp->rxz = base + offs->rxz;
+
 	if (cfg->tbls.ln_shrd)
 		qmp->ln_shrd = base + offs->ln_shrd;
 
@@ -4478,6 +4686,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
 	}, {
 		.compatible = "qcom,x1e80100-qmp-gen4x4-pcie-phy",
 		.data = &x1e80100_qmp_gen4x4_pciephy_cfg,
+	}, {
+		.compatible = "qcom,x1e80100-qmp-gen4x8-pcie-phy",
+		.data = &x1e80100_qmp_gen4x8_pciephy_cfg,
 	},
 	{ },
 };
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
new file mode 100644
index 000000000000..5a58ff197e6e
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_PCIE_V6_30_H_
+#define QCOM_PHY_QMP_PCS_PCIE_V6_30_H_
+
+/* Only for QMP V6_30 PHY - PCIE have different offsets than V6 */
+#define QPHY_PCIE_V6_30_PCS_POWER_STATE_CONFIG2		0x014
+#define QPHY_PCIE_V6_30_PCS_TX_RX_CONFIG		0x020
+#define QPHY_PCIE_V6_30_PCS_ENDPOINT_REFCLK_DRIVE	0x024
+#define QPHY_PCIE_V6_30_PCS_OSC_DTCT_ACTIONS		0x098
+#define QPHY_PCIE_V6_30_PCS_EQ_CONFIG1			0x0a8
+#define QPHY_PCIE_V6_30_PCS_G3_RXEQEVAL_TIME		0x0f8
+#define QPHY_PCIE_V6_30_PCS_G4_RXEQEVAL_TIME		0x0fc
+#define QPHY_PCIE_V6_30_PCS_G4_EQ_CONFIG5		0x110
+#define QPHY_PCIE_V6_30_PCS_G4_PRE_GAIN			0x164
+#define QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG1	0x184
+#define QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG3	0x18c
+#define QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG5	0x194
+#define QPHY_PCIE_V6_30_PCS_G3_FOM_EQ_CONFIG5		0x1b4
+#define QPHY_PCIE_V6_30_PCS_G4_FOM_EQ_CONFIG5		0x1c8
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h
new file mode 100644
index 000000000000..369120d88bc2
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_V6_30_H_
+#define QCOM_PHY_QMP_PCS_V6_30_H_
+
+/* Only for QMP V6_30 PHY - PCIe PCS registers */
+#define QPHY_V6_30_PCS_LOCK_DETECT_CONFIG2		0x0cc
+#define QPHY_V6_30_PCS_G3S2_PRE_GAIN			0x17c
+#define QPHY_V6_30_PCS_RX_SIGDET_LVL			0x194
+#define QPHY_V6_30_PCS_ALIGN_DETECT_CONFIG7		0x1dc
+#define QPHY_V6_30_PCS_TX_RX_CONFIG			0x1e0
+#define QPHY_V6_30_PCS_TX_RX_CONFIG2			0x1e4
+#define QPHY_V6_30_PCS_EQ_CONFIG4			0x1fc
+#define QPHY_V6_30_PCS_EQ_CONFIG5			0x200
+
+#endif
-- 
2.34.1



From quic_qianyu at quicinc.com  Fri Sep 13 01:37:23 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Fri, 13 Sep 2024 01:37:23 -0700
Subject: [PATCH v2 4/5] clk: qcom: gcc-x1e80100: Fix halt_check for pipediv2 clocks
In-Reply-To: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
Message-ID: <20240913083724.1217691-5-quic_qianyu@quicinc.com>

The pipediv2_clk's source from the same mux as pipe clock. So they have
same limitation, which is that the PHY sequence requires to enable these
local CBCs before the PHY is actually outputting a clock to them. This
means the clock won't actually turn on when we vote them. Hence, let's
skip the halt bit check of the pipediv2_clk, otherwise pipediv2_clk may
stuck at off state during bootup.

Suggested-by: Mike Tipton <quic_mdtipton at quicinc.com>
Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
Reviewed-by: Konrad Dybcio <konradybcio at kernel.org>
---
 drivers/clk/qcom/gcc-x1e80100.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c
index 0f578771071f..81ba5ceab342 100644
--- a/drivers/clk/qcom/gcc-x1e80100.c
+++ b/drivers/clk/qcom/gcc-x1e80100.c
@@ -3123,7 +3123,7 @@ static struct clk_branch gcc_pcie_3_pipe_clk = {
 
 static struct clk_branch gcc_pcie_3_pipediv2_clk = {
 	.halt_reg = 0x58060,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52020,
 		.enable_mask = BIT(5),
@@ -3248,7 +3248,7 @@ static struct clk_branch gcc_pcie_4_pipe_clk = {
 
 static struct clk_branch gcc_pcie_4_pipediv2_clk = {
 	.halt_reg = 0x6b054,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52010,
 		.enable_mask = BIT(27),
@@ -3373,7 +3373,7 @@ static struct clk_branch gcc_pcie_5_pipe_clk = {
 
 static struct clk_branch gcc_pcie_5_pipediv2_clk = {
 	.halt_reg = 0x2f054,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52018,
 		.enable_mask = BIT(19),
@@ -3511,7 +3511,7 @@ static struct clk_branch gcc_pcie_6a_pipe_clk = {
 
 static struct clk_branch gcc_pcie_6a_pipediv2_clk = {
 	.halt_reg = 0x31060,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52018,
 		.enable_mask = BIT(28),
@@ -3649,7 +3649,7 @@ static struct clk_branch gcc_pcie_6b_pipe_clk = {
 
 static struct clk_branch gcc_pcie_6b_pipediv2_clk = {
 	.halt_reg = 0x8d060,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52010,
 		.enable_mask = BIT(28),
-- 
2.34.1



From quic_qianyu at quicinc.com  Fri Sep 13 01:37:19 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Fri, 13 Sep 2024 01:37:19 -0700
Subject: [PATCH v2 0/5] Add support for PCIe3 on x1e80100
Message-ID: <20240913083724.1217691-1-quic_qianyu@quicinc.com>

This series add support for PCIe3 on x1e80100.

PCIe3 needs additional set of clocks, regulators and new set of PCIe QMP
PHY configuration compare other PCIe instances on x1e80100. Hence add
required resource configuration and usage for PCIe3.

v2->v1:
1. Squash [PATCH 1/8], [PATCH 2/8],[PATCH 3/8] into one patch and make the
   indentation consistent.
2. Put dts patch at the end of the patchset.
3. Put dt-binding patch at the first of the patchset.
4. Add a new patch where opp-table is added in dt-binding to avoid dtbs
   checking error.
5. Remove GCC_PCIE_3_AUX_CLK, RPMH_CXO_CLK, put in TCSR_PCIE_8L_CLKREF_EN
   as ref.
6. Remove lane_broadcasting.
7. Add 64 bit bar, Remove GCC_PCIE_3_PIPE_CLK_SRC, 
   GCC_CFG_NOC_PCIE_ANOC_SOUTH_AHB_CLK is changed to
   GCC_CFG_NOC_PCIE_ANOC_NORTH_AHB_CLK.
8. Add Reviewed-by tag.
9. Remove [PATCH 7/8], [PATCH 8/8].

Qiang Yu (5):
  dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the X1E80100
    QMP PCIe PHY Gen4 x8
  dt-bindings: PCI: qcom: Add OPP table for X1E80100
  phy: qcom: qmp: Add phy register and clk setting for x1e80100 PCIe3
  clk: qcom: gcc-x1e80100: Fix halt_check for pipediv2 clocks
  arm64: dts: qcom: x1e80100: Add support for PCIe3 on x1e80100

 .../bindings/pci/qcom,pcie-x1e80100.yaml      |   4 +
 .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml       |   3 +
 arch/arm64/boot/dts/qcom/x1e80100.dtsi        | 202 ++++++++++++++++-
 drivers/clk/qcom/gcc-x1e80100.c               |  10 +-
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c      | 211 ++++++++++++++++++
 .../qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h    |  25 +++
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h |  19 ++
 7 files changed, 468 insertions(+), 6 deletions(-)
 create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
 create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h

-- 
2.34.1



From quic_qianyu at quicinc.com  Fri Sep 13 01:37:24 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Fri, 13 Sep 2024 01:37:24 -0700
Subject: [PATCH v2 5/5] arm64: dts: qcom: x1e80100: Add support for PCIe3 on x1e80100
In-Reply-To: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
Message-ID: <20240913083724.1217691-6-quic_qianyu@quicinc.com>

Describe PCIe3 controller and PHY. Also add required system resources like
regulators, clocks, interrupts and registers configuration for PCIe3.

Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
---
 arch/arm64/boot/dts/qcom/x1e80100.dtsi | 202 ++++++++++++++++++++++++-
 1 file changed, 201 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
index a36076e3c56b..a7703e4974a6 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
+++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
@@ -744,7 +744,7 @@ gcc: clock-controller at 100000 {
 
 			clocks = <&bi_tcxo_div2>,
 				 <&sleep_clk>,
-				 <0>,
+				 <&pcie3_phy>,
 				 <&pcie4_phy>,
 				 <&pcie5_phy>,
 				 <&pcie6a_phy>,
@@ -2907,6 +2907,206 @@ mmss_noc: interconnect at 1780000 {
 			#interconnect-cells = <2>;
 		};
 
+		pcie3: pci at 1bd0000 {
+			device_type = "pci";
+			compatible = "qcom,pcie-x1e80100";
+			reg = <0 0x01bd0000 0 0x3000>,
+			      <0 0x78000000 0 0xf1d>,
+			      <0 0x78000f40 0 0xa8>,
+			      <0 0x78001000 0 0x1000>,
+			      <0 0x78100000 0 0x100000>,
+			      <0 0x01bd3000 0 0x1000>;
+			reg-names = "parf",
+				    "dbi",
+				    "elbi",
+				    "atu",
+				    "config",
+				    "mhi";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x78200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x78300000 0x0 0x78300000 0x0 0x3d00000>,
+				 <0x03000000 0x7 0x40000000 0x7 0x40000000 0x0 0x40000000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <3>;
+			num-lanes = <8>;
+
+			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 769 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 671 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi0",
+					  "msi1",
+					  "msi2",
+					  "msi3",
+					  "msi4",
+					  "msi5",
+					  "msi6",
+					  "msi7";
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &intc 0 0 0 220 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc 0 0 0 221 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc 0 0 0 237 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc 0 0 0 238 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_3_AUX_CLK>,
+				 <&gcc GCC_PCIE_3_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_3_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_3_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_3_SLV_Q2A_AXI_CLK>,
+				 <&gcc GCC_CFG_NOC_PCIE_ANOC_NORTH_AHB_CLK>,
+				 <&gcc GCC_CNOC_PCIE_NORTH_SF_AXI_CLK>;
+			clock-names = "aux",
+				      "cfg",
+				      "bus_master",
+				      "bus_slave",
+				      "slave_q2a",
+				      "noc_aggr",
+				      "cnoc_sf_axi";
+
+			assigned-clocks = <&gcc GCC_PCIE_3_AUX_CLK>;
+			assigned-clock-rates = <19200000>;
+
+			interconnects = <&pcie_south_anoc MASTER_PCIE_3 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+					 &cnoc_main SLAVE_PCIE_3 QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "pcie-mem",
+					     "cpu-pcie";
+
+			resets = <&gcc GCC_PCIE_3_BCR>,
+				 <&gcc GCC_PCIE_3_LINK_DOWN_BCR>;
+			reset-names = "pci",
+				      "link_down";
+
+			power-domains = <&gcc GCC_PCIE_3_GDSC>;
+
+			phys = <&pcie3_phy>;
+			phy-names = "pciephy";
+
+			operating-points-v2 = <&pcie3_opp_table>;
+
+			status = "disabled";
+
+			pcie3_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				/* GEN 1 x1 */
+				opp-2500000 {
+					opp-hz = /bits/ 64 <2500000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <250000 1>;
+				};
+
+				/* GEN 1 x2 and GEN 2 x1 */
+				opp-5000000 {
+					opp-hz = /bits/ 64 <5000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <500000 1>;
+				};
+
+				/* GEN 1 x4 and GEN 2 x2 */
+				opp-10000000 {
+					opp-hz = /bits/ 64 <10000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1000000 1>;
+				};
+
+				/* GEN 1 x8 and GEN 2 x4 */
+				opp-20000000 {
+					opp-hz = /bits/ 64 <20000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <2000000 1>;
+				};
+
+				/* GEN 2 x8 */
+				opp-40000000 {
+					opp-hz = /bits/ 64 <40000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <4000000 1>;
+				};
+
+				/* GEN 3 x1 */
+				opp-8000000 {
+					opp-hz = /bits/ 64 <8000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <984500 1>;
+				};
+
+				/* GEN 3 x2 and GEN 4 x1 */
+				opp-16000000 {
+					opp-hz = /bits/ 64 <16000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <1969000 1>;
+				};
+
+				/* GEN 3 x4 and GEN 4 x2 */
+				opp-32000000 {
+					opp-hz = /bits/ 64 <32000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <3938000 1>;
+				};
+
+				/* GEN 3 x8 and GEN 4 x4 */
+				opp-64000000 {
+					opp-hz = /bits/ 64 <64000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <7876000 1>;
+				};
+
+				/* GEN 4 x8 */
+				opp-128000000 {
+					opp-hz = /bits/ 64 <128000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <15753000 1>;
+				};
+			};
+		};
+
+		pcie3_phy: phy at 1be0000 {
+			compatible = "qcom,x1e80100-qmp-gen4x8-pcie-phy";
+			reg = <0 0x01be0000 0 0x10000>;
+
+			clocks = <&gcc GCC_PCIE_3_PHY_AUX_CLK>,
+				 <&gcc GCC_PCIE_3_CFG_AHB_CLK>,
+				 <&tcsr TCSR_PCIE_8L_CLKREF_EN>,
+				 <&gcc GCC_PCIE_3_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_3_PIPE_CLK>,
+				 <&gcc GCC_PCIE_3_PIPEDIV2_CLK>;
+			clock-names = "aux",
+				      "cfg_ahb",
+				      "ref",
+				      "rchng",
+				      "pipe",
+				      "pipediv2";
+
+			resets = <&gcc GCC_PCIE_3_PHY_BCR>,
+				 <&gcc GCC_PCIE_3_NOCSR_COM_PHY_BCR>;
+			reset-names = "phy",
+				      "phy_nocsr";
+
+			assigned-clocks = <&gcc GCC_PCIE_3_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>;
+
+			power-domains = <&gcc GCC_PCIE_3_PHY_GDSC>;
+
+			#clock-cells = <0>;
+			clock-output-names = "pcie3_pipe_clk";
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
 		pcie6a: pci at 1bf8000 {
 			device_type = "pci";
 			compatible = "qcom,pcie-x1e80100";
-- 
2.34.1



From quic_qianyu at quicinc.com  Fri Sep 13 01:41:00 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Fri, 13 Sep 2024 16:41:00 +0800
Subject: [PATCH 8/8] PCI: qcom: Add support to PCIe slot power supplies
In-Reply-To: <CAA8EJppSFb+Me6w5vUpmbogQ4DS2=15FmHu4nzGz2POWQPouwA@mail.gmail.com>
References: <20240827063631.3932971-1-quic_qianyu@quicinc.com>
 <20240827063631.3932971-9-quic_qianyu@quicinc.com>
 <CAA8EJpq5KergZ8czg4F=EYMLANoOeBsiSVoO-zAgfG0ezQrKCQ@mail.gmail.com>
 <20240827165826.moe6cnemeheos6jn@thinkpad>
 <26f2845f-2e29-4887-9f33-0b5b2a06adb6@quicinc.com>
 <20240911153228.7ajcqicxnu2afhbp@thinkpad>
 <9222ef18-2eef-4ba3-95aa-fae540c06925@quicinc.com>
 <d5468dd2-0f81-4d89-a3bd-a546b2395ca6@kernel.org>
 <20240912144439.fnne4x7qvggveve2@thinkpad>
 <CAA8EJppSFb+Me6w5vUpmbogQ4DS2=15FmHu4nzGz2POWQPouwA@mail.gmail.com>
Message-ID: <0c3347a5-85a0-4f28-a393-58f9653d80c6@quicinc.com>


On 9/12/2024 10:49 PM, Dmitry Baryshkov wrote:
> On Thu, 12 Sept 2024 at 17:45, Manivannan Sadhasivam
> <manivannan.sadhasivam at linaro.org> wrote:
>> On Thu, Sep 12, 2024 at 04:15:56PM +0200, Konrad Dybcio wrote:
>>> On 12.09.2024 3:39 PM, Qiang Yu wrote:
>>>> On 9/11/2024 11:32 PM, Manivannan Sadhasivam wrote:
>>>>> On Wed, Sep 11, 2024 at 04:17:41PM +0800, Qiang Yu wrote:
>>>>>> On 8/28/2024 12:58 AM, Manivannan Sadhasivam wrote:
>>>>>>> On Tue, Aug 27, 2024 at 02:44:09PM +0300, Dmitry Baryshkov wrote:
>>>>>>>> On Tue, 27 Aug 2024 at 09:36, Qiang Yu <quic_qianyu at quicinc.com> wrote:
>>>>>>>>> On platform x1e80100 QCP, PCIe3 is a standard x8 form factor. Hence, add
>>>>>>>>> support to use 3.3v, 3.3v aux and 12v regulators.
>>>>>>>> First of all, I don't see corresponding bindings change.
>>>>>>>>
>>>>>>>> Second, these supplies power up the slot, not the host controller
>>>>>>>> itself. As such these supplies do not belong to the host controller
>>>>>>>> entry. Please consider using the pwrseq framework instead.
>>>>>>>>
>>>>>>> Indeed. For legacy reasons, slot power supplies were populated in the host
>>>>>>> bridge node itself until recently Rob started objecting it [1]. And it makes
>>>>>>> real sense to put these supplies in the root port node and handle them in the
>>>>>>> relevant driver.
>>>>>>>
>>>>>>> I'm still evaluating whether the handling should be done in the portdrv or
>>>>>>> pwrctl driver, but haven't reached the conclusion. Pwrctl seems to be the ideal
>>>>>>> choice, but I see a few issues related to handling the OF node for the root
>>>>>>> port.
>>>>>>>
>>>>>>> Hope I'll come to a conclusion in the next few days and will update this thread.
>>>>>>>
>>>>>>> - Mani
>>>>>>>
>>>>>>> [1] https://lore.kernel.org/lkml/20240604235806.GA1903493-robh at kernel.org/
>>>>>> Hi Mani, do you have any updates?
>>>>>>
>>>>> I'm working with Bartosz to add a new pwrctl driver for rootports. And we are
>>>>> debugging an issue currently. Unfortunately, the progress is very slow as I'm on
>>>>> vacation still.
>>>>>
>>>>> Will post the patches once it got resolved.
>>>>>
>>>>> - Mani
>>>> OK, thanks for your update.
>>> Qiang, you can still resubmit the rest of the patches without having
>>> to wait on that to be resolved
>>>
>> In that case, the slot supplies should be described in the PCIe bridge.
> Patches 1-6 don't seem to depend on slot supplies, so they can be
> submitted separately.
OK, let me send v2 patch. Hi Mani, if you need any supports, please let 
me know.

Thanks,
Qiang
>
>> - Mani
>>
>>> Konrad
>> --
>> ????????? ????????
>
>


From sandor.yu at nxp.com  Fri Sep 13 02:46:12 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Fri, 13 Sep 2024 09:46:12 +0000
Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501
 DP/HDMI driver
In-Reply-To: <20240912-zippy-mongoose-of-domination-2ebc1d@houat>
References: <cover.1719903904.git.Sandor.yu@nxp.com>
 <359914108b879e995d4a39de32a33310009f0fab.1719903904.git.Sandor.yu@nxp.com>
 <20240702-quartz-salamander-of-culture-eec264@houat>
 <PAXPR04MB94480AB0490BBF00D2BA17BBF4932@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <20240903-gay-capable-hound-3cbef2@houat>
 <PAXPR04MB9448EF507CB5C18A43239A80F49E2@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <20240912-zippy-mongoose-of-domination-2ebc1d@houat>
Message-ID: <PAXPR04MB94484D86A71A7527ADD42EA4F4652@PAXPR04MB9448.eurprd04.prod.outlook.com>


> Subject: Re: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501
> DP/HDMI driver
> 
> On Fri, Sep 06, 2024 at 02:50:08AM GMT, Sandor Yu wrote:
> > > On Tue, Sep 03, 2024 at 06:07:25AM GMT, Sandor Yu wrote:
> > > > > -----Original Message-----
> > > > > From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On
> > > > > Behalf Of Maxime Ripard
> > > > > Sent: 2024?7?2? 21:25
> > > > > To: Sandor Yu <sandor.yu at nxp.com>
> > > > > Cc: dmitry.baryshkov at linaro.org; andrzej.hajda at intel.com;
> > > > > neil.armstrong at linaro.org; Laurent Pinchart
> > > > > <laurent.pinchart at ideasonboard.com>; jonas at kwiboo.se;
> > > > > jernej.skrabec at gmail.com; airlied at gmail.com; daniel at ffwll.ch;
> > > > > robh+dt at kernel.org; krzysztof.kozlowski+dt at linaro.org;
> > > > > shawnguo at kernel.org; s.hauer at pengutronix.de;
> festevam at gmail.com;
> > > > > vkoul at kernel.org; dri-devel at lists.freedesktop.org;
> > > > > devicetree at vger.kernel.org;
> > > > > linux-arm-kernel at lists.infradead.org;
> > > > > linux-kernel at vger.kernel.org; linux-phy at lists.infradead.org;
> > > > > kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>; Oliver
> > > > > Brown <oliver.brown at nxp.com>; alexander.stein at ew.tq-group.com;
> > > > > sam at ravnborg.org
> > > > > Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add
> > > > > MHDP8501 DP/HDMI driver
> > > > >
> > > > > Hi,
> > > > >
> > > > > There's still the scrambler issue we discussed on v15, but I
> > > > > have some more comments.
> > > > >
> > > > > On Tue, Jul 02, 2024 at 08:22:36PM GMT, Sandor Yu wrote:
> > > > > > +enum drm_connector_status cdns_mhdp8501_detect(struct
> > > > > > +cdns_mhdp8501_device *mhdp) {
> > > > > > +	u8 hpd = 0xf;
> > > > > > +
> > > > > > +	hpd = cdns_mhdp8501_read_hpd(mhdp);
> > > > > > +	if (hpd == 1)
> > > > > > +		return connector_status_connected;
> > > > > > +	else if (hpd == 0)
> > > > > > +		return connector_status_disconnected;
> > > > > > +
> > > > > > +	dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n",
> hpd);
> > > > > > +	return connector_status_unknown; }
> > > > > > +
> > > > > > +static void hotplug_work_func(struct work_struct *work) {
> > > > > > +	struct cdns_mhdp8501_device *mhdp = container_of(work,
> > > > > > +						     struct cdns_mhdp8501_device,
> > > > > > +						     hotplug_work.work);
> > > > > > +	enum drm_connector_status status =
> > > cdns_mhdp8501_detect(mhdp);
> > > > > > +
> > > > > > +	drm_bridge_hpd_notify(&mhdp->bridge, status);
> > > > > > +
> > > > > > +	if (status == connector_status_connected) {
> > > > > > +		/* Cable connected  */
> > > > > > +		DRM_INFO("HDMI/DP Cable Plug In\n");
> > > > > > +		enable_irq(mhdp->irq[IRQ_OUT]);
> > > > > > +	} else if (status == connector_status_disconnected) {
> > > > > > +		/* Cable Disconnected  */
> > > > > > +		DRM_INFO("HDMI/DP Cable Plug Out\n");
> > > > > > +		enable_irq(mhdp->irq[IRQ_IN]);
> > > > > > +	}
> > > > > > +}
> > > > >
> > > > > You shouldn't play with the interrupt being enabled here:
> > > > > hotplug interrupts should always enabled.
> > > > >
> > > > > If you can't for some reason, the reason should be documented in
> > > > > your
> > > driver.
> > > >
> > > > iMX8MQ have two HPD interrupters, one for plugout and the other
> > > > for plugin, because they could not be masked, so we have to enable
> > > > one and
> > > disable the other.
> > > > I will add more comments here.
> > >
> > > Right, but why do you need to enable and disable them? Do you get
> > > spurious interrupts?
> >
> > They don't have status registers and cannot be masked. If they are not
> > disabled, they will continuously generate interrupts. Therefore, I have to
> disable one and enable the other.
> 
> Sorry, I still don't get it. How can it be useful to detect hotplug interrupts if it
> constantly sends spurious interrupts when it's enabled?

Yes, this interrupt is different from a normal one; it's likely a design flaw. 
For instance, the plugin interrupt is continuously generated as long as the cable is plugged in,
only stopping when the cable is unplugged. 
That's why two interrupts are used to detect cable plugout and plugin separately. 
If interrupts aren't used, the only option is polling.

> 
> > > > > > +	/* Mailbox protect for HDMI PHY access */
> > > > > > +	mutex_lock(&mhdp->mbox_mutex);
> > > > > > +	ret = phy_init(mhdp->phy);
> > > > > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > > > > +	if (ret) {
> > > > > > +		dev_err(dev, "Failed to initialize PHY: %d\n", ret);
> > > > > > +		goto clk_disable;
> > > > > > +	}
> > > > > > +
> > > > > > +	/* Mailbox protect for HDMI PHY access */
> > > > > > +	mutex_lock(&mhdp->mbox_mutex);
> > > > > > +	ret = phy_set_mode(mhdp->phy, phy_mode);
> > > > > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > > > > +	if (ret) {
> > > > > > +		dev_err(dev, "Failed to configure PHY: %d\n", ret);
> > > > > > +		goto clk_disable;
> > > > > > +	}
> > > > >
> > > > > Why do you need a shared mutex between the phy and HDMI
> controller?
> > > >
> > > > Both PHY and HDMI controller could access to the HDMI firmware by
> > > > mailbox, So add mutex to avoid race condition.
> > >
> > > That should be handled at either the phy or mailbox level, not in
> > > your hdmi driver.
> >
> > In both HDMI driver and PHY driver, every mailbox access had protected
> > by its owns mutex. However, this mutex can only protect each mailbox
> > access within their respective drivers, and it cannot provide
> > protection for access between the HDMI and PHY drivers.
> >
> > The PHY driver only provides two API functions, and these functions
> > are only called in the HDMI driver. Therefore, when accessing these
> > functions, we use a mutex to protect them. This ensures that mailbox
> > access is protected across different PHY and HDMI drivers.
> 
> It's really about abstraction. You're using a publicly defined API, and change
> the semantics for your driver only, and that's not ok.
> 
> Why can't the mailbox driver itself serialize the accesses from any user, HDMI
> and PHY drivers included?
> 

In the current code implementation, cdns-mhdp-helper.c isn't a standalone driver but rather a library. 
It provides fundamental mailbox access functions and basic register read/write operations that rely on the mailbox. 
These functions are highly reusable across MHDP8501 and MHDP8546 and can be leveraged by future MHDP versions.

However, most MHDP firmware interactions involve a sequence of mailbox accesses, including sending commands and receiving firmware responses. 
These commands constitute a significant portion of all firmware interactions, encompassing operations like EDID reading and DP link training. 
Unfortunately, these commands cannot be reused between MHDP8501 and MHDP8546.

Creating a dedicated mailbox driver with its own mutex would effectively address race conditions. 
However, this would necessitate relocating all mailbox-related functions to this driver. 
Including these non-reusable functions would defeat the purpose of code reuse.

To strike a balance between code reusability and race condition mitigation, adding mutexes to PHY access functions seems like a reasonable solution.

Sandor

> > > > >
> > > > > > +static enum drm_mode_status
> > > > > > +cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
> > > > > > +			       const struct drm_display_mode *mode,
> > > > > > +			       unsigned long long tmds_rate) {
> > > > > > +	struct cdns_mhdp8501_device *mhdp =
> bridge->driver_private;
> > > > > > +	union phy_configure_opts phy_cfg;
> > > > > > +	int ret;
> > > > > > +
> > > > > > +	phy_cfg.hdmi.tmds_char_rate = tmds_rate;
> > > > > > +
> > > > > > +	/* Mailbox protect for HDMI PHY access */
> > > > > > +	mutex_lock(&mhdp->mbox_mutex);
> > > > > > +	ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0,
> &phy_cfg);
> > > > > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > > > > +	if (ret < 0)
> > > > > > +		return MODE_CLOCK_RANGE;
> > > > > > +
> > > > > > +	return MODE_OK;
> > > > > > +}
> > > > > > +
> > > > > > +static enum drm_mode_status
> > > > > > +cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
> > > > > > +			    const struct drm_display_info *info,
> > > > > > +			    const struct drm_display_mode *mode) {
> > > > > > +	unsigned long long tmds_rate;
> > > > > > +
> > > > > > +	/* We don't support double-clocked and Interlaced modes */
> > > > > > +	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
> > > > > > +	    mode->flags & DRM_MODE_FLAG_INTERLACE)
> > > > > > +		return MODE_BAD;
> > > > > > +
> > > > > > +	/* MAX support pixel clock rate 594MHz */
> > > > > > +	if (mode->clock > 594000)
> > > > > > +		return MODE_CLOCK_HIGH;
> > > > >
> > > > > This needs to be in the tmds_char_rate_valid function
> > > > This clock rate check is covered by function
> > > > tmds_char_rate_valid() It could be removed if keep function
> > > > tmds_char_rate_valid() be called by
> > > mode_valid.
> > >
> > > Yeah, it's not something you should have to duplicate.
> > >
> > > > >
> > > > > > +	if (mode->hdisplay > 3840)
> > > > > > +		return MODE_BAD_HVALUE;
> > > > > > +
> > > > > > +	if (mode->vdisplay > 2160)
> > > > > > +		return MODE_BAD_VVALUE;
> > > > > > +
> > > > > > +	tmds_rate = mode->clock * 1000ULL;
> > > > > > +	return cdns_hdmi_tmds_char_rate_valid(bridge, mode,
> > > > > > +tmds_rate);
> > > > >
> > > > > It will already be called by the core so this is redundant.
> > > >
> > > > mode_valid function is use to filter the mode list in
> > > > drm_helper_probe_single_connector_modes(),
> > > > if function cdns_hdmi_tmds_char_rate_valid() is not called,
> > > > unsupported
> > > modes will in mode list.
> > >
> > > It's probably something we should deal with in the core somehow. I'm
> > > not entirely sure how to reconcile drm_bridge_connector and the hdmi
> > > framework there, but we should at the very least provide a
> > > mode_valid helper for bridges.
> >
> > I agree with that. In fact, I'm a bit confused about the current
> > mode_valid and tmds_char_rate_valid functions. Ideally, we should find
> > a way to make tmds_char_rate_valid also work for filtering out the
> > mode list, rather than just during atomic_check.
> 
> Yeah, definitely. The way we did so on vc4 for example was to compute the
> rate for a 8bpc, RGB, output and try to validate that. I think it would be
> reasonable to start with that.
> 
> Maxime

From quic_mukhopad at quicinc.com  Fri Sep 13 03:37:51 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Fri, 13 Sep 2024 16:07:51 +0530
Subject: [PATCH v2 1/5] dt-bindings: phy: Add eDP PHY compatible for sa8775p
In-Reply-To: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
Message-ID: <20240913103755.7290-2-quic_mukhopad@quicinc.com>

Add compatible string for the supported eDP PHY on sa8775p platform.

Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
v2: No change
 
---
 Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
index 4e15d90d08b0..293fb6a9b1c3 100644
--- a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
@@ -17,6 +17,7 @@ description:
 properties:
   compatible:
     enum:
+      - qcom,sa8775p-edp-phy
       - qcom,sc7280-edp-phy
       - qcom,sc8180x-edp-phy
       - qcom,sc8280xp-dp-phy
-- 
2.17.1



From quic_mukhopad at quicinc.com  Fri Sep 13 03:37:52 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Fri, 13 Sep 2024 16:07:52 +0530
Subject: [PATCH v2 2/5] phy: qcom: edp: Introduce aux_cfg array for version specific aux settings
In-Reply-To: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
Message-ID: <20240913103755.7290-3-quic_mukhopad@quicinc.com>

In order to support different HW versions, introduce aux_cfg array
to move v4 specific aux configuration settings.

Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
v2: Fixed review comments from Bjorn and Dmitry
	- Made aux_cfg array as const.

---
 drivers/phy/qualcomm/phy-qcom-edp.c | 37 ++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
index da2b32fb5b45..bcd5aced9e06 100644
--- a/drivers/phy/qualcomm/phy-qcom-edp.c
+++ b/drivers/phy/qualcomm/phy-qcom-edp.c
@@ -90,6 +90,7 @@ struct phy_ver_ops {
 
 struct qcom_edp_phy_cfg {
 	bool is_edp;
+	const u8 *aux_cfg;
 	const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
 	const struct phy_ver_ops *ver_ops;
 };
@@ -186,11 +187,15 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
 	.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
 };
 
+static const u8 edp_phy_aux_cfg_v4[10] = {
+	0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
+};
+
 static int qcom_edp_phy_init(struct phy *phy)
 {
 	struct qcom_edp *edp = phy_get_drvdata(phy);
+	u8 aux_cfg[10];
 	int ret;
-	u8 cfg8;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
 	if (ret)
@@ -200,6 +205,8 @@ static int qcom_edp_phy_init(struct phy *phy)
 	if (ret)
 		goto out_disable_supplies;
 
+	memcpy(aux_cfg, edp->cfg->aux_cfg, sizeof(aux_cfg));
+
 	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
 	       DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
 	       edp->edp + DP_PHY_PD_CTL);
@@ -222,22 +229,20 @@ static int qcom_edp_phy_init(struct phy *phy)
 	 * even needed.
 	 */
 	if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
-		cfg8 = 0xb7;
-	else
-		cfg8 = 0x37;
+		aux_cfg[8] = 0xb7;
 
 	writel(0xfc, edp->edp + DP_PHY_MODE);
 
-	writel(0x00, edp->edp + DP_PHY_AUX_CFG0);
-	writel(0x13, edp->edp + DP_PHY_AUX_CFG1);
-	writel(0x24, edp->edp + DP_PHY_AUX_CFG2);
-	writel(0x00, edp->edp + DP_PHY_AUX_CFG3);
-	writel(0x0a, edp->edp + DP_PHY_AUX_CFG4);
-	writel(0x26, edp->edp + DP_PHY_AUX_CFG5);
-	writel(0x0a, edp->edp + DP_PHY_AUX_CFG6);
-	writel(0x03, edp->edp + DP_PHY_AUX_CFG7);
-	writel(cfg8, edp->edp + DP_PHY_AUX_CFG8);
-	writel(0x03, edp->edp + DP_PHY_AUX_CFG9);
+	writel(aux_cfg[0], edp->edp + DP_PHY_AUX_CFG0);
+	writel(aux_cfg[1], edp->edp + DP_PHY_AUX_CFG1);
+	writel(aux_cfg[2], edp->edp + DP_PHY_AUX_CFG2);
+	writel(aux_cfg[3], edp->edp + DP_PHY_AUX_CFG3);
+	writel(aux_cfg[4], edp->edp + DP_PHY_AUX_CFG4);
+	writel(aux_cfg[5], edp->edp + DP_PHY_AUX_CFG5);
+	writel(aux_cfg[6], edp->edp + DP_PHY_AUX_CFG6);
+	writel(aux_cfg[7], edp->edp + DP_PHY_AUX_CFG7);
+	writel(aux_cfg[8], edp->edp + DP_PHY_AUX_CFG8);
+	writel(aux_cfg[9], edp->edp + DP_PHY_AUX_CFG9);
 
 	writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
 	       PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
@@ -519,16 +524,19 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
 };
 
 static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
+	.aux_cfg = edp_phy_aux_cfg_v4,
 	.ver_ops = &qcom_edp_phy_ops_v4,
 };
 
 static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
+	.aux_cfg = edp_phy_aux_cfg_v4,
 	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
 	.ver_ops = &qcom_edp_phy_ops_v4,
 };
 
 static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
 	.is_edp = true,
+	.aux_cfg = edp_phy_aux_cfg_v4,
 	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
 	.ver_ops = &qcom_edp_phy_ops_v4,
 };
@@ -707,6 +715,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
 };
 
 static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
+	.aux_cfg = edp_phy_aux_cfg_v4,
 	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
 	.ver_ops = &qcom_edp_phy_ops_v6,
 };
-- 
2.17.1



From quic_mukhopad at quicinc.com  Fri Sep 13 03:37:53 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Fri, 13 Sep 2024 16:07:53 +0530
Subject: [PATCH v2 3/5] phy: qcom: edp: Add support for eDP PHY on SA8775P
In-Reply-To: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
Message-ID: <20240913103755.7290-4-quic_mukhopad@quicinc.com>

Add support for eDP PHY v5 found on the Qualcomm SA8775P platform.

Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
v2: Fixed review comments from Dmitry
	- Reused edp_swing_hbr_rbr and edp_swing_hbr2_hbr3 for v5.

---
 drivers/phy/qualcomm/phy-qcom-edp.c | 33 +++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
index bcd5aced9e06..5e3053ccced1 100644
--- a/drivers/phy/qualcomm/phy-qcom-edp.c
+++ b/drivers/phy/qualcomm/phy-qcom-edp.c
@@ -191,6 +191,31 @@ static const u8 edp_phy_aux_cfg_v4[10] = {
 	0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
 };
 
+static const u8 edp_pre_emp_hbr_rbr_v5[4][4] = {
+	{ 0x05, 0x11, 0x17, 0x1d },
+	{ 0x05, 0x11, 0x18, 0xff },
+	{ 0x06, 0x11, 0xff, 0xff },
+	{ 0x00, 0xff, 0xff, 0xff }
+};
+
+static const u8 edp_pre_emp_hbr2_hbr3_v5[4][4] = {
+	{ 0x0c, 0x15, 0x19, 0x1e },
+	{ 0x0b, 0x15, 0x19, 0xff },
+	{ 0x0e, 0x14, 0xff, 0xff },
+	{ 0x0d, 0xff, 0xff, 0xff }
+};
+
+static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v5 = {
+	.swing_hbr_rbr = &edp_swing_hbr_rbr,
+	.swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3,
+	.pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr_v5,
+	.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v5,
+};
+
+static const u8 edp_phy_aux_cfg_v5[10] = {
+	0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
+};
+
 static int qcom_edp_phy_init(struct phy *phy)
 {
 	struct qcom_edp *edp = phy_get_drvdata(phy);
@@ -523,6 +548,13 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
 	.com_configure_ssc	= qcom_edp_com_configure_ssc_v4,
 };
 
+static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
+	.is_edp = false,
+	.aux_cfg = edp_phy_aux_cfg_v5,
+	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5,
+	.ver_ops = &qcom_edp_phy_ops_v4,
+};
+
 static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
 	.aux_cfg = edp_phy_aux_cfg_v4,
 	.ver_ops = &qcom_edp_phy_ops_v4,
@@ -1117,6 +1149,7 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id qcom_edp_phy_match_table[] = {
+	{ .compatible = "qcom,sa8775p-edp-phy", .data = &sa8775p_dp_phy_cfg, },
 	{ .compatible = "qcom,sc7280-edp-phy", .data = &sc7280_dp_phy_cfg, },
 	{ .compatible = "qcom,sc8180x-edp-phy", .data = &sc7280_dp_phy_cfg, },
 	{ .compatible = "qcom,sc8280xp-dp-phy", .data = &sc8280xp_dp_phy_cfg, },
-- 
2.17.1



From quic_mukhopad at quicinc.com  Fri Sep 13 03:37:55 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Fri, 13 Sep 2024 16:07:55 +0530
Subject: [PATCH v2 5/5] drm/msm/dp: Add DisplayPort controller for SA8775P
In-Reply-To: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
Message-ID: <20240913103755.7290-6-quic_mukhopad@quicinc.com>

The Qualcomm SA8775P platform comes with a DisplayPort controller
with a different base offset than the previous SoCs,
add support for this in the DisplayPort driver.

Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
v2: No change

---
 drivers/gpu/drm/msm/dp/dp_display.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index e1228fb093ee..e4954fd99eb0 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -118,6 +118,12 @@ struct msm_dp_desc {
 	bool wide_bus_supported;
 };
 
+static const struct msm_dp_desc sa8775p_dp_descs[] = {
+	{ .io_start = 0xaf54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{ .io_start = 0xaf5c000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
+	{}
+};
+
 static const struct msm_dp_desc sc7180_dp_descs[] = {
 	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
 	{}
@@ -162,6 +168,7 @@ static const struct msm_dp_desc x1e80100_dp_descs[] = {
 };
 
 static const struct of_device_id dp_dt_match[] = {
+	{ .compatible = "qcom,sa8775p-dp", .data = &sa8775p_dp_descs },
 	{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
 	{ .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
 	{ .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_descs },
-- 
2.17.1



From quic_mukhopad at quicinc.com  Fri Sep 13 03:37:54 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Fri, 13 Sep 2024 16:07:54 +0530
Subject: [PATCH v2 4/5] dt-bindings: display: msm: dp-controller: document SA8775P compatible
In-Reply-To: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
Message-ID: <20240913103755.7290-5-quic_mukhopad@quicinc.com>

Add compatible string for the DisplayPort controller found on the
Qualcomm SA8775P platform.

Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
v2: No change

---
 Documentation/devicetree/bindings/display/msm/dp-controller.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index 97993feda193..a212f335d5ff 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -17,6 +17,7 @@ properties:
   compatible:
     oneOf:
       - enum:
+          - qcom,sa8775p-dp
           - qcom,sc7180-dp
           - qcom,sc7280-dp
           - qcom,sc7280-edp
-- 
2.17.1



From quic_mukhopad at quicinc.com  Fri Sep 13 03:37:50 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Fri, 13 Sep 2024 16:07:50 +0530
Subject: [PATCH v2 0/5] Add support for DisplayPort on SA8775P platform
Message-ID: <20240913103755.7290-1-quic_mukhopad@quicinc.com>

This series adds support for the DisplayPort controller
and eDP PHY v5 found on the Qualcomm SA8775P platform.

---
v2: Fixed review comments from Dmitry and Bjorn
	- Made aux_cfg array as const.
	- Reused edp_swing_hbr_rbr and edp_swing_hbr2_hbr3 for v5.
	 
---
Soutrik Mukhopadhyay (5):
  dt-bindings: phy: Add eDP PHY compatible for sa8775p
  phy: qcom: edp: Introduce aux_cfg array for version specific aux
    settings
  phy: qcom: edp: Add support for eDP PHY on SA8775P
  dt-bindings: display: msm: dp-controller: document SA8775P compatible
  drm/msm/dp: Add DisplayPort controller for SA8775P

 .../bindings/display/msm/dp-controller.yaml   |  1 +
 .../devicetree/bindings/phy/qcom,edp-phy.yaml |  1 +
 drivers/gpu/drm/msm/dp/dp_display.c           |  7 ++
 drivers/phy/qualcomm/phy-qcom-edp.c           | 70 +++++++++++++++----
 4 files changed, 65 insertions(+), 14 deletions(-)

-- 
2.17.1



From dmitry.baryshkov at linaro.org  Fri Sep 13 04:42:56 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 13 Sep 2024 14:42:56 +0300
Subject: [PATCH v2 2/5] phy: qcom: edp: Introduce aux_cfg array for
 version specific aux settings
In-Reply-To: <20240913103755.7290-3-quic_mukhopad@quicinc.com>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com> <20240913103755.7290-3-quic_mukhopad@quicinc.com>
Message-ID: <CAA8EJppddLmzJ9WSkLLr-nwM-qe647Sm6jV8SpHdB=0vRQT-=Q@mail.gmail.com>

On Fri, 13 Sept 2024 at 13:38, Soutrik Mukhopadhyay
<quic_mukhopad at quicinc.com> wrote:
>
> In order to support different HW versions, introduce aux_cfg array
> to move v4 specific aux configuration settings.
>
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
> v2: Fixed review comments from Bjorn and Dmitry
>         - Made aux_cfg array as const.
>
> ---
>  drivers/phy/qualcomm/phy-qcom-edp.c | 37 ++++++++++++++++++-----------
>  1 file changed, 23 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> index da2b32fb5b45..bcd5aced9e06 100644
> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> @@ -90,6 +90,7 @@ struct phy_ver_ops {
>
>  struct qcom_edp_phy_cfg {
>         bool is_edp;
> +       const u8 *aux_cfg;
>         const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
>         const struct phy_ver_ops *ver_ops;
>  };
> @@ -186,11 +187,15 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
>         .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
>  };
>
> +static const u8 edp_phy_aux_cfg_v4[10] = {
> +       0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
> +};
> +
>  static int qcom_edp_phy_init(struct phy *phy)
>  {
>         struct qcom_edp *edp = phy_get_drvdata(phy);
> +       u8 aux_cfg[10];

Please define 10, so that there are no magic numbers (and less chance
of damaging the stack if it gets changed in one place only.

>         int ret;
> -       u8 cfg8;
>
>         ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
>         if (ret)
> @@ -200,6 +205,8 @@ static int qcom_edp_phy_init(struct phy *phy)
>         if (ret)
>                 goto out_disable_supplies;
>
> +       memcpy(aux_cfg, edp->cfg->aux_cfg, sizeof(aux_cfg));
> +
>         writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
>                DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
>                edp->edp + DP_PHY_PD_CTL);
> @@ -222,22 +229,20 @@ static int qcom_edp_phy_init(struct phy *phy)
>          * even needed.
>          */
>         if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
> -               cfg8 = 0xb7;
> -       else
> -               cfg8 = 0x37;
> +               aux_cfg[8] = 0xb7;
>
>         writel(0xfc, edp->edp + DP_PHY_MODE);
>
> -       writel(0x00, edp->edp + DP_PHY_AUX_CFG0);
> -       writel(0x13, edp->edp + DP_PHY_AUX_CFG1);
> -       writel(0x24, edp->edp + DP_PHY_AUX_CFG2);
> -       writel(0x00, edp->edp + DP_PHY_AUX_CFG3);
> -       writel(0x0a, edp->edp + DP_PHY_AUX_CFG4);
> -       writel(0x26, edp->edp + DP_PHY_AUX_CFG5);
> -       writel(0x0a, edp->edp + DP_PHY_AUX_CFG6);
> -       writel(0x03, edp->edp + DP_PHY_AUX_CFG7);
> -       writel(cfg8, edp->edp + DP_PHY_AUX_CFG8);
> -       writel(0x03, edp->edp + DP_PHY_AUX_CFG9);
> +       writel(aux_cfg[0], edp->edp + DP_PHY_AUX_CFG0);
> +       writel(aux_cfg[1], edp->edp + DP_PHY_AUX_CFG1);
> +       writel(aux_cfg[2], edp->edp + DP_PHY_AUX_CFG2);
> +       writel(aux_cfg[3], edp->edp + DP_PHY_AUX_CFG3);
> +       writel(aux_cfg[4], edp->edp + DP_PHY_AUX_CFG4);
> +       writel(aux_cfg[5], edp->edp + DP_PHY_AUX_CFG5);
> +       writel(aux_cfg[6], edp->edp + DP_PHY_AUX_CFG6);
> +       writel(aux_cfg[7], edp->edp + DP_PHY_AUX_CFG7);
> +       writel(aux_cfg[8], edp->edp + DP_PHY_AUX_CFG8);
> +       writel(aux_cfg[9], edp->edp + DP_PHY_AUX_CFG9);

Replace this with a loop?

>
>         writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
>                PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
> @@ -519,16 +524,19 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
>  };
>
>  static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
> +       .aux_cfg = edp_phy_aux_cfg_v4,
>         .ver_ops = &qcom_edp_phy_ops_v4,
>  };
>
>  static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
> +       .aux_cfg = edp_phy_aux_cfg_v4,
>         .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
>         .ver_ops = &qcom_edp_phy_ops_v4,
>  };
>
>  static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
>         .is_edp = true,
> +       .aux_cfg = edp_phy_aux_cfg_v4,
>         .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
>         .ver_ops = &qcom_edp_phy_ops_v4,
>  };
> @@ -707,6 +715,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
>  };
>
>  static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
> +       .aux_cfg = edp_phy_aux_cfg_v4,
>         .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
>         .ver_ops = &qcom_edp_phy_ops_v6,
>  };
> --
> 2.17.1
>


-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Fri Sep 13 04:44:06 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 13 Sep 2024 14:44:06 +0300
Subject: [PATCH v2 5/5] drm/msm/dp: Add DisplayPort controller for SA8775P
In-Reply-To: <20240913103755.7290-6-quic_mukhopad@quicinc.com>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com> <20240913103755.7290-6-quic_mukhopad@quicinc.com>
Message-ID: <CAA8EJpqyr0b4zUZ3h+bTASru74fm1U9LGJkpqcQhEChH2EexXQ@mail.gmail.com>

On Fri, 13 Sept 2024 at 13:38, Soutrik Mukhopadhyay
<quic_mukhopad at quicinc.com> wrote:
>
> The Qualcomm SA8775P platform comes with a DisplayPort controller
> with a different base offset than the previous SoCs,
> add support for this in the DisplayPort driver.
>
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
> v2: No change
>
> ---
>  drivers/gpu/drm/msm/dp/dp_display.c | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> index e1228fb093ee..e4954fd99eb0 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -118,6 +118,12 @@ struct msm_dp_desc {
>         bool wide_bus_supported;
>  };
>
> +static const struct msm_dp_desc sa8775p_dp_descs[] = {
> +       { .io_start = 0xaf54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
> +       { .io_start = 0xaf5c000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },

Please wait for the discussion to end before posting new iterations.
In this case Bjorn pointed out that this is not the full
configuration. Please add a comment, describing that there is a second
MDSS, which isn't declared here as it wasn't validated.

> +       {}
> +};
> +
>  static const struct msm_dp_desc sc7180_dp_descs[] = {
>         { .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
>         {}
> @@ -162,6 +168,7 @@ static const struct msm_dp_desc x1e80100_dp_descs[] = {
>  };
>
>  static const struct of_device_id dp_dt_match[] = {
> +       { .compatible = "qcom,sa8775p-dp", .data = &sa8775p_dp_descs },
>         { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
>         { .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
>         { .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_descs },
> --
> 2.17.1
>


-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Fri Sep 13 05:28:40 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 13 Sep 2024 15:28:40 +0300
Subject: [PATCH v2 3/5] phy: qcom: qmp: Add phy register and clk setting
 for x1e80100 PCIe3
In-Reply-To: <20240913083724.1217691-4-quic_qianyu@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-4-quic_qianyu@quicinc.com>
Message-ID: <tkt6ox75xsbqhbopgi2dkexvubpmuizuzeyy5hkdv7si7jljzq@x3tgbepgxeni>

On Fri, Sep 13, 2024 at 01:37:22AM GMT, Qiang Yu wrote:
> Currently driver supports only x4 lane based functionality using tx/rx and
> tx2/rx2 pair of register sets. To support 8 lane functionality with PCIe3,
> PCIe3 related QMP PHY provides additional programming which are available
> as txz and rxz based register set. Hence adds txz and rxz based registers
> usage and programming sequences. Phy register setting for txz and rxz will
> be applied to all 8 lanes. Some lanes may have different settings on
> several registers than txz/rxz, these registers should be programmed after
> txz/rxz programming sequences completing.
> 
> Besides, x1e80100 SoC uses QMP phy with version v6.30 for PCIe Gen4 x8.
> Add the new register offsets in a dedicated header file.
> 
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c      | 211 ++++++++++++++++++
>  .../qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h    |  25 +++
>  drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h |  19 ++
>  3 files changed, 255 insertions(+)
>  create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
>  create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Fri Sep 13 05:30:59 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 13 Sep 2024 15:30:59 +0300
Subject: [PATCH v2 2/5] dt-bindings: PCI: qcom: Add OPP table for X1E80100
In-Reply-To: <20240913083724.1217691-3-quic_qianyu@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-3-quic_qianyu@quicinc.com>
Message-ID: <tf4z475uqjenohdgqj4ltoty3j3gopxnbdhrrn6zo3ug5yuvyq@us2nysv2ggxh>

On Fri, Sep 13, 2024 at 01:37:21AM GMT, Qiang Yu wrote:
> Add OPP table so that PCIe is able to adjust power domain performance
> state and ICC peak bw according to PCIe gen speed and link width.
> 
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> ---
>  Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
> index a9db0a231563..e2d6719ca54d 100644
> --- a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
> +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
> @@ -70,6 +70,10 @@ properties:
>        - const: pci # PCIe core reset
>        - const: link_down # PCIe link down reset
>  
> +  operating-points-v2: true
> +  opp-table:
> +    type: object

I think these properties are generic enough and we might want to have
them for most if not all platforms. Maybe we should move them to
qcom,pcie-common.yaml?

Krzysztof, Mani, WDYT?

> +
>  allOf:
>    - $ref: qcom,pcie-common.yaml#
>  
> -- 
> 2.34.1
> 
> 
> -- 
> linux-phy mailing list
> linux-phy at lists.infradead.org
> https://lists.infradead.org/mailman/listinfo/linux-phy

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Fri Sep 13 05:35:30 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 13 Sep 2024 15:35:30 +0300
Subject: [PATCH v2 5/5] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <20240913083724.1217691-6-quic_qianyu@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-6-quic_qianyu@quicinc.com>
Message-ID: <bizip6exhqdm34fhdw7dvqws4oqgexp2f2lp2zxoblqu2zfupi@t33svola3tq4>

On Fri, Sep 13, 2024 at 01:37:24AM GMT, Qiang Yu wrote:
> Describe PCIe3 controller and PHY. Also add required system resources like
> regulators, clocks, interrupts and registers configuration for PCIe3.
> 
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> ---
>  arch/arm64/boot/dts/qcom/x1e80100.dtsi | 202 ++++++++++++++++++++++++-
>  1 file changed, 201 insertions(+), 1 deletion(-)

I didn't verify the addresses, the rest LGTM

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Fri Sep 13 05:35:56 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 13 Sep 2024 15:35:56 +0300
Subject: [PATCH v2 3/5] phy: qcom: edp: Add support for eDP PHY on SA8775P
In-Reply-To: <20240913103755.7290-4-quic_mukhopad@quicinc.com>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
 <20240913103755.7290-4-quic_mukhopad@quicinc.com>
Message-ID: <f6pyasnn34ufvrphfwiskkk75nuzbcjxqz2uuurk3wujubfaal@nyktpvjiaonn>

On Fri, Sep 13, 2024 at 04:07:53PM GMT, Soutrik Mukhopadhyay wrote:
> Add support for eDP PHY v5 found on the Qualcomm SA8775P platform.
> 
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
> v2: Fixed review comments from Dmitry
> 	- Reused edp_swing_hbr_rbr and edp_swing_hbr2_hbr3 for v5.
> 
> ---
>  drivers/phy/qualcomm/phy-qcom-edp.c | 33 +++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From manivannan.sadhasivam at linaro.org  Fri Sep 13 06:36:19 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Fri, 13 Sep 2024 19:06:19 +0530
Subject: [PATCH v2 2/5] dt-bindings: PCI: qcom: Add OPP table for X1E80100
In-Reply-To: <tf4z475uqjenohdgqj4ltoty3j3gopxnbdhrrn6zo3ug5yuvyq@us2nysv2ggxh>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-3-quic_qianyu@quicinc.com>
 <tf4z475uqjenohdgqj4ltoty3j3gopxnbdhrrn6zo3ug5yuvyq@us2nysv2ggxh>
Message-ID: <20240913133619.z7cc4whhpvs2uecb@thinkpad>

On Fri, Sep 13, 2024 at 03:30:59PM +0300, Dmitry Baryshkov wrote:
> On Fri, Sep 13, 2024 at 01:37:21AM GMT, Qiang Yu wrote:
> > Add OPP table so that PCIe is able to adjust power domain performance
> > state and ICC peak bw according to PCIe gen speed and link width.
> > 
> > Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> > ---
> >  Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml | 4 ++++
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
> > index a9db0a231563..e2d6719ca54d 100644
> > --- a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
> > +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
> > @@ -70,6 +70,10 @@ properties:
> >        - const: pci # PCIe core reset
> >        - const: link_down # PCIe link down reset
> >  
> > +  operating-points-v2: true
> > +  opp-table:
> > +    type: object
> 
> I think these properties are generic enough and we might want to have
> them for most if not all platforms. Maybe we should move them to
> qcom,pcie-common.yaml?
> 

Agree. It should be moved to qcom,pcie-common.yaml.

- Mani

> Krzysztof, Mani, WDYT?
> 
> > +
> >  allOf:
> >    - $ref: qcom,pcie-common.yaml#
> >  
> > -- 
> > 2.34.1
> > 
> > 
> > -- 
> > linux-phy mailing list
> > linux-phy at lists.infradead.org
> > https://lists.infradead.org/mailman/listinfo/linux-phy
> 
> -- 
> With best wishes
> Dmitry

-- 
????????? ????????


From manivannan.sadhasivam at linaro.org  Fri Sep 13 06:37:51 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Fri, 13 Sep 2024 19:07:51 +0530
Subject: [PATCH v2 1/5] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document the X1E80100 QMP PCIe PHY Gen4 x8
In-Reply-To: <20240913083724.1217691-2-quic_qianyu@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-2-quic_qianyu@quicinc.com>
Message-ID: <20240913133751.2yegqbobvfzbogxc@thinkpad>

On Fri, Sep 13, 2024 at 01:37:20AM -0700, Qiang Yu wrote:
> PCIe 3rd instance of X1E80100 support Gen 4x8 which needs different 8 lane
> capable QMP PCIe PHY. Document Gen 4x8 PHY as separate module.
> 

Nit: please use 'Gen 4 x8'

- Mani

> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> ---
>  .../devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml    | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> index dcf4fa55fbba..680ec3113c2b 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> @@ -41,6 +41,7 @@ properties:
>        - qcom,x1e80100-qmp-gen3x2-pcie-phy
>        - qcom,x1e80100-qmp-gen4x2-pcie-phy
>        - qcom,x1e80100-qmp-gen4x4-pcie-phy
> +      - qcom,x1e80100-qmp-gen4x8-pcie-phy
>  
>    reg:
>      minItems: 1
> @@ -172,6 +173,7 @@ allOf:
>                - qcom,sc8280xp-qmp-gen3x2-pcie-phy
>                - qcom,sc8280xp-qmp-gen3x4-pcie-phy
>                - qcom,x1e80100-qmp-gen4x4-pcie-phy
> +              - qcom,x1e80100-qmp-gen4x8-pcie-phy
>      then:
>        properties:
>          clocks:
> @@ -201,6 +203,7 @@ allOf:
>                - qcom,sm8550-qmp-gen4x2-pcie-phy
>                - qcom,sm8650-qmp-gen4x2-pcie-phy
>                - qcom,x1e80100-qmp-gen4x2-pcie-phy
> +              - qcom,x1e80100-qmp-gen4x8-pcie-phy
>      then:
>        properties:
>          resets:
> -- 
> 2.34.1
> 

-- 
????????? ????????


From manivannan.sadhasivam at linaro.org  Fri Sep 13 06:57:10 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Fri, 13 Sep 2024 19:27:10 +0530
Subject: [PATCH v2 5/5] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <20240913083724.1217691-6-quic_qianyu@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-6-quic_qianyu@quicinc.com>
Message-ID: <20240913135710.6ionsmzo45orin6n@thinkpad>

On Fri, Sep 13, 2024 at 01:37:24AM -0700, Qiang Yu wrote:
> Describe PCIe3 controller and PHY. Also add required system resources like
> regulators, clocks, interrupts and registers configuration for PCIe3.
> 
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> ---
>  arch/arm64/boot/dts/qcom/x1e80100.dtsi | 202 ++++++++++++++++++++++++-
>  1 file changed, 201 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> index a36076e3c56b..a7703e4974a6 100644
> --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> +++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> @@ -744,7 +744,7 @@ gcc: clock-controller at 100000 {
>  
>  			clocks = <&bi_tcxo_div2>,
>  				 <&sleep_clk>,
> -				 <0>,
> +				 <&pcie3_phy>,
>  				 <&pcie4_phy>,
>  				 <&pcie5_phy>,
>  				 <&pcie6a_phy>,
> @@ -2907,6 +2907,206 @@ mmss_noc: interconnect at 1780000 {
>  			#interconnect-cells = <2>;
>  		};
>  
> +		pcie3: pci at 1bd0000 {

pcie@

> +			device_type = "pci";
> +			compatible = "qcom,pcie-x1e80100";
> +			reg = <0 0x01bd0000 0 0x3000>,
> +			      <0 0x78000000 0 0xf1d>,

0x0 here and below.

> +			      <0 0x78000f40 0 0xa8>,
> +			      <0 0x78001000 0 0x1000>,
> +			      <0 0x78100000 0 0x100000>,
> +			      <0 0x01bd3000 0 0x1000>;
> +			reg-names = "parf",
> +				    "dbi",
> +				    "elbi",
> +				    "atu",
> +				    "config",
> +				    "mhi";
> +			#address-cells = <3>;
> +			#size-cells = <2>;
> +			ranges = <0x01000000 0x0 0x00000000 0x0 0x78200000 0x0 0x100000>,
> +				 <0x02000000 0x0 0x78300000 0x0 0x78300000 0x0 0x3d00000>,
> +				 <0x03000000 0x7 0x40000000 0x7 0x40000000 0x0 0x40000000>;
> +			bus-range = <0x00 0xff>;
> +
> +			dma-coherent;
> +
> +			linux,pci-domain = <3>;
> +			num-lanes = <8>;
> +
> +			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 769 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 671 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
> +			interrupt-names = "msi0",
> +					  "msi1",
> +					  "msi2",
> +					  "msi3",
> +					  "msi4",
> +					  "msi5",
> +					  "msi6",
> +					  "msi7";

Can you add 'global' interrupt as well? While doing so, please make sure the
global_irq related patches are applied and Link up works fine. Those patches are
already in linux-next.

> +
> +			#interrupt-cells = <1>;
> +			interrupt-map-mask = <0 0 0 0x7>;
> +			interrupt-map = <0 0 0 1 &intc 0 0 0 220 IRQ_TYPE_LEVEL_HIGH>,

Use GIC_SPI for the parent interrupt specifier.

- Mani

> +					<0 0 0 2 &intc 0 0 0 221 IRQ_TYPE_LEVEL_HIGH>,
> +					<0 0 0 3 &intc 0 0 0 237 IRQ_TYPE_LEVEL_HIGH>,
> +					<0 0 0 4 &intc 0 0 0 238 IRQ_TYPE_LEVEL_HIGH>;
> +
> +			clocks = <&gcc GCC_PCIE_3_AUX_CLK>,
> +				 <&gcc GCC_PCIE_3_CFG_AHB_CLK>,
> +				 <&gcc GCC_PCIE_3_MSTR_AXI_CLK>,
> +				 <&gcc GCC_PCIE_3_SLV_AXI_CLK>,
> +				 <&gcc GCC_PCIE_3_SLV_Q2A_AXI_CLK>,
> +				 <&gcc GCC_CFG_NOC_PCIE_ANOC_NORTH_AHB_CLK>,
> +				 <&gcc GCC_CNOC_PCIE_NORTH_SF_AXI_CLK>;
> +			clock-names = "aux",
> +				      "cfg",
> +				      "bus_master",
> +				      "bus_slave",
> +				      "slave_q2a",
> +				      "noc_aggr",
> +				      "cnoc_sf_axi";
> +
> +			assigned-clocks = <&gcc GCC_PCIE_3_AUX_CLK>;
> +			assigned-clock-rates = <19200000>;
> +
> +			interconnects = <&pcie_south_anoc MASTER_PCIE_3 QCOM_ICC_TAG_ALWAYS
> +					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
> +					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
> +					 &cnoc_main SLAVE_PCIE_3 QCOM_ICC_TAG_ALWAYS>;
> +			interconnect-names = "pcie-mem",
> +					     "cpu-pcie";
> +
> +			resets = <&gcc GCC_PCIE_3_BCR>,
> +				 <&gcc GCC_PCIE_3_LINK_DOWN_BCR>;
> +			reset-names = "pci",
> +				      "link_down";
> +
> +			power-domains = <&gcc GCC_PCIE_3_GDSC>;
> +
> +			phys = <&pcie3_phy>;
> +			phy-names = "pciephy";
> +
> +			operating-points-v2 = <&pcie3_opp_table>;
> +
> +			status = "disabled";
> +
> +			pcie3_opp_table: opp-table {
> +				compatible = "operating-points-v2";
> +
> +				/* GEN 1 x1 */
> +				opp-2500000 {
> +					opp-hz = /bits/ 64 <2500000>;
> +					required-opps = <&rpmhpd_opp_low_svs>;
> +					opp-peak-kBps = <250000 1>;
> +				};
> +
> +				/* GEN 1 x2 and GEN 2 x1 */
> +				opp-5000000 {
> +					opp-hz = /bits/ 64 <5000000>;
> +					required-opps = <&rpmhpd_opp_low_svs>;
> +					opp-peak-kBps = <500000 1>;
> +				};
> +
> +				/* GEN 1 x4 and GEN 2 x2 */
> +				opp-10000000 {
> +					opp-hz = /bits/ 64 <10000000>;
> +					required-opps = <&rpmhpd_opp_low_svs>;
> +					opp-peak-kBps = <1000000 1>;
> +				};
> +
> +				/* GEN 1 x8 and GEN 2 x4 */
> +				opp-20000000 {
> +					opp-hz = /bits/ 64 <20000000>;
> +					required-opps = <&rpmhpd_opp_low_svs>;
> +					opp-peak-kBps = <2000000 1>;
> +				};
> +
> +				/* GEN 2 x8 */
> +				opp-40000000 {
> +					opp-hz = /bits/ 64 <40000000>;
> +					required-opps = <&rpmhpd_opp_low_svs>;
> +					opp-peak-kBps = <4000000 1>;
> +				};
> +
> +				/* GEN 3 x1 */
> +				opp-8000000 {
> +					opp-hz = /bits/ 64 <8000000>;
> +					required-opps = <&rpmhpd_opp_svs>;
> +					opp-peak-kBps = <984500 1>;
> +				};
> +
> +				/* GEN 3 x2 and GEN 4 x1 */
> +				opp-16000000 {
> +					opp-hz = /bits/ 64 <16000000>;
> +					required-opps = <&rpmhpd_opp_svs>;
> +					opp-peak-kBps = <1969000 1>;
> +				};
> +
> +				/* GEN 3 x4 and GEN 4 x2 */
> +				opp-32000000 {
> +					opp-hz = /bits/ 64 <32000000>;
> +					required-opps = <&rpmhpd_opp_svs>;
> +					opp-peak-kBps = <3938000 1>;
> +				};
> +
> +				/* GEN 3 x8 and GEN 4 x4 */
> +				opp-64000000 {
> +					opp-hz = /bits/ 64 <64000000>;
> +					required-opps = <&rpmhpd_opp_svs>;
> +					opp-peak-kBps = <7876000 1>;
> +				};
> +
> +				/* GEN 4 x8 */
> +				opp-128000000 {
> +					opp-hz = /bits/ 64 <128000000>;
> +					required-opps = <&rpmhpd_opp_svs>;
> +					opp-peak-kBps = <15753000 1>;
> +				};
> +			};
> +		};
> +
> +		pcie3_phy: phy at 1be0000 {
> +			compatible = "qcom,x1e80100-qmp-gen4x8-pcie-phy";
> +			reg = <0 0x01be0000 0 0x10000>;
> +
> +			clocks = <&gcc GCC_PCIE_3_PHY_AUX_CLK>,
> +				 <&gcc GCC_PCIE_3_CFG_AHB_CLK>,
> +				 <&tcsr TCSR_PCIE_8L_CLKREF_EN>,
> +				 <&gcc GCC_PCIE_3_PHY_RCHNG_CLK>,
> +				 <&gcc GCC_PCIE_3_PIPE_CLK>,
> +				 <&gcc GCC_PCIE_3_PIPEDIV2_CLK>;
> +			clock-names = "aux",
> +				      "cfg_ahb",
> +				      "ref",
> +				      "rchng",
> +				      "pipe",
> +				      "pipediv2";
> +
> +			resets = <&gcc GCC_PCIE_3_PHY_BCR>,
> +				 <&gcc GCC_PCIE_3_NOCSR_COM_PHY_BCR>;
> +			reset-names = "phy",
> +				      "phy_nocsr";
> +
> +			assigned-clocks = <&gcc GCC_PCIE_3_PHY_RCHNG_CLK>;
> +			assigned-clock-rates = <100000000>;
> +
> +			power-domains = <&gcc GCC_PCIE_3_PHY_GDSC>;
> +
> +			#clock-cells = <0>;
> +			clock-output-names = "pcie3_pipe_clk";
> +
> +			#phy-cells = <0>;
> +
> +			status = "disabled";
> +		};
> +
>  		pcie6a: pci at 1bf8000 {
>  			device_type = "pci";
>  			compatible = "qcom,pcie-x1e80100";
> -- 
> 2.34.1
> 

-- 
????????? ????????


From conor at kernel.org  Fri Sep 13 11:24:40 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 13 Sep 2024 19:24:40 +0100
Subject: [PATCH 1/2] dt-bindings: phy: bcm-ns-usb2-phy: drop deprecated
 variant
In-Reply-To: <20240913044557.28315-1-zajec5@gmail.com>
References: <20240913044557.28315-1-zajec5@gmail.com>
Message-ID: <20240913-spiritual-sneeze-7c48a16d2700@spud>

On Fri, Sep 13, 2024 at 06:45:56AM +0200, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> The old binding variant (the one covering whole DMU block) was
> deprecated 3 years ago. Linux kernel was warning when using it for
> similar amount of time.
> 
> There aren't any known Northstar devices with bootloader providing DT to
> operating system. Actually OpenWrt seems to be the only project using
> this binding and it always appends DTB to kernel. It has switched to the
> non-deprecated binding years ago.
> 
> Given there is close to zero chance this breaks anyone's setup it should
> more than safe to drop this binding variant after 3 years.

I love a commit message like this.
Acked-by: Conor Dooley <conor.dooley at microchip.com>

Thanks,
Conor.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20240913/3989224a/attachment.sig>

From quic_bjorande at quicinc.com  Fri Sep 13 14:24:33 2024
From: quic_bjorande at quicinc.com (Bjorn Andersson)
Date: Fri, 13 Sep 2024 14:24:33 -0700
Subject: [PATCH 5/5] drm/msm/dp: Add DisplayPort controller for SA8775P
In-Reply-To: <a44a6f08-1f4a-4e5c-a4e4-30ab65c467f7@quicinc.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com>
 <20240911100813.338-6-quic_mukhopad@quicinc.com>
 <ZuH3WqMwn7fl3nhh@hu-bjorande-lv.qualcomm.com>
 <a44a6f08-1f4a-4e5c-a4e4-30ab65c467f7@quicinc.com>
Message-ID: <ZuStkRFvwJT7re6D@hu-bjorande-lv.qualcomm.com>

On Thu, Sep 12, 2024 at 03:34:05PM +0530, Soutrik Mukhopadhyay wrote:
> 
> On 9/12/2024 1:32 AM, Bjorn Andersson wrote:
> > On Wed, Sep 11, 2024 at 03:38:13PM +0530, Soutrik Mukhopadhyay wrote:
> > > The Qualcomm SA8775P platform comes with a DisplayPort controller
> > > with a different base offset than the previous SoCs,
> > > add support for this in the DisplayPort driver.

Please check the line wrapping of this as well; the lines here should be
wrapped at 75 columns.

> > > 
> > > Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> > > ---
> > >   drivers/gpu/drm/msm/dp/dp_display.c | 7 +++++++
> > >   1 file changed, 7 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> > > index e1228fb093ee..e4954fd99eb0 100644
> > > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > > @@ -118,6 +118,12 @@ struct msm_dp_desc {
> > >   	bool wide_bus_supported;
> > >   };
> > > +static const struct msm_dp_desc sa8775p_dp_descs[] = {
> > > +	{ .io_start = 0xaf54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
> > > +	{ .io_start = 0xaf5c000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
> > Why is this list incomplete?
> > 
> > Regards,
> > Bjorn
> 
> 
> Do you mean to add for mdss_1 as well?
> 

I don't see a reason for not submitting them as well.

> We only added dp controllers for mdss_0 as we plan to validate and enable
> only these.
> 

As far as I can tell there are 5 DPTX blocks on mdss_0.


It is perfectly fine that you just state in the commit message that
"Only MDSS0 DPTX0 and DPTX1 have been validated", but please add the
others as well in this commit.

Regards,
Bjorn

> 
> > 
> > > +	{}
> > > +};
> > > +
> > >   static const struct msm_dp_desc sc7180_dp_descs[] = {
> > >   	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
> > >   	{}
> > > @@ -162,6 +168,7 @@ static const struct msm_dp_desc x1e80100_dp_descs[] = {
> > >   };
> > >   static const struct of_device_id dp_dt_match[] = {
> > > +	{ .compatible = "qcom,sa8775p-dp", .data = &sa8775p_dp_descs },
> > >   	{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
> > >   	{ .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
> > >   	{ .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_descs },
> > > -- 
> > > 2.17.1
> > > 


From quic_krichai at quicinc.com  Fri Sep 13 20:59:17 2024
From: quic_krichai at quicinc.com (Krishna Chaitanya Chundru)
Date: Sat, 14 Sep 2024 09:29:17 +0530
Subject: [PATCH v2 0/5] Add support for PCIe3 on x1e80100
In-Reply-To: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
Message-ID: <36bd9f69-e263-08a1-af07-45185ea03671@quicinc.com>

Hi qiang,

In next series can you add logic in controller driver
to have new ops for this x1e80100 since this hardware
has smmuv3 support but currently the ops_1_9_0 ops which
is being used has configuring bdf to sid table which will
be not present for this devices.


- Krishna Chaitanya.

On 9/13/2024 2:07 PM, Qiang Yu wrote:
> This series add support for PCIe3 on x1e80100.
> 
> PCIe3 needs additional set of clocks, regulators and new set of PCIe QMP
> PHY configuration compare other PCIe instances on x1e80100. Hence add
> required resource configuration and usage for PCIe3.
> 
> v2->v1:
> 1. Squash [PATCH 1/8], [PATCH 2/8],[PATCH 3/8] into one patch and make the
>     indentation consistent.
> 2. Put dts patch at the end of the patchset.
> 3. Put dt-binding patch at the first of the patchset.
> 4. Add a new patch where opp-table is added in dt-binding to avoid dtbs
>     checking error.
> 5. Remove GCC_PCIE_3_AUX_CLK, RPMH_CXO_CLK, put in TCSR_PCIE_8L_CLKREF_EN
>     as ref.
> 6. Remove lane_broadcasting.
> 7. Add 64 bit bar, Remove GCC_PCIE_3_PIPE_CLK_SRC,
>     GCC_CFG_NOC_PCIE_ANOC_SOUTH_AHB_CLK is changed to
>     GCC_CFG_NOC_PCIE_ANOC_NORTH_AHB_CLK.
> 8. Add Reviewed-by tag.
> 9. Remove [PATCH 7/8], [PATCH 8/8].
> 
> Qiang Yu (5):
>    dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the X1E80100
>      QMP PCIe PHY Gen4 x8
>    dt-bindings: PCI: qcom: Add OPP table for X1E80100
>    phy: qcom: qmp: Add phy register and clk setting for x1e80100 PCIe3
>    clk: qcom: gcc-x1e80100: Fix halt_check for pipediv2 clocks
>    arm64: dts: qcom: x1e80100: Add support for PCIe3 on x1e80100
> 
>   .../bindings/pci/qcom,pcie-x1e80100.yaml      |   4 +
>   .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml       |   3 +
>   arch/arm64/boot/dts/qcom/x1e80100.dtsi        | 202 ++++++++++++++++-
>   drivers/clk/qcom/gcc-x1e80100.c               |  10 +-
>   drivers/phy/qualcomm/phy-qcom-qmp-pcie.c      | 211 ++++++++++++++++++
>   .../qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h    |  25 +++
>   drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h |  19 ++
>   7 files changed, 468 insertions(+), 6 deletions(-)
>   create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
>   create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h
> 


From minda.chen at starfivetech.com  Fri Sep 13 23:49:04 2024
From: minda.chen at starfivetech.com (Minda Chen)
Date: Sat, 14 Sep 2024 06:49:04 +0000
Subject: [PATCH v3 1/1] phy: starfive: jh7110-usb: Fix link configuration to
 controller
In-Reply-To: <20240909-drizzle-hydroxide-dd405c4c3a6d@wendy>
References: <20240902111127.15155-1-minda.chen@starfivetech.com>
 <20240902111127.15155-2-minda.chen@starfivetech.com>
 <20240909-drizzle-hydroxide-dd405c4c3a6d@wendy>
Message-ID: <SHXPR01MB0863955434409B0269300E6EE6662@SHXPR01MB0863.CHNPR01.prod.partner.outlook.cn>

> 
> On Mon, Sep 02, 2024 at 07:11:27PM +0800, Minda Chen wrote:
> > From: Jan Kiszka <jan.kiszka at siemens.com>
> >
> > In order to connect the USB 2.0 PHY to its controller, we also need to
> > set "u0_pdrstn_split_sw_usbpipe_plugen" [1]. Some downstream U-Boot
> > versions did that, but upstream firmware does not, and the kernel must
> > not rely on such behavior anyway. Failing to set this left the USB
> > gadget port invisible to connected hosts behind.
> >
> > Link:
> > https://doc-en.rvspace.org/JH7110/TRM/JH7110_TRM/sys_syscon.html#sys_s
> > yscon__section_b3l_fqs_wsb [1]
> > Fixes: 16d3a71c20cf ("phy: starfive: Add JH7110 USB 2.0 PHY driver")
> > Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
> > Signed-off-by: Minda Chen <minda.chen at starfivetech.com>
> 
> Reviewed-by: Conor Dooley <conor.dooley at microchip.com>

Conor :
   Thanks


From aford173 at gmail.com  Sat Sep 14 04:27:44 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 14 Sep 2024 06:27:44 -0500
Subject: [PATCH V8 0/5] phy: freescale: fsl-samsung-hdmi: Expand phy clock options
Message-ID: <20240914112816.520224-1-aford173@gmail.com>

Currently, there is a look-up-table to describe all the clock options the HDMI PHY
can use.  Some of these entries in the LUT are using a fractional divider which does
not have a well documented algorithm for determinging values, but the the integer
divider can use an algorithm to calculate the integer divder values dynamically
beyond those listed in the LUT and also duplicates some of the entries.

The first two patches do not do anything functionally other than simplify
some of the register accesses and de-duplicates some of the register look-ups.

The third patch adds support for the integer divider and uses it whenever the
clock request is an exact match.  Otherwise, it will use the LUT as before.
The rouding is still based on the LUT if the integer clock isn't an exact match.

The forth patch updates thes set_rate and round_rate functions to use either
the fractional clock LUT or the the integer divder mechanism to determine
which ever clock rate might be closest match.

The last patch removes the integer divider entries from the LUT since by then
it'll be comparing both the integer divider calculator and the closest value
in the LUT.

In my testing with a AOC 4K monitor, I was able to add 4 entries in my modetest
table.  I do not have an HDMI analyzer, so I just used my monitor to determine
if this series worked.

Adam Ford (5):
  phy: freescale: fsl-samsung-hdmi: Replace register defines with macro
  phy: freescale: fsl-samsung-hdmi: Simplify REG21_PMS_S_MASK lookup
  phy: freescale: fsl-samsung-hdmi: Support dynamic integer
  phy: freescale: fsl-samsung-hdmi: Use closest divider
  phy: freescale: fsl-samsung-hdmi: Remove unnecessary LUT entries

 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 604 ++++++++++---------
 1 file changed, 325 insertions(+), 279 deletions(-)

-- 
2.43.0



From aford173 at gmail.com  Sat Sep 14 04:27:45 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 14 Sep 2024 06:27:45 -0500
Subject: [PATCH V8 1/5] phy: freescale: fsl-samsung-hdmi: Replace register defines with macro
In-Reply-To: <20240914112816.520224-1-aford173@gmail.com>
References: <20240914112816.520224-1-aford173@gmail.com>
Message-ID: <20240914112816.520224-2-aford173@gmail.com>

There are 47 registers defined as PHY_REG_xx were xx goes from 00 to
47.  Simplify this by replacing them all with a macro which is passed
the register number to return the proper register offset.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Reviewed-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
Tested-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
---
V7:  No change
V6:  No change
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 133 ++++++-------------
 1 file changed, 43 insertions(+), 90 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 9048cdc760c2..acea7008aefc 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -14,76 +14,29 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 
-#define PHY_REG_00		0x00
-#define PHY_REG_01		0x04
-#define PHY_REG_02		0x08
-#define PHY_REG_08		0x20
-#define PHY_REG_09		0x24
-#define PHY_REG_10		0x28
-#define PHY_REG_11		0x2c
-
-#define PHY_REG_12		0x30
-#define  REG12_CK_DIV_MASK	GENMASK(5, 4)
-
-#define PHY_REG_13		0x34
-#define  REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
-
-#define PHY_REG_14		0x38
-#define  REG14_TOL_MASK		GENMASK(7, 4)
-#define  REG14_RP_CODE_MASK	GENMASK(3, 1)
-#define  REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
-
-#define PHY_REG_15		0x3c
-#define PHY_REG_16		0x40
-#define PHY_REG_17		0x44
-#define PHY_REG_18		0x48
-#define PHY_REG_19		0x4c
-#define PHY_REG_20		0x50
-
-#define PHY_REG_21		0x54
-#define  REG21_SEL_TX_CK_INV	BIT(7)
-#define  REG21_PMS_S_MASK	GENMASK(3, 0)
-
-#define PHY_REG_22		0x58
-#define PHY_REG_23		0x5c
-#define PHY_REG_24		0x60
-#define PHY_REG_25		0x64
-#define PHY_REG_26		0x68
-#define PHY_REG_27		0x6c
-#define PHY_REG_28		0x70
-#define PHY_REG_29		0x74
-#define PHY_REG_30		0x78
-#define PHY_REG_31		0x7c
-#define PHY_REG_32		0x80
+#define PHY_REG(reg)		(reg * 4)
 
+#define REG12_CK_DIV_MASK	GENMASK(5, 4)
+
+#define REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
+
+#define REG14_TOL_MASK		GENMASK(7, 4)
+#define REG14_RP_CODE_MASK	GENMASK(3, 1)
+#define REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
+
+#define REG21_SEL_TX_CK_INV	BIT(7)
+#define REG21_PMS_S_MASK	GENMASK(3, 0)
 /*
  * REG33 does not match the ref manual. According to Sandor Yu from NXP,
  * "There is a doc issue on the i.MX8MP latest RM"
  * REG33 is being used per guidance from Sandor
  */
+#define REG33_MODE_SET_DONE	BIT(7)
+#define REG33_FIX_DA		BIT(1)
 
-#define PHY_REG_33		0x84
-#define  REG33_MODE_SET_DONE	BIT(7)
-#define  REG33_FIX_DA		BIT(1)
-
-#define PHY_REG_34		0x88
-#define  REG34_PHY_READY	BIT(7)
-#define  REG34_PLL_LOCK		BIT(6)
-#define  REG34_PHY_CLK_READY	BIT(5)
-
-#define PHY_REG_35		0x8c
-#define PHY_REG_36		0x90
-#define PHY_REG_37		0x94
-#define PHY_REG_38		0x98
-#define PHY_REG_39		0x9c
-#define PHY_REG_40		0xa0
-#define PHY_REG_41		0xa4
-#define PHY_REG_42		0xa8
-#define PHY_REG_43		0xac
-#define PHY_REG_44		0xb0
-#define PHY_REG_45		0xb4
-#define PHY_REG_46		0xb8
-#define PHY_REG_47		0xbc
+#define REG34_PHY_READY	BIT(7)
+#define REG34_PLL_LOCK		BIT(6)
+#define REG34_PHY_CLK_READY	BIT(5)
 
 #define PHY_PLL_DIV_REGS_NUM 6
 
@@ -369,29 +322,29 @@ struct reg_settings {
 };
 
 static const struct reg_settings common_phy_cfg[] = {
-	{ PHY_REG_00, 0x00 }, { PHY_REG_01, 0xd1 },
-	{ PHY_REG_08, 0x4f }, { PHY_REG_09, 0x30 },
-	{ PHY_REG_10, 0x33 }, { PHY_REG_11, 0x65 },
+	{ PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
+	{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
+	{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
 	/* REG12 pixclk specific */
 	/* REG13 pixclk specific */
 	/* REG14 pixclk specific */
-	{ PHY_REG_15, 0x80 }, { PHY_REG_16, 0x6c },
-	{ PHY_REG_17, 0xf2 }, { PHY_REG_18, 0x67 },
-	{ PHY_REG_19, 0x00 }, { PHY_REG_20, 0x10 },
+	{ PHY_REG(15), 0x80 }, { PHY_REG(16), 0x6c },
+	{ PHY_REG(17), 0xf2 }, { PHY_REG(18), 0x67 },
+	{ PHY_REG(19), 0x00 }, { PHY_REG(20), 0x10 },
 	/* REG21 pixclk specific */
-	{ PHY_REG_22, 0x30 }, { PHY_REG_23, 0x32 },
-	{ PHY_REG_24, 0x60 }, { PHY_REG_25, 0x8f },
-	{ PHY_REG_26, 0x00 }, { PHY_REG_27, 0x00 },
-	{ PHY_REG_28, 0x08 }, { PHY_REG_29, 0x00 },
-	{ PHY_REG_30, 0x00 }, { PHY_REG_31, 0x00 },
-	{ PHY_REG_32, 0x00 }, { PHY_REG_33, 0x80 },
-	{ PHY_REG_34, 0x00 }, { PHY_REG_35, 0x00 },
-	{ PHY_REG_36, 0x00 }, { PHY_REG_37, 0x00 },
-	{ PHY_REG_38, 0x00 }, { PHY_REG_39, 0x00 },
-	{ PHY_REG_40, 0x00 }, { PHY_REG_41, 0xe0 },
-	{ PHY_REG_42, 0x83 }, { PHY_REG_43, 0x0f },
-	{ PHY_REG_44, 0x3E }, { PHY_REG_45, 0xf8 },
-	{ PHY_REG_46, 0x00 }, { PHY_REG_47, 0x00 }
+	{ PHY_REG(22), 0x30 }, { PHY_REG(23), 0x32 },
+	{ PHY_REG(24), 0x60 }, { PHY_REG(25), 0x8f },
+	{ PHY_REG(26), 0x00 }, { PHY_REG(27), 0x00 },
+	{ PHY_REG(28), 0x08 }, { PHY_REG(29), 0x00 },
+	{ PHY_REG(30), 0x00 }, { PHY_REG(31), 0x00 },
+	{ PHY_REG(32), 0x00 }, { PHY_REG(33), 0x80 },
+	{ PHY_REG(34), 0x00 }, { PHY_REG(35), 0x00 },
+	{ PHY_REG(36), 0x00 }, { PHY_REG(37), 0x00 },
+	{ PHY_REG(38), 0x00 }, { PHY_REG(39), 0x00 },
+	{ PHY_REG(40), 0x00 }, { PHY_REG(41), 0xe0 },
+	{ PHY_REG(42), 0x83 }, { PHY_REG(43), 0x0f },
+	{ PHY_REG(44), 0x3E }, { PHY_REG(45), 0xf8 },
+	{ PHY_REG(46), 0x00 }, { PHY_REG(47), 0x00 }
 };
 
 struct fsl_samsung_hdmi_phy {
@@ -442,7 +395,7 @@ fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
 	}
 
 	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
-	       phy->regs + PHY_REG_21);
+	       phy->regs + PHY_REG(21));
 }
 
 static void
@@ -469,7 +422,7 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 		break;
 	}
 
-	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG_12);
+	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG(12));
 
 	/*
 	 * Calculation for the frequency lock detector target code (fld_tg_code)
@@ -489,11 +442,11 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 
 	/* FLD_TOL and FLD_RP_CODE taken from downstream driver */
 	writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),
-	       phy->regs + PHY_REG_13);
+	       phy->regs + PHY_REG(13));
 	writeb(FIELD_PREP(REG14_TOL_MASK, 2) |
 	       FIELD_PREP(REG14_RP_CODE_MASK, 2) |
 	       FIELD_PREP(REG14_TG_CODE_HIGH_MASK, fld_tg_code >> 8),
-	       phy->regs + PHY_REG_14);
+	       phy->regs + PHY_REG(14));
 }
 
 static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
@@ -503,7 +456,7 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	u8 val;
 
 	/* HDMI PHY init */
-	writeb(REG33_FIX_DA, phy->regs + PHY_REG_33);
+	writeb(REG33_FIX_DA, phy->regs + PHY_REG(33));
 
 	/* common PHY registers */
 	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
@@ -511,14 +464,14 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 
 	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
-		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG_02 + i * 4);
+		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
 
 	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
-	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG_33);
+	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));
 
-	ret = readb_poll_timeout(phy->regs + PHY_REG_34, val,
+	ret = readb_poll_timeout(phy->regs + PHY_REG(34), val,
 				 val & REG34_PLL_LOCK, 50, 20000);
 	if (ret)
 		dev_err(phy->dev, "PLL failed to lock\n");
-- 
2.43.0



From aford173 at gmail.com  Sat Sep 14 04:27:46 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 14 Sep 2024 06:27:46 -0500
Subject: [PATCH V8 2/5] phy: freescale: fsl-samsung-hdmi: Simplify REG21_PMS_S_MASK lookup
In-Reply-To: <20240914112816.520224-1-aford173@gmail.com>
References: <20240914112816.520224-1-aford173@gmail.com>
Message-ID: <20240914112816.520224-3-aford173@gmail.com>

The value of 'S' is writen to two places, PHY_REG3[7:4] and
PHY_REG21[3:0].  There is a lookup table which contains
the value of PHY_REG3.  Rather than using a switch statement
based on the pixel clock to search for the value of 'S' again,
just shift the contents of PHY_REG3[7:4] >> 4 and place the value
in PHY_REG21[3:0].  Doing this can eliminate an entire function.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Reviewed-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
Tested-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
---
V7:  No Change
V6:  No Change
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 39 ++------------------
 1 file changed, 4 insertions(+), 35 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index acea7008aefc..4f6874226f9a 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -364,40 +364,6 @@ to_fsl_samsung_hdmi_phy(struct clk_hw *hw)
 	return container_of(hw, struct fsl_samsung_hdmi_phy, hw);
 }
 
-static void
-fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
-				      const struct phy_config *cfg)
-{
-	u8 div = 0x1;
-
-	switch (cfg->pixclk) {
-	case  22250000 ...  33750000:
-		div = 0xf;
-		break;
-	case  35000000 ...  40000000:
-		div = 0xb;
-		break;
-	case  43200000 ...  47500000:
-		div = 0x9;
-		break;
-	case  50349650 ...  63500000:
-		div = 0x7;
-		break;
-	case  67500000 ...  90000000:
-		div = 0x5;
-		break;
-	case  94000000 ... 148500000:
-		div = 0x3;
-		break;
-	case 154000000 ... 297000000:
-		div = 0x1;
-		break;
-	}
-
-	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
-	       phy->regs + PHY_REG(21));
-}
-
 static void
 fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 					    const struct phy_config *cfg)
@@ -466,7 +432,10 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
 		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
 
-	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
+	/* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
+	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
+	       cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
+
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
 	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));
-- 
2.43.0



From aford173 at gmail.com  Sat Sep 14 04:27:47 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 14 Sep 2024 06:27:47 -0500
Subject: [PATCH V8 3/5] phy: freescale: fsl-samsung-hdmi: Support dynamic integer
In-Reply-To: <20240914112816.520224-1-aford173@gmail.com>
References: <20240914112816.520224-1-aford173@gmail.com>
Message-ID: <20240914112816.520224-4-aford173@gmail.com>

There is currently a look-up table for a variety of resolutions.
Since the phy has the ability to dynamically calculate the values
necessary to use the intger divider which should allow more
resolutions without having to update the look-up-table.

If the lookup table cannot find an exact match, fall back to the
dynamic calculator of the integer divider.

Previously, the value of P was hard-coded to 1, this required an
update to the phy_pll_cfg table to add in the extra value into the
table, so if the value of P is calculated to be something else
by the PMS calculator, the calculated_phy_pll_cfg structure
can be used instead without having to keep track of which method
was used.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
Tested-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
---
V8:  Fix VCO note and remove one goto by using a helper function
V7:  Refactored much of the code to create smaller helper functions
     to eliminate redundant code and improve code flow and comment
     readability.   Any t-b and s-o-b tags removed due to the
     extent of the changes.

V6:  Fix comment typos and remove an unnecesary extra calculation
     by using the cached value.
V5:  No Change
V4:  No Change
V3:  Change size of pll_div_regs to include PHY_REG01 (P)
     Create calculated_phy_pll_cfg to containe the values
     Eliminate the PMS calculation from fsl_samsung_hdmi_phy_configure
     Make the LUT primary and fall back to integer calculator in
     phy_clk_round_rate.
     Check the range right away to ensure it's reaonsable rather than
     trying to find a clock only to learn it's outside the range.
     Overall added notes and comments where stuff may not be intuitive.

V2:  Update phy_clk_round_rate and phy_clk_set_rate to both support
     the integer clock PMS calculator.
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 377 +++++++++++++------
 1 file changed, 270 insertions(+), 107 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 4f6874226f9a..029de69fbeaf 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -16,6 +16,8 @@
 
 #define PHY_REG(reg)		(reg * 4)
 
+#define REG01_PMS_P_MASK	GENMASK(3, 0)
+#define REG03_PMS_S_MASK	GENMASK(7, 4)
 #define REG12_CK_DIV_MASK	GENMASK(5, 4)
 
 #define REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
@@ -38,281 +40,296 @@
 #define REG34_PLL_LOCK		BIT(6)
 #define REG34_PHY_CLK_READY	BIT(5)
 
-#define PHY_PLL_DIV_REGS_NUM 6
+#ifndef MHZ
+#define MHZ	(1000UL * 1000UL)
+#endif
+
+#define PHY_PLL_DIV_REGS_NUM 7
 
 struct phy_config {
 	u32	pixclk;
 	u8	pll_div_regs[PHY_PLL_DIV_REGS_NUM];
 };
 
+/*
+ * The calculated_phy_pll_cfg only handles integer divider for PMS,
+ * meaning the last four entries will be fixed, but the first three will
+ * be calculated by the PMS calculator.
+ */
+static struct phy_config calculated_phy_pll_cfg = {
+	.pixclk = 0,
+	.pll_div_regs = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
+};
+
+/* The lookup table contains values for which the fractional divder is used */
 static const struct phy_config phy_pll_cfg[] = {
 	{
 		.pixclk = 22250000,
-		.pll_div_regs = { 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 23750000,
-		.pll_div_regs = { 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
 	}, {
 		.pixclk = 24000000,
-		.pll_div_regs = { 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 24024000,
-		.pll_div_regs = { 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
 	}, {
 		.pixclk = 25175000,
-		.pll_div_regs = { 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
 	}, {
 		.pixclk = 25200000,
-		.pll_div_regs = { 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 26750000,
-		.pll_div_regs = { 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 27000000,
-		.pll_div_regs = { 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 27027000,
-		.pll_div_regs = { 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 29500000,
-		.pll_div_regs = { 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 30750000,
-		.pll_div_regs = { 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 30888000,
-		.pll_div_regs = { 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
 	}, {
 		.pixclk = 33750000,
-		.pll_div_regs = { 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 35000000,
-		.pll_div_regs = { 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 36000000,
-		.pll_div_regs = { 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 36036000,
-		.pll_div_regs = { 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 40000000,
-		.pll_div_regs = { 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43200000,
-		.pll_div_regs = { 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43243200,
-		.pll_div_regs = { 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 44500000,
-		.pll_div_regs = { 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
 	}, {
 		.pixclk = 47000000,
-		.pll_div_regs = { 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
 	}, {
 		.pixclk = 47500000,
-		.pll_div_regs = { 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
 	}, {
 		.pixclk = 50349650,
-		.pll_div_regs = { 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
 	}, {
 		.pixclk = 50400000,
-		.pll_div_regs = { 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 53250000,
-		.pll_div_regs = { 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 53500000,
-		.pll_div_regs = { 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 54000000,
-		.pll_div_regs = { 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 54054000,
-		.pll_div_regs = { 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 59000000,
-		.pll_div_regs = { 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 59340659,
-		.pll_div_regs = { 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
 	}, {
 		.pixclk = 59400000,
-		.pll_div_regs = { 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 61500000,
-		.pll_div_regs = { 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 63500000,
-		.pll_div_regs = { 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 67500000,
-		.pll_div_regs = { 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
 	}, {
 		.pixclk = 70000000,
-		.pll_div_regs = { 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 72000000,
-		.pll_div_regs = { 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 72072000,
-		.pll_div_regs = { 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 74176000,
-		.pll_div_regs = { 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
 	}, {
 		.pixclk = 74250000,
-		.pll_div_regs = { 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
+		.pll_div_regs = { 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
 	}, {
 		.pixclk = 78500000,
-		.pll_div_regs = { 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 80000000,
-		.pll_div_regs = { 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 82000000,
-		.pll_div_regs = { 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 82500000,
-		.pll_div_regs = { 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
 	}, {
 		.pixclk = 89000000,
-		.pll_div_regs = { 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
 	}, {
 		.pixclk = 90000000,
-		.pll_div_regs = { 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 94000000,
-		.pll_div_regs = { 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
 	}, {
 		.pixclk = 95000000,
-		.pll_div_regs = { 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
 	}, {
 		.pixclk = 98901099,
-		.pll_div_regs = { 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
 	}, {
 		.pixclk = 99000000,
-		.pll_div_regs = { 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
 	}, {
 		.pixclk = 100699300,
-		.pll_div_regs = { 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
 	}, {
 		.pixclk = 100800000,
-		.pll_div_regs = { 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 102500000,
-		.pll_div_regs = { 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
 		.pixclk = 104750000,
-		.pll_div_regs = { 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
 	}, {
 		.pixclk = 106500000,
-		.pll_div_regs = { 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 107000000,
-		.pll_div_regs = { 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
 	}, {
 		.pixclk = 108000000,
-		.pll_div_regs = { 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 108108000,
-		.pll_div_regs = { 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 118000000,
-		.pll_div_regs = { 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 118800000,
-		.pll_div_regs = { 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 123000000,
-		.pll_div_regs = { 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
+		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
 	}, {
 		.pixclk = 127000000,
-		.pll_div_regs = { 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 135000000,
-		.pll_div_regs = { 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
 	}, {
 		.pixclk = 135580000,
-		.pll_div_regs = { 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
+		.pll_div_regs = { 0xd1, 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
 	}, {
 		.pixclk = 137520000,
-		.pll_div_regs = { 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
+		.pll_div_regs = { 0xd1, 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
 	}, {
 		.pixclk = 138750000,
-		.pll_div_regs = { 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
+		.pll_div_regs = { 0xd1, 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
 	}, {
 		.pixclk = 140000000,
-		.pll_div_regs = { 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
 	}, {
 		.pixclk = 144000000,
-		.pll_div_regs = { 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 148352000,
-		.pll_div_regs = { 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
 	}, {
 		.pixclk = 148500000,
-		.pll_div_regs = { 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
 	}, {
 		.pixclk = 154000000,
-		.pll_div_regs = { 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
+		.pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
 	}, {
 		.pixclk = 157000000,
-		.pll_div_regs = { 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
 	}, {
 		.pixclk = 160000000,
-		.pll_div_regs = { 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
 	}, {
 		.pixclk = 162000000,
-		.pll_div_regs = { 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
+		.pll_div_regs = { 0xd1, 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
 	}, {
 		.pixclk = 164000000,
-		.pll_div_regs = { 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
 	}, {
 		.pixclk = 165000000,
-		.pll_div_regs = { 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
 	}, {
 		.pixclk = 180000000,
-		.pll_div_regs = { 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 185625000,
-		.pll_div_regs = { 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
 	}, {
 		.pixclk = 188000000,
-		.pll_div_regs = { 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
 	}, {
 		.pixclk = 198000000,
-		.pll_div_regs = { 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
+		.pll_div_regs = { 0xd1, 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
 	}, {
 		.pixclk = 205000000,
-		.pll_div_regs = { 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
+		.pll_div_regs = { 0xd1, 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
 		.pixclk = 209500000,
-		.pll_div_regs = { 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
+		.pll_div_regs = { 0xd1, 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
 	}, {
 		.pixclk = 213000000,
-		.pll_div_regs = { 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
+		.pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 216000000,
-		.pll_div_regs = { 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 216216000,
-		.pll_div_regs = { 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 237600000,
-		.pll_div_regs = { 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 254000000,
-		.pll_div_regs = { 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
+		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 277500000,
-		.pll_div_regs = { 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
+		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
 	}, {
 		.pixclk = 288000000,
-		.pll_div_regs = { 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
+		.pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 297000000,
-		.pll_div_regs = { 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
+		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
 	},
 };
 
@@ -322,7 +339,8 @@ struct reg_settings {
 };
 
 static const struct reg_settings common_phy_cfg[] = {
-	{ PHY_REG(0), 0x00 }, { PHY_REG(1), 0xd1 },
+	{ PHY_REG(0), 0x00 },
+	/* PHY_REG(1-7) pix clk specific */
 	{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
 	{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
 	/* REG12 pixclk specific */
@@ -415,6 +433,83 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
 	       phy->regs + PHY_REG(14));
 }
 
+static unsigned long fsl_samsung_hdmi_phy_find_pms(unsigned long fout, u8 *p, u16 *m, u8 *s)
+{
+	unsigned long best_freq = 0;
+	u32 min_delta = 0xffffffff;
+	u8 _p, best_p;
+	u16 _m, best_m;
+	u8 _s, best_s;
+
+	/*
+	 * Figure 13-78 of the reference manual states the PLL should be TMDS x 5
+	 * while the TMDS_CLKO should be the PLL / 5.  So to calculate the PLL,
+	 * take the pix clock x 5, then return the value of the PLL / 5.
+	 */
+	fout *= 5;
+
+	/* The ref manual states the values of 'P' range from 1 to 11 */
+	for (_p = 1; _p <= 11; ++_p) {
+		for (_s = 1; _s <= 16; ++_s) {
+			u64 tmp;
+			u32 delta;
+
+			/* s must be one or even */
+			if (_s > 1 && (_s & 0x01) == 1)
+				_s++;
+
+			/* _s cannot be 14 per the TRM */
+			if (_s == 14)
+				continue;
+
+			/*
+			 * TODO: Ref Manual doesn't state the range of _m
+			 * so this should be further refined if possible.
+			 * This range was set based on the original values
+			 * in the lookup table
+			 */
+			tmp = (u64)fout * (_p * _s);
+			do_div(tmp, 24 * MHZ);
+			_m = tmp;
+			if (_m < 0x30 || _m > 0x7b)
+				continue;
+
+			/*
+			 * Rev 2 of the Ref Manual states the
+			 * VCO can range between 750MHz and
+			 * 3GHz. The VCO is assumed to be
+			 * Fvco = (M * f_ref) / P,
+			 * where f_ref is 24MHz.
+			 */
+			tmp = (u64)_m * 24 * MHZ;
+			do_div(tmp, _p);
+			if (tmp < 750 * MHZ ||
+			    tmp > 3000 * MHZ)
+				continue;
+
+			/* Final frequency after post-divider */
+			do_div(tmp, _s);
+
+			delta = abs(fout - tmp);
+			if (delta < min_delta) {
+				best_p = _p;
+				best_s = _s;
+				best_m = _m;
+				min_delta = delta;
+				best_freq = tmp;
+			}
+		}
+	}
+
+	if (best_freq) {
+		*p = best_p;
+		*m = best_m;
+		*s = best_s;
+	}
+
+	return best_freq / 5;
+}
+
 static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 					  const struct phy_config *cfg)
 {
@@ -428,13 +523,13 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
 		writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
 
-	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
+	/* set individual PLL registers PHY_REG1 ... PHY_REG7 */
 	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
-		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(2) + i * 4);
+		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(1) + i * 4);
 
-	/* High nibble of pll_div_regs[1] contains S which also gets written to REG21 */
+	/* High nibble of PHY_REG3 and low nibble of PHY_REG21 both contain 'S' */
 	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
-	       cfg->pll_div_regs[1] >> 4), phy->regs + PHY_REG(21));
+	       cfg->pll_div_regs[2] >> 4), phy->regs + PHY_REG(21));
 
 	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
 
@@ -459,34 +554,102 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
 	return phy->cur_cfg->pixclk;
 }
 
-static long phy_clk_round_rate(struct clk_hw *hw,
-			       unsigned long rate, unsigned long *parent_rate)
+/* Helper function to lookup the available fractional-divider rate */
+static const struct phy_config *fsl_samsung_hdmi_phy_lookup_rate(unsigned long rate)
 {
 	int i;
 
+	/* Search the lookup table */
 	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
 		if (phy_pll_cfg[i].pixclk <= rate)
-			return phy_pll_cfg[i].pixclk;
+			break;
+
+	return &phy_pll_cfg[i];
+}
+
+static void fsl_samsung_hdmi_calculate_phy(struct phy_config *cal_phy, unsigned long rate,
+				    u8 p, u16 m, u8 s)
+{
+	cal_phy->pixclk = rate;
+	cal_phy->pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
+	cal_phy->pll_div_regs[1] = m;
+	cal_phy->pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
+	/* pll_div_regs 3-6 are fixed and pre-defined already */
+}
+
+static long phy_clk_round_rate(struct clk_hw *hw,
+			       unsigned long rate, unsigned long *parent_rate)
+{
+	const struct phy_config *fract_div_phy;
+	u32 int_div_clk;
+	u16 m;
+	u8 p, s;
+
+	/* If the clock is out of range return error instead of searching */
+	if (rate > 297000000 || rate < 22250000)
+		return -EINVAL;
+
+	/* Search the fractional divider lookup table */
+	fract_div_phy = fsl_samsung_hdmi_phy_lookup_rate(rate);
 
-	return -EINVAL;
+	/* If the rate is an exact match, return that value */
+	if (rate == fract_div_phy->pixclk)
+		return fract_div_phy->pixclk;
+
+	/* If the exact match isn't found, calculate the integer divider */
+	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
+
+	/* If the int_div_clk rate is an exact match, return that value */
+	if (int_div_clk == rate)
+		return int_div_clk;
+
+	/* If neither rate is an exact match, use the value from the LUT */
+	return fract_div_phy->pixclk;
+}
+
+static int phy_use_fract_div(struct fsl_samsung_hdmi_phy *phy, const struct phy_config *fract_div_phy)
+{
+	phy->cur_cfg = fract_div_phy;
+	dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider rate = %u\n",
+		phy->cur_cfg->pixclk);
+	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
 }
 
 static int phy_clk_set_rate(struct clk_hw *hw,
 			    unsigned long rate, unsigned long parent_rate)
 {
 	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
-	int i;
+	const struct phy_config *fract_div_phy;
+	u32 int_div_clk;
+	u16 m;
+	u8 p, s;
 
-	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
-		if (phy_pll_cfg[i].pixclk <= rate)
-			break;
+	/* Search the fractional divider lookup table */
+	fract_div_phy = fsl_samsung_hdmi_phy_lookup_rate(rate);
 
-	if (i < 0)
-		return -EINVAL;
+	/* If the rate is an exact match, use that value */
+	if (fract_div_phy->pixclk == rate)
+		return phy_use_fract_div(phy, fract_div_phy);
 
-	phy->cur_cfg = &phy_pll_cfg[i];
+	/*
+	 * If the rate from the fractional divider is not exact, check the integer divider,
+	 * and use it if that value is an exact match.
+	 */
+	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
+	if (int_div_clk == rate) {
+		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n",
+				   int_div_clk);
+
+		fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
+		phy->cur_cfg  = &calculated_phy_pll_cfg;
+		return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
+	}
 
-	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
+	/*
+	 * If neither the fractional divider nor the integer divider can find an exact value
+	 * fall back to using the fractional divider
+	 */
+	return phy_use_fract_div(phy, fract_div_phy);
 }
 
 static const struct clk_ops phy_clk_ops = {
-- 
2.43.0



From aford173 at gmail.com  Sat Sep 14 04:27:48 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 14 Sep 2024 06:27:48 -0500
Subject: [PATCH V8 4/5] phy: freescale: fsl-samsung-hdmi: Use closest divider
In-Reply-To: <20240914112816.520224-1-aford173@gmail.com>
References: <20240914112816.520224-1-aford173@gmail.com>
Message-ID: <20240914112816.520224-5-aford173@gmail.com>

Currently, if the clock values cannot be set to the exact rate,
the round_rate and set_rate functions use the closest value found in
the look-up-table.  In preparation of removing values from the LUT
that can be calculated evenly with the integer calculator, it's
necessary to ensure to check both the look-up-table and the integer
divider clock values to get the closest values to the requested
value.  It does this by measuring the difference between the
requested clock value and the closest value in both integer divider
calucator and the fractional clock look-up-table.

Which ever has the smallest difference between them is returned as
the closest rate.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
Tested-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
---
V8:  Replace Goto statement with calls to helper functions
     use ABS for both integer and fractional divider entries.
V7:  Because of the previous patch refactoring, the flow of this patch
     changed quite a bit to use more help functions and goto statements
     to hopefully make the code flow better and improve comment
     readability.  Because of the change, I removed s-o-b and r-b,
     and t-b tags.

V6:  Simplify the calculation of the closest rate and fix
     a situation where the integer divider values may not be properly
     setup before they are used.
     Fixup some comments
V5:  No Change
V4:  New to series
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 40 ++++++++++++++------
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 029de69fbeaf..381742e8b618 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -577,6 +577,16 @@ static void fsl_samsung_hdmi_calculate_phy(struct phy_config *cal_phy, unsigned
 	/* pll_div_regs 3-6 are fixed and pre-defined already */
 }
 
+static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate,
+						 u32 int_div_clk, u32 frac_div_clk)
+{
+	/* Calculate the absolute value of the differences and return whichever is closest */
+	if (abs((long)rate - (long)int_div_clk) < abs((long)(rate - (long)frac_div_clk)))
+		return int_div_clk;
+
+	return frac_div_clk;
+}
+
 static long phy_clk_round_rate(struct clk_hw *hw,
 			       unsigned long rate, unsigned long *parent_rate)
 {
@@ -615,6 +625,15 @@ static int phy_use_fract_div(struct fsl_samsung_hdmi_phy *phy, const struct phy_
 	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
 }
 
+static int phy_use_integer_div(struct fsl_samsung_hdmi_phy *phy,
+			       const struct phy_config *int_div_clk)
+{
+	phy->cur_cfg  = &calculated_phy_pll_cfg;
+	dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n",
+		phy->cur_cfg->pixclk);
+	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
+}
+
 static int phy_clk_set_rate(struct clk_hw *hw,
 			    unsigned long rate, unsigned long parent_rate)
 {
@@ -636,20 +655,19 @@ static int phy_clk_set_rate(struct clk_hw *hw,
 	 * and use it if that value is an exact match.
 	 */
 	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
-	if (int_div_clk == rate) {
-		dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n",
-				   int_div_clk);
-
-		fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
-		phy->cur_cfg  = &calculated_phy_pll_cfg;
-		return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
-	}
+	fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
+	if (int_div_clk == rate)
+		return phy_use_integer_div(phy, &calculated_phy_pll_cfg);
 
 	/*
-	 * If neither the fractional divider nor the integer divider can find an exact value
-	 * fall back to using the fractional divider
+	 * Compare the difference between the integer clock and the fractional clock against
+	 * the desired clock and which whichever is closest.
 	 */
-	return phy_use_fract_div(phy, fract_div_phy);
+	if (fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk,
+						  fract_div_phy->pixclk) == fract_div_phy->pixclk)
+		return phy_use_fract_div(phy, fract_div_phy);
+	else
+		return phy_use_integer_div(phy, &calculated_phy_pll_cfg);
 }
 
 static const struct clk_ops phy_clk_ops = {
-- 
2.43.0



From aford173 at gmail.com  Sat Sep 14 04:27:49 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 14 Sep 2024 06:27:49 -0500
Subject: [PATCH V8 5/5] phy: freescale: fsl-samsung-hdmi: Remove unnecessary LUT entries
In-Reply-To: <20240914112816.520224-1-aford173@gmail.com>
References: <20240914112816.520224-1-aford173@gmail.com>
Message-ID: <20240914112816.520224-6-aford173@gmail.com>

The lookup table contains entries which use the integer divider
instead of just the fractional divider. Since the set and round
functions check both the integer divider values and the LUT values,
it's no longer necessary to keep the integer divider values in the
lookup table, as can be dynamically calcuated.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Reviewed-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
Tested-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
---
V8: No change
V7: No Change
V6: Fix typos in commit message
V5: No Change
V4: New to series
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 83 +++-----------------
 1 file changed, 13 insertions(+), 70 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 381742e8b618..a08c1bfa657c 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -69,25 +69,16 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 23750000,
 		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
-	}, {
-		.pixclk = 24000000,
-		.pll_div_regs = { 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 24024000,
 		.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
 	}, {
 		.pixclk = 25175000,
 		.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
-	}, {
-		.pixclk = 25200000,
-		.pll_div_regs = { 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 26750000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 27000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 27027000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -105,18 +96,9 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 35000000,
 		.pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 36000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 36036000,
 		.pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
-	}, {
-		.pixclk = 40000000,
-		.pll_div_regs = { 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
-	}, {
-		.pixclk = 43200000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 43243200,
 		.pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
@@ -132,19 +114,13 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 50349650,
 		.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
-	}, {
-		.pixclk = 50400000,
-		.pll_div_regs = { 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 53250000,
 		.pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
 	}, {
 		.pixclk = 53500000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 54000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 54054000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -153,10 +129,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 59340659,
 		.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
-	}, {
-		.pixclk = 59400000,
-		.pll_div_regs = { 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 61500000,
 		.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -168,10 +141,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 70000000,
 		.pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 72000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 72072000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
@@ -183,10 +153,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 78500000,
 		.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
-	}, {
-		.pixclk = 80000000,
-		.pll_div_regs = { 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 82000000,
 		.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -213,10 +180,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 100699300,
 		.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
-	}, {
-		.pixclk = 100800000,
-		.pll_div_regs = { 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 102500000,
 		.pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
 	}, {
@@ -228,19 +192,13 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 107000000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
-	}, {
-		.pixclk = 108000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 108108000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
 	}, {
 		.pixclk = 118000000,
 		.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
-	}, {
-		.pixclk = 118800000,
-		.pll_div_regs = { 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 123000000,
 		.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
 	}, {
@@ -261,10 +219,7 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 140000000,
 		.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
-	}, {
-		.pixclk = 144000000,
-		.pll_div_regs = { 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 148352000,
 		.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
 	}, {
@@ -288,9 +243,6 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 165000000,
 		.pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
-	}, {
-		.pixclk = 180000000,
-		.pll_div_regs = { 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 185625000,
 		.pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
@@ -309,25 +261,16 @@ static const struct phy_config phy_pll_cfg[] = {
 	}, {
 		.pixclk = 213000000,
 		.pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
-	}, {
-		.pixclk = 216000000,
-		.pll_div_regs = { 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
 	}, {
 		.pixclk = 216216000,
 		.pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
-	}, {
-		.pixclk = 237600000,
-		.pll_div_regs = { 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 254000000,
 		.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
 	}, {
 		.pixclk = 277500000,
 		.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
-	}, {
-		.pixclk = 288000000,
-		.pll_div_regs = { 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
-	}, {
+	},  {
 		.pixclk = 297000000,
 		.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
 	},
-- 
2.43.0



From konradybcio at kernel.org  Sat Sep 14 04:29:31 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Sat, 14 Sep 2024 13:29:31 +0200
Subject: [PATCH v2 2/5] phy: qcom: edp: Introduce aux_cfg array for
 version specific aux settings
In-Reply-To: <20240913103755.7290-3-quic_mukhopad@quicinc.com>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
 <20240913103755.7290-3-quic_mukhopad@quicinc.com>
Message-ID: <9fee28de-24eb-46b1-aa5b-6febc2972a3c@kernel.org>

On 13.09.2024 12:37 PM, Soutrik Mukhopadhyay wrote:
> In order to support different HW versions, introduce aux_cfg array
> to move v4 specific aux configuration settings.
> 
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
> v2: Fixed review comments from Bjorn and Dmitry
> 	- Made aux_cfg array as const.
> 
> ---
>  drivers/phy/qualcomm/phy-qcom-edp.c | 37 ++++++++++++++++++-----------
>  1 file changed, 23 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> index da2b32fb5b45..bcd5aced9e06 100644
> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> @@ -90,6 +90,7 @@ struct phy_ver_ops {
>  
>  struct qcom_edp_phy_cfg {
>  	bool is_edp;
> +	const u8 *aux_cfg;
>  	const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
>  	const struct phy_ver_ops *ver_ops;
>  };
> @@ -186,11 +187,15 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
>  	.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
>  };
>  
> +static const u8 edp_phy_aux_cfg_v4[10] = {
> +	0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
> +};

How about we only abstract the values that differ? It would seem like more
platforms reuse about half of these magic bytes

Konrad


From dmitry.baryshkov at linaro.org  Sat Sep 14 05:04:48 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sat, 14 Sep 2024 15:04:48 +0300
Subject: [PATCH v2 2/5] phy: qcom: edp: Introduce aux_cfg array for
 version specific aux settings
In-Reply-To: <9fee28de-24eb-46b1-aa5b-6febc2972a3c@kernel.org>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
 <20240913103755.7290-3-quic_mukhopad@quicinc.com> <9fee28de-24eb-46b1-aa5b-6febc2972a3c@kernel.org>
Message-ID: <CAA8EJpquBih8jO_Tv8RFLVYN0c+N7KC45VztGSJHV87x22tdcA@mail.gmail.com>

On Sat, 14 Sept 2024 at 14:29, Konrad Dybcio <konradybcio at kernel.org> wrote:
>
> On 13.09.2024 12:37 PM, Soutrik Mukhopadhyay wrote:
> > In order to support different HW versions, introduce aux_cfg array
> > to move v4 specific aux configuration settings.
> >
> > Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> > ---
> > v2: Fixed review comments from Bjorn and Dmitry
> >       - Made aux_cfg array as const.
> >
> > ---
> >  drivers/phy/qualcomm/phy-qcom-edp.c | 37 ++++++++++++++++++-----------
> >  1 file changed, 23 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> > index da2b32fb5b45..bcd5aced9e06 100644
> > --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> > +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> > @@ -90,6 +90,7 @@ struct phy_ver_ops {
> >
> >  struct qcom_edp_phy_cfg {
> >       bool is_edp;
> > +     const u8 *aux_cfg;
> >       const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
> >       const struct phy_ver_ops *ver_ops;
> >  };
> > @@ -186,11 +187,15 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
> >       .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
> >  };
> >
> > +static const u8 edp_phy_aux_cfg_v4[10] = {
> > +     0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
> > +};
>
> How about we only abstract the values that differ? It would seem like more
> platforms reuse about half of these magic bytes

I think it's easier to review and compare the whole sequence rather
than numbers here and then numbers there.


-- 
With best wishes
Dmitry


From lkp at intel.com  Sat Sep 14 06:26:26 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 14 Sep 2024 21:26:26 +0800
Subject: [PATCH v8 2/5] phy: stm32: Add support for STM32MP25 COMBOPHY.
In-Reply-To: <20240911104646.2980821-3-christian.bruel@foss.st.com>
References: <20240911104646.2980821-3-christian.bruel@foss.st.com>
Message-ID: <202409142143.iJkSYPUK-lkp@intel.com>

Hi Christian,

kernel test robot noticed the following build errors:

[auto build test ERROR on atorgue-stm32/stm32-next]
[also build test ERROR on robh/for-next linus/master v6.11-rc7 next-20240913]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Christian-Bruel/dt-bindings-phy-Add-STM32MP25-COMBOPHY-bindings/20240911-185452
base:   https://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32.git stm32-next
patch link:    https://lore.kernel.org/r/20240911104646.2980821-3-christian.bruel%40foss.st.com
patch subject: [PATCH v8 2/5] phy: stm32: Add support for STM32MP25 COMBOPHY.
config: um-randconfig-r132-20240914 (https://download.01.org/0day-ci/archive/20240914/202409142143.iJkSYPUK-lkp at intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240914/202409142143.iJkSYPUK-lkp at 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 at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409142143.iJkSYPUK-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/phy/st/phy-stm32-combophy.c:12:
   In file included from include/linux/phy/phy.h:17:
   In file included from include/linux/regulator/consumer.h:35:
   In file included from include/linux/suspend.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:13:
   In file included from include/linux/cgroup.h:25:
   In file included from include/linux/kernel_stat.h:8:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from arch/um/include/asm/hardirq.h:5:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/um/include/asm/io.h:24:
   include/asm-generic/io.h:548:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __raw_readb(PCI_IOBASE + addr);
                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:561:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
   #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
                                                     ^
   In file included from drivers/phy/st/phy-stm32-combophy.c:12:
   In file included from include/linux/phy/phy.h:17:
   In file included from include/linux/regulator/consumer.h:35:
   In file included from include/linux/suspend.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:13:
   In file included from include/linux/cgroup.h:25:
   In file included from include/linux/kernel_stat.h:8:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from arch/um/include/asm/hardirq.h:5:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/um/include/asm/io.h:24:
   include/asm-generic/io.h:574:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
                                                     ^
   In file included from drivers/phy/st/phy-stm32-combophy.c:12:
   In file included from include/linux/phy/phy.h:17:
   In file included from include/linux/regulator/consumer.h:35:
   In file included from include/linux/suspend.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:13:
   In file included from include/linux/cgroup.h:25:
   In file included from include/linux/kernel_stat.h:8:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from arch/um/include/asm/hardirq.h:5:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/um/include/asm/io.h:24:
   include/asm-generic/io.h:585:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:595:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:605:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:693:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsb(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:701:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsw(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:709:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsl(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:718:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesb(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:727:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesw(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:736:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesl(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
>> drivers/phy/st/phy-stm32-combophy.c:140:8: error: implicit declaration of function 'FIELD_PREP' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                                      FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_OHM, imp_of));
                                      ^
>> drivers/phy/st/phy-stm32-combophy.c:143:12: error: implicit declaration of function 'FIELD_GET' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                   imp_of = FIELD_GET(STM32MP25_PCIEPRG_IMPCTRL_OHM, val);
                            ^
   drivers/phy/st/phy-stm32-combophy.c:161:8: error: implicit declaration of function 'FIELD_PREP' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                                      FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of));
                                      ^
   drivers/phy/st/phy-stm32-combophy.c:530:10: warning: variable 'ret' is uninitialized when used here [-Wuninitialized]
                   return ret;
                          ^~~
   drivers/phy/st/phy-stm32-combophy.c:515:9: note: initialize the variable 'ret' to silence this warning
           int ret, irq;
                  ^
                   = 0
   13 warnings and 3 errors generated.


vim +/FIELD_PREP +140 drivers/phy/st/phy-stm32-combophy.c

   113	
   114	static int stm32_impedance_tune(struct stm32_combophy *combophy)
   115	{
   116		u8 imp_size = ARRAY_SIZE(imp_lookup);
   117		u8 vswing_size = ARRAY_SIZE(imp_lookup[0].vswing);
   118		u8 imp_of, vswing_of;
   119		u32 max_imp = imp_lookup[0].microohm;
   120		u32 min_imp = imp_lookup[imp_size - 1].microohm;
   121		u32 max_vswing = imp_lookup[imp_size - 1].vswing[vswing_size - 1];
   122		u32 min_vswing = imp_lookup[0].vswing[0];
   123		u32 val;
   124	
   125		if (!of_property_read_u32(combophy->dev->of_node, "st,output-micro-ohms", &val)) {
   126			if (val < min_imp || val > max_imp) {
   127				dev_err(combophy->dev, "Invalid value %u for output ohm\n", val);
   128				return -EINVAL;
   129			}
   130	
   131			for (imp_of = 0; imp_of < ARRAY_SIZE(imp_lookup); imp_of++)
   132				if (imp_lookup[imp_of].microohm <= val)
   133					break;
   134	
   135			dev_dbg(combophy->dev, "Set %u micro-ohms output impedance\n",
   136				imp_lookup[imp_of].microohm);
   137	
   138			regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
   139					   STM32MP25_PCIEPRG_IMPCTRL_OHM,
 > 140					   FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_OHM, imp_of));
   141		} else {
   142			regmap_read(combophy->regmap, SYSCFG_PCIEPRGCR, &val);
 > 143			imp_of = FIELD_GET(STM32MP25_PCIEPRG_IMPCTRL_OHM, val);
   144		}
   145	
   146		if (!of_property_read_u32(combophy->dev->of_node, "st,output-vswing-microvolt", &val)) {
   147			if (val < min_vswing || val > max_vswing) {
   148				dev_err(combophy->dev, "Invalid value %u for output vswing\n", val);
   149				return -EINVAL;
   150			}
   151	
   152			for (vswing_of = 0; vswing_of < ARRAY_SIZE(imp_lookup[imp_of].vswing); vswing_of++)
   153				if (imp_lookup[imp_of].vswing[vswing_of] >= val)
   154					break;
   155	
   156			dev_dbg(combophy->dev, "Set %u microvolt swing\n",
   157				 imp_lookup[imp_of].vswing[vswing_of]);
   158	
   159			regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
   160					   STM32MP25_PCIEPRG_IMPCTRL_VSWING,
   161					   FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of));
   162		}
   163	
   164		return 0;
   165	}
   166	

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


From christophe.jaillet at wanadoo.fr  Sat Sep 14 09:07:24 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sat, 14 Sep 2024 18:07:24 +0200
Subject: [PATCH v3] phy: renesas: rcar-gen3-usb2: Fix an error handling path in rcar_gen3_phy_usb2_probe()
Message-ID: <290b25827e3f0742808940719455ff0c5cb9d01d.1726329925.git.christophe.jaillet@wanadoo.fr>

If an error occurs after the reset_control_deassert(),
reset_control_assert() must be called, as already done in the remove
function.

Use devm_add_action_or_reset() to add the missing call and simplify the
.remove() function accordingly.

Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus")
Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
This patch changes the order of function calls when releasing the resources
in the .remove function(). Looks fine to me, but pm_ functions are
sometimes tricky.

Changes in v3:
  - Use devm_add_action_or_reset()   [Biju Das]

Changes in v2: (broken proposal)
  - Re-use 'error' to simplify the patch   [claudiu beznea]
  - Update the commit description to explain why it is safe.
v2: https://lore.kernel.org/all/4efe2d0419cbe98163e2422ebe0c7896b8a5efed.1725717505.git.christophe.jaillet at wanadoo.fr/

v1: https://lore.kernel.org/all/fc9f7b444f0ca645411868992bbe16514aeccfed.1725652654.git.christophe.jaillet at wanadoo.fr/
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 58e123305152..c8a3727f56aa 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -668,6 +668,13 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np)
 	return candidate;
 }
 
+static void rcar_gen3_reset_assert(void *data)
+{
+	struct reset_control *rstc = data;
+
+	reset_control_assert(rstc);
+}
+
 static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)
 {
 	struct device *dev = channel->dev;
@@ -686,6 +693,11 @@ static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)
 	if (ret)
 		goto rpm_put;
 
+	ret = devm_add_action_or_reset(dev, rcar_gen3_reset_assert,
+				       channel->rstc);
+	if (ret)
+		return ret;
+
 	val = readl(channel->base + USB2_AHB_BUS_CTR);
 	val &= ~USB2_AHB_BUS_CTR_MBL_MASK;
 	val |= USB2_AHB_BUS_CTR_MBL_INCR4;
@@ -815,7 +827,6 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev)
 	if (channel->is_otg_channel)
 		device_remove_file(&pdev->dev, &dev_attr_role);
 
-	reset_control_assert(channel->rstc);
 	pm_runtime_disable(&pdev->dev);
 };
 
-- 
2.46.0



From christophe.jaillet at wanadoo.fr  Sat Sep 14 09:11:00 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sat, 14 Sep 2024 18:11:00 +0200
Subject: [PATCH v3] phy: renesas: rcar-gen3-usb2: Fix an error handling
 path in rcar_gen3_phy_usb2_probe()
In-Reply-To: <290b25827e3f0742808940719455ff0c5cb9d01d.1726329925.git.christophe.jaillet@wanadoo.fr>
References: <290b25827e3f0742808940719455ff0c5cb9d01d.1726329925.git.christophe.jaillet@wanadoo.fr>
Message-ID: <c394ebc5-c19d-4e52-9cb1-939be554a153@wanadoo.fr>

Le 14/09/2024 ? 18:07, Christophe JAILLET a ?crit?:
> If an error occurs after the reset_control_deassert(),
> reset_control_assert() must be called, as already done in the remove
> function.
> 
> Use devm_add_action_or_reset() to add the missing call and simplify the
> .remove() function accordingly.
> 
> Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus")
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> ---
> This patch changes the order of function calls when releasing the resources
> in the .remove function(). Looks fine to me, but pm_ functions are
> sometimes tricky.
> 
> Changes in v3:
>    - Use devm_add_action_or_reset()   [Biju Das]
> 
> Changes in v2: (broken proposal)
>    - Re-use 'error' to simplify the patch   [claudiu beznea]
>    - Update the commit description to explain why it is safe.
> v2: https://lore.kernel.org/all/4efe2d0419cbe98163e2422ebe0c7896b8a5efed.1725717505.git.christophe.jaillet at wanadoo.fr/
> 
> v1: https://lore.kernel.org/all/fc9f7b444f0ca645411868992bbe16514aeccfed.1725652654.git.christophe.jaillet at wanadoo.fr/
> ---
>   drivers/phy/renesas/phy-rcar-gen3-usb2.c | 13 ++++++++++++-
>   1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> index 58e123305152..c8a3727f56aa 100644
> --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> @@ -668,6 +668,13 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np)
>   	return candidate;
>   }
>   
> +static void rcar_gen3_reset_assert(void *data)
> +{
> +	struct reset_control *rstc = data;
> +
> +	reset_control_assert(rstc);
> +}
> +
>   static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)
>   {
>   	struct device *dev = channel->dev;
> @@ -686,6 +693,11 @@ static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)
>   	if (ret)
>   		goto rpm_put;
>   
> +	ret = devm_add_action_or_reset(dev, rcar_gen3_reset_assert,
> +				       channel->rstc);
> +	if (ret)
> +		return ret;

NACK

This is still broken.
Should be goto rpm_put;

I'll send a v4.

CJ

> +
>   	val = readl(channel->base + USB2_AHB_BUS_CTR);
>   	val &= ~USB2_AHB_BUS_CTR_MBL_MASK;
>   	val |= USB2_AHB_BUS_CTR_MBL_INCR4;
> @@ -815,7 +827,6 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev)
>   	if (channel->is_otg_channel)
>   		device_remove_file(&pdev->dev, &dev_attr_role);
>   
> -	reset_control_assert(channel->rstc);
>   	pm_runtime_disable(&pdev->dev);
>   };
>   



From christophe.jaillet at wanadoo.fr  Sat Sep 14 10:02:44 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sat, 14 Sep 2024 19:02:44 +0200
Subject: [PATCH v4] phy: renesas: rcar-gen3-usb2: Fix an error handling path in rcar_gen3_phy_usb2_probe()
Message-ID: <1457c401e3cdf792c5170f5c703cb24de137c19a.1726333335.git.christophe.jaillet@wanadoo.fr>

If an error occurs after the reset_control_deassert(),
reset_control_assert() must be called, as already done in the remove
function.

Use devm_add_action_or_reset() to add the missing call and simplify the
.remove() function accordingly.

Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus")
Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
This patch changes the order of function calls when releasing the resources
in the .remove function(). Looks fine to me, but pm_ functions are
sometimes tricky.

Changes in v4:
  - Use the error handling path in rcar_gen3_phy_usb2_init_bus()

Changes in v3:
  - Use devm_add_action_or_reset()   [Biju Das]
v3: https://lore.kernel.org/all/290b25827e3f0742808940719455ff0c5cb9d01d.1726329925.git.christophe.jaillet at wanadoo.fr/

Changes in v2: (broken proposal)
  - Re-use 'error' to simplify the patch   [claudiu beznea]
  - Update the commit description to explain why it is safe.
v2: https://lore.kernel.org/all/4efe2d0419cbe98163e2422ebe0c7896b8a5efed.1725717505.git.christophe.jaillet at wanadoo.fr/

v1: https://lore.kernel.org/all/fc9f7b444f0ca645411868992bbe16514aeccfed.1725652654.git.christophe.jaillet at wanadoo.fr/
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 58e123305152..f900fe42c311 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -668,6 +668,13 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np)
 	return candidate;
 }
 
+static void rcar_gen3_reset_assert(void *data)
+{
+	struct reset_control *rstc = data;
+
+	reset_control_assert(rstc);
+}
+
 static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)
 {
 	struct device *dev = channel->dev;
@@ -686,6 +693,11 @@ static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)
 	if (ret)
 		goto rpm_put;
 
+	ret = devm_add_action_or_reset(dev, rcar_gen3_reset_assert,
+				       channel->rstc);
+	if (ret)
+		goto rpm_put;
+
 	val = readl(channel->base + USB2_AHB_BUS_CTR);
 	val &= ~USB2_AHB_BUS_CTR_MBL_MASK;
 	val |= USB2_AHB_BUS_CTR_MBL_INCR4;
@@ -815,7 +827,6 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev)
 	if (channel->is_otg_channel)
 		device_remove_file(&pdev->dev, &dev_attr_role);
 
-	reset_control_assert(channel->rstc);
 	pm_runtime_disable(&pdev->dev);
 };
 
-- 
2.46.0



From ilordash02 at gmail.com  Sun Sep 15 07:13:40 2024
From: ilordash02 at gmail.com (Ilya Orazov)
Date: Sun, 15 Sep 2024 17:13:40 +0300
Subject: [PATCH v4 1/1] dt-bindings: phy: ti,tcan104x-can: Document Microchip ATA6561
In-Reply-To: <20240915141340.2802953-1-ilordash02@gmail.com>
References: <20240915141340.2802953-1-ilordash02@gmail.com>
Message-ID: <20240915141340.2802953-2-ilordash02@gmail.com>

Microchip ATA6561 is High-Speed CAN Transceiver with Standby Mode.
It is pin-compatible with TI TCAN1042 and has a compatible programming
model, therefore use ti,tcan1042 as fallback compatible.

Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Ilya Orazov <ilordash02 at gmail.com>
---
 .../devicetree/bindings/phy/ti,tcan104x-can.yaml    | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
index 79dad3e89aa6..4a8c3829d85d 100644
--- a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
+++ b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
@@ -14,10 +14,15 @@ properties:
     pattern: "^can-phy"
 
   compatible:
-    enum:
-      - nxp,tjr1443
-      - ti,tcan1042
-      - ti,tcan1043
+    oneOf:
+      - items:
+          - enum:
+              - microchip,ata6561
+          - const: ti,tcan1042
+      - enum:
+          - ti,tcan1042
+          - ti,tcan1043
+          - nxp,tjr1443
 
   '#phy-cells':
     const: 0
-- 
2.34.1



From ilordash02 at gmail.com  Sun Sep 15 07:13:39 2024
From: ilordash02 at gmail.com (Ilya Orazov)
Date: Sun, 15 Sep 2024 17:13:39 +0300
Subject: [PATCH v4 0/1] dt-bindings: phy: ti,tcan104x-can: Document Microchip
Message-ID: <20240915141340.2802953-1-ilordash02@gmail.com>

Hi,

In this v4, I addressed Krzysztof's comments and incorporated the changelog
and tag received from Conor.

v3:
https://lore.kernel.org/r/20240808191735.1483572-1-ilordash02 at gmail.com/

v2:
https://lore.kernel.org/r/20240807180210.1334724-1-ilordash02 at gmail.com/

v1:
https://lore.kernel.org/r/20240718210322.37492-1-ilordash02 at gmail.com/

First of all, I want to apologize for the silly mistakes in my patch
preparation. I wasn?t aware of the need to include the changelog and
received tags in new versions. This is my first patch in the kernel,
and I am very excited about it. I am eager to gain experience in working
on FOSS.

I greatly appreciate all your feedback, and I will do my best to address
and fix any issues.

Ilya Orazov (1):
  dt-bindings: phy: ti,tcan104x-can: Document Microchip ATA6561

 .../devicetree/bindings/phy/ti,tcan104x-can.yaml    | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)


base-commit: 872cf28b8df9c5c3a1e71a88ee750df7c2513971
-- 
2.34.1



From ilordash02 at gmail.com  Sun Sep 15 07:18:30 2024
From: ilordash02 at gmail.com (Ilya Orazov)
Date: Sun, 15 Sep 2024 17:18:30 +0300
Subject: [RESEND PATCH v4 0/1] dt-bindings: phy: ti,tcan104x-can: Document Microchip ATA6561
Message-ID: <20240915141831.2809208-1-ilordash02@gmail.com>

I wanted to kindly remind you about my patch submission. Just to clarify,
my patch doesn't introduce a new driver. Compatible fields from
ti,tcan104x-can.yaml is used by the phy-can-transceiver.c driver, which is
already part of the kernel. There was an issue with my previous attempt to
resend this patch. Please ignore it.

Could you please review it when you have a chance?

In this v4, I addressed Krzysztof's comments and incorporated the changelog
and tag received from Conor.

Thank you for your time!

v3:
https://lore.kernel.org/r/20240808191735.1483572-1-ilordash02 at gmail.com/

v2:
https://lore.kernel.org/r/20240807180210.1334724-1-ilordash02 at gmail.com/

v1:
https://lore.kernel.org/r/20240718210322.37492-1-ilordash02 at gmail.com/

First of all, I want to apologize for the silly mistakes in my patch
preparation. I wasn?t aware of the need to include the changelog and
received tags in new versions. This is my first patch in the kernel,
and I am very excited about it. I am eager to gain experience in working
on FOSS.

I greatly appreciate all your feedback, and I will do my best to address
and fix any issues.

Ilya Orazov (1):
  dt-bindings: phy: ti,tcan104x-can: Document Microchip ATA6561

 .../devicetree/bindings/phy/ti,tcan104x-can.yaml    | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)


base-commit: 872cf28b8df9c5c3a1e71a88ee750df7c2513971
-- 
2.34.1



From ilordash02 at gmail.com  Sun Sep 15 07:18:31 2024
From: ilordash02 at gmail.com (Ilya Orazov)
Date: Sun, 15 Sep 2024 17:18:31 +0300
Subject: [RESEND PATCH v4 1/1] dt-bindings: phy: ti,tcan104x-can: Document Microchip ATA6561
In-Reply-To: <20240915141831.2809208-1-ilordash02@gmail.com>
References: <20240915141831.2809208-1-ilordash02@gmail.com>
Message-ID: <20240915141831.2809208-2-ilordash02@gmail.com>

Microchip ATA6561 is High-Speed CAN Transceiver with Standby Mode.
It is pin-compatible with TI TCAN1042 and has a compatible programming
model, therefore use ti,tcan1042 as fallback compatible.

Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Ilya Orazov <ilordash02 at gmail.com>
---
 .../devicetree/bindings/phy/ti,tcan104x-can.yaml    | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
index 79dad3e89aa6..4a8c3829d85d 100644
--- a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
+++ b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
@@ -14,10 +14,15 @@ properties:
     pattern: "^can-phy"
 
   compatible:
-    enum:
-      - nxp,tjr1443
-      - ti,tcan1042
-      - ti,tcan1043
+    oneOf:
+      - items:
+          - enum:
+              - microchip,ata6561
+          - const: ti,tcan1042
+      - enum:
+          - ti,tcan1042
+          - ti,tcan1043
+          - nxp,tjr1443
 
   '#phy-cells':
     const: 0
-- 
2.34.1



From biju.das.jz at bp.renesas.com  Sun Sep 15 08:23:13 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Sun, 15 Sep 2024 15:23:13 +0000
Subject: [PATCH v4] phy: renesas: rcar-gen3-usb2: Fix an error handling
 path in rcar_gen3_phy_usb2_probe()
In-Reply-To: <1457c401e3cdf792c5170f5c703cb24de137c19a.1726333335.git.christophe.jaillet@wanadoo.fr>
References: <1457c401e3cdf792c5170f5c703cb24de137c19a.1726333335.git.christophe.jaillet@wanadoo.fr>
Message-ID: <TYCPR01MB113329930BA5E2149C9BE2A1986672@TYCPR01MB11332.jpnprd01.prod.outlook.com>

Hi,

> -----Original Message-----
> From: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> Sent: Saturday, September 14, 2024 6:03 PM
> Subject: [PATCH v4] phy: renesas: rcar-gen3-usb2: Fix an error handling path in
> rcar_gen3_phy_usb2_probe()
> 
> If an error occurs after the reset_control_deassert(),
> reset_control_assert() must be called, as already done in the remove function.
> 
> Use devm_add_action_or_reset() to add the missing call and simplify the
> .remove() function accordingly.
> 
> Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus")
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> ---
> This patch changes the order of function calls when releasing the resources in the .remove function().
> Looks fine to me, but pm_ functions are sometimes tricky.
> 
> Changes in v4:
>   - Use the error handling path in rcar_gen3_phy_usb2_init_bus()
> 
> Changes in v3:
>   - Use devm_add_action_or_reset()   [Biju Das]
> v3:
> https://lore.kernel.org/all/290b25827e3f0742808940719455ff0c5cb9d01d.1726329925.git.christophe.jaillet
> @wanadoo.fr/
> 
> Changes in v2: (broken proposal)
>   - Re-use 'error' to simplify the patch   [claudiu beznea]
>   - Update the commit description to explain why it is safe.
> v2:
> https://lore.kernel.org/all/4efe2d0419cbe98163e2422ebe0c7896b8a5efed.1725717505.git.christophe.jaillet
> @wanadoo.fr/
> 
> v1:
> https://lore.kernel.org/all/fc9f7b444f0ca645411868992bbe16514aeccfed.1725652654.git.christophe.jaillet
> @wanadoo.fr/
> ---
>  drivers/phy/renesas/phy-rcar-gen3-usb2.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> index 58e123305152..f900fe42c311 100644
> --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> @@ -668,6 +668,13 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np)
>  	return candidate;
>  }
> 
> +static void rcar_gen3_reset_assert(void *data) {
> +	struct reset_control *rstc = data;

nit:
Maybe since it is void*, you could avoid this assignment and use data instead??

Reviewed-by: Biju Das <biju.das.jz at bp.renesas.com>

Cheers,
Biju
> +
> +	reset_control_assert(rstc);
> +}
> +
>  static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)  {
>  	struct device *dev = channel->dev;
> @@ -686,6 +693,11 @@ static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)
>  	if (ret)
>  		goto rpm_put;
> 
> +	ret = devm_add_action_or_reset(dev, rcar_gen3_reset_assert,
> +				       channel->rstc);
> +	if (ret)
> +		goto rpm_put;
> +
>  	val = readl(channel->base + USB2_AHB_BUS_CTR);
>  	val &= ~USB2_AHB_BUS_CTR_MBL_MASK;
>  	val |= USB2_AHB_BUS_CTR_MBL_INCR4;
> @@ -815,7 +827,6 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev)
>  	if (channel->is_otg_channel)
>  		device_remove_file(&pdev->dev, &dev_attr_role);
> 
> -	reset_control_assert(channel->rstc);
>  	pm_runtime_disable(&pdev->dev);
>  };
> 
> --
> 2.46.0



From dmitry.baryshkov at linaro.org  Sun Sep 15 22:29:35 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Sep 2024 07:29:35 +0200
Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501
 DP/HDMI driver
In-Reply-To: <PAXPR04MB94484D86A71A7527ADD42EA4F4652@PAXPR04MB9448.eurprd04.prod.outlook.com>
References: <cover.1719903904.git.Sandor.yu@nxp.com> <359914108b879e995d4a39de32a33310009f0fab.1719903904.git.Sandor.yu@nxp.com>
 <20240702-quartz-salamander-of-culture-eec264@houat> <PAXPR04MB94480AB0490BBF00D2BA17BBF4932@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <20240903-gay-capable-hound-3cbef2@houat> <PAXPR04MB9448EF507CB5C18A43239A80F49E2@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <20240912-zippy-mongoose-of-domination-2ebc1d@houat> <PAXPR04MB94484D86A71A7527ADD42EA4F4652@PAXPR04MB9448.eurprd04.prod.outlook.com>
Message-ID: <CAA8EJpphegHmBFgH1-n9PEkrr-Ys+HCvekKGNYRp=xQxgmC0Cw@mail.gmail.com>

On Fri, 13 Sept 2024 at 11:46, Sandor Yu <sandor.yu at nxp.com> wrote:
>
>
> > Subject: Re: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501
> > DP/HDMI driver
> >
> > On Fri, Sep 06, 2024 at 02:50:08AM GMT, Sandor Yu wrote:
> > > > On Tue, Sep 03, 2024 at 06:07:25AM GMT, Sandor Yu wrote:
> > > > > > -----Original Message-----
> > > > > > From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On
> > > > > > Behalf Of Maxime Ripard
> > > > > > Sent: 2024?7?2? 21:25
> > > > > > To: Sandor Yu <sandor.yu at nxp.com>
> > > > > > Cc: dmitry.baryshkov at linaro.org; andrzej.hajda at intel.com;
> > > > > > neil.armstrong at linaro.org; Laurent Pinchart
> > > > > > <laurent.pinchart at ideasonboard.com>; jonas at kwiboo.se;
> > > > > > jernej.skrabec at gmail.com; airlied at gmail.com; daniel at ffwll.ch;
> > > > > > robh+dt at kernel.org; krzysztof.kozlowski+dt at linaro.org;
> > > > > > shawnguo at kernel.org; s.hauer at pengutronix.de;
> > festevam at gmail.com;
> > > > > > vkoul at kernel.org; dri-devel at lists.freedesktop.org;
> > > > > > devicetree at vger.kernel.org;
> > > > > > linux-arm-kernel at lists.infradead.org;
> > > > > > linux-kernel at vger.kernel.org; linux-phy at lists.infradead.org;
> > > > > > kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>; Oliver
> > > > > > Brown <oliver.brown at nxp.com>; alexander.stein at ew.tq-group.com;
> > > > > > sam at ravnborg.org
> > > > > > Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add
> > > > > > MHDP8501 DP/HDMI driver
> > > > > >
> > > > > > Hi,
> > > > > >
> > > > > > There's still the scrambler issue we discussed on v15, but I
> > > > > > have some more comments.
> > > > > >
> > > > > > On Tue, Jul 02, 2024 at 08:22:36PM GMT, Sandor Yu wrote:
> > > > > > > +enum drm_connector_status cdns_mhdp8501_detect(struct
> > > > > > > +cdns_mhdp8501_device *mhdp) {
> > > > > > > +   u8 hpd = 0xf;
> > > > > > > +
> > > > > > > +   hpd = cdns_mhdp8501_read_hpd(mhdp);
> > > > > > > +   if (hpd == 1)
> > > > > > > +           return connector_status_connected;
> > > > > > > +   else if (hpd == 0)
> > > > > > > +           return connector_status_disconnected;
> > > > > > > +
> > > > > > > +   dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n",
> > hpd);
> > > > > > > +   return connector_status_unknown; }
> > > > > > > +
> > > > > > > +static void hotplug_work_func(struct work_struct *work) {
> > > > > > > +   struct cdns_mhdp8501_device *mhdp = container_of(work,
> > > > > > > +                                                struct cdns_mhdp8501_device,
> > > > > > > +                                                hotplug_work.work);
> > > > > > > +   enum drm_connector_status status =
> > > > cdns_mhdp8501_detect(mhdp);
> > > > > > > +
> > > > > > > +   drm_bridge_hpd_notify(&mhdp->bridge, status);
> > > > > > > +
> > > > > > > +   if (status == connector_status_connected) {
> > > > > > > +           /* Cable connected  */
> > > > > > > +           DRM_INFO("HDMI/DP Cable Plug In\n");
> > > > > > > +           enable_irq(mhdp->irq[IRQ_OUT]);
> > > > > > > +   } else if (status == connector_status_disconnected) {
> > > > > > > +           /* Cable Disconnected  */
> > > > > > > +           DRM_INFO("HDMI/DP Cable Plug Out\n");
> > > > > > > +           enable_irq(mhdp->irq[IRQ_IN]);
> > > > > > > +   }
> > > > > > > +}
> > > > > >
> > > > > > You shouldn't play with the interrupt being enabled here:
> > > > > > hotplug interrupts should always enabled.
> > > > > >
> > > > > > If you can't for some reason, the reason should be documented in
> > > > > > your
> > > > driver.
> > > > >
> > > > > iMX8MQ have two HPD interrupters, one for plugout and the other
> > > > > for plugin, because they could not be masked, so we have to enable
> > > > > one and
> > > > disable the other.
> > > > > I will add more comments here.
> > > >
> > > > Right, but why do you need to enable and disable them? Do you get
> > > > spurious interrupts?
> > >
> > > They don't have status registers and cannot be masked. If they are not
> > > disabled, they will continuously generate interrupts. Therefore, I have to
> > disable one and enable the other.
> >
> > Sorry, I still don't get it. How can it be useful to detect hotplug interrupts if it
> > constantly sends spurious interrupts when it's enabled?
>
> Yes, this interrupt is different from a normal one; it's likely a design flaw.
> For instance, the plugin interrupt is continuously generated as long as the cable is plugged in,
> only stopping when the cable is unplugged.
> That's why two interrupts are used to detect cable plugout and plugin separately.
> If interrupts aren't used, the only option is polling.

I think I've seen such strange design on other platforms, level
interrupt for HPD, which needs to be disabled via disable_irq().

>
> >
> > > > > > > +   /* Mailbox protect for HDMI PHY access */
> > > > > > > +   mutex_lock(&mhdp->mbox_mutex);
> > > > > > > +   ret = phy_init(mhdp->phy);
> > > > > > > +   mutex_unlock(&mhdp->mbox_mutex);
> > > > > > > +   if (ret) {
> > > > > > > +           dev_err(dev, "Failed to initialize PHY: %d\n", ret);
> > > > > > > +           goto clk_disable;
> > > > > > > +   }
> > > > > > > +
> > > > > > > +   /* Mailbox protect for HDMI PHY access */
> > > > > > > +   mutex_lock(&mhdp->mbox_mutex);
> > > > > > > +   ret = phy_set_mode(mhdp->phy, phy_mode);
> > > > > > > +   mutex_unlock(&mhdp->mbox_mutex);
> > > > > > > +   if (ret) {
> > > > > > > +           dev_err(dev, "Failed to configure PHY: %d\n", ret);
> > > > > > > +           goto clk_disable;
> > > > > > > +   }
> > > > > >
> > > > > > Why do you need a shared mutex between the phy and HDMI
> > controller?
> > > > >
> > > > > Both PHY and HDMI controller could access to the HDMI firmware by
> > > > > mailbox, So add mutex to avoid race condition.
> > > >
> > > > That should be handled at either the phy or mailbox level, not in
> > > > your hdmi driver.
> > >
> > > In both HDMI driver and PHY driver, every mailbox access had protected
> > > by its owns mutex. However, this mutex can only protect each mailbox
> > > access within their respective drivers, and it cannot provide
> > > protection for access between the HDMI and PHY drivers.
> > >
> > > The PHY driver only provides two API functions, and these functions
> > > are only called in the HDMI driver. Therefore, when accessing these
> > > functions, we use a mutex to protect them. This ensures that mailbox
> > > access is protected across different PHY and HDMI drivers.
> >
> > It's really about abstraction. You're using a publicly defined API, and change
> > the semantics for your driver only, and that's not ok.
> >
> > Why can't the mailbox driver itself serialize the accesses from any user, HDMI
> > and PHY drivers included?
> >
>
> In the current code implementation, cdns-mhdp-helper.c isn't a standalone driver but rather a library.
> It provides fundamental mailbox access functions and basic register read/write operations that rely on the mailbox.
> These functions are highly reusable across MHDP8501 and MHDP8546 and can be leveraged by future MHDP versions.
>
> However, most MHDP firmware interactions involve a sequence of mailbox accesses, including sending commands and receiving firmware responses.
> These commands constitute a significant portion of all firmware interactions, encompassing operations like EDID reading and DP link training.
> Unfortunately, these commands cannot be reused between MHDP8501 and MHDP8546.
>
> Creating a dedicated mailbox driver with its own mutex would effectively address race conditions.
> However, this would necessitate relocating all mailbox-related functions to this driver.
> Including these non-reusable functions would defeat the purpose of code reuse.
>
> To strike a balance between code reusability and race condition mitigation, adding mutexes to PHY access functions seems like a reasonable solution.

You seem to have two kinds of scenarios when talking to MHDP: just
cdns_mhdp_mailbox_send(), no response needed and then the
cdns_mhdp_mailbox_send() /  cdns_mhdp_mailbox_recv_header() /
cdns_mhdp_mailbox_recv_data() sequence. Extract those + the mutex
access to separate functions, add a mutex to those sequences and use
them as a high-level API for your HDMI and PHY drivers.

Adding mutexes around phy_foo() calls doesn't look like a proper
solution _at_ _all_.

>
> Sandor
>
> > > > > >
> > > > > > > +static enum drm_mode_status
> > > > > > > +cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
> > > > > > > +                          const struct drm_display_mode *mode,
> > > > > > > +                          unsigned long long tmds_rate) {
> > > > > > > +   struct cdns_mhdp8501_device *mhdp =
> > bridge->driver_private;
> > > > > > > +   union phy_configure_opts phy_cfg;
> > > > > > > +   int ret;
> > > > > > > +
> > > > > > > +   phy_cfg.hdmi.tmds_char_rate = tmds_rate;
> > > > > > > +
> > > > > > > +   /* Mailbox protect for HDMI PHY access */
> > > > > > > +   mutex_lock(&mhdp->mbox_mutex);
> > > > > > > +   ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0,
> > &phy_cfg);
> > > > > > > +   mutex_unlock(&mhdp->mbox_mutex);
> > > > > > > +   if (ret < 0)
> > > > > > > +           return MODE_CLOCK_RANGE;
> > > > > > > +
> > > > > > > +   return MODE_OK;
> > > > > > > +}
> > > > > > > +
> > > > > > > +static enum drm_mode_status
> > > > > > > +cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
> > > > > > > +                       const struct drm_display_info *info,
> > > > > > > +                       const struct drm_display_mode *mode) {
> > > > > > > +   unsigned long long tmds_rate;
> > > > > > > +
> > > > > > > +   /* We don't support double-clocked and Interlaced modes */
> > > > > > > +   if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
> > > > > > > +       mode->flags & DRM_MODE_FLAG_INTERLACE)
> > > > > > > +           return MODE_BAD;
> > > > > > > +
> > > > > > > +   /* MAX support pixel clock rate 594MHz */
> > > > > > > +   if (mode->clock > 594000)
> > > > > > > +           return MODE_CLOCK_HIGH;
> > > > > >
> > > > > > This needs to be in the tmds_char_rate_valid function
> > > > > This clock rate check is covered by function
> > > > > tmds_char_rate_valid() It could be removed if keep function
> > > > > tmds_char_rate_valid() be called by
> > > > mode_valid.
> > > >
> > > > Yeah, it's not something you should have to duplicate.
> > > >
> > > > > >
> > > > > > > +   if (mode->hdisplay > 3840)
> > > > > > > +           return MODE_BAD_HVALUE;
> > > > > > > +
> > > > > > > +   if (mode->vdisplay > 2160)
> > > > > > > +           return MODE_BAD_VVALUE;
> > > > > > > +
> > > > > > > +   tmds_rate = mode->clock * 1000ULL;
> > > > > > > +   return cdns_hdmi_tmds_char_rate_valid(bridge, mode,
> > > > > > > +tmds_rate);
> > > > > >
> > > > > > It will already be called by the core so this is redundant.
> > > > >
> > > > > mode_valid function is use to filter the mode list in
> > > > > drm_helper_probe_single_connector_modes(),
> > > > > if function cdns_hdmi_tmds_char_rate_valid() is not called,
> > > > > unsupported
> > > > modes will in mode list.
> > > >
> > > > It's probably something we should deal with in the core somehow. I'm
> > > > not entirely sure how to reconcile drm_bridge_connector and the hdmi
> > > > framework there, but we should at the very least provide a
> > > > mode_valid helper for bridges.
> > >
> > > I agree with that. In fact, I'm a bit confused about the current
> > > mode_valid and tmds_char_rate_valid functions. Ideally, we should find
> > > a way to make tmds_char_rate_valid also work for filtering out the
> > > mode list, rather than just during atomic_check.
> >
> > Yeah, definitely. The way we did so on vc4 for example was to compute the
> > rate for a 8bpc, RGB, output and try to validate that. I think it would be
> > reasonable to start with that.

+1, please extract this code as a helper. You can even submit it
separately, reworking sun4i and vc4 to use a new helper.

-- 
With best wishes
Dmitry


From frieder.schrempf at kontron.de  Mon Sep 16 00:15:49 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Mon, 16 Sep 2024 09:15:49 +0200
Subject: [PATCH V8 3/5] phy: freescale: fsl-samsung-hdmi: Support dynamic
 integer
In-Reply-To: <20240914112816.520224-4-aford173@gmail.com>
References: <20240914112816.520224-1-aford173@gmail.com>
 <20240914112816.520224-4-aford173@gmail.com>
Message-ID: <cddbe1ad-047a-4c28-9594-db574cfa77f9@kontron.de>

On 14.09.24 1:27 PM, Adam Ford wrote:
> There is currently a look-up table for a variety of resolutions.
> Since the phy has the ability to dynamically calculate the values
> necessary to use the intger divider which should allow more
> resolutions without having to update the look-up-table.
> 
> If the lookup table cannot find an exact match, fall back to the
> dynamic calculator of the integer divider.
> 
> Previously, the value of P was hard-coded to 1, this required an
> update to the phy_pll_cfg table to add in the extra value into the
> table, so if the value of P is calculated to be something else
> by the PMS calculator, the calculated_phy_pll_cfg structure
> can be used instead without having to keep track of which method
> was used.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
> Tested-by: Dominique Martinet <dominique.martinet at atmark-techno.com>

Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>


From frieder.schrempf at kontron.de  Mon Sep 16 00:16:14 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Mon, 16 Sep 2024 09:16:14 +0200
Subject: [PATCH V8 4/5] phy: freescale: fsl-samsung-hdmi: Use closest
 divider
In-Reply-To: <20240914112816.520224-5-aford173@gmail.com>
References: <20240914112816.520224-1-aford173@gmail.com>
 <20240914112816.520224-5-aford173@gmail.com>
Message-ID: <c655e745-0289-4d12-9d91-612c18d6e607@kontron.de>

On 14.09.24 1:27 PM, Adam Ford wrote:
> Currently, if the clock values cannot be set to the exact rate,
> the round_rate and set_rate functions use the closest value found in
> the look-up-table.  In preparation of removing values from the LUT
> that can be calculated evenly with the integer calculator, it's
> necessary to ensure to check both the look-up-table and the integer
> divider clock values to get the closest values to the requested
> value.  It does this by measuring the difference between the
> requested clock value and the closest value in both integer divider
> calucator and the fractional clock look-up-table.
> 
> Which ever has the smallest difference between them is returned as
> the closest rate.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
> Tested-by: Dominique Martinet <dominique.martinet at atmark-techno.com>

Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>


From johan+linaro at kernel.org  Mon Sep 16 01:23:06 2024
From: johan+linaro at kernel.org (Johan Hovold)
Date: Mon, 16 Sep 2024 10:23:06 +0200
Subject: [PATCH 2/3] arm64: dts: qcom: x1e80100: fix PCIe4 and PCIe6a PHY clocks
In-Reply-To: <20240916082307.29393-1-johan+linaro@kernel.org>
References: <20240916082307.29393-1-johan+linaro@kernel.org>
Message-ID: <20240916082307.29393-3-johan+linaro@kernel.org>

Add the missing clkref enable and pipediv2 clocks to the PCIe4 and
PCIe6a PHYs.

Fixes: 5eb83fc10289 ("arm64: dts: qcom: x1e80100: Add PCIe nodes")
Cc: stable at vger.kernel.org	# 6.9
Cc: Abel Vesa <abel.vesa at linaro.org>
Signed-off-by: Johan Hovold <johan+linaro at kernel.org>
---
 arch/arm64/boot/dts/qcom/x1e80100.dtsi | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
index 0cf4f3c12428..53e7d1e603cb 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
+++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
@@ -2980,14 +2980,16 @@ pcie6a_phy: phy at 1bfc000 {
 
 			clocks = <&gcc GCC_PCIE_6A_PHY_AUX_CLK>,
 				 <&gcc GCC_PCIE_6A_CFG_AHB_CLK>,
-				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&tcsr TCSR_PCIE_4L_CLKREF_EN>,
 				 <&gcc GCC_PCIE_6A_PHY_RCHNG_CLK>,
-				 <&gcc GCC_PCIE_6A_PIPE_CLK>;
+				 <&gcc GCC_PCIE_6A_PIPE_CLK>,
+				 <&gcc GCC_PCIE_6A_PIPEDIV2_CLK>;
 			clock-names = "aux",
 				      "cfg_ahb",
 				      "ref",
 				      "rchng",
-				      "pipe";
+				      "pipe",
+				      "pipediv2";
 
 			resets = <&gcc GCC_PCIE_6A_PHY_BCR>,
 				 <&gcc GCC_PCIE_6A_NOCSR_COM_PHY_BCR>;
@@ -3232,14 +3234,16 @@ pcie4_phy: phy at 1c0e000 {
 
 			clocks = <&gcc GCC_PCIE_4_AUX_CLK>,
 				 <&gcc GCC_PCIE_4_CFG_AHB_CLK>,
-				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&tcsr TCSR_PCIE_2L_4_CLKREF_EN>,
 				 <&gcc GCC_PCIE_4_PHY_RCHNG_CLK>,
-				 <&gcc GCC_PCIE_4_PIPE_CLK>;
+				 <&gcc GCC_PCIE_4_PIPE_CLK>,
+				 <&gcc GCC_PCIE_4_PIPEDIV2_CLK>;
 			clock-names = "aux",
 				      "cfg_ahb",
 				      "ref",
 				      "rchng",
-				      "pipe";
+				      "pipe",
+				      "pipediv2";
 
 			resets = <&gcc GCC_PCIE_4_PHY_BCR>;
 			reset-names = "phy";
-- 
2.44.2



From johan+linaro at kernel.org  Mon Sep 16 01:23:04 2024
From: johan+linaro at kernel.org (Johan Hovold)
Date: Mon, 16 Sep 2024 10:23:04 +0200
Subject: [PATCH 0/3] arm64: dts: qcom: x1e80100: fix missing PCIe PHY clocks
Message-ID: <20240916082307.29393-1-johan+linaro@kernel.org>

Add the missing clkref enable and pipediv2 clocks to the x1e80100 PCIe
PHYs as needed for functional PCIe (e.g. without relying on boot
firmware to have left these on).

Johan


Johan Hovold (3):
  dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: add missing x1e80100
    pipediv2 clocks
  arm64: dts: qcom: x1e80100: fix PCIe4 and PCIe6a PHY clocks
  arm64: dts: qcom: x1e80100: fix PCIe5 PHY clocks

 .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml       |  4 ++--
 arch/arm64/boot/dts/qcom/x1e80100.dtsi        | 24 ++++++++++++-------
 2 files changed, 17 insertions(+), 11 deletions(-)

-- 
2.44.2



From johan+linaro at kernel.org  Mon Sep 16 01:23:07 2024
From: johan+linaro at kernel.org (Johan Hovold)
Date: Mon, 16 Sep 2024 10:23:07 +0200
Subject: [PATCH 3/3] arm64: dts: qcom: x1e80100: fix PCIe5 PHY clocks
In-Reply-To: <20240916082307.29393-1-johan+linaro@kernel.org>
References: <20240916082307.29393-1-johan+linaro@kernel.org>
Message-ID: <20240916082307.29393-4-johan+linaro@kernel.org>

Add the missing clkref enable and pipediv2 clocks to the PCIe5 PHY.

Fixes: 62ab23e15508 ("arm64: dts: qcom: x1e80100: add PCIe5 nodes")
Signed-off-by: Johan Hovold <johan+linaro at kernel.org>
---
 arch/arm64/boot/dts/qcom/x1e80100.dtsi | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
index 53e7d1e603cb..d1bb14a375c3 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
+++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
@@ -3104,14 +3104,16 @@ pcie5_phy: phy at 1c06000 {
 
 			clocks = <&gcc GCC_PCIE_5_AUX_CLK>,
 				 <&gcc GCC_PCIE_5_CFG_AHB_CLK>,
-				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&tcsr TCSR_PCIE_2L_5_CLKREF_EN>,
 				 <&gcc GCC_PCIE_5_PHY_RCHNG_CLK>,
-				 <&gcc GCC_PCIE_5_PIPE_CLK>;
+				 <&gcc GCC_PCIE_5_PIPE_CLK>,
+				 <&gcc GCC_PCIE_5_PIPEDIV2_CLK>;
 			clock-names = "aux",
 				      "cfg_ahb",
 				      "ref",
 				      "rchng",
-				      "pipe";
+				      "pipe",
+				      "pipediv2";
 
 			resets = <&gcc GCC_PCIE_5_PHY_BCR>;
 			reset-names = "phy";
-- 
2.44.2



From johan+linaro at kernel.org  Mon Sep 16 01:23:05 2024
From: johan+linaro at kernel.org (Johan Hovold)
Date: Mon, 16 Sep 2024 10:23:05 +0200
Subject: [PATCH 1/3] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: add missing x1e80100 pipediv2 clocks
In-Reply-To: <20240916082307.29393-1-johan+linaro@kernel.org>
References: <20240916082307.29393-1-johan+linaro@kernel.org>
Message-ID: <20240916082307.29393-2-johan+linaro@kernel.org>

The x1e80100 QMP PCIe PHYs all have a pipediv2 clock that needs to be
described.

Fixes: e94b29f2bd73 ("dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the X1E80100 QMP PCIe PHYs")
Cc: Abel Vesa <abel.vesa at linaro.org>
Signed-off-by: Johan Hovold <johan+linaro at kernel.org>
---
 .../devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
index dcf4fa55fbba..447b379aa83d 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -154,8 +154,6 @@ allOf:
               - qcom,sm8550-qmp-gen4x2-pcie-phy
               - qcom,sm8650-qmp-gen3x2-pcie-phy
               - qcom,sm8650-qmp-gen4x2-pcie-phy
-              - qcom,x1e80100-qmp-gen3x2-pcie-phy
-              - qcom,x1e80100-qmp-gen4x2-pcie-phy
     then:
       properties:
         clocks:
@@ -171,6 +169,8 @@ allOf:
               - qcom,sc8280xp-qmp-gen3x1-pcie-phy
               - qcom,sc8280xp-qmp-gen3x2-pcie-phy
               - qcom,sc8280xp-qmp-gen3x4-pcie-phy
+              - qcom,x1e80100-qmp-gen3x2-pcie-phy
+              - qcom,x1e80100-qmp-gen4x2-pcie-phy
               - qcom,x1e80100-qmp-gen4x4-pcie-phy
     then:
       properties:
-- 
2.44.2



From abel.vesa at linaro.org  Mon Sep 16 04:36:23 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Mon, 16 Sep 2024 14:36:23 +0300
Subject: [PATCH 2/3] arm64: dts: qcom: x1e80100: fix PCIe4 and PCIe6a PHY
 clocks
In-Reply-To: <20240916082307.29393-3-johan+linaro@kernel.org>
References: <20240916082307.29393-1-johan+linaro@kernel.org>
 <20240916082307.29393-3-johan+linaro@kernel.org>
Message-ID: <ZugYN0L/dj0iJxaH@linaro.org>

On 24-09-16 10:23:06, Johan Hovold wrote:
> Add the missing clkref enable and pipediv2 clocks to the PCIe4 and
> PCIe6a PHYs.
> 
> Fixes: 5eb83fc10289 ("arm64: dts: qcom: x1e80100: Add PCIe nodes")
> Cc: stable at vger.kernel.org	# 6.9
> Cc: Abel Vesa <abel.vesa at linaro.org>
> Signed-off-by: Johan Hovold <johan+linaro at kernel.org>

Reviewed-by: Abel Vesa <abel.vesa at linaro.org>

> ---
>  arch/arm64/boot/dts/qcom/x1e80100.dtsi | 16 ++++++++++------
>  1 file changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> index 0cf4f3c12428..53e7d1e603cb 100644
> --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> +++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> @@ -2980,14 +2980,16 @@ pcie6a_phy: phy at 1bfc000 {
>  
>  			clocks = <&gcc GCC_PCIE_6A_PHY_AUX_CLK>,
>  				 <&gcc GCC_PCIE_6A_CFG_AHB_CLK>,
> -				 <&rpmhcc RPMH_CXO_CLK>,
> +				 <&tcsr TCSR_PCIE_4L_CLKREF_EN>,
>  				 <&gcc GCC_PCIE_6A_PHY_RCHNG_CLK>,
> -				 <&gcc GCC_PCIE_6A_PIPE_CLK>;
> +				 <&gcc GCC_PCIE_6A_PIPE_CLK>,
> +				 <&gcc GCC_PCIE_6A_PIPEDIV2_CLK>;
>  			clock-names = "aux",
>  				      "cfg_ahb",
>  				      "ref",
>  				      "rchng",
> -				      "pipe";
> +				      "pipe",
> +				      "pipediv2";
>  
>  			resets = <&gcc GCC_PCIE_6A_PHY_BCR>,
>  				 <&gcc GCC_PCIE_6A_NOCSR_COM_PHY_BCR>;
> @@ -3232,14 +3234,16 @@ pcie4_phy: phy at 1c0e000 {
>  
>  			clocks = <&gcc GCC_PCIE_4_AUX_CLK>,
>  				 <&gcc GCC_PCIE_4_CFG_AHB_CLK>,
> -				 <&rpmhcc RPMH_CXO_CLK>,
> +				 <&tcsr TCSR_PCIE_2L_4_CLKREF_EN>,
>  				 <&gcc GCC_PCIE_4_PHY_RCHNG_CLK>,
> -				 <&gcc GCC_PCIE_4_PIPE_CLK>;
> +				 <&gcc GCC_PCIE_4_PIPE_CLK>,
> +				 <&gcc GCC_PCIE_4_PIPEDIV2_CLK>;
>  			clock-names = "aux",
>  				      "cfg_ahb",
>  				      "ref",
>  				      "rchng",
> -				      "pipe";
> +				      "pipe",
> +				      "pipediv2";
>  
>  			resets = <&gcc GCC_PCIE_4_PHY_BCR>;
>  			reset-names = "phy";
> -- 
> 2.44.2
> 


From krzk at kernel.org  Mon Sep 16 07:53:01 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Sep 2024 16:53:01 +0200
Subject: [PATCH v2] dt-bindings: phy: Add QMP UFS PHY comptible for
 QCS8300
In-Reply-To: <20240911-qcs8300_ufs_phy_binding-v2-1-c801a2d27a84@quicinc.com>
References: <20240911-qcs8300_ufs_phy_binding-v2-1-c801a2d27a84@quicinc.com>
Message-ID: <ztpetznwid2om6vylyl2boi665ch3wnkprkmzcq6bem6cqhqtf@ogsi657y4kex>

On Wed, Sep 11, 2024 at 02:56:16PM +0800, Jingyi Wang wrote:
> From: Xin Liu <quic_liuxin at quicinc.com>
> 
> Document the QMP UFS PHY compatible for Qualcomm QCS8300 to support
> physical layer functionality for UFS found on the SoC. Use fallback to
> indicate the compatibility of the QMP UFS PHY on the QCS8300 with that
> on the SA8775P.
> 
> Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
> ---
> Changes in v2:
> - decoupled from the original series.
> - Use fallback to indicate compatibility with SA8775P.
> - typo fixup
> - Link to v1: https://lore.kernel.org/r/20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007 at quicinc.com
> ---
>  .../bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml    | 46 ++++++++++++----------
>  1 file changed, 26 insertions(+), 20 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
> index f9cfbd0b2de6..626a2039e177 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
> @@ -15,26 +15,31 @@ description:
>  
>  properties:
>    compatible:
> -    enum:
> -      - qcom,msm8996-qmp-ufs-phy
> -      - qcom,msm8998-qmp-ufs-phy
> -      - qcom,sa8775p-qmp-ufs-phy
> -      - qcom,sc7180-qmp-ufs-phy
> -      - qcom,sc7280-qmp-ufs-phy
> -      - qcom,sc8180x-qmp-ufs-phy
> -      - qcom,sc8280xp-qmp-ufs-phy
> -      - qcom,sdm845-qmp-ufs-phy
> -      - qcom,sm6115-qmp-ufs-phy
> -      - qcom,sm6125-qmp-ufs-phy
> -      - qcom,sm6350-qmp-ufs-phy
> -      - qcom,sm7150-qmp-ufs-phy
> -      - qcom,sm8150-qmp-ufs-phy
> -      - qcom,sm8250-qmp-ufs-phy
> -      - qcom,sm8350-qmp-ufs-phy
> -      - qcom,sm8450-qmp-ufs-phy
> -      - qcom,sm8475-qmp-ufs-phy
> -      - qcom,sm8550-qmp-ufs-phy
> -      - qcom,sm8650-qmp-ufs-phy
> +    oneOf:
> +      - items:
> +          - enum:
> +              - qcom,qcs8300-qmp-ufs-phy
> +          - const: qcom,sa8775p-qmp-ufs-phy
> +      - enum:
> +          - qcom,msm8996-qmp-ufs-phy
> +          - qcom,msm8998-qmp-ufs-phy
> +          - qcom,sa8775p-qmp-ufs-phy
> +          - qcom,sc7180-qmp-ufs-phy
> +          - qcom,sc7280-qmp-ufs-phy
> +          - qcom,sc8180x-qmp-ufs-phy
> +          - qcom,sc8280xp-qmp-ufs-phy
> +          - qcom,sdm845-qmp-ufs-phy
> +          - qcom,sm6115-qmp-ufs-phy
> +          - qcom,sm6125-qmp-ufs-phy
> +          - qcom,sm6350-qmp-ufs-phy
> +          - qcom,sm7150-qmp-ufs-phy
> +          - qcom,sm8150-qmp-ufs-phy
> +          - qcom,sm8250-qmp-ufs-phy
> +          - qcom,sm8350-qmp-ufs-phy
> +          - qcom,sm8450-qmp-ufs-phy
> +          - qcom,sm8475-qmp-ufs-phy
> +          - qcom,sm8550-qmp-ufs-phy
> +          - qcom,sm8650-qmp-ufs-phy
>  
>    reg:
>      maxItems: 1
> @@ -85,6 +90,7 @@ allOf:
>            contains:
>              enum:
>                - qcom,msm8998-qmp-ufs-phy
> +              - qcom,qcs8300-qmp-ufs-phy

Not needed.

BTW, please be sure you organize your patchsets per subsystem. IOW, that
you do not split same subsystem bindings patches into separate
patchsets.

Best regards,
Krzysztof



From krzk at kernel.org  Mon Sep 16 08:15:27 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Sep 2024 17:15:27 +0200
Subject: [PATCH v2 1/5] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document the X1E80100 QMP PCIe PHY Gen4 x8
In-Reply-To: <20240913083724.1217691-2-quic_qianyu@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-2-quic_qianyu@quicinc.com>
Message-ID: <lrcridndulcurod7tc5z76tmfhcf5uqumkw7cijsqicmad2rim@blyor66wt4e4>

On Fri, Sep 13, 2024 at 01:37:20AM -0700, Qiang Yu wrote:
> PCIe 3rd instance of X1E80100 support Gen 4x8 which needs different 8 lane
> capable QMP PCIe PHY. Document Gen 4x8 PHY as separate module.

And this is really different hardware? Not just different number of lanes? We discussed it, but I don't see the explanation in commit msg.

> 
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> ---
>  .../devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml    | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> index dcf4fa55fbba..680ec3113c2b 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> @@ -41,6 +41,7 @@ properties:
>        - qcom,x1e80100-qmp-gen3x2-pcie-phy
>        - qcom,x1e80100-qmp-gen4x2-pcie-phy
>        - qcom,x1e80100-qmp-gen4x4-pcie-phy
> +      - qcom,x1e80100-qmp-gen4x8-pcie-phy
>  
>    reg:
>      minItems: 1
> @@ -172,6 +173,7 @@ allOf:
>                - qcom,sc8280xp-qmp-gen3x2-pcie-phy
>                - qcom,sc8280xp-qmp-gen3x4-pcie-phy
>                - qcom,x1e80100-qmp-gen4x4-pcie-phy
> +              - qcom,x1e80100-qmp-gen4x8-pcie-phy
>      then:
>        properties:
>          clocks:
> @@ -201,6 +203,7 @@ allOf:
>                - qcom,sm8550-qmp-gen4x2-pcie-phy
>                - qcom,sm8650-qmp-gen4x2-pcie-phy
>                - qcom,x1e80100-qmp-gen4x2-pcie-phy

Hm, why 4x4 is not here?

Best regards,
Krzysztof



From krzk at kernel.org  Mon Sep 16 08:20:06 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Sep 2024 17:20:06 +0200
Subject: [PATCH v2 2/5] dt-bindings: PCI: qcom: Add OPP table for X1E80100
In-Reply-To: <20240913083724.1217691-3-quic_qianyu@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-3-quic_qianyu@quicinc.com>
Message-ID: <hyhcycqedztrstcl2aixs6e2xwiowlrijkj3g6a2kheqap34qq@hhqxp5i3mbyq>

On Fri, Sep 13, 2024 at 01:37:21AM -0700, Qiang Yu wrote:
> Add OPP table so that PCIe is able to adjust power domain performance
> state and ICC peak bw according to PCIe gen speed and link width.
> 
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> ---
>  Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml | 4 ++++
>  1 file changed, 4 insertions(+)

Reviewed-by: Krzysztof Kozlowski <krzk at kernel.org>

Best regards,
Krzysztof



From krzk at kernel.org  Mon Sep 16 08:20:25 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Sep 2024 17:20:25 +0200
Subject: [PATCH v2 2/5] dt-bindings: PCI: qcom: Add OPP table for X1E80100
In-Reply-To: <20240913133619.z7cc4whhpvs2uecb@thinkpad>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-3-quic_qianyu@quicinc.com>
 <tf4z475uqjenohdgqj4ltoty3j3gopxnbdhrrn6zo3ug5yuvyq@us2nysv2ggxh>
 <20240913133619.z7cc4whhpvs2uecb@thinkpad>
Message-ID: <npm3szetf55hw6ghmscol2rl5jb5h3neywit2axea53vbgarvh@pgqq5j5y5pcb>

On Fri, Sep 13, 2024 at 07:06:19PM +0530, Manivannan Sadhasivam wrote:
> On Fri, Sep 13, 2024 at 03:30:59PM +0300, Dmitry Baryshkov wrote:
> > On Fri, Sep 13, 2024 at 01:37:21AM GMT, Qiang Yu wrote:
> > > Add OPP table so that PCIe is able to adjust power domain performance
> > > state and ICC peak bw according to PCIe gen speed and link width.
> > > 
> > > Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> > > ---
> > >  Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml | 4 ++++
> > >  1 file changed, 4 insertions(+)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
> > > index a9db0a231563..e2d6719ca54d 100644
> > > --- a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
> > > +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
> > > @@ -70,6 +70,10 @@ properties:
> > >        - const: pci # PCIe core reset
> > >        - const: link_down # PCIe link down reset
> > >  
> > > +  operating-points-v2: true
> > > +  opp-table:
> > > +    type: object
> > 
> > I think these properties are generic enough and we might want to have
> > them for most if not all platforms. Maybe we should move them to
> > qcom,pcie-common.yaml?
> > 
> 
> Agree. It should be moved to qcom,pcie-common.yaml.

Yep, ack.

Best regards,
Krzysztof



From krzk at kernel.org  Mon Sep 16 08:21:12 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Sep 2024 17:21:12 +0200
Subject: [PATCH v2 1/5] dt-bindings: phy: Add eDP PHY compatible for
 sa8775p
In-Reply-To: <20240913103755.7290-2-quic_mukhopad@quicinc.com>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
 <20240913103755.7290-2-quic_mukhopad@quicinc.com>
Message-ID: <qy4hizhsrz6nnfq4a5eremcc7b2gtw6czpav2j34nyj4i6fenv@p6vzlxanhmd5>

On Fri, Sep 13, 2024 at 04:07:51PM +0530, Soutrik Mukhopadhyay wrote:
> Add compatible string for the supported eDP PHY on sa8775p platform.
> 
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
> v2: No change
>  
> ---
>  Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml | 1 +

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzk at kernel.org  Mon Sep 16 08:23:55 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Sep 2024 17:23:55 +0200
Subject: [PATCH v2 1/5] dt-bindings: phy: Add eDP PHY compatible for
 sa8775p
In-Reply-To: <20240913103755.7290-2-quic_mukhopad@quicinc.com>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
 <20240913103755.7290-2-quic_mukhopad@quicinc.com>
Message-ID: <2hv2hcpbanduw4wg2wbza4jkze4sgilrtyc7zack23uygwsjol@ckskl2rkd5xp>

On Fri, Sep 13, 2024 at 04:07:51PM +0530, Soutrik Mukhopadhyay wrote:
> Add compatible string for the supported eDP PHY on sa8775p platform.
> 
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
> v2: No change
>  

Acked-by: Krzysztof Kozlowski <krzk at kernel.org>

Best regards,
Krzysztof



From dmitry.baryshkov at linaro.org  Mon Sep 16 13:33:38 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Sep 2024 23:33:38 +0300
Subject: [PATCH v2 1/5] dt-bindings: phy: Add eDP PHY compatible for
 sa8775p
In-Reply-To: <2hv2hcpbanduw4wg2wbza4jkze4sgilrtyc7zack23uygwsjol@ckskl2rkd5xp>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
 <20240913103755.7290-2-quic_mukhopad@quicinc.com>
 <2hv2hcpbanduw4wg2wbza4jkze4sgilrtyc7zack23uygwsjol@ckskl2rkd5xp>
Message-ID: <t4ytnii3sdiqsni74d7qsi2c6uv2klwmzmgznnirt2z55to4hj@lyaoh5fzcyti>

On Mon, Sep 16, 2024 at 05:23:55PM GMT, Krzysztof Kozlowski wrote:
> On Fri, Sep 13, 2024 at 04:07:51PM +0530, Soutrik Mukhopadhyay wrote:
> > Add compatible string for the supported eDP PHY on sa8775p platform.
> > 
> > Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> > ---
> > v2: No change
> >  
> 
> Acked-by: Krzysztof Kozlowski <krzk at kernel.org>

So, is it reviewed or acked?

-- 
With best wishes
Dmitry


From konradybcio at kernel.org  Mon Sep 16 16:26:45 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Tue, 17 Sep 2024 01:26:45 +0200
Subject: [PATCH v2 1/5] dt-bindings: phy: Add eDP PHY compatible for
 sa8775p
In-Reply-To: <t4ytnii3sdiqsni74d7qsi2c6uv2klwmzmgznnirt2z55to4hj@lyaoh5fzcyti>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
 <20240913103755.7290-2-quic_mukhopad@quicinc.com>
 <2hv2hcpbanduw4wg2wbza4jkze4sgilrtyc7zack23uygwsjol@ckskl2rkd5xp>
 <t4ytnii3sdiqsni74d7qsi2c6uv2klwmzmgznnirt2z55to4hj@lyaoh5fzcyti>
Message-ID: <f736f02e-f19b-4be2-86ad-73d6ae7c6dc2@kernel.org>

On 16.09.2024 10:33 PM, Dmitry Baryshkov wrote:
> On Mon, Sep 16, 2024 at 05:23:55PM GMT, Krzysztof Kozlowski wrote:
>> On Fri, Sep 13, 2024 at 04:07:51PM +0530, Soutrik Mukhopadhyay wrote:
>>> Add compatible string for the supported eDP PHY on sa8775p platform.
>>>
>>> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
>>> ---
>>> v2: No change
>>>  
>>
>> Acked-by: Krzysztof Kozlowski <krzk at kernel.org>
> 
> So, is it reviewed or acked?

After a thorough review, it has been acked

Konrad


From konradybcio at kernel.org  Mon Sep 16 16:29:58 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Tue, 17 Sep 2024 01:29:58 +0200
Subject: [PATCH v2 3/5] phy: qcom: qmp: Add phy register and clk setting
 for x1e80100 PCIe3
In-Reply-To: <20240913083724.1217691-4-quic_qianyu@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-4-quic_qianyu@quicinc.com>
Message-ID: <c4696a9d-e3f2-4ff5-8323-84f75f2f1a68@kernel.org>

On 13.09.2024 10:37 AM, Qiang Yu wrote:
> Currently driver supports only x4 lane based functionality using tx/rx and
> tx2/rx2 pair of register sets. To support 8 lane functionality with PCIe3,
> PCIe3 related QMP PHY provides additional programming which are available
> as txz and rxz based register set. Hence adds txz and rxz based registers
> usage and programming sequences. Phy register setting for txz and rxz will
> be applied to all 8 lanes. Some lanes may have different settings on
> several registers than txz/rxz, these registers should be programmed after
> txz/rxz programming sequences completing.
> 
> Besides, x1e80100 SoC uses QMP phy with version v6.30 for PCIe Gen4 x8.
> Add the new register offsets in a dedicated header file.
> 
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> ---

Reviewed-by: Konrad Dybcio <konradybcio at kernel.org>

Konrad


From konradybcio at kernel.org  Mon Sep 16 16:31:27 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Tue, 17 Sep 2024 01:31:27 +0200
Subject: [PATCH 2/3] arm64: dts: qcom: x1e80100: fix PCIe4 and PCIe6a PHY
 clocks
In-Reply-To: <20240916082307.29393-3-johan+linaro@kernel.org>
References: <20240916082307.29393-1-johan+linaro@kernel.org>
 <20240916082307.29393-3-johan+linaro@kernel.org>
Message-ID: <d182614c-d6d3-4dde-8faf-d89142ad41d1@kernel.org>

On 16.09.2024 10:23 AM, Johan Hovold wrote:
> Add the missing clkref enable and pipediv2 clocks to the PCIe4 and
> PCIe6a PHYs.
> 
> Fixes: 5eb83fc10289 ("arm64: dts: qcom: x1e80100: Add PCIe nodes")
> Cc: stable at vger.kernel.org	# 6.9
> Cc: Abel Vesa <abel.vesa at linaro.org>
> Signed-off-by: Johan Hovold <johan+linaro at kernel.org>
> ---

I reckon you split it like you day so that it's easier to backport..

Reviewed-by: Konrad Dybcio <konradybcio at kernel.org>

Konrad


From konradybcio at kernel.org  Mon Sep 16 16:31:37 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Tue, 17 Sep 2024 01:31:37 +0200
Subject: [PATCH 3/3] arm64: dts: qcom: x1e80100: fix PCIe5 PHY clocks
In-Reply-To: <20240916082307.29393-4-johan+linaro@kernel.org>
References: <20240916082307.29393-1-johan+linaro@kernel.org>
 <20240916082307.29393-4-johan+linaro@kernel.org>
Message-ID: <0069dc15-250e-4cac-a641-ab7d7ae5b497@kernel.org>

On 16.09.2024 10:23 AM, Johan Hovold wrote:
> Add the missing clkref enable and pipediv2 clocks to the PCIe5 PHY.
> 
> Fixes: 62ab23e15508 ("arm64: dts: qcom: x1e80100: add PCIe5 nodes")
> Signed-off-by: Johan Hovold <johan+linaro at kernel.org>
> ---

Reviewed-by: Konrad Dybcio <konradybcio at kernel.org>

Konrad


From krzk at kernel.org  Mon Sep 16 23:04:01 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Sep 2024 08:04:01 +0200
Subject: [PATCH v2 1/5] dt-bindings: phy: Add eDP PHY compatible for
 sa8775p
In-Reply-To: <f736f02e-f19b-4be2-86ad-73d6ae7c6dc2@kernel.org>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
 <20240913103755.7290-2-quic_mukhopad@quicinc.com>
 <2hv2hcpbanduw4wg2wbza4jkze4sgilrtyc7zack23uygwsjol@ckskl2rkd5xp>
 <t4ytnii3sdiqsni74d7qsi2c6uv2klwmzmgznnirt2z55to4hj@lyaoh5fzcyti>
 <f736f02e-f19b-4be2-86ad-73d6ae7c6dc2@kernel.org>
Message-ID: <e9ee952a-7c88-4c4c-b12f-fc4a33b3a517@kernel.org>

On 17/09/2024 01:26, Konrad Dybcio wrote:
> On 16.09.2024 10:33 PM, Dmitry Baryshkov wrote:
>> On Mon, Sep 16, 2024 at 05:23:55PM GMT, Krzysztof Kozlowski wrote:
>>> On Fri, Sep 13, 2024 at 04:07:51PM +0530, Soutrik Mukhopadhyay wrote:
>>>> Add compatible string for the supported eDP PHY on sa8775p platform.
>>>>
>>>> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
>>>> ---
>>>> v2: No change
>>>>  
>>>
>>> Acked-by: Krzysztof Kozlowski <krzk at kernel.org>
>>
>> So, is it reviewed or acked?
> 
> After a thorough review, it has been acked

Way too many emails in inbox after short trip... This should be only acked.

Best regards,
Krzysztof



From quic_mukhopad at quicinc.com  Tue Sep 17 01:12:54 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Tue, 17 Sep 2024 13:42:54 +0530
Subject: [PATCH 5/5] drm/msm/dp: Add DisplayPort controller for SA8775P
In-Reply-To: <ZuStkRFvwJT7re6D@hu-bjorande-lv.qualcomm.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com>
 <20240911100813.338-6-quic_mukhopad@quicinc.com>
 <ZuH3WqMwn7fl3nhh@hu-bjorande-lv.qualcomm.com>
 <a44a6f08-1f4a-4e5c-a4e4-30ab65c467f7@quicinc.com>
 <ZuStkRFvwJT7re6D@hu-bjorande-lv.qualcomm.com>
Message-ID: <b2d94fa5-6924-46f6-95cf-bde315ccbdbd@quicinc.com>


On 9/14/2024 2:54 AM, Bjorn Andersson wrote:
> On Thu, Sep 12, 2024 at 03:34:05PM +0530, Soutrik Mukhopadhyay wrote:
>> On 9/12/2024 1:32 AM, Bjorn Andersson wrote:
>>> On Wed, Sep 11, 2024 at 03:38:13PM +0530, Soutrik Mukhopadhyay wrote:
>>>> The Qualcomm SA8775P platform comes with a DisplayPort controller
>>>> with a different base offset than the previous SoCs,
>>>> add support for this in the DisplayPort driver.
> Please check the line wrapping of this as well; the lines here should be
> wrapped at 75 columns.


Yes, it is within 75 columns, we ran checkpatch.pl before posting the patch.


>
>>>> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
>>>> ---
>>>>    drivers/gpu/drm/msm/dp/dp_display.c | 7 +++++++
>>>>    1 file changed, 7 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
>>>> index e1228fb093ee..e4954fd99eb0 100644
>>>> --- a/drivers/gpu/drm/msm/dp/dp_display.c
>>>> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
>>>> @@ -118,6 +118,12 @@ struct msm_dp_desc {
>>>>    	bool wide_bus_supported;
>>>>    };
>>>> +static const struct msm_dp_desc sa8775p_dp_descs[] = {
>>>> +	{ .io_start = 0xaf54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
>>>> +	{ .io_start = 0xaf5c000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
>>> Why is this list incomplete?
>>>
>>> Regards,
>>> Bjorn
>>
>> Do you mean to add for mdss_1 as well?
>>
> I don't see a reason for not submitting them as well.


Sure, we will add for mdss_1 as well.


>
>> We only added dp controllers for mdss_0 as we plan to validate and enable
>> only these.
>>
> As far as I can tell there are 5 DPTX blocks on mdss_0.
>
>
> It is perfectly fine that you just state in the commit message that
> "Only MDSS0 DPTX0 and DPTX1 have been validated", but please add the
> others as well in this commit.
>
> Regards,
> Bjorn


We cross-checked the mdss architecture and found that there are only 2 
dp controllers for each mdss.

We will add all 4 and mention in the commit message that "Only MDSS0 
DPTX0 and DPTX1 have been validated".


>
>>>> +	{}
>>>> +};
>>>> +
>>>>    static const struct msm_dp_desc sc7180_dp_descs[] = {
>>>>    	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
>>>>    	{}
>>>> @@ -162,6 +168,7 @@ static const struct msm_dp_desc x1e80100_dp_descs[] = {
>>>>    };
>>>>    static const struct of_device_id dp_dt_match[] = {
>>>> +	{ .compatible = "qcom,sa8775p-dp", .data = &sa8775p_dp_descs },
>>>>    	{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
>>>>    	{ .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
>>>>    	{ .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_descs },
>>>> -- 
>>>> 2.17.1
>>>>


From quic_mukhopad at quicinc.com  Tue Sep 17 01:40:10 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Tue, 17 Sep 2024 14:10:10 +0530
Subject: [PATCH v2 2/5] phy: qcom: edp: Introduce aux_cfg array for
 version specific aux settings
In-Reply-To: <CAA8EJppddLmzJ9WSkLLr-nwM-qe647Sm6jV8SpHdB=0vRQT-=Q@mail.gmail.com>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
 <20240913103755.7290-3-quic_mukhopad@quicinc.com>
 <CAA8EJppddLmzJ9WSkLLr-nwM-qe647Sm6jV8SpHdB=0vRQT-=Q@mail.gmail.com>
Message-ID: <3ea1189b-8b06-45bb-9d60-178f69ee407d@quicinc.com>


On 9/13/2024 5:12 PM, Dmitry Baryshkov wrote:
> On Fri, 13 Sept 2024 at 13:38, Soutrik Mukhopadhyay
> <quic_mukhopad at quicinc.com> wrote:
>> In order to support different HW versions, introduce aux_cfg array
>> to move v4 specific aux configuration settings.
>>
>> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
>> ---
>> v2: Fixed review comments from Bjorn and Dmitry
>>          - Made aux_cfg array as const.
>>
>> ---
>>   drivers/phy/qualcomm/phy-qcom-edp.c | 37 ++++++++++++++++++-----------
>>   1 file changed, 23 insertions(+), 14 deletions(-)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
>> index da2b32fb5b45..bcd5aced9e06 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
>> @@ -90,6 +90,7 @@ struct phy_ver_ops {
>>
>>   struct qcom_edp_phy_cfg {
>>          bool is_edp;
>> +       const u8 *aux_cfg;
>>          const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
>>          const struct phy_ver_ops *ver_ops;
>>   };
>> @@ -186,11 +187,15 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
>>          .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
>>   };
>>
>> +static const u8 edp_phy_aux_cfg_v4[10] = {
>> +       0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
>> +};
>> +
>>   static int qcom_edp_phy_init(struct phy *phy)
>>   {
>>          struct qcom_edp *edp = phy_get_drvdata(phy);
>> +       u8 aux_cfg[10];
> Please define 10, so that there are no magic numbers (and less chance
> of damaging the stack if it gets changed in one place only.


Sure, we will update this in the next version.


>
>>          int ret;
>> -       u8 cfg8;
>>
>>          ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
>>          if (ret)
>> @@ -200,6 +205,8 @@ static int qcom_edp_phy_init(struct phy *phy)
>>          if (ret)
>>                  goto out_disable_supplies;
>>
>> +       memcpy(aux_cfg, edp->cfg->aux_cfg, sizeof(aux_cfg));
>> +
>>          writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
>>                 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
>>                 edp->edp + DP_PHY_PD_CTL);
>> @@ -222,22 +229,20 @@ static int qcom_edp_phy_init(struct phy *phy)
>>           * even needed.
>>           */
>>          if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
>> -               cfg8 = 0xb7;
>> -       else
>> -               cfg8 = 0x37;
>> +               aux_cfg[8] = 0xb7;
>>
>>          writel(0xfc, edp->edp + DP_PHY_MODE);
>>
>> -       writel(0x00, edp->edp + DP_PHY_AUX_CFG0);
>> -       writel(0x13, edp->edp + DP_PHY_AUX_CFG1);
>> -       writel(0x24, edp->edp + DP_PHY_AUX_CFG2);
>> -       writel(0x00, edp->edp + DP_PHY_AUX_CFG3);
>> -       writel(0x0a, edp->edp + DP_PHY_AUX_CFG4);
>> -       writel(0x26, edp->edp + DP_PHY_AUX_CFG5);
>> -       writel(0x0a, edp->edp + DP_PHY_AUX_CFG6);
>> -       writel(0x03, edp->edp + DP_PHY_AUX_CFG7);
>> -       writel(cfg8, edp->edp + DP_PHY_AUX_CFG8);
>> -       writel(0x03, edp->edp + DP_PHY_AUX_CFG9);
>> +       writel(aux_cfg[0], edp->edp + DP_PHY_AUX_CFG0);
>> +       writel(aux_cfg[1], edp->edp + DP_PHY_AUX_CFG1);
>> +       writel(aux_cfg[2], edp->edp + DP_PHY_AUX_CFG2);
>> +       writel(aux_cfg[3], edp->edp + DP_PHY_AUX_CFG3);
>> +       writel(aux_cfg[4], edp->edp + DP_PHY_AUX_CFG4);
>> +       writel(aux_cfg[5], edp->edp + DP_PHY_AUX_CFG5);
>> +       writel(aux_cfg[6], edp->edp + DP_PHY_AUX_CFG6);
>> +       writel(aux_cfg[7], edp->edp + DP_PHY_AUX_CFG7);
>> +       writel(aux_cfg[8], edp->edp + DP_PHY_AUX_CFG8);
>> +       writel(aux_cfg[9], edp->edp + DP_PHY_AUX_CFG9);
> Replace this with a loop?


Can we use below approach for this :

#define DP_PHY_AUX_CFG(n)??? ??? (0x24 + (0x04 * (n)))

for (int i = 0; i < 10; i++)

 ??? writel(aux_cfg[i], edp->edp + DP_PHY_AUX_CFG(i));


>
>>          writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
>>                 PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
>> @@ -519,16 +524,19 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
>>   };
>>
>>   static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
>> +       .aux_cfg = edp_phy_aux_cfg_v4,
>>          .ver_ops = &qcom_edp_phy_ops_v4,
>>   };
>>
>>   static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
>> +       .aux_cfg = edp_phy_aux_cfg_v4,
>>          .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
>>          .ver_ops = &qcom_edp_phy_ops_v4,
>>   };
>>
>>   static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
>>          .is_edp = true,
>> +       .aux_cfg = edp_phy_aux_cfg_v4,
>>          .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
>>          .ver_ops = &qcom_edp_phy_ops_v4,
>>   };
>> @@ -707,6 +715,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
>>   };
>>
>>   static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
>> +       .aux_cfg = edp_phy_aux_cfg_v4,
>>          .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
>>          .ver_ops = &qcom_edp_phy_ops_v6,
>>   };
>> --
>> 2.17.1
>>
>


From dmitry.baryshkov at linaro.org  Tue Sep 17 02:41:17 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Sep 2024 11:41:17 +0200
Subject: [PATCH v2 2/5] phy: qcom: edp: Introduce aux_cfg array for
 version specific aux settings
In-Reply-To: <3ea1189b-8b06-45bb-9d60-178f69ee407d@quicinc.com>
References: <20240913103755.7290-1-quic_mukhopad@quicinc.com>
 <20240913103755.7290-3-quic_mukhopad@quicinc.com> <CAA8EJppddLmzJ9WSkLLr-nwM-qe647Sm6jV8SpHdB=0vRQT-=Q@mail.gmail.com>
 <3ea1189b-8b06-45bb-9d60-178f69ee407d@quicinc.com>
Message-ID: <CAA8EJppKrOVi3B7g9dUMXwCDWR9GKUVD2BgSnNy+PkC5fq3GGA@mail.gmail.com>

On Tue, 17 Sept 2024 at 10:40, Soutrik Mukhopadhyay
<quic_mukhopad at quicinc.com> wrote:
>
>
> On 9/13/2024 5:12 PM, Dmitry Baryshkov wrote:
> > On Fri, 13 Sept 2024 at 13:38, Soutrik Mukhopadhyay
> > <quic_mukhopad at quicinc.com> wrote:
> >> In order to support different HW versions, introduce aux_cfg array
> >> to move v4 specific aux configuration settings.
> >>
> >> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> >> ---
> >> v2: Fixed review comments from Bjorn and Dmitry
> >>          - Made aux_cfg array as const.
> >>
> >> ---
> >>   drivers/phy/qualcomm/phy-qcom-edp.c | 37 ++++++++++++++++++-----------
> >>   1 file changed, 23 insertions(+), 14 deletions(-)
> >>
> >> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> >> index da2b32fb5b45..bcd5aced9e06 100644
> >> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> >> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> >> @@ -90,6 +90,7 @@ struct phy_ver_ops {
> >>
> >>   struct qcom_edp_phy_cfg {
> >>          bool is_edp;
> >> +       const u8 *aux_cfg;
> >>          const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
> >>          const struct phy_ver_ops *ver_ops;
> >>   };
> >> @@ -186,11 +187,15 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
> >>          .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
> >>   };
> >>
> >> +static const u8 edp_phy_aux_cfg_v4[10] = {
> >> +       0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
> >> +};
> >> +
> >>   static int qcom_edp_phy_init(struct phy *phy)
> >>   {
> >>          struct qcom_edp *edp = phy_get_drvdata(phy);
> >> +       u8 aux_cfg[10];
> > Please define 10, so that there are no magic numbers (and less chance
> > of damaging the stack if it gets changed in one place only.
>
>
> Sure, we will update this in the next version.
>
>
> >
> >>          int ret;
> >> -       u8 cfg8;
> >>
> >>          ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
> >>          if (ret)
> >> @@ -200,6 +205,8 @@ static int qcom_edp_phy_init(struct phy *phy)
> >>          if (ret)
> >>                  goto out_disable_supplies;
> >>
> >> +       memcpy(aux_cfg, edp->cfg->aux_cfg, sizeof(aux_cfg));
> >> +
> >>          writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> >>                 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
> >>                 edp->edp + DP_PHY_PD_CTL);
> >> @@ -222,22 +229,20 @@ static int qcom_edp_phy_init(struct phy *phy)
> >>           * even needed.
> >>           */
> >>          if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
> >> -               cfg8 = 0xb7;
> >> -       else
> >> -               cfg8 = 0x37;
> >> +               aux_cfg[8] = 0xb7;
> >>
> >>          writel(0xfc, edp->edp + DP_PHY_MODE);
> >>
> >> -       writel(0x00, edp->edp + DP_PHY_AUX_CFG0);
> >> -       writel(0x13, edp->edp + DP_PHY_AUX_CFG1);
> >> -       writel(0x24, edp->edp + DP_PHY_AUX_CFG2);
> >> -       writel(0x00, edp->edp + DP_PHY_AUX_CFG3);
> >> -       writel(0x0a, edp->edp + DP_PHY_AUX_CFG4);
> >> -       writel(0x26, edp->edp + DP_PHY_AUX_CFG5);
> >> -       writel(0x0a, edp->edp + DP_PHY_AUX_CFG6);
> >> -       writel(0x03, edp->edp + DP_PHY_AUX_CFG7);
> >> -       writel(cfg8, edp->edp + DP_PHY_AUX_CFG8);
> >> -       writel(0x03, edp->edp + DP_PHY_AUX_CFG9);
> >> +       writel(aux_cfg[0], edp->edp + DP_PHY_AUX_CFG0);
> >> +       writel(aux_cfg[1], edp->edp + DP_PHY_AUX_CFG1);
> >> +       writel(aux_cfg[2], edp->edp + DP_PHY_AUX_CFG2);
> >> +       writel(aux_cfg[3], edp->edp + DP_PHY_AUX_CFG3);
> >> +       writel(aux_cfg[4], edp->edp + DP_PHY_AUX_CFG4);
> >> +       writel(aux_cfg[5], edp->edp + DP_PHY_AUX_CFG5);
> >> +       writel(aux_cfg[6], edp->edp + DP_PHY_AUX_CFG6);
> >> +       writel(aux_cfg[7], edp->edp + DP_PHY_AUX_CFG7);
> >> +       writel(aux_cfg[8], edp->edp + DP_PHY_AUX_CFG8);
> >> +       writel(aux_cfg[9], edp->edp + DP_PHY_AUX_CFG9);
> > Replace this with a loop?
>
>
> Can we use below approach for this :
>
> #define DP_PHY_AUX_CFG(n)        (0x24 + (0x04 * (n)))
>
> for (int i = 0; i < 10; i++)
>
>      writel(aux_cfg[i], edp->edp + DP_PHY_AUX_CFG(i));

That's what I meant, thank you!

>
>
> >
> >>          writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
> >>                 PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
> >> @@ -519,16 +524,19 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
> >>   };
> >>
> >>   static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
> >> +       .aux_cfg = edp_phy_aux_cfg_v4,
> >>          .ver_ops = &qcom_edp_phy_ops_v4,
> >>   };
> >>
> >>   static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
> >> +       .aux_cfg = edp_phy_aux_cfg_v4,
> >>          .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
> >>          .ver_ops = &qcom_edp_phy_ops_v4,
> >>   };
> >>
> >>   static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
> >>          .is_edp = true,
> >> +       .aux_cfg = edp_phy_aux_cfg_v4,
> >>          .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
> >>          .ver_ops = &qcom_edp_phy_ops_v4,
> >>   };
> >> @@ -707,6 +715,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
> >>   };
> >>
> >>   static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
> >> +       .aux_cfg = edp_phy_aux_cfg_v4,
> >>          .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
> >>          .ver_ops = &qcom_edp_phy_ops_v6,
> >>   };
> >> --
> >> 2.17.1
> >>
> >



-- 
With best wishes
Dmitry


From martin at stroomer.com  Tue Sep 17 03:49:48 2024
From: martin at stroomer.com (Martinus Stroomer)
Date: Tue, 17 Sep 2024 11:49:48 +0100
Subject: [PATCH 0/2] MIPI DSI phy for rk3588
In-Reply-To: <20240506124836.3621528-1-heiko@sntech.de>
Message-ID: <6012a5d3d43137803beafe0c15ecd7a3fe86d703.camel@stroomer.com>





From konradybcio at kernel.org  Tue Sep 17 06:44:41 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Tue, 17 Sep 2024 15:44:41 +0200
Subject: [PATCH 5/5] drm/msm/dp: Add DisplayPort controller for SA8775P
In-Reply-To: <b2d94fa5-6924-46f6-95cf-bde315ccbdbd@quicinc.com>
References: <20240911100813.338-1-quic_mukhopad@quicinc.com>
 <20240911100813.338-6-quic_mukhopad@quicinc.com>
 <ZuH3WqMwn7fl3nhh@hu-bjorande-lv.qualcomm.com>
 <a44a6f08-1f4a-4e5c-a4e4-30ab65c467f7@quicinc.com>
 <ZuStkRFvwJT7re6D@hu-bjorande-lv.qualcomm.com>
 <b2d94fa5-6924-46f6-95cf-bde315ccbdbd@quicinc.com>
Message-ID: <c7d18bce-cabc-4edc-b1b9-085653110528@kernel.org>

On 17.09.2024 10:12 AM, Soutrik Mukhopadhyay wrote:
> 
> On 9/14/2024 2:54 AM, Bjorn Andersson wrote:
>> On Thu, Sep 12, 2024 at 03:34:05PM +0530, Soutrik Mukhopadhyay wrote:
>>> On 9/12/2024 1:32 AM, Bjorn Andersson wrote:
>>>> On Wed, Sep 11, 2024 at 03:38:13PM +0530, Soutrik Mukhopadhyay wrote:
>>>>> The Qualcomm SA8775P platform comes with a DisplayPort controller
>>>>> with a different base offset than the previous SoCs,
>>>>> add support for this in the DisplayPort driver.
>> Please check the line wrapping of this as well; the lines here should be
>> wrapped at 75 columns.

[...]

> 
> 
> We cross-checked the mdss architecture and found that there are only 2 dp controllers for each mdss.
> 
> We will add all 4 and mention in the commit message that "Only MDSS0 DPTX0 and DPTX1 have been validated".

Looking at some docs, it seems like 2x 2 controllers is indeed the
correct config after all

Konrad


From johan at kernel.org  Wed Sep 18 03:05:59 2024
From: johan at kernel.org (Johan Hovold)
Date: Wed, 18 Sep 2024 12:05:59 +0200
Subject: [PATCH] phy: qcom: edp: Add runtime PM support
In-Reply-To: <20240907-phy-qcom-edp-enable-runtime-pm-v1-1-8b9ee4210e1e@linaro.org>
References: <20240907-phy-qcom-edp-enable-runtime-pm-v1-1-8b9ee4210e1e@linaro.org>
Message-ID: <ZuqmB3Cn7mGfA2PU@hovoldconsulting.com>

On Sat, Sep 07, 2024 at 06:25:21PM +0300, Abel Vesa wrote:
> Enable runtime PM support by adding proper ops which will handle the

Avoid words like 'proper' here (what are non-proper runtime PM ops?).

> clocks and regulators. These resources will now be handled on power_on and
> power_off instead of init and exit PHY ops.

No, this is simply a false claim and indicates that you haven't reviewed
how PHY runtime PM works. Core will increment the usage count on init()
and decrement it on exit().

> Also enable these resources on
> probe in order to balance out the disabling that is happening right after.
> Prevent runtime PM from being ON by default as well.

And here you just regressed all current systems that do not have udev
rules to enable runtime PM, and which will now be stuck with these
resources always-on (e.g. during DPMS off and system suspend).

In fact, you are even regressing systems that would enable runtime PM,
as the runtime suspend callback would not currently be called when you
enter system suspend so the regulators and clocks will be left on.

This clearly hasn't been tested and analysed properly.

> +static int __maybe_unused qcom_edp_runtime_suspend(struct device *dev)
> +{
> +	struct qcom_edp *edp = dev_get_drvdata(dev);
> +
> +	dev_err(dev, "Suspending DP phy\n");

You forgot to drop your development printks (same below).

Johan


From abel.vesa at linaro.org  Wed Sep 18 06:10:05 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 18 Sep 2024 16:10:05 +0300
Subject: [PATCH] phy: qcom: edp: Add runtime PM support
In-Reply-To: <ZuqmB3Cn7mGfA2PU@hovoldconsulting.com>
References: <20240907-phy-qcom-edp-enable-runtime-pm-v1-1-8b9ee4210e1e@linaro.org>
 <ZuqmB3Cn7mGfA2PU@hovoldconsulting.com>
Message-ID: <ZurRLf8S1j6s8GPz@linaro.org>

On 24-09-18 12:05:59, Johan Hovold wrote:
> On Sat, Sep 07, 2024 at 06:25:21PM +0300, Abel Vesa wrote:
> > Enable runtime PM support by adding proper ops which will handle the
> 
> Avoid words like 'proper' here (what are non-proper runtime PM ops?).

Sure.

> 
> > clocks and regulators. These resources will now be handled on power_on and
> > power_off instead of init and exit PHY ops.
> 
> No, this is simply a false claim and indicates that you haven't reviewed
> how PHY runtime PM works. Core will increment the usage count on init()
> and decrement it on exit().

Yeah, I guess the better argument here would be that the PHY needs
regulators and clocks enabled. Anyway, ignore this version as it
was already NACKed by Dmitry.

> 
> > Also enable these resources on
> > probe in order to balance out the disabling that is happening right after.
> > Prevent runtime PM from being ON by default as well.
> 
> And here you just regressed all current systems that do not have udev
> rules to enable runtime PM, and which will now be stuck with these
> resources always-on (e.g. during DPMS off and system suspend).
> 
> In fact, you are even regressing systems that would enable runtime PM,
> as the runtime suspend callback would not currently be called when you
> enter system suspend so the regulators and clocks will be left on.
> 
> This clearly hasn't been tested and analysed properly.
> 
> > +static int __maybe_unused qcom_edp_runtime_suspend(struct device *dev)
> > +{
> > +	struct qcom_edp *edp = dev_get_drvdata(dev);
> > +
> > +	dev_err(dev, "Suspending DP phy\n");
> 
> You forgot to drop your development printks (same below).
> 
> Johan


From lorenzo at kernel.org  Wed Sep 18 06:32:51 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Wed, 18 Sep 2024 15:32:51 +0200
Subject: [PATCH 0/4] phy: Fix some typos in phy-airoha-pcie driver
Message-ID: <20240918-airoha-en7581-phy-fixes-v1-0-8291729a87f8@kernel.org>

Address some typos during hw configuration in phy-airoha-pcie driver

---
Lorenzo Bianconi (4):
      phy: airoha: Fix REG_CSR_2L_PLL_CMN_RESERVE0 config in airoha_pcie_phy_init_clk_out()
      phy: airoha: Fix REG_PCIE_PMA_TX_RESET config in airoha_pcie_phy_init_csr_2l()
      phy: airoha: Fix REG_CSR_2L_JCPLL_SDM_HREN config in airoha_pcie_phy_init_ssc_jcpll()
      phy: airoha: Fix REG_CSR_2L_RX{0,1}_REV0 definitions

 drivers/phy/phy-airoha-pcie-regs.h | 6 +++---
 drivers/phy/phy-airoha-pcie.c      | 8 ++++----
 2 files changed, 7 insertions(+), 7 deletions(-)
---
base-commit: 3c2ea12a625dbf5a864f4920235fa1c739d06e7d
change-id: 20240918-airoha-en7581-phy-fixes-13f77b2f371a

Best regards,
-- 
Lorenzo Bianconi <lorenzo at kernel.org>



From lorenzo at kernel.org  Wed Sep 18 06:32:52 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Wed, 18 Sep 2024 15:32:52 +0200
Subject: [PATCH 1/4] phy: airoha: Fix REG_CSR_2L_PLL_CMN_RESERVE0 config in
 airoha_pcie_phy_init_clk_out()
In-Reply-To: <20240918-airoha-en7581-phy-fixes-v1-0-8291729a87f8@kernel.org>
References: <20240918-airoha-en7581-phy-fixes-v1-0-8291729a87f8@kernel.org>
Message-ID: <20240918-airoha-en7581-phy-fixes-v1-1-8291729a87f8@kernel.org>

Fix typo configuring REG_CSR_2L_PLL_CMN_RESERVE0 register in
airoha_pcie_phy_init_clk_out routine.

Fixes: d7d2818b9383 ("phy: airoha: Add PCIe PHY driver for EN7581 SoC.")
Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
 drivers/phy/phy-airoha-pcie.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/phy-airoha-pcie.c b/drivers/phy/phy-airoha-pcie.c
index 1e410eb41058..4624aa9dd712 100644
--- a/drivers/phy/phy-airoha-pcie.c
+++ b/drivers/phy/phy-airoha-pcie.c
@@ -459,7 +459,7 @@ static void airoha_pcie_phy_init_clk_out(struct airoha_pcie_phy *pcie_phy)
 	airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CLKTX1_OFFSET,
 				     CSR_2L_PXP_CLKTX1_SR);
 	airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_PLL_CMN_RESERVE0,
-				       CSR_2L_PXP_PLL_RESERVE_MASK, 0xdd);
+				       CSR_2L_PXP_PLL_RESERVE_MASK, 0xd0d);
 }
 
 static void airoha_pcie_phy_init_csr_2l(struct airoha_pcie_phy *pcie_phy)

-- 
2.46.0



From lorenzo at kernel.org  Wed Sep 18 06:32:53 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Wed, 18 Sep 2024 15:32:53 +0200
Subject: [PATCH 2/4] phy: airoha: Fix REG_PCIE_PMA_TX_RESET config in
 airoha_pcie_phy_init_csr_2l()
In-Reply-To: <20240918-airoha-en7581-phy-fixes-v1-0-8291729a87f8@kernel.org>
References: <20240918-airoha-en7581-phy-fixes-v1-0-8291729a87f8@kernel.org>
Message-ID: <20240918-airoha-en7581-phy-fixes-v1-2-8291729a87f8@kernel.org>

Fix typos configuring REG_PCIE_PMA_TX_RESET register in
airoha_pcie_phy_init_csr_2l routine for lane0 and lane1

Fixes: d7d2818b9383 ("phy: airoha: Add PCIe PHY driver for EN7581 SoC.")
Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
 drivers/phy/phy-airoha-pcie.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/phy-airoha-pcie.c b/drivers/phy/phy-airoha-pcie.c
index 4624aa9dd712..9a7ce65f87f0 100644
--- a/drivers/phy/phy-airoha-pcie.c
+++ b/drivers/phy/phy-airoha-pcie.c
@@ -471,9 +471,9 @@ static void airoha_pcie_phy_init_csr_2l(struct airoha_pcie_phy *pcie_phy)
 				 PCIE_SW_XFI_RXPCS_RST | PCIE_SW_REF_RST |
 				 PCIE_SW_RX_RST);
 	airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_TX_RESET,
-				 PCIE_TX_TOP_RST | REG_PCIE_PMA_TX_RESET);
+				 PCIE_TX_TOP_RST | PCIE_TX_CAL_RST);
 	airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_TX_RESET,
-				 PCIE_TX_TOP_RST | REG_PCIE_PMA_TX_RESET);
+				 PCIE_TX_TOP_RST | PCIE_TX_CAL_RST);
 }
 
 static void airoha_pcie_phy_init_rx(struct airoha_pcie_phy *pcie_phy)

-- 
2.46.0



From lorenzo at kernel.org  Wed Sep 18 06:32:54 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Wed, 18 Sep 2024 15:32:54 +0200
Subject: [PATCH 3/4] phy: airoha: Fix REG_CSR_2L_JCPLL_SDM_HREN config in
 airoha_pcie_phy_init_ssc_jcpll()
In-Reply-To: <20240918-airoha-en7581-phy-fixes-v1-0-8291729a87f8@kernel.org>
References: <20240918-airoha-en7581-phy-fixes-v1-0-8291729a87f8@kernel.org>
Message-ID: <20240918-airoha-en7581-phy-fixes-v1-3-8291729a87f8@kernel.org>

Fix typo configuring REG_CSR_2L_JCPLL_SDM_HREN register in
airoha_pcie_phy_init_ssc_jcpll routine.

Fixes: d7d2818b9383 ("phy: airoha: Add PCIe PHY driver for EN7581 SoC.")
Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
 drivers/phy/phy-airoha-pcie.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/phy-airoha-pcie.c b/drivers/phy/phy-airoha-pcie.c
index 9a7ce65f87f0..56e9ade8a9fd 100644
--- a/drivers/phy/phy-airoha-pcie.c
+++ b/drivers/phy/phy-airoha-pcie.c
@@ -802,7 +802,7 @@ static void airoha_pcie_phy_init_ssc_jcpll(struct airoha_pcie_phy *pcie_phy)
 	airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_IFM,
 				   CSR_2L_PXP_JCPLL_SDM_IFM);
 	airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN,
-				   REG_CSR_2L_JCPLL_SDM_HREN);
+				   CSR_2L_PXP_JCPLL_SDM_HREN);
 	airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY,
 				     CSR_2L_PXP_JCPLL_SDM_DI_EN);
 	airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC,

-- 
2.46.0



From lorenzo at kernel.org  Wed Sep 18 06:32:55 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Wed, 18 Sep 2024 15:32:55 +0200
Subject: [PATCH 4/4] phy: airoha: Fix REG_CSR_2L_RX{0,1}_REV0 definitions
In-Reply-To: <20240918-airoha-en7581-phy-fixes-v1-0-8291729a87f8@kernel.org>
References: <20240918-airoha-en7581-phy-fixes-v1-0-8291729a87f8@kernel.org>
Message-ID: <20240918-airoha-en7581-phy-fixes-v1-4-8291729a87f8@kernel.org>

Fix the following register definitions for REG_CSR_2L_RX{0,1}_REV0
registers:
- CSR_2L_PXP_VOS_PNINV
- CSR_2L_PXP_FE_GAIN_NORMAL_MODE
- CSR_2L_PXP_FE_GAIN_TRAIN_MODE

Fixes: d7d2818b9383 ("phy: airoha: Add PCIe PHY driver for EN7581 SoC.")
Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
 drivers/phy/phy-airoha-pcie-regs.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/phy-airoha-pcie-regs.h b/drivers/phy/phy-airoha-pcie-regs.h
index bb1f679ca1df..b938a7b468fe 100644
--- a/drivers/phy/phy-airoha-pcie-regs.h
+++ b/drivers/phy/phy-airoha-pcie-regs.h
@@ -197,9 +197,9 @@
 #define CSR_2L_PXP_TX1_MULTLANE_EN		BIT(0)
 
 #define REG_CSR_2L_RX0_REV0			0x00fc
-#define CSR_2L_PXP_VOS_PNINV			GENMASK(3, 2)
-#define CSR_2L_PXP_FE_GAIN_NORMAL_MODE		GENMASK(6, 4)
-#define CSR_2L_PXP_FE_GAIN_TRAIN_MODE		GENMASK(10, 8)
+#define CSR_2L_PXP_VOS_PNINV			GENMASK(19, 18)
+#define CSR_2L_PXP_FE_GAIN_NORMAL_MODE		GENMASK(22, 20)
+#define CSR_2L_PXP_FE_GAIN_TRAIN_MODE		GENMASK(26, 24)
 
 #define REG_CSR_2L_RX0_PHYCK_DIV		0x0100
 #define CSR_2L_PXP_RX0_PHYCK_SEL		GENMASK(9, 8)

-- 
2.46.0



From robh at kernel.org  Wed Sep 18 10:14:53 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 18 Sep 2024 12:14:53 -0500
Subject: [PATCH 1/3] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: add
 missing x1e80100 pipediv2 clocks
In-Reply-To: <20240916082307.29393-2-johan+linaro@kernel.org>
References: <20240916082307.29393-1-johan+linaro@kernel.org>
 <20240916082307.29393-2-johan+linaro@kernel.org>
Message-ID: <172667969326.1817225.11425040649410740756.robh@kernel.org>


On Mon, 16 Sep 2024 10:23:05 +0200, Johan Hovold wrote:
> The x1e80100 QMP PCIe PHYs all have a pipediv2 clock that needs to be
> described.
> 
> Fixes: e94b29f2bd73 ("dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the X1E80100 QMP PCIe PHYs")
> Cc: Abel Vesa <abel.vesa at linaro.org>
> Signed-off-by: Johan Hovold <johan+linaro at kernel.org>
> ---
>  .../devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml   | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 

Acked-by: Rob Herring (Arm) <robh at kernel.org>



From quic_qianyu at quicinc.com  Thu Sep 19 06:47:29 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Thu, 19 Sep 2024 21:47:29 +0800
Subject: [PATCH v2 1/5] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document the X1E80100 QMP PCIe PHY Gen4 x8
In-Reply-To: <20240913133751.2yegqbobvfzbogxc@thinkpad>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-2-quic_qianyu@quicinc.com>
 <20240913133751.2yegqbobvfzbogxc@thinkpad>
Message-ID: <1dff17e3-580b-4829-b889-0c559db64f26@quicinc.com>


On 9/13/2024 9:37 PM, Manivannan Sadhasivam wrote:
> On Fri, Sep 13, 2024 at 01:37:20AM -0700, Qiang Yu wrote:
>> PCIe 3rd instance of X1E80100 support Gen 4x8 which needs different 8 lane
>> capable QMP PCIe PHY. Document Gen 4x8 PHY as separate module.
>>
> Nit: please use 'Gen 4 x8'
Will update in next version patch.

Thanks,
Qiang
>
> - Mani
>
>> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
>> ---
>>   .../devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml    | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
>> index dcf4fa55fbba..680ec3113c2b 100644
>> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
>> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
>> @@ -41,6 +41,7 @@ properties:
>>         - qcom,x1e80100-qmp-gen3x2-pcie-phy
>>         - qcom,x1e80100-qmp-gen4x2-pcie-phy
>>         - qcom,x1e80100-qmp-gen4x4-pcie-phy
>> +      - qcom,x1e80100-qmp-gen4x8-pcie-phy
>>   
>>     reg:
>>       minItems: 1
>> @@ -172,6 +173,7 @@ allOf:
>>                 - qcom,sc8280xp-qmp-gen3x2-pcie-phy
>>                 - qcom,sc8280xp-qmp-gen3x4-pcie-phy
>>                 - qcom,x1e80100-qmp-gen4x4-pcie-phy
>> +              - qcom,x1e80100-qmp-gen4x8-pcie-phy
>>       then:
>>         properties:
>>           clocks:
>> @@ -201,6 +203,7 @@ allOf:
>>                 - qcom,sm8550-qmp-gen4x2-pcie-phy
>>                 - qcom,sm8650-qmp-gen4x2-pcie-phy
>>                 - qcom,x1e80100-qmp-gen4x2-pcie-phy
>> +              - qcom,x1e80100-qmp-gen4x8-pcie-phy
>>       then:
>>         properties:
>>           resets:
>> -- 
>> 2.34.1
>>


From quic_qianyu at quicinc.com  Thu Sep 19 07:03:05 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Thu, 19 Sep 2024 22:03:05 +0800
Subject: [PATCH v2 1/5] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document the X1E80100 QMP PCIe PHY Gen4 x8
In-Reply-To: <lrcridndulcurod7tc5z76tmfhcf5uqumkw7cijsqicmad2rim@blyor66wt4e4>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-2-quic_qianyu@quicinc.com>
 <lrcridndulcurod7tc5z76tmfhcf5uqumkw7cijsqicmad2rim@blyor66wt4e4>
Message-ID: <b36819ed-0e4a-4820-8c38-ac9d2c6f0f28@quicinc.com>


On 9/16/2024 11:15 PM, Krzysztof Kozlowski wrote:
> On Fri, Sep 13, 2024 at 01:37:20AM -0700, Qiang Yu wrote:
>> PCIe 3rd instance of X1E80100 support Gen 4x8 which needs different 8 lane
>> capable QMP PCIe PHY. Document Gen 4x8 PHY as separate module.
> And this is really different hardware? Not just different number of lanes? We discussed it, but I don't see the explanation in commit msg.
Yes, PCIe3 use a different phy that supports 8 lanes and provides
additional register set, txz and rxz. It is not a bifurcation mode which
actually combines two same phys like PCIe6a. It's also not just different
number of lanes. Will explain this in commit msg.

Thanks,
Qiang
>> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
>> ---
>>   .../devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml    | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
>> index dcf4fa55fbba..680ec3113c2b 100644
>> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
>> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
>> @@ -41,6 +41,7 @@ properties:
>>         - qcom,x1e80100-qmp-gen3x2-pcie-phy
>>         - qcom,x1e80100-qmp-gen4x2-pcie-phy
>>         - qcom,x1e80100-qmp-gen4x4-pcie-phy
>> +      - qcom,x1e80100-qmp-gen4x8-pcie-phy
>>   
>>     reg:
>>       minItems: 1
>> @@ -172,6 +173,7 @@ allOf:
>>                 - qcom,sc8280xp-qmp-gen3x2-pcie-phy
>>                 - qcom,sc8280xp-qmp-gen3x4-pcie-phy
>>                 - qcom,x1e80100-qmp-gen4x4-pcie-phy
>> +              - qcom,x1e80100-qmp-gen4x8-pcie-phy
>>       then:
>>         properties:
>>           clocks:
>> @@ -201,6 +203,7 @@ allOf:
>>                 - qcom,sm8550-qmp-gen4x2-pcie-phy
>>                 - qcom,sm8650-qmp-gen4x2-pcie-phy
>>                 - qcom,x1e80100-qmp-gen4x2-pcie-phy
> Hm, why 4x4 is not here?
>
> Best regards,
> Krzysztof


From quic_qianyu at quicinc.com  Thu Sep 19 07:05:38 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Thu, 19 Sep 2024 22:05:38 +0800
Subject: [PATCH v2 5/5] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <20240913135710.6ionsmzo45orin6n@thinkpad>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-6-quic_qianyu@quicinc.com>
 <20240913135710.6ionsmzo45orin6n@thinkpad>
Message-ID: <af601078-3ab7-484e-bdd3-6220a5fb3083@quicinc.com>


On 9/13/2024 9:57 PM, Manivannan Sadhasivam wrote:
> On Fri, Sep 13, 2024 at 01:37:24AM -0700, Qiang Yu wrote:
>> Describe PCIe3 controller and PHY. Also add required system resources like
>> regulators, clocks, interrupts and registers configuration for PCIe3.
>>
>> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
>> ---
>>   arch/arm64/boot/dts/qcom/x1e80100.dtsi | 202 ++++++++++++++++++++++++-
>>   1 file changed, 201 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
>> index a36076e3c56b..a7703e4974a6 100644
>> --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
>> @@ -744,7 +744,7 @@ gcc: clock-controller at 100000 {
>>   
>>   			clocks = <&bi_tcxo_div2>,
>>   				 <&sleep_clk>,
>> -				 <0>,
>> +				 <&pcie3_phy>,
>>   				 <&pcie4_phy>,
>>   				 <&pcie5_phy>,
>>   				 <&pcie6a_phy>,
>> @@ -2907,6 +2907,206 @@ mmss_noc: interconnect at 1780000 {
>>   			#interconnect-cells = <2>;
>>   		};
>>   
>> +		pcie3: pci at 1bd0000 {
> pcie@
>
>> +			device_type = "pci";
>> +			compatible = "qcom,pcie-x1e80100";
>> +			reg = <0 0x01bd0000 0 0x3000>,
>> +			      <0 0x78000000 0 0xf1d>,
> 0x0 here and below.
>
>> +			      <0 0x78000f40 0 0xa8>,
>> +			      <0 0x78001000 0 0x1000>,
>> +			      <0 0x78100000 0 0x100000>,
>> +			      <0 0x01bd3000 0 0x1000>;
>> +			reg-names = "parf",
>> +				    "dbi",
>> +				    "elbi",
>> +				    "atu",
>> +				    "config",
>> +				    "mhi";
>> +			#address-cells = <3>;
>> +			#size-cells = <2>;
>> +			ranges = <0x01000000 0x0 0x00000000 0x0 0x78200000 0x0 0x100000>,
>> +				 <0x02000000 0x0 0x78300000 0x0 0x78300000 0x0 0x3d00000>,
>> +				 <0x03000000 0x7 0x40000000 0x7 0x40000000 0x0 0x40000000>;
>> +			bus-range = <0x00 0xff>;
>> +
>> +			dma-coherent;
>> +
>> +			linux,pci-domain = <3>;
>> +			num-lanes = <8>;
>> +
>> +			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 769 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 671 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
>> +			interrupt-names = "msi0",
>> +					  "msi1",
>> +					  "msi2",
>> +					  "msi3",
>> +					  "msi4",
>> +					  "msi5",
>> +					  "msi6",
>> +					  "msi7";
> Can you add 'global' interrupt as well? While doing so, please make sure the
> global_irq related patches are applied and Link up works fine. Those patches are
> already in linux-next.
Sure, let me add global interrupt and have a try. Will also update patch
according to your other comments.

Thanks,
Qiang
>
>> +
>> +			#interrupt-cells = <1>;
>> +			interrupt-map-mask = <0 0 0 0x7>;
>> +			interrupt-map = <0 0 0 1 &intc 0 0 0 220 IRQ_TYPE_LEVEL_HIGH>,
> Use GIC_SPI for the parent interrupt specifier.
>
> - Mani
>
>> +					<0 0 0 2 &intc 0 0 0 221 IRQ_TYPE_LEVEL_HIGH>,
>> +					<0 0 0 3 &intc 0 0 0 237 IRQ_TYPE_LEVEL_HIGH>,
>> +					<0 0 0 4 &intc 0 0 0 238 IRQ_TYPE_LEVEL_HIGH>;
>> +
>> +			clocks = <&gcc GCC_PCIE_3_AUX_CLK>,
>> +				 <&gcc GCC_PCIE_3_CFG_AHB_CLK>,
>> +				 <&gcc GCC_PCIE_3_MSTR_AXI_CLK>,
>> +				 <&gcc GCC_PCIE_3_SLV_AXI_CLK>,
>> +				 <&gcc GCC_PCIE_3_SLV_Q2A_AXI_CLK>,
>> +				 <&gcc GCC_CFG_NOC_PCIE_ANOC_NORTH_AHB_CLK>,
>> +				 <&gcc GCC_CNOC_PCIE_NORTH_SF_AXI_CLK>;
>> +			clock-names = "aux",
>> +				      "cfg",
>> +				      "bus_master",
>> +				      "bus_slave",
>> +				      "slave_q2a",
>> +				      "noc_aggr",
>> +				      "cnoc_sf_axi";
>> +
>> +			assigned-clocks = <&gcc GCC_PCIE_3_AUX_CLK>;
>> +			assigned-clock-rates = <19200000>;
>> +
>> +			interconnects = <&pcie_south_anoc MASTER_PCIE_3 QCOM_ICC_TAG_ALWAYS
>> +					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
>> +					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
>> +					 &cnoc_main SLAVE_PCIE_3 QCOM_ICC_TAG_ALWAYS>;
>> +			interconnect-names = "pcie-mem",
>> +					     "cpu-pcie";
>> +
>> +			resets = <&gcc GCC_PCIE_3_BCR>,
>> +				 <&gcc GCC_PCIE_3_LINK_DOWN_BCR>;
>> +			reset-names = "pci",
>> +				      "link_down";
>> +
>> +			power-domains = <&gcc GCC_PCIE_3_GDSC>;
>> +
>> +			phys = <&pcie3_phy>;
>> +			phy-names = "pciephy";
>> +
>> +			operating-points-v2 = <&pcie3_opp_table>;
>> +
>> +			status = "disabled";
>> +
>> +			pcie3_opp_table: opp-table {
>> +				compatible = "operating-points-v2";
>> +
>> +				/* GEN 1 x1 */
>> +				opp-2500000 {
>> +					opp-hz = /bits/ 64 <2500000>;
>> +					required-opps = <&rpmhpd_opp_low_svs>;
>> +					opp-peak-kBps = <250000 1>;
>> +				};
>> +
>> +				/* GEN 1 x2 and GEN 2 x1 */
>> +				opp-5000000 {
>> +					opp-hz = /bits/ 64 <5000000>;
>> +					required-opps = <&rpmhpd_opp_low_svs>;
>> +					opp-peak-kBps = <500000 1>;
>> +				};
>> +
>> +				/* GEN 1 x4 and GEN 2 x2 */
>> +				opp-10000000 {
>> +					opp-hz = /bits/ 64 <10000000>;
>> +					required-opps = <&rpmhpd_opp_low_svs>;
>> +					opp-peak-kBps = <1000000 1>;
>> +				};
>> +
>> +				/* GEN 1 x8 and GEN 2 x4 */
>> +				opp-20000000 {
>> +					opp-hz = /bits/ 64 <20000000>;
>> +					required-opps = <&rpmhpd_opp_low_svs>;
>> +					opp-peak-kBps = <2000000 1>;
>> +				};
>> +
>> +				/* GEN 2 x8 */
>> +				opp-40000000 {
>> +					opp-hz = /bits/ 64 <40000000>;
>> +					required-opps = <&rpmhpd_opp_low_svs>;
>> +					opp-peak-kBps = <4000000 1>;
>> +				};
>> +
>> +				/* GEN 3 x1 */
>> +				opp-8000000 {
>> +					opp-hz = /bits/ 64 <8000000>;
>> +					required-opps = <&rpmhpd_opp_svs>;
>> +					opp-peak-kBps = <984500 1>;
>> +				};
>> +
>> +				/* GEN 3 x2 and GEN 4 x1 */
>> +				opp-16000000 {
>> +					opp-hz = /bits/ 64 <16000000>;
>> +					required-opps = <&rpmhpd_opp_svs>;
>> +					opp-peak-kBps = <1969000 1>;
>> +				};
>> +
>> +				/* GEN 3 x4 and GEN 4 x2 */
>> +				opp-32000000 {
>> +					opp-hz = /bits/ 64 <32000000>;
>> +					required-opps = <&rpmhpd_opp_svs>;
>> +					opp-peak-kBps = <3938000 1>;
>> +				};
>> +
>> +				/* GEN 3 x8 and GEN 4 x4 */
>> +				opp-64000000 {
>> +					opp-hz = /bits/ 64 <64000000>;
>> +					required-opps = <&rpmhpd_opp_svs>;
>> +					opp-peak-kBps = <7876000 1>;
>> +				};
>> +
>> +				/* GEN 4 x8 */
>> +				opp-128000000 {
>> +					opp-hz = /bits/ 64 <128000000>;
>> +					required-opps = <&rpmhpd_opp_svs>;
>> +					opp-peak-kBps = <15753000 1>;
>> +				};
>> +			};
>> +		};
>> +
>> +		pcie3_phy: phy at 1be0000 {
>> +			compatible = "qcom,x1e80100-qmp-gen4x8-pcie-phy";
>> +			reg = <0 0x01be0000 0 0x10000>;
>> +
>> +			clocks = <&gcc GCC_PCIE_3_PHY_AUX_CLK>,
>> +				 <&gcc GCC_PCIE_3_CFG_AHB_CLK>,
>> +				 <&tcsr TCSR_PCIE_8L_CLKREF_EN>,
>> +				 <&gcc GCC_PCIE_3_PHY_RCHNG_CLK>,
>> +				 <&gcc GCC_PCIE_3_PIPE_CLK>,
>> +				 <&gcc GCC_PCIE_3_PIPEDIV2_CLK>;
>> +			clock-names = "aux",
>> +				      "cfg_ahb",
>> +				      "ref",
>> +				      "rchng",
>> +				      "pipe",
>> +				      "pipediv2";
>> +
>> +			resets = <&gcc GCC_PCIE_3_PHY_BCR>,
>> +				 <&gcc GCC_PCIE_3_NOCSR_COM_PHY_BCR>;
>> +			reset-names = "phy",
>> +				      "phy_nocsr";
>> +
>> +			assigned-clocks = <&gcc GCC_PCIE_3_PHY_RCHNG_CLK>;
>> +			assigned-clock-rates = <100000000>;
>> +
>> +			power-domains = <&gcc GCC_PCIE_3_PHY_GDSC>;
>> +
>> +			#clock-cells = <0>;
>> +			clock-output-names = "pcie3_pipe_clk";
>> +
>> +			#phy-cells = <0>;
>> +
>> +			status = "disabled";
>> +		};
>> +
>>   		pcie6a: pci at 1bf8000 {
>>   			device_type = "pci";
>>   			compatible = "qcom,pcie-x1e80100";
>> -- 
>> 2.34.1
>>


From quic_qianyu at quicinc.com  Thu Sep 19 07:14:06 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Thu, 19 Sep 2024 22:14:06 +0800
Subject: [PATCH v2 0/5] Add support for PCIe3 on x1e80100
In-Reply-To: <36bd9f69-e263-08a1-af07-45185ea03671@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <36bd9f69-e263-08a1-af07-45185ea03671@quicinc.com>
Message-ID: <6f1118eb-89cf-4fd4-a35d-e8b98b0b7a8d@quicinc.com>


On 9/14/2024 11:59 AM, Krishna Chaitanya Chundru wrote:
> Hi qiang,
>
> In next series can you add logic in controller driver
> to have new ops for this x1e80100 since this hardware
> has smmuv3 support but currently the ops_1_9_0 ops which
> is being used has configuring bdf to sid table which will
> be not present for this devices.
>
Sure, bdf2sid map is not supported and required since we use smmuv3 for
pcie on x1e80100. Can I add a new ops which is same as ops_1_9_0 basically
and only config_sid callback is removed. Or add a new flag to determine if
we need to config bdf2sid map like no_l0s.

Hi Mani, what do you think about this?

Thanks,
Qiang
>
> - Krishna Chaitanya.
>
> On 9/13/2024 2:07 PM, Qiang Yu wrote:
>> This series add support for PCIe3 on x1e80100.
>>
>> PCIe3 needs additional set of clocks, regulators and new set of PCIe QMP
>> PHY configuration compare other PCIe instances on x1e80100. Hence add
>> required resource configuration and usage for PCIe3.
>>
>> v2->v1:
>> 1. Squash [PATCH 1/8], [PATCH 2/8],[PATCH 3/8] into one patch and 
>> make the
>> ??? indentation consistent.
>> 2. Put dts patch at the end of the patchset.
>> 3. Put dt-binding patch at the first of the patchset.
>> 4. Add a new patch where opp-table is added in dt-binding to avoid dtbs
>> ??? checking error.
>> 5. Remove GCC_PCIE_3_AUX_CLK, RPMH_CXO_CLK, put in 
>> TCSR_PCIE_8L_CLKREF_EN
>> ??? as ref.
>> 6. Remove lane_broadcasting.
>> 7. Add 64 bit bar, Remove GCC_PCIE_3_PIPE_CLK_SRC,
>> ??? GCC_CFG_NOC_PCIE_ANOC_SOUTH_AHB_CLK is changed to
>> ??? GCC_CFG_NOC_PCIE_ANOC_NORTH_AHB_CLK.
>> 8. Add Reviewed-by tag.
>> 9. Remove [PATCH 7/8], [PATCH 8/8].
>>
>> Qiang Yu (5):
>> ?? dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the X1E80100
>> ???? QMP PCIe PHY Gen4 x8
>> ?? dt-bindings: PCI: qcom: Add OPP table for X1E80100
>> ?? phy: qcom: qmp: Add phy register and clk setting for x1e80100 PCIe3
>> ?? clk: qcom: gcc-x1e80100: Fix halt_check for pipediv2 clocks
>> ?? arm64: dts: qcom: x1e80100: Add support for PCIe3 on x1e80100
>>
>> ? .../bindings/pci/qcom,pcie-x1e80100.yaml????? |?? 4 +
>> ? .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml?????? |?? 3 +
>> ? arch/arm64/boot/dts/qcom/x1e80100.dtsi??????? | 202 ++++++++++++++++-
>> ? drivers/clk/qcom/gcc-x1e80100.c?????????????? |? 10 +-
>> ? drivers/phy/qualcomm/phy-qcom-qmp-pcie.c????? | 211 ++++++++++++++++++
>> ? .../qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h??? |? 25 +++
>> ? drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h |? 19 ++
>> ? 7 files changed, 468 insertions(+), 6 deletions(-)
>> ? create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
>> ? create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h
>>


From konradybcio at kernel.org  Thu Sep 19 08:37:33 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Thu, 19 Sep 2024 17:37:33 +0200
Subject: [PATCH v2 1/5] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document the X1E80100 QMP PCIe PHY Gen4 x8
In-Reply-To: <b36819ed-0e4a-4820-8c38-ac9d2c6f0f28@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-2-quic_qianyu@quicinc.com>
 <lrcridndulcurod7tc5z76tmfhcf5uqumkw7cijsqicmad2rim@blyor66wt4e4>
 <b36819ed-0e4a-4820-8c38-ac9d2c6f0f28@quicinc.com>
Message-ID: <2acbaedc-e577-4685-875c-ba599d845b19@kernel.org>

On 19.09.2024 4:03 PM, Qiang Yu wrote:
> 
> On 9/16/2024 11:15 PM, Krzysztof Kozlowski wrote:
>> On Fri, Sep 13, 2024 at 01:37:20AM -0700, Qiang Yu wrote:
>>> PCIe 3rd instance of X1E80100 support Gen 4x8 which needs different 8 lane
>>> capable QMP PCIe PHY. Document Gen 4x8 PHY as separate module.
>> And this is really different hardware? Not just different number of lanes? We discussed it, but I don't see the explanation in commit msg.
> Yes, PCIe3 use a different phy that supports 8 lanes and provides
> additional register set, txz and rxz. It is not a bifurcation mode which
> actually combines two same phys like PCIe6a. It's also not just different
> number of lanes. Will explain this in commit msg.

Krzysztof, this PHY is new and has a different hardware revision (v6.30 as
opposed to v6.20? of the other ones)

Konrad


From johan at kernel.org  Fri Sep 20 01:40:13 2024
From: johan at kernel.org (Johan Hovold)
Date: Fri, 20 Sep 2024 10:40:13 +0200
Subject: [PATCH] phy: qcom: edp: Add runtime PM support
In-Reply-To: <ZurRLf8S1j6s8GPz@linaro.org>
References: <20240907-phy-qcom-edp-enable-runtime-pm-v1-1-8b9ee4210e1e@linaro.org>
 <ZuqmB3Cn7mGfA2PU@hovoldconsulting.com>
 <ZurRLf8S1j6s8GPz@linaro.org>
Message-ID: <Zu007YUYie7bEQvj@hovoldconsulting.com>

On Wed, Sep 18, 2024 at 04:10:05PM +0300, Abel Vesa wrote:
> On 24-09-18 12:05:59, Johan Hovold wrote:
> > On Sat, Sep 07, 2024 at 06:25:21PM +0300, Abel Vesa wrote:
> > > Enable runtime PM support by adding proper ops which will handle the
 
> > > clocks and regulators. These resources will now be handled on power_on and
> > > power_off instead of init and exit PHY ops.
> > 
> > No, this is simply a false claim and indicates that you haven't reviewed
> > how PHY runtime PM works. Core will increment the usage count on init()
> > and decrement it on exit().
> 
> Yeah, I guess the better argument here would be that the PHY needs
> regulators and clocks enabled

No, that's already handled today so is clearly not a valid argument.

> Anyway, ignore this version as it was already NACKed by Dmitry.

No, my feedback is still valid, and you're bound to repeat the same
mistakes over and over again unless you try to understand what I've been
saying here.

> > > Also enable these resources on
> > > probe in order to balance out the disabling that is happening right after.
> > > Prevent runtime PM from being ON by default as well.
> > 
> > And here you just regressed all current systems that do not have udev
> > rules to enable runtime PM, and which will now be stuck with these
> > resources always-on (e.g. during DPMS off and system suspend).
> > 
> > In fact, you are even regressing systems that would enable runtime PM,
> > as the runtime suspend callback would not currently be called when you
> > enter system suspend so the regulators and clocks will be left on.
> > 
> > This clearly hasn't been tested and analysed properly.

Johan


From abel.vesa at linaro.org  Fri Sep 20 02:02:25 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Fri, 20 Sep 2024 12:02:25 +0300
Subject: [PATCH] phy: qcom: edp: Add runtime PM support
In-Reply-To: <Zu007YUYie7bEQvj@hovoldconsulting.com>
References: <20240907-phy-qcom-edp-enable-runtime-pm-v1-1-8b9ee4210e1e@linaro.org>
 <ZuqmB3Cn7mGfA2PU@hovoldconsulting.com>
 <ZurRLf8S1j6s8GPz@linaro.org>
 <Zu007YUYie7bEQvj@hovoldconsulting.com>
Message-ID: <Zu06IXym0it9UPpa@linaro.org>

On 24-09-20 10:40:13, Johan Hovold wrote:
> On Wed, Sep 18, 2024 at 04:10:05PM +0300, Abel Vesa wrote:
> > On 24-09-18 12:05:59, Johan Hovold wrote:
> > > On Sat, Sep 07, 2024 at 06:25:21PM +0300, Abel Vesa wrote:
> > > > Enable runtime PM support by adding proper ops which will handle the
>  
> > > > clocks and regulators. These resources will now be handled on power_on and
> > > > power_off instead of init and exit PHY ops.
> > > 
> > > No, this is simply a false claim and indicates that you haven't reviewed
> > > how PHY runtime PM works. Core will increment the usage count on init()
> > > and decrement it on exit().
> > 
> > Yeah, I guess the better argument here would be that the PHY needs
> > regulators and clocks enabled
> 
> No, that's already handled today so is clearly not a valid argument.

I think we're saying the same thing here. I was trying to say that,
as it is currently done and it's correct, the init() needs those
resources enabled.

> 
> > Anyway, ignore this version as it was already NACKed by Dmitry.
> 
> No, my feedback is still valid, and you're bound to repeat the same
> mistakes over and over again unless you try to understand what I've been
> saying here.

Duly noted. My reply wasn't trying to dismiss your feedback.

Thanks for your feedback.

> 
> > > > Also enable these resources on
> > > > probe in order to balance out the disabling that is happening right after.
> > > > Prevent runtime PM from being ON by default as well.
> > > 
> > > And here you just regressed all current systems that do not have udev
> > > rules to enable runtime PM, and which will now be stuck with these
> > > resources always-on (e.g. during DPMS off and system suspend).
> > > 
> > > In fact, you are even regressing systems that would enable runtime PM,
> > > as the runtime suspend callback would not currently be called when you
> > > enter system suspend so the regulators and clocks will be left on.
> > > 
> > > This clearly hasn't been tested and analysed properly.
> 
> Johan


From andyshrk at 163.com  Fri Sep 20 02:36:28 2024
From: andyshrk at 163.com (Andy Yan)
Date: Fri, 20 Sep 2024 17:36:28 +0800
Subject: [PATCH] phy: phy-rockchip-samsung-hdptx: Don't request RST_PHY/RST_ROPLL/RST_LCPLL
Message-ID: <20240920093629.7410-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

RST_PHY/RST_ROPLL/RST_LCPLL are used for debug only on rk3588,
and they are not exported on rk3576, no need to request it in
driver.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
---
 .../phy/rockchip/phy-rockchip-samsung-hdptx.c   | 17 +----------------
 1 file changed, 1 insertion(+), 16 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 946c01210ac8..f3f03914bf78 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -252,13 +252,10 @@ struct ropll_config {
 };
 
 enum rk_hdptx_reset {
-	RST_PHY = 0,
-	RST_APB,
+	RST_APB = 0,
 	RST_INIT,
 	RST_CMN,
 	RST_LANE,
-	RST_ROPLL,
-	RST_LCPLL,
 	RST_MAX
 };
 
@@ -655,11 +652,6 @@ static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx)
 {
 	u32 val;
 
-	/* reset phy and apb, or phy locked flag may keep 1 */
-	reset_control_assert(hdptx->rsts[RST_PHY].rstc);
-	usleep_range(20, 30);
-	reset_control_deassert(hdptx->rsts[RST_PHY].rstc);
-
 	reset_control_assert(hdptx->rsts[RST_APB].rstc);
 	usleep_range(20, 30);
 	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
@@ -780,10 +772,6 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
 
 	rk_hdptx_pre_power_up(hdptx);
 
-	reset_control_assert(hdptx->rsts[RST_ROPLL].rstc);
-	usleep_range(20, 30);
-	reset_control_deassert(hdptx->rsts[RST_ROPLL].rstc);
-
 	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq);
 	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_cmn_init_seq);
 
@@ -958,13 +946,10 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(hdptx->regmap),
 				     "Failed to init regmap\n");
 
-	hdptx->rsts[RST_PHY].id = "phy";
 	hdptx->rsts[RST_APB].id = "apb";
 	hdptx->rsts[RST_INIT].id = "init";
 	hdptx->rsts[RST_CMN].id = "cmn";
 	hdptx->rsts[RST_LANE].id = "lane";
-	hdptx->rsts[RST_ROPLL].id = "ropll";
-	hdptx->rsts[RST_LCPLL].id = "lcpll";
 
 	ret = devm_reset_control_bulk_get_exclusive(dev, RST_MAX, hdptx->rsts);
 	if (ret)
-- 
2.34.1



From krzk at kernel.org  Fri Sep 20 04:22:35 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 20 Sep 2024 13:22:35 +0200
Subject: [PATCH v2 1/5] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document the X1E80100 QMP PCIe PHY Gen4 x8
In-Reply-To: <2acbaedc-e577-4685-875c-ba599d845b19@kernel.org>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <20240913083724.1217691-2-quic_qianyu@quicinc.com>
 <lrcridndulcurod7tc5z76tmfhcf5uqumkw7cijsqicmad2rim@blyor66wt4e4>
 <b36819ed-0e4a-4820-8c38-ac9d2c6f0f28@quicinc.com>
 <2acbaedc-e577-4685-875c-ba599d845b19@kernel.org>
Message-ID: <cd40d57c-51d2-480e-80ef-7d87dd96a6b2@kernel.org>

On 19/09/2024 17:37, Konrad Dybcio wrote:
> On 19.09.2024 4:03 PM, Qiang Yu wrote:
>>
>> On 9/16/2024 11:15 PM, Krzysztof Kozlowski wrote:
>>> On Fri, Sep 13, 2024 at 01:37:20AM -0700, Qiang Yu wrote:
>>>> PCIe 3rd instance of X1E80100 support Gen 4x8 which needs different 8 lane
>>>> capable QMP PCIe PHY. Document Gen 4x8 PHY as separate module.
>>> And this is really different hardware? Not just different number of lanes? We discussed it, but I don't see the explanation in commit msg.
>> Yes, PCIe3 use a different phy that supports 8 lanes and provides
>> additional register set, txz and rxz. It is not a bifurcation mode which
>> actually combines two same phys like PCIe6a. It's also not just different
>> number of lanes. Will explain this in commit msg.
> 
> Krzysztof, this PHY is new and has a different hardware revision (v6.30 as
> opposed to v6.20? of the other ones)

It's fine for me then, but I expect commit msg to say this. For I am a
bear of very little brain, and I forget the topic right after I close
the email.

Best regards,
Krzysztof



From dmitry.baryshkov at linaro.org  Sat Sep 21 13:28:21 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sat, 21 Sep 2024 23:28:21 +0300
Subject: [PATCH v16 2/8] phy: Add HDMI configuration options
In-Reply-To: <b1acbd48470d41b53b359d27fa2ea9358a037324.1719903904.git.Sandor.yu@nxp.com>
References: <cover.1719903904.git.Sandor.yu@nxp.com>
 <b1acbd48470d41b53b359d27fa2ea9358a037324.1719903904.git.Sandor.yu@nxp.com>
Message-ID: <5bn3qcbzyyudjh34y76jj2r5j2p7mzpig4xntmjjlneznoipjw@ca7sbco5ceyk>

On Tue, Jul 02, 2024 at 08:22:34PM GMT, Sandor Yu wrote:
> Allow HDMI PHYs to be configured through the generic
> functions through a custom structure added to the generic union.
> 
> The parameters added here are based on HDMI PHY
> implementation practices.  The current set of parameters
> should cover the potential users.
> 
> Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> ---
> v15->v16:
> - Remove pixel_clk_rate, bpc and color_space fields from struct
>   phy_configure_opts_hdmi, they were replaced by unsigned long long tmds_char_rate.
> - Remove r-b and a-c tags because this patch have important change.
> 
> v9->v15:
>  *No change.
> 
>  include/linux/phy/phy-hdmi.h | 20 ++++++++++++++++++++
>  include/linux/phy/phy.h      |  7 ++++++-
>  2 files changed, 26 insertions(+), 1 deletion(-)
>  create mode 100644 include/linux/phy/phy-hdmi.h
> 
> diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
> new file mode 100644
> index 000000000000..dd923e19d17c
> --- /dev/null
> +++ b/include/linux/phy/phy-hdmi.h
> @@ -0,0 +1,20 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright 2022 NXP
> + */
> +
> +#ifndef __PHY_HDMI_H_
> +#define __PHY_HDMI_H_
> +
> +#include <linux/hdmi.h>

This header is not neccessary anymore. With it removed:

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Maxime, is this patch fine with you?

Vinod, could you please pick up this patch for 6.13 and possibly provide
an immutable tag for it? I see drm drivers using bad workarounds because
we don't have this in the API yet.

> +/**
> + * struct phy_configure_opts_hdmi - HDMI configuration set
> + * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
> + *
> + * This structure is used to represent the configuration state of a HDMI phy.
> + */
> +struct phy_configure_opts_hdmi {
> +	unsigned long long tmds_char_rate;
> +};
> +
> +#endif /* __PHY_HDMI_H_ */
> diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
> index 03cd5bae92d3..4ac486b101fe 100644
> --- a/include/linux/phy/phy.h
> +++ b/include/linux/phy/phy.h
> @@ -17,6 +17,7 @@
>  #include <linux/regulator/consumer.h>
>  
>  #include <linux/phy/phy-dp.h>
> +#include <linux/phy/phy-hdmi.h>
>  #include <linux/phy/phy-lvds.h>
>  #include <linux/phy/phy-mipi-dphy.h>
>  
> @@ -42,7 +43,8 @@ enum phy_mode {
>  	PHY_MODE_MIPI_DPHY,
>  	PHY_MODE_SATA,
>  	PHY_MODE_LVDS,
> -	PHY_MODE_DP
> +	PHY_MODE_DP,
> +	PHY_MODE_HDMI,
>  };
>  
>  enum phy_media {
> @@ -60,11 +62,14 @@ enum phy_media {
>   *		the DisplayPort protocol.
>   * @lvds:	Configuration set applicable for phys supporting
>   *		the LVDS phy mode.
> + * @hdmi:	Configuration set applicable for phys supporting
> + *		the HDMI phy mode.
>   */
>  union phy_configure_opts {
>  	struct phy_configure_opts_mipi_dphy	mipi_dphy;
>  	struct phy_configure_opts_dp		dp;
>  	struct phy_configure_opts_lvds		lvds;
> +	struct phy_configure_opts_hdmi		hdmi;
>  };
>  
>  /**
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From manivannan.sadhasivam at linaro.org  Sun Sep 22 10:09:25 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Sun, 22 Sep 2024 19:09:25 +0200
Subject: [PATCH v2 0/5] Add support for PCIe3 on x1e80100
In-Reply-To: <6f1118eb-89cf-4fd4-a35d-e8b98b0b7a8d@quicinc.com>
References: <20240913083724.1217691-1-quic_qianyu@quicinc.com>
 <36bd9f69-e263-08a1-af07-45185ea03671@quicinc.com>
 <6f1118eb-89cf-4fd4-a35d-e8b98b0b7a8d@quicinc.com>
Message-ID: <20240922170925.qcuwja6oaqlbng5j@thinkpad>

On Thu, Sep 19, 2024 at 10:14:06PM +0800, Qiang Yu wrote:
> 
> On 9/14/2024 11:59 AM, Krishna Chaitanya Chundru wrote:
> > Hi qiang,
> > 
> > In next series can you add logic in controller driver
> > to have new ops for this x1e80100 since this hardware
> > has smmuv3 support but currently the ops_1_9_0 ops which
> > is being used has configuring bdf to sid table which will
> > be not present for this devices.
> > 
> Sure, bdf2sid map is not supported and required since we use smmuv3 for
> pcie on x1e80100. Can I add a new ops which is same as ops_1_9_0 basically
> and only config_sid callback is removed. Or add a new flag to determine if
> we need to config bdf2sid map like no_l0s.
> 
> Hi Mani, what do you think about this?
> 

Good question. IMO it is better to add a new ops even though it duplictes the
callbacks. Because the newer platforms are not going to need this bdf2sid map
anyway. But if we add a flag to determine that, then the check will become,

	if (pcie->cfg->ops->config_sid && !pcie->cfg->smmuv3)
		...

And this doesn't look good as both conditions are false for X1E80100 i.e., it
doesn't need bdf2sid mapping and it is also a SMMUv3 platform. Moreover having
two checks here makes it confusing also.

So let's use a new callback. But please mention the IP revision in comments as
like other ops.

- Mani

> Thanks,
> Qiang
> > 
> > - Krishna Chaitanya.
> > 
> > On 9/13/2024 2:07 PM, Qiang Yu wrote:
> > > This series add support for PCIe3 on x1e80100.
> > > 
> > > PCIe3 needs additional set of clocks, regulators and new set of PCIe QMP
> > > PHY configuration compare other PCIe instances on x1e80100. Hence add
> > > required resource configuration and usage for PCIe3.
> > > 
> > > v2->v1:
> > > 1. Squash [PATCH 1/8], [PATCH 2/8],[PATCH 3/8] into one patch and
> > > make the
> > > ??? indentation consistent.
> > > 2. Put dts patch at the end of the patchset.
> > > 3. Put dt-binding patch at the first of the patchset.
> > > 4. Add a new patch where opp-table is added in dt-binding to avoid dtbs
> > > ??? checking error.
> > > 5. Remove GCC_PCIE_3_AUX_CLK, RPMH_CXO_CLK, put in
> > > TCSR_PCIE_8L_CLKREF_EN
> > > ??? as ref.
> > > 6. Remove lane_broadcasting.
> > > 7. Add 64 bit bar, Remove GCC_PCIE_3_PIPE_CLK_SRC,
> > > ??? GCC_CFG_NOC_PCIE_ANOC_SOUTH_AHB_CLK is changed to
> > > ??? GCC_CFG_NOC_PCIE_ANOC_NORTH_AHB_CLK.
> > > 8. Add Reviewed-by tag.
> > > 9. Remove [PATCH 7/8], [PATCH 8/8].
> > > 
> > > Qiang Yu (5):
> > > ?? dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the X1E80100
> > > ???? QMP PCIe PHY Gen4 x8
> > > ?? dt-bindings: PCI: qcom: Add OPP table for X1E80100
> > > ?? phy: qcom: qmp: Add phy register and clk setting for x1e80100 PCIe3
> > > ?? clk: qcom: gcc-x1e80100: Fix halt_check for pipediv2 clocks
> > > ?? arm64: dts: qcom: x1e80100: Add support for PCIe3 on x1e80100
> > > 
> > > ? .../bindings/pci/qcom,pcie-x1e80100.yaml????? |?? 4 +
> > > ? .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml?????? |?? 3 +
> > > ? arch/arm64/boot/dts/qcom/x1e80100.dtsi??????? | 202 ++++++++++++++++-
> > > ? drivers/clk/qcom/gcc-x1e80100.c?????????????? |? 10 +-
> > > ? drivers/phy/qualcomm/phy-qcom-qmp-pcie.c????? | 211 ++++++++++++++++++
> > > ? .../qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h??? |? 25 +++
> > > ? drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h |? 19 ++
> > > ? 7 files changed, 468 insertions(+), 6 deletions(-)
> > > ? create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
> > > ? create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h
> > > 

-- 
????????? ????????


From frank.wang at rock-chips.com  Sun Sep 22 19:44:25 2024
From: frank.wang at rock-chips.com (Frank Wang)
Date: Mon, 23 Sep 2024 10:44:25 +0800
Subject: [PATCH 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add rk3576
Message-ID: <20240923024426.10330-1-frank.wang@rock-chips.com>

Add compatible for the USB2 phy in the Rockchip RK3576 SoC.

Change-Id: Ia976f68069ae96a01e30db7183a7b51f78a92951
Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
---
 .../devicetree/bindings/phy/rockchip,inno-usb2phy.yaml | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
index 5254413137c64..214917e55c0b6 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
@@ -20,6 +20,7 @@ properties:
       - rockchip,rk3366-usb2phy
       - rockchip,rk3399-usb2phy
       - rockchip,rk3568-usb2phy
+      - rockchip,rk3576-usb2phy
       - rockchip,rk3588-usb2phy
       - rockchip,rv1108-usb2phy
 
@@ -34,10 +35,16 @@ properties:
     const: 0
 
   clocks:
-    maxItems: 1
+    minItems: 1
+    items:
+      - description: phyclk - PHY input reference clocks.
+      - description: aclk and aclk_slv are optional and used for USB MMU.
 
   clock-names:
+    minItems: 1
     const: phyclk
+    const: aclk
+    const: aclk_slv
 
   assigned-clocks:
     description:
@@ -144,6 +151,7 @@ allOf:
             enum:
               - rockchip,rk3568-usb2phy
               - rockchip,rk3588-usb2phy
+              - rockchip,rk3576-usb2phy
 
     then:
       properties:
-- 
2.45.2



From frank.wang at rock-chips.com  Sun Sep 22 19:44:26 2024
From: frank.wang at rock-chips.com (Frank Wang)
Date: Mon, 23 Sep 2024 10:44:26 +0800
Subject: [PATCH 2/2] phy: rockchip: inno-usb2: Add usb2 phys support for rk3576
In-Reply-To: <20240923024426.10330-1-frank.wang@rock-chips.com>
References: <20240923024426.10330-1-frank.wang@rock-chips.com>
Message-ID: <20240923024426.10330-2-frank.wang@rock-chips.com>

From: William Wu <william.wu at rock-chips.com>

The RK3576 SoC has two independent USB2.0 PHYs, and
each PHY has one port.

Change-Id: I291b062e12ffb20e3df8462fe9a2fd32c3091317
Signed-off-by: William Wu <william.wu at rock-chips.com>
Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 131 ++++++++++++++++--
 1 file changed, 123 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 4f71373ae6e1a..51ca16cbb86cb 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -229,9 +229,10 @@ struct rockchip_usb2phy_port {
  * @dev: pointer to device.
  * @grf: General Register Files regmap.
  * @usbgrf: USB General Register Files regmap.
- * @clk: clock struct of phy input clk.
+ * @clks: array of phy input clocks.
  * @clk480m: clock struct of phy output clk.
  * @clk480m_hw: clock struct of phy output clk management.
+ * @num_clks: number of phy input clocks.
  * @phy_reset: phy reset control.
  * @chg_state: states involved in USB charger detection.
  * @chg_type: USB charger types.
@@ -246,9 +247,10 @@ struct rockchip_usb2phy {
 	struct device	*dev;
 	struct regmap	*grf;
 	struct regmap	*usbgrf;
-	struct clk	*clk;
+	struct clk_bulk_data	*clks;
 	struct clk	*clk480m;
 	struct clk_hw	clk480m_hw;
+	int			num_clks;
 	struct reset_control	*phy_reset;
 	enum usb_chg_state	chg_state;
 	enum power_supply_type	chg_type;
@@ -376,6 +378,7 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
 {
 	struct device_node *node = rphy->dev->of_node;
 	struct clk_init_data init;
+	struct clk *refclk = of_clk_get_by_name(node, "phyclk");
 	const char *clk_name;
 	int ret = 0;
 
@@ -386,8 +389,8 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
 	/* optional override of the clockname */
 	of_property_read_string(node, "clock-output-names", &init.name);
 
-	if (rphy->clk) {
-		clk_name = __clk_get_name(rphy->clk);
+	if (!IS_ERR(refclk)) {
+		clk_name = __clk_get_name(refclk);
 		init.parent_names = &clk_name;
 		init.num_parents = 1;
 	} else {
@@ -1406,22 +1409,29 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 	if (IS_ERR(rphy->phy_reset))
 		return PTR_ERR(rphy->phy_reset);
 
-	rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk");
-	if (IS_ERR(rphy->clk)) {
-		return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk),
+	ret = devm_clk_bulk_get_all(dev, &rphy->clks);
+	if (ret == -EPROBE_DEFER) {
+		return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
 				     "failed to get phyclk\n");
 	}
 
+	/* Clocks are optional */
+	rphy->num_clks = ret < 0 ? 0 : ret;
+
 	ret = rockchip_usb2phy_clk480m_register(rphy);
 	if (ret) {
 		dev_err(dev, "failed to register 480m output clock\n");
 		return ret;
 	}
 
+	ret = clk_bulk_prepare_enable(rphy->num_clks, rphy->clks);
+	if (ret)
+		return ret;
+
 	if (rphy->phy_cfg->phy_tuning) {
 		ret = rphy->phy_cfg->phy_tuning(rphy);
 		if (ret)
-			return ret;
+			goto disable_clks;
 	}
 
 	index = 0;
@@ -1484,6 +1494,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 
 put_child:
 	of_node_put(child_np);
+disable_clks:
+	clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks);
 	return ret;
 }
 
@@ -1495,6 +1507,30 @@ static int rk3128_usb2phy_tuning(struct rockchip_usb2phy *rphy)
 				BIT(2) << BIT_WRITEABLE_SHIFT | 0);
 }
 
+static int rk3576_usb2phy_tuning(struct rockchip_usb2phy *rphy)
+{
+	int ret;
+	u32 reg = rphy->phy_cfg->reg;
+
+	/* Deassert SIDDQ to power on analog block */
+	ret = regmap_write(rphy->grf, reg + 0x0010, GENMASK(29, 29) | 0x0000);
+	if (ret)
+		return ret;
+
+	/* Do reset after exit IDDQ mode */
+	ret = rockchip_usb2phy_reset(rphy);
+	if (ret)
+		return ret;
+
+	/* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */
+	ret |= regmap_write(rphy->grf, reg + 0x000c, GENMASK(27, 24) | 0x0900);
+
+	/* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
+	ret |= regmap_write(rphy->grf, reg + 0x0010, GENMASK(20, 19) | 0x0010);
+
+	return ret;
+}
+
 static int rk3588_usb2phy_tuning(struct rockchip_usb2phy *rphy)
 {
 	int ret;
@@ -1923,6 +1959,84 @@ static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
 	{ /* sentinel */ }
 };
 
+static const struct rockchip_usb2phy_cfg rk3576_phy_cfgs[] = {
+	{
+		.reg = 0x0,
+		.num_ports	= 1,
+		.phy_tuning	= rk3576_usb2phy_tuning,
+		.clkout_ctl	= { 0x0008, 0, 0, 1, 0 },
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x0000, 8, 0, 0, 0x1d1 },
+				.bvalid_det_en	= { 0x00c0, 1, 1, 0, 1 },
+				.bvalid_det_st	= { 0x00c4, 1, 1, 0, 1 },
+				.bvalid_det_clr = { 0x00c8, 1, 1, 0, 1 },
+				.ls_det_en	= { 0x00c0, 0, 0, 0, 1 },
+				.ls_det_st	= { 0x00c4, 0, 0, 0, 1 },
+				.ls_det_clr	= { 0x00c8, 0, 0, 0, 1 },
+				.disfall_en	= { 0x00c0, 6, 6, 0, 1 },
+				.disfall_st	= { 0x00c4, 6, 6, 0, 1 },
+				.disfall_clr	= { 0x00c8, 6, 6, 0, 1 },
+				.disrise_en	= { 0x00c0, 5, 5, 0, 1 },
+				.disrise_st	= { 0x00c4, 5, 5, 0, 1 },
+				.disrise_clr	= { 0x00c8, 5, 5, 0, 1 },
+				.utmi_avalid	= { 0x0080, 1, 1, 0, 1 },
+				.utmi_bvalid	= { 0x0080, 0, 0, 0, 1 },
+				.utmi_ls	= { 0x0080, 5, 4, 0, 1 },
+			}
+		},
+		.chg_det = {
+			.cp_det		= { 0x0080, 8, 8, 0, 1 },
+			.dcp_det	= { 0x0080, 8, 8, 0, 1 },
+			.dp_det		= { 0x0080, 9, 9, 1, 0 },
+			.idm_sink_en	= { 0x0010, 5, 5, 1, 0 },
+			.idp_sink_en	= { 0x0010, 5, 5, 0, 1 },
+			.idp_src_en	= { 0x0010, 14, 14, 0, 1 },
+			.rdm_pdwn_en	= { 0x0010, 14, 14, 0, 1 },
+			.vdm_src_en	= { 0x0010, 7, 6, 0, 3 },
+			.vdp_src_en	= { 0x0010, 7, 6, 0, 3 },
+		},
+	},
+	{
+		.reg = 0x2000,
+		.num_ports	= 1,
+		.phy_tuning	= rk3576_usb2phy_tuning,
+		.clkout_ctl	= { 0x2008, 0, 0, 1, 0 },
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x2000, 8, 0, 0, 0x1d1 },
+				.bvalid_det_en	= { 0x20c0, 1, 1, 0, 1 },
+				.bvalid_det_st	= { 0x20c4, 1, 1, 0, 1 },
+				.bvalid_det_clr = { 0x20c8, 1, 1, 0, 1 },
+				.ls_det_en	= { 0x20c0, 0, 0, 0, 1 },
+				.ls_det_st	= { 0x20c4, 0, 0, 0, 1 },
+				.ls_det_clr	= { 0x20c8, 0, 0, 0, 1 },
+				.disfall_en	= { 0x20c0, 6, 6, 0, 1 },
+				.disfall_st	= { 0x20c4, 6, 6, 0, 1 },
+				.disfall_clr	= { 0x20c8, 6, 6, 0, 1 },
+				.disrise_en	= { 0x20c0, 5, 5, 0, 1 },
+				.disrise_st	= { 0x20c4, 5, 5, 0, 1 },
+				.disrise_clr	= { 0x20c8, 5, 5, 0, 1 },
+				.utmi_avalid	= { 0x2080, 1, 1, 0, 1 },
+				.utmi_bvalid	= { 0x2080, 0, 0, 0, 1 },
+				.utmi_ls	= { 0x2080, 5, 4, 0, 1 },
+			}
+		},
+		.chg_det = {
+			.cp_det		= { 0x2080, 8, 8, 0, 1 },
+			.dcp_det	= { 0x2080, 8, 8, 0, 1 },
+			.dp_det		= { 0x2080, 9, 9, 1, 0 },
+			.idm_sink_en	= { 0x2010, 5, 5, 1, 0 },
+			.idp_sink_en	= { 0x2010, 5, 5, 0, 1 },
+			.idp_src_en	= { 0x2010, 14, 14, 0, 1 },
+			.rdm_pdwn_en	= { 0x2010, 14, 14, 0, 1 },
+			.vdm_src_en	= { 0x2010, 7, 6, 0, 3 },
+			.vdp_src_en	= { 0x2010, 7, 6, 0, 3 },
+		},
+	},
+	{ /* sentinel */ }
+};
+
 static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
 	{
 		.reg = 0x0000,
@@ -2094,6 +2208,7 @@ static const struct of_device_id rockchip_usb2phy_dt_match[] = {
 	{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
 	{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
 	{ .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
+	{ .compatible = "rockchip,rk3576-usb2phy", .data = &rk3576_phy_cfgs },
 	{ .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs },
 	{ .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
 	{}
-- 
2.45.2



From frank.wang at rock-chips.com  Sun Sep 22 19:53:25 2024
From: frank.wang at rock-chips.com (Frank Wang)
Date: Mon, 23 Sep 2024 10:53:25 +0800
Subject: [RESEND PATCH 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add rk3576
Message-ID: <20240923025326.10467-1-frank.wang@rock-chips.com>

Add compatible for the USB2 phy in the Rockchip RK3576 SoC.

Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
---
 .../devicetree/bindings/phy/rockchip,inno-usb2phy.yaml | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
index 5254413137c64..214917e55c0b6 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
@@ -20,6 +20,7 @@ properties:
       - rockchip,rk3366-usb2phy
       - rockchip,rk3399-usb2phy
       - rockchip,rk3568-usb2phy
+      - rockchip,rk3576-usb2phy
       - rockchip,rk3588-usb2phy
       - rockchip,rv1108-usb2phy
 
@@ -34,10 +35,16 @@ properties:
     const: 0
 
   clocks:
-    maxItems: 1
+    minItems: 1
+    items:
+      - description: phyclk - PHY input reference clocks.
+      - description: aclk and aclk_slv are optional and used for USB MMU.
 
   clock-names:
+    minItems: 1
     const: phyclk
+    const: aclk
+    const: aclk_slv
 
   assigned-clocks:
     description:
@@ -144,6 +151,7 @@ allOf:
             enum:
               - rockchip,rk3568-usb2phy
               - rockchip,rk3588-usb2phy
+              - rockchip,rk3576-usb2phy
 
     then:
       properties:
-- 
2.45.2



From frank.wang at rock-chips.com  Sun Sep 22 19:53:26 2024
From: frank.wang at rock-chips.com (Frank Wang)
Date: Mon, 23 Sep 2024 10:53:26 +0800
Subject: [RESEND PATCH 2/2] phy: rockchip: inno-usb2: Add usb2 phys support for rk3576
In-Reply-To: <20240923025326.10467-1-frank.wang@rock-chips.com>
References: <20240923025326.10467-1-frank.wang@rock-chips.com>
Message-ID: <20240923025326.10467-2-frank.wang@rock-chips.com>

From: William Wu <william.wu at rock-chips.com>

The RK3576 SoC has two independent USB2.0 PHYs, and
each PHY has one port.

Signed-off-by: William Wu <william.wu at rock-chips.com>
Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 131 ++++++++++++++++--
 1 file changed, 123 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 4f71373ae6e1a..51ca16cbb86cb 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -229,9 +229,10 @@ struct rockchip_usb2phy_port {
  * @dev: pointer to device.
  * @grf: General Register Files regmap.
  * @usbgrf: USB General Register Files regmap.
- * @clk: clock struct of phy input clk.
+ * @clks: array of phy input clocks.
  * @clk480m: clock struct of phy output clk.
  * @clk480m_hw: clock struct of phy output clk management.
+ * @num_clks: number of phy input clocks.
  * @phy_reset: phy reset control.
  * @chg_state: states involved in USB charger detection.
  * @chg_type: USB charger types.
@@ -246,9 +247,10 @@ struct rockchip_usb2phy {
 	struct device	*dev;
 	struct regmap	*grf;
 	struct regmap	*usbgrf;
-	struct clk	*clk;
+	struct clk_bulk_data	*clks;
 	struct clk	*clk480m;
 	struct clk_hw	clk480m_hw;
+	int			num_clks;
 	struct reset_control	*phy_reset;
 	enum usb_chg_state	chg_state;
 	enum power_supply_type	chg_type;
@@ -376,6 +378,7 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
 {
 	struct device_node *node = rphy->dev->of_node;
 	struct clk_init_data init;
+	struct clk *refclk = of_clk_get_by_name(node, "phyclk");
 	const char *clk_name;
 	int ret = 0;
 
@@ -386,8 +389,8 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
 	/* optional override of the clockname */
 	of_property_read_string(node, "clock-output-names", &init.name);
 
-	if (rphy->clk) {
-		clk_name = __clk_get_name(rphy->clk);
+	if (!IS_ERR(refclk)) {
+		clk_name = __clk_get_name(refclk);
 		init.parent_names = &clk_name;
 		init.num_parents = 1;
 	} else {
@@ -1406,22 +1409,29 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 	if (IS_ERR(rphy->phy_reset))
 		return PTR_ERR(rphy->phy_reset);
 
-	rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk");
-	if (IS_ERR(rphy->clk)) {
-		return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk),
+	ret = devm_clk_bulk_get_all(dev, &rphy->clks);
+	if (ret == -EPROBE_DEFER) {
+		return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
 				     "failed to get phyclk\n");
 	}
 
+	/* Clocks are optional */
+	rphy->num_clks = ret < 0 ? 0 : ret;
+
 	ret = rockchip_usb2phy_clk480m_register(rphy);
 	if (ret) {
 		dev_err(dev, "failed to register 480m output clock\n");
 		return ret;
 	}
 
+	ret = clk_bulk_prepare_enable(rphy->num_clks, rphy->clks);
+	if (ret)
+		return ret;
+
 	if (rphy->phy_cfg->phy_tuning) {
 		ret = rphy->phy_cfg->phy_tuning(rphy);
 		if (ret)
-			return ret;
+			goto disable_clks;
 	}
 
 	index = 0;
@@ -1484,6 +1494,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 
 put_child:
 	of_node_put(child_np);
+disable_clks:
+	clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks);
 	return ret;
 }
 
@@ -1495,6 +1507,30 @@ static int rk3128_usb2phy_tuning(struct rockchip_usb2phy *rphy)
 				BIT(2) << BIT_WRITEABLE_SHIFT | 0);
 }
 
+static int rk3576_usb2phy_tuning(struct rockchip_usb2phy *rphy)
+{
+	int ret;
+	u32 reg = rphy->phy_cfg->reg;
+
+	/* Deassert SIDDQ to power on analog block */
+	ret = regmap_write(rphy->grf, reg + 0x0010, GENMASK(29, 29) | 0x0000);
+	if (ret)
+		return ret;
+
+	/* Do reset after exit IDDQ mode */
+	ret = rockchip_usb2phy_reset(rphy);
+	if (ret)
+		return ret;
+
+	/* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */
+	ret |= regmap_write(rphy->grf, reg + 0x000c, GENMASK(27, 24) | 0x0900);
+
+	/* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
+	ret |= regmap_write(rphy->grf, reg + 0x0010, GENMASK(20, 19) | 0x0010);
+
+	return ret;
+}
+
 static int rk3588_usb2phy_tuning(struct rockchip_usb2phy *rphy)
 {
 	int ret;
@@ -1923,6 +1959,84 @@ static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
 	{ /* sentinel */ }
 };
 
+static const struct rockchip_usb2phy_cfg rk3576_phy_cfgs[] = {
+	{
+		.reg = 0x0,
+		.num_ports	= 1,
+		.phy_tuning	= rk3576_usb2phy_tuning,
+		.clkout_ctl	= { 0x0008, 0, 0, 1, 0 },
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x0000, 8, 0, 0, 0x1d1 },
+				.bvalid_det_en	= { 0x00c0, 1, 1, 0, 1 },
+				.bvalid_det_st	= { 0x00c4, 1, 1, 0, 1 },
+				.bvalid_det_clr = { 0x00c8, 1, 1, 0, 1 },
+				.ls_det_en	= { 0x00c0, 0, 0, 0, 1 },
+				.ls_det_st	= { 0x00c4, 0, 0, 0, 1 },
+				.ls_det_clr	= { 0x00c8, 0, 0, 0, 1 },
+				.disfall_en	= { 0x00c0, 6, 6, 0, 1 },
+				.disfall_st	= { 0x00c4, 6, 6, 0, 1 },
+				.disfall_clr	= { 0x00c8, 6, 6, 0, 1 },
+				.disrise_en	= { 0x00c0, 5, 5, 0, 1 },
+				.disrise_st	= { 0x00c4, 5, 5, 0, 1 },
+				.disrise_clr	= { 0x00c8, 5, 5, 0, 1 },
+				.utmi_avalid	= { 0x0080, 1, 1, 0, 1 },
+				.utmi_bvalid	= { 0x0080, 0, 0, 0, 1 },
+				.utmi_ls	= { 0x0080, 5, 4, 0, 1 },
+			}
+		},
+		.chg_det = {
+			.cp_det		= { 0x0080, 8, 8, 0, 1 },
+			.dcp_det	= { 0x0080, 8, 8, 0, 1 },
+			.dp_det		= { 0x0080, 9, 9, 1, 0 },
+			.idm_sink_en	= { 0x0010, 5, 5, 1, 0 },
+			.idp_sink_en	= { 0x0010, 5, 5, 0, 1 },
+			.idp_src_en	= { 0x0010, 14, 14, 0, 1 },
+			.rdm_pdwn_en	= { 0x0010, 14, 14, 0, 1 },
+			.vdm_src_en	= { 0x0010, 7, 6, 0, 3 },
+			.vdp_src_en	= { 0x0010, 7, 6, 0, 3 },
+		},
+	},
+	{
+		.reg = 0x2000,
+		.num_ports	= 1,
+		.phy_tuning	= rk3576_usb2phy_tuning,
+		.clkout_ctl	= { 0x2008, 0, 0, 1, 0 },
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x2000, 8, 0, 0, 0x1d1 },
+				.bvalid_det_en	= { 0x20c0, 1, 1, 0, 1 },
+				.bvalid_det_st	= { 0x20c4, 1, 1, 0, 1 },
+				.bvalid_det_clr = { 0x20c8, 1, 1, 0, 1 },
+				.ls_det_en	= { 0x20c0, 0, 0, 0, 1 },
+				.ls_det_st	= { 0x20c4, 0, 0, 0, 1 },
+				.ls_det_clr	= { 0x20c8, 0, 0, 0, 1 },
+				.disfall_en	= { 0x20c0, 6, 6, 0, 1 },
+				.disfall_st	= { 0x20c4, 6, 6, 0, 1 },
+				.disfall_clr	= { 0x20c8, 6, 6, 0, 1 },
+				.disrise_en	= { 0x20c0, 5, 5, 0, 1 },
+				.disrise_st	= { 0x20c4, 5, 5, 0, 1 },
+				.disrise_clr	= { 0x20c8, 5, 5, 0, 1 },
+				.utmi_avalid	= { 0x2080, 1, 1, 0, 1 },
+				.utmi_bvalid	= { 0x2080, 0, 0, 0, 1 },
+				.utmi_ls	= { 0x2080, 5, 4, 0, 1 },
+			}
+		},
+		.chg_det = {
+			.cp_det		= { 0x2080, 8, 8, 0, 1 },
+			.dcp_det	= { 0x2080, 8, 8, 0, 1 },
+			.dp_det		= { 0x2080, 9, 9, 1, 0 },
+			.idm_sink_en	= { 0x2010, 5, 5, 1, 0 },
+			.idp_sink_en	= { 0x2010, 5, 5, 0, 1 },
+			.idp_src_en	= { 0x2010, 14, 14, 0, 1 },
+			.rdm_pdwn_en	= { 0x2010, 14, 14, 0, 1 },
+			.vdm_src_en	= { 0x2010, 7, 6, 0, 3 },
+			.vdp_src_en	= { 0x2010, 7, 6, 0, 3 },
+		},
+	},
+	{ /* sentinel */ }
+};
+
 static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
 	{
 		.reg = 0x0000,
@@ -2094,6 +2208,7 @@ static const struct of_device_id rockchip_usb2phy_dt_match[] = {
 	{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
 	{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
 	{ .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
+	{ .compatible = "rockchip,rk3576-usb2phy", .data = &rk3576_phy_cfgs },
 	{ .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs },
 	{ .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
 	{}
-- 
2.45.2



From krzk at kernel.org  Mon Sep 23 02:31:06 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 23 Sep 2024 11:31:06 +0200
Subject: [RESEND PATCH 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <20240923025326.10467-1-frank.wang@rock-chips.com>
References: <20240923025326.10467-1-frank.wang@rock-chips.com>
Message-ID: <snccizbw6thn3lhwad4xppp7vqii4p56ttl2gufwc3ke7vfckf@e4b7nvwwtdfr>

On Mon, Sep 23, 2024 at 10:53:25AM +0800, Frank Wang wrote:
> Add compatible for the USB2 phy in the Rockchip RK3576 SoC.
> 
> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
> ---
>  .../devicetree/bindings/phy/rockchip,inno-usb2phy.yaml | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
> index 5254413137c64..214917e55c0b6 100644
> --- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
> @@ -20,6 +20,7 @@ properties:
>        - rockchip,rk3366-usb2phy
>        - rockchip,rk3399-usb2phy
>        - rockchip,rk3568-usb2phy
> +      - rockchip,rk3576-usb2phy
>        - rockchip,rk3588-usb2phy
>        - rockchip,rv1108-usb2phy
>  
> @@ -34,10 +35,16 @@ properties:
>      const: 0
>  
>    clocks:
> -    maxItems: 1
> +    minItems: 1
> +    items:
> +      - description: phyclk - PHY input reference clocks.
> +      - description: aclk and aclk_slv are optional and used for USB MMU.
>  
>    clock-names:
> +    minItems: 1
>      const: phyclk
> +    const: aclk
> +    const: aclk_slv

Please test... Not sure what you wanted to achieve here, but maybe
oneOf?

Best regards,
Krzysztof



From quic_mukhopad at quicinc.com  Mon Sep 23 04:31:45 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Mon, 23 Sep 2024 17:01:45 +0530
Subject: [PATCH v3 0/5] Add support for DisplayPort on SA8775P platform
Message-ID: <20240923113150.24711-1-quic_mukhopad@quicinc.com>

This series adds support for the DisplayPort controller
and eDP PHY v5 found on the Qualcomm SA8775P platform.

---
v2: Fixed review comments from Dmitry and Bjorn
	- Made aux_cfg array as const.
	- Reused edp_swing_hbr_rbr and edp_swing_hbr2_hbr3 for v5.

v3: Fixed review comments from Dmitry, Konrad and Bjorn
	- Used a for loop to write the dp_phy_aux_cfg registers.
	- Pre-defined the aux_cfg size to prevent any magic numbers.
	- Added all the necessary DPTX controllers for this platform.
	 
---
Soutrik Mukhopadhyay (5):
  dt-bindings: phy: Add eDP PHY compatible for sa8775p
  phy: qcom: edp: Introduce aux_cfg array for version specific aux
    settings
  phy: qcom: edp: Add support for eDP PHY on SA8775P
  dt-bindings: display: msm: dp-controller: document SA8775P compatible
  drm/msm/dp: Add DisplayPort controller for SA8775P

 .../bindings/display/msm/dp-controller.yaml   |  1 +
 .../devicetree/bindings/phy/qcom,edp-phy.yaml |  1 +
 drivers/gpu/drm/msm/dp/dp_display.c           |  9 +++
 drivers/phy/qualcomm/phy-qcom-edp.c           | 74 +++++++++++++------
 4 files changed, 61 insertions(+), 24 deletions(-)

-- 
2.17.1



From quic_mukhopad at quicinc.com  Mon Sep 23 04:31:47 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Mon, 23 Sep 2024 17:01:47 +0530
Subject: [PATCH v3 2/5] phy: qcom: edp: Introduce aux_cfg array for version specific aux settings
In-Reply-To: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
References: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
Message-ID: <20240923113150.24711-3-quic_mukhopad@quicinc.com>

In order to support different HW versions, introduce aux_cfg array
to move v4 specific aux configuration settings.

Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
v2: Fixed review comments from Bjorn and Dmitry
	- Made aux_cfg array as const.

v3: Fixed review comments from Dmitry
	- Used a for loop to write the dp_phy_aux_cfg registers.
	- Pre-defined the aux_cfg size to prevent any magic numbers.

---
 drivers/phy/qualcomm/phy-qcom-edp.c | 41 ++++++++++++-----------------
 1 file changed, 17 insertions(+), 24 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
index da2b32fb5b45..2ecff164ec44 100644
--- a/drivers/phy/qualcomm/phy-qcom-edp.c
+++ b/drivers/phy/qualcomm/phy-qcom-edp.c
@@ -32,16 +32,8 @@
 #define DP_PHY_PD_CTL                           0x001c
 #define DP_PHY_MODE                             0x0020
 
-#define DP_PHY_AUX_CFG0				0x0024
-#define DP_PHY_AUX_CFG1				0x0028
-#define DP_PHY_AUX_CFG2				0x002C
-#define DP_PHY_AUX_CFG3				0x0030
-#define DP_PHY_AUX_CFG4				0x0034
-#define DP_PHY_AUX_CFG5				0x0038
-#define DP_PHY_AUX_CFG6				0x003C
-#define DP_PHY_AUX_CFG7				0x0040
-#define DP_PHY_AUX_CFG8				0x0044
-#define DP_PHY_AUX_CFG9				0x0048
+#define DP_AUX_CFG_SIZE                         10
+#define DP_PHY_AUX_CFG(n)                       (0x24 + (0x04 * (n)))
 
 #define DP_PHY_AUX_INTERRUPT_MASK		0x0058
 
@@ -90,6 +82,7 @@ struct phy_ver_ops {
 
 struct qcom_edp_phy_cfg {
 	bool is_edp;
+	const u8 *aux_cfg;
 	const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
 	const struct phy_ver_ops *ver_ops;
 };
@@ -186,11 +179,15 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
 	.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
 };
 
+static const u8 edp_phy_aux_cfg_v4[10] = {
+	0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
+};
+
 static int qcom_edp_phy_init(struct phy *phy)
 {
 	struct qcom_edp *edp = phy_get_drvdata(phy);
+	u8 aux_cfg[DP_AUX_CFG_SIZE];
 	int ret;
-	u8 cfg8;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
 	if (ret)
@@ -200,6 +197,8 @@ static int qcom_edp_phy_init(struct phy *phy)
 	if (ret)
 		goto out_disable_supplies;
 
+	memcpy(aux_cfg, edp->cfg->aux_cfg, sizeof(aux_cfg));
+
 	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
 	       DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
 	       edp->edp + DP_PHY_PD_CTL);
@@ -222,22 +221,12 @@ static int qcom_edp_phy_init(struct phy *phy)
 	 * even needed.
 	 */
 	if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
-		cfg8 = 0xb7;
-	else
-		cfg8 = 0x37;
+		aux_cfg[8] = 0xb7;
 
 	writel(0xfc, edp->edp + DP_PHY_MODE);
 
-	writel(0x00, edp->edp + DP_PHY_AUX_CFG0);
-	writel(0x13, edp->edp + DP_PHY_AUX_CFG1);
-	writel(0x24, edp->edp + DP_PHY_AUX_CFG2);
-	writel(0x00, edp->edp + DP_PHY_AUX_CFG3);
-	writel(0x0a, edp->edp + DP_PHY_AUX_CFG4);
-	writel(0x26, edp->edp + DP_PHY_AUX_CFG5);
-	writel(0x0a, edp->edp + DP_PHY_AUX_CFG6);
-	writel(0x03, edp->edp + DP_PHY_AUX_CFG7);
-	writel(cfg8, edp->edp + DP_PHY_AUX_CFG8);
-	writel(0x03, edp->edp + DP_PHY_AUX_CFG9);
+	for (int i = 0; i < DP_AUX_CFG_SIZE; i++)
+		writel(aux_cfg[i], edp->edp + DP_PHY_AUX_CFG(i));
 
 	writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
 	       PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
@@ -519,16 +508,19 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
 };
 
 static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
+	.aux_cfg = edp_phy_aux_cfg_v4,
 	.ver_ops = &qcom_edp_phy_ops_v4,
 };
 
 static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
+	.aux_cfg = edp_phy_aux_cfg_v4,
 	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
 	.ver_ops = &qcom_edp_phy_ops_v4,
 };
 
 static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
 	.is_edp = true,
+	.aux_cfg = edp_phy_aux_cfg_v4,
 	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
 	.ver_ops = &qcom_edp_phy_ops_v4,
 };
@@ -707,6 +699,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
 };
 
 static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
+	.aux_cfg = edp_phy_aux_cfg_v4,
 	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
 	.ver_ops = &qcom_edp_phy_ops_v6,
 };
-- 
2.17.1



From quic_mukhopad at quicinc.com  Mon Sep 23 04:31:50 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Mon, 23 Sep 2024 17:01:50 +0530
Subject: [PATCH v3 5/5] drm/msm/dp: Add DisplayPort controller for SA8775P
In-Reply-To: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
References: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
Message-ID: <20240923113150.24711-6-quic_mukhopad@quicinc.com>

The Qualcomm SA8775P platform comes with 2 DisplayPort controllers
for each mdss, having different base offsets than the previous
SoCs. The support for all 4 DPTX have been added here, and
validation of MDSS0 DPTX0 and DPTX1 have been conducted.

Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
v2: No change

v3: Fixed review comments from Konrad and Bjorn
	-Added all the necessary DPTX controllers for this platform.

---
 drivers/gpu/drm/msm/dp/dp_display.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index e1228fb093ee..2195779584dc 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -118,6 +118,14 @@ struct msm_dp_desc {
 	bool wide_bus_supported;
 };
 
+static const struct msm_dp_desc sa8775p_dp_descs[] = {
+	{ .io_start = 0xaf54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{ .io_start = 0xaf5c000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
+	{ .io_start = 0x22154000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },
+	{ .io_start = 0x2215c000, .id = MSM_DP_CONTROLLER_3, .wide_bus_supported = true },
+	{}
+};
+
 static const struct msm_dp_desc sc7180_dp_descs[] = {
 	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
 	{}
@@ -162,6 +170,7 @@ static const struct msm_dp_desc x1e80100_dp_descs[] = {
 };
 
 static const struct of_device_id dp_dt_match[] = {
+	{ .compatible = "qcom,sa8775p-dp", .data = &sa8775p_dp_descs },
 	{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
 	{ .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
 	{ .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_descs },
-- 
2.17.1



From quic_mukhopad at quicinc.com  Mon Sep 23 04:31:46 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Mon, 23 Sep 2024 17:01:46 +0530
Subject: [PATCH v3 1/5] dt-bindings: phy: Add eDP PHY compatible for sa8775p
In-Reply-To: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
References: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
Message-ID: <20240923113150.24711-2-quic_mukhopad@quicinc.com>

Add compatible string for the supported eDP PHY on sa8775p platform.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Krzysztof Kozlowski <krzk at kernel.org>
Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
v2: No change

v3: No change

---
 Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
index 4e15d90d08b0..293fb6a9b1c3 100644
--- a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
@@ -17,6 +17,7 @@ description:
 properties:
   compatible:
     enum:
+      - qcom,sa8775p-edp-phy
       - qcom,sc7280-edp-phy
       - qcom,sc8180x-edp-phy
       - qcom,sc8280xp-dp-phy
-- 
2.17.1



From quic_mukhopad at quicinc.com  Mon Sep 23 04:31:48 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Mon, 23 Sep 2024 17:01:48 +0530
Subject: [PATCH v3 3/5] phy: qcom: edp: Add support for eDP PHY on SA8775P
In-Reply-To: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
References: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
Message-ID: <20240923113150.24711-4-quic_mukhopad@quicinc.com>

Add support for eDP PHY v5 found on the Qualcomm SA8775P platform.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
v2: Fixed review comments from Dmitry
	- Reused edp_swing_hbr_rbr and edp_swing_hbr2_hbr3 for v5.

v3: No change

---
 drivers/phy/qualcomm/phy-qcom-edp.c | 33 +++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
index 2ecff164ec44..f1b51018683d 100644
--- a/drivers/phy/qualcomm/phy-qcom-edp.c
+++ b/drivers/phy/qualcomm/phy-qcom-edp.c
@@ -183,6 +183,31 @@ static const u8 edp_phy_aux_cfg_v4[10] = {
 	0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
 };
 
+static const u8 edp_pre_emp_hbr_rbr_v5[4][4] = {
+	{ 0x05, 0x11, 0x17, 0x1d },
+	{ 0x05, 0x11, 0x18, 0xff },
+	{ 0x06, 0x11, 0xff, 0xff },
+	{ 0x00, 0xff, 0xff, 0xff }
+};
+
+static const u8 edp_pre_emp_hbr2_hbr3_v5[4][4] = {
+	{ 0x0c, 0x15, 0x19, 0x1e },
+	{ 0x0b, 0x15, 0x19, 0xff },
+	{ 0x0e, 0x14, 0xff, 0xff },
+	{ 0x0d, 0xff, 0xff, 0xff }
+};
+
+static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v5 = {
+	.swing_hbr_rbr = &edp_swing_hbr_rbr,
+	.swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3,
+	.pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr_v5,
+	.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v5,
+};
+
+static const u8 edp_phy_aux_cfg_v5[10] = {
+	0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
+};
+
 static int qcom_edp_phy_init(struct phy *phy)
 {
 	struct qcom_edp *edp = phy_get_drvdata(phy);
@@ -507,6 +532,13 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
 	.com_configure_ssc	= qcom_edp_com_configure_ssc_v4,
 };
 
+static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
+	.is_edp = false,
+	.aux_cfg = edp_phy_aux_cfg_v5,
+	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5,
+	.ver_ops = &qcom_edp_phy_ops_v4,
+};
+
 static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
 	.aux_cfg = edp_phy_aux_cfg_v4,
 	.ver_ops = &qcom_edp_phy_ops_v4,
@@ -1101,6 +1133,7 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id qcom_edp_phy_match_table[] = {
+	{ .compatible = "qcom,sa8775p-edp-phy", .data = &sa8775p_dp_phy_cfg, },
 	{ .compatible = "qcom,sc7280-edp-phy", .data = &sc7280_dp_phy_cfg, },
 	{ .compatible = "qcom,sc8180x-edp-phy", .data = &sc7280_dp_phy_cfg, },
 	{ .compatible = "qcom,sc8280xp-dp-phy", .data = &sc8280xp_dp_phy_cfg, },
-- 
2.17.1



From quic_mukhopad at quicinc.com  Mon Sep 23 04:31:49 2024
From: quic_mukhopad at quicinc.com (Soutrik Mukhopadhyay)
Date: Mon, 23 Sep 2024 17:01:49 +0530
Subject: [PATCH v3 4/5] dt-bindings: display: msm: dp-controller: document SA8775P compatible
In-Reply-To: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
References: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
Message-ID: <20240923113150.24711-5-quic_mukhopad@quicinc.com>

Add compatible string for the DisplayPort controller found on the
Qualcomm SA8775P platform.

Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
---
v2: No change

v3: No change

---
 Documentation/devicetree/bindings/display/msm/dp-controller.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index 97993feda193..a212f335d5ff 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -17,6 +17,7 @@ properties:
   compatible:
     oneOf:
       - enum:
+          - qcom,sa8775p-dp
           - qcom,sc7180-dp
           - qcom,sc7280-dp
           - qcom,sc7280-edp
-- 
2.17.1



From dmitry.baryshkov at linaro.org  Mon Sep 23 04:44:57 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Sep 2024 14:44:57 +0300
Subject: [PATCH v3 2/5] phy: qcom: edp: Introduce aux_cfg array for
 version specific aux settings
In-Reply-To: <20240923113150.24711-3-quic_mukhopad@quicinc.com>
References: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
 <20240923113150.24711-3-quic_mukhopad@quicinc.com>
Message-ID: <qughwerqucheykdwxhip32n7epijn3625jxn2ls7t7nptu4tkw@ls2u7uzaoegj>

On Mon, Sep 23, 2024 at 05:01:47PM GMT, Soutrik Mukhopadhyay wrote:
> In order to support different HW versions, introduce aux_cfg array
> to move v4 specific aux configuration settings.
> 
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
> v2: Fixed review comments from Bjorn and Dmitry
> 	- Made aux_cfg array as const.
> 
> v3: Fixed review comments from Dmitry
> 	- Used a for loop to write the dp_phy_aux_cfg registers.
> 	- Pre-defined the aux_cfg size to prevent any magic numbers.
> 
> ---
>  drivers/phy/qualcomm/phy-qcom-edp.c | 41 ++++++++++++-----------------
>  1 file changed, 17 insertions(+), 24 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Mon Sep 23 04:45:25 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Sep 2024 14:45:25 +0300
Subject: [PATCH v3 3/5] phy: qcom: edp: Add support for eDP PHY on SA8775P
In-Reply-To: <20240923113150.24711-4-quic_mukhopad@quicinc.com>
References: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
 <20240923113150.24711-4-quic_mukhopad@quicinc.com>
Message-ID: <mrx2flabzgzsfyenqowgslb5654wcai6q3oclkc2i3em3iqusr@ed3af2qdx7vb>

On Mon, Sep 23, 2024 at 05:01:48PM GMT, Soutrik Mukhopadhyay wrote:
> Add support for eDP PHY v5 found on the Qualcomm SA8775P platform.
> 
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
> v2: Fixed review comments from Dmitry
> 	- Reused edp_swing_hbr_rbr and edp_swing_hbr2_hbr3 for v5.
> 
> v3: No change
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Mon Sep 23 04:47:42 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Sep 2024 14:47:42 +0300
Subject: [PATCH v3 5/5] drm/msm/dp: Add DisplayPort controller for SA8775P
In-Reply-To: <20240923113150.24711-6-quic_mukhopad@quicinc.com>
References: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
 <20240923113150.24711-6-quic_mukhopad@quicinc.com>
Message-ID: <vdzxghgr3uhj36mjqnphagf2mftpsnqg3mubjo7gfiexcrdb55@6i2s7s4a4qr4>

On Mon, Sep 23, 2024 at 05:01:50PM GMT, Soutrik Mukhopadhyay wrote:
> The Qualcomm SA8775P platform comes with 2 DisplayPort controllers
> for each mdss, having different base offsets than the previous
> SoCs. The support for all 4 DPTX have been added here, and
> validation of MDSS0 DPTX0 and DPTX1 have been conducted.

I'd prefer if there was a word 'only' in the last phrase, but I can live
without it.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>


> 
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
> v2: No change
> 
> v3: Fixed review comments from Konrad and Bjorn
> 	-Added all the necessary DPTX controllers for this platform.
> 
> ---
>  drivers/gpu/drm/msm/dp/dp_display.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 

-- 
With best wishes
Dmitry


From quic_qianyu at quicinc.com  Mon Sep 23 05:57:09 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Mon, 23 Sep 2024 05:57:09 -0700
Subject: [PATCH v3 2/6] dt-bindings: PCI: qcom: Add OPP table for X1E80100
In-Reply-To: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
References: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
Message-ID: <20240923125713.3411487-3-quic_qianyu@quicinc.com>

Add OPP table so that PCIe is able to adjust power domain performance
state and ICC peak bw according to PCIe gen speed and link width.

Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
---
 Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml
index 704c0f58eea5..3c6430fe9331 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml
@@ -78,6 +78,10 @@ properties:
     description: GPIO controlled connection to WAKE# signal
     maxItems: 1
 
+  operating-points-v2: true
+  opp-table:
+    type: object
+
 required:
   - reg
   - reg-names
-- 
2.34.1



From quic_qianyu at quicinc.com  Mon Sep 23 05:57:12 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Mon, 23 Sep 2024 05:57:12 -0700
Subject: [PATCH v3 5/6] PCI: qcom: Add new cfg and ops without config_sid callback for X1E80100
In-Reply-To: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
References: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
Message-ID: <20240923125713.3411487-6-quic_qianyu@quicinc.com>

Currently the ops_1_9_0 which is being used for X1E80100 has config_sid
callback to config BDF to SID table. However, this callback is not
required for X1E80100 because it has smmuv3 support and BDF to SID table
will be not present.

Hence introduce cfg_1_38_0 and ops_1_38_0 with config_sid callback being
NULL since X1E80100 has IP version 1.38.0.

Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
---
 drivers/pci/controller/dwc/pcie-qcom.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 88a98be930e3..56ba8bc72f78 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1367,6 +1367,16 @@ static const struct qcom_pcie_ops ops_2_9_0 = {
 	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
 };
 
+/* Qcom IP rev.: 1.38.0 */
+static const struct qcom_pcie_ops ops_1_38_0 = {
+	.get_resources = qcom_pcie_get_resources_2_7_0,
+	.init = qcom_pcie_init_2_7_0,
+	.post_init = qcom_pcie_post_init_2_7_0,
+	.host_post_init = qcom_pcie_host_post_init_2_7_0,
+	.deinit = qcom_pcie_deinit_2_7_0,
+	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
+};
+
 static const struct qcom_pcie_cfg cfg_1_0_0 = {
 	.ops = &ops_1_0_0,
 };
@@ -1409,6 +1419,10 @@ static const struct qcom_pcie_cfg cfg_sc8280xp = {
 	.no_l0s = true,
 };
 
+static const struct qcom_pcie_cfg cfg_1_38_0 = {
+	.ops = &ops_1_38_0,
+};
+
 static const struct dw_pcie_ops dw_pcie_ops = {
 	.link_up = qcom_pcie_link_up,
 	.start_link = qcom_pcie_start_link,
@@ -1837,7 +1851,7 @@ static const struct of_device_id qcom_pcie_match[] = {
 	{ .compatible = "qcom,pcie-sm8450-pcie0", .data = &cfg_1_9_0 },
 	{ .compatible = "qcom,pcie-sm8450-pcie1", .data = &cfg_1_9_0 },
 	{ .compatible = "qcom,pcie-sm8550", .data = &cfg_1_9_0 },
-	{ .compatible = "qcom,pcie-x1e80100", .data = &cfg_1_9_0 },
+	{ .compatible = "qcom,pcie-x1e80100", .data = &cfg_1_38_0 },
 	{ }
 };
 
-- 
2.34.1



From quic_qianyu at quicinc.com  Mon Sep 23 05:57:07 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Mon, 23 Sep 2024 05:57:07 -0700
Subject: [PATCH v3 0/6] Add support for PCIe3 on x1e80100
Message-ID: <20240923125713.3411487-1-quic_qianyu@quicinc.com>

This series add support for PCIe3 on x1e80100.

PCIe3 needs additional set of clocks, regulators and new set of PCIe QMP
PHY configuration compare other PCIe instances on x1e80100. Hence add
required resource configuration and usage for PCIe3.

v2->v3:
1. Use 'Gen 4 x8' in commit msg
2. Move opp-table property to qcom,pcie-common.yaml
3. Add Reviewed-by tag
4. Add global interrupt and use GIC_SPI for the parent interrupt specifier
5. Use 0x0 in reg property and use pcie@ for pcie3 device node
6. Show different IP version v6.30 in commit msg
7. Add logic in controller driver to have new ops for x1e80100

v2->v1:
1. Squash [PATCH 1/8], [PATCH 2/8],[PATCH 3/8] into one patch and make the
   indentation consistent.
2. Put dts patch at the end of the patchset.
3. Put dt-binding patch at the first of the patchset.
4. Add a new patch where opp-table is added in dt-binding to avoid dtbs
   checking error.
5. Remove GCC_PCIE_3_AUX_CLK, RPMH_CXO_CLK, put in TCSR_PCIE_8L_CLKREF_EN
   as ref.
6. Remove lane_broadcasting.
7. Add 64 bit bar, Remove GCC_PCIE_3_PIPE_CLK_SRC, 
   GCC_CFG_NOC_PCIE_ANOC_SOUTH_AHB_CLK is changed to
   GCC_CFG_NOC_PCIE_ANOC_NORTH_AHB_CLK.
8. Add Reviewed-by tag.
9. Remove [PATCH 7/8], [PATCH 8/8].

Qiang Yu (6):
  dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the X1E80100
    QMP PCIe PHY Gen4 x8
  dt-bindings: PCI: qcom: Add OPP table for X1E80100
  phy: qcom: qmp: Add phy register and clk setting for x1e80100 PCIe3
  clk: qcom: gcc-x1e80100: Fix halt_check for pipediv2 clocks
  PCI: qcom: Add new cfg and ops without config_sid callback for
    X1E80100
  arm64: dts: qcom: x1e80100: Add support for PCIe3 on x1e80100

 .../bindings/pci/qcom,pcie-common.yaml        |   4 +
 .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml       |   3 +
 arch/arm64/boot/dts/qcom/x1e80100.dtsi        | 204 ++++++++++++++++-
 drivers/clk/qcom/gcc-x1e80100.c               |  10 +-
 drivers/pci/controller/dwc/pcie-qcom.c        |  16 +-
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c      | 211 ++++++++++++++++++
 .../qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h    |  25 +++
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h |  19 ++
 8 files changed, 485 insertions(+), 7 deletions(-)
 create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
 create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h

-- 
2.34.1



From quic_qianyu at quicinc.com  Mon Sep 23 05:57:11 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Mon, 23 Sep 2024 05:57:11 -0700
Subject: [PATCH v3 4/6] clk: qcom: gcc-x1e80100: Fix halt_check for pipediv2 clocks
In-Reply-To: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
References: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
Message-ID: <20240923125713.3411487-5-quic_qianyu@quicinc.com>

The pipediv2_clk's source from the same mux as pipe clock. So they have
same limitation, which is that the PHY sequence requires to enable these
local CBCs before the PHY is actually outputting a clock to them. This
means the clock won't actually turn on when we vote them. Hence, let's
skip the halt bit check of the pipediv2_clk, otherwise pipediv2_clk may
stuck at off state during bootup.

Suggested-by: Mike Tipton <quic_mdtipton at quicinc.com>
Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
Reviewed-by: Konrad Dybcio <konradybcio at kernel.org>
---
 drivers/clk/qcom/gcc-x1e80100.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c
index 0f578771071f..81ba5ceab342 100644
--- a/drivers/clk/qcom/gcc-x1e80100.c
+++ b/drivers/clk/qcom/gcc-x1e80100.c
@@ -3123,7 +3123,7 @@ static struct clk_branch gcc_pcie_3_pipe_clk = {
 
 static struct clk_branch gcc_pcie_3_pipediv2_clk = {
 	.halt_reg = 0x58060,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52020,
 		.enable_mask = BIT(5),
@@ -3248,7 +3248,7 @@ static struct clk_branch gcc_pcie_4_pipe_clk = {
 
 static struct clk_branch gcc_pcie_4_pipediv2_clk = {
 	.halt_reg = 0x6b054,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52010,
 		.enable_mask = BIT(27),
@@ -3373,7 +3373,7 @@ static struct clk_branch gcc_pcie_5_pipe_clk = {
 
 static struct clk_branch gcc_pcie_5_pipediv2_clk = {
 	.halt_reg = 0x2f054,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52018,
 		.enable_mask = BIT(19),
@@ -3511,7 +3511,7 @@ static struct clk_branch gcc_pcie_6a_pipe_clk = {
 
 static struct clk_branch gcc_pcie_6a_pipediv2_clk = {
 	.halt_reg = 0x31060,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52018,
 		.enable_mask = BIT(28),
@@ -3649,7 +3649,7 @@ static struct clk_branch gcc_pcie_6b_pipe_clk = {
 
 static struct clk_branch gcc_pcie_6b_pipediv2_clk = {
 	.halt_reg = 0x8d060,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52010,
 		.enable_mask = BIT(28),
-- 
2.34.1



From quic_qianyu at quicinc.com  Mon Sep 23 05:57:08 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Mon, 23 Sep 2024 05:57:08 -0700
Subject: [PATCH v3 1/6] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the X1E80100 QMP PCIe PHY Gen4 x8
In-Reply-To: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
References: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
Message-ID: <20240923125713.3411487-2-quic_qianyu@quicinc.com>

PCIe 3rd instance of X1E80100 supports Gen 4 x8 which needs different
8 lane capable QMP PCIe PHY with hardware revision v6.30. Document Gen
4 x8 PHY as separate module.

Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
---
 .../devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml    | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
index dcf4fa55fbba..680ec3113c2b 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -41,6 +41,7 @@ properties:
       - qcom,x1e80100-qmp-gen3x2-pcie-phy
       - qcom,x1e80100-qmp-gen4x2-pcie-phy
       - qcom,x1e80100-qmp-gen4x4-pcie-phy
+      - qcom,x1e80100-qmp-gen4x8-pcie-phy
 
   reg:
     minItems: 1
@@ -172,6 +173,7 @@ allOf:
               - qcom,sc8280xp-qmp-gen3x2-pcie-phy
               - qcom,sc8280xp-qmp-gen3x4-pcie-phy
               - qcom,x1e80100-qmp-gen4x4-pcie-phy
+              - qcom,x1e80100-qmp-gen4x8-pcie-phy
     then:
       properties:
         clocks:
@@ -201,6 +203,7 @@ allOf:
               - qcom,sm8550-qmp-gen4x2-pcie-phy
               - qcom,sm8650-qmp-gen4x2-pcie-phy
               - qcom,x1e80100-qmp-gen4x2-pcie-phy
+              - qcom,x1e80100-qmp-gen4x8-pcie-phy
     then:
       properties:
         resets:
-- 
2.34.1



From quic_qianyu at quicinc.com  Mon Sep 23 05:57:10 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Mon, 23 Sep 2024 05:57:10 -0700
Subject: [PATCH v3 3/6] phy: qcom: qmp: Add phy register and clk setting for x1e80100 PCIe3
In-Reply-To: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
References: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
Message-ID: <20240923125713.3411487-4-quic_qianyu@quicinc.com>

Currently driver supports only x4 lane based functionality using tx/rx and
tx2/rx2 pair of register sets. To support 8 lane functionality with PCIe3,
PCIe3 related QMP PHY provides additional programming which are available
as txz and rxz based register set. Hence adds txz and rxz based registers
usage and programming sequences. Phy register setting for txz and rxz will
be applied to all 8 lanes. Some lanes may have different settings on
several registers than txz/rxz, these registers should be programmed after
txz/rxz programming sequences completing.

Besides, x1e80100 SoC uses QMP phy with version v6.30 for PCIe Gen4 x8.
Add the new register offsets in a dedicated header file.

Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Reviewed-by: Konrad Dybcio <konradybcio at kernel.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c      | 211 ++++++++++++++++++
 .../qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h    |  25 +++
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h |  19 ++
 3 files changed, 255 insertions(+)
 create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
 create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index f71787fb4d7e..d7bbd9df11d7 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -34,6 +34,8 @@
 #include "phy-qcom-qmp-pcs-pcie-v5_20.h"
 #include "phy-qcom-qmp-pcs-pcie-v6.h"
 #include "phy-qcom-qmp-pcs-pcie-v6_20.h"
+#include "phy-qcom-qmp-pcs-pcie-v6_30.h"
+#include "phy-qcom-qmp-pcs-v6_30.h"
 #include "phy-qcom-qmp-pcie-qhp.h"
 
 #define PHY_INIT_COMPLETE_TIMEOUT		10000
@@ -1344,6 +1346,155 @@ static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
 	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_FOM_EQ_CONFIG5, 0x8a),
 };
 
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_txz_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_TX, 0x1a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_RX, 0x05),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_1, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_2, 0x10),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_3, 0x51),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_TRAN_DRVR_EMP_EN, 0x34),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_rxz_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_2, 0x0c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_GAIN_RATE_2, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_3, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_PI_CONTROLS, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_ACC_DEFAULT_VAL_RATE3, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_CAL_CTRL2, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_POSTCAL_OFFSET, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_BKUP_CTRL1, 0x15),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_3, 0x45),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_VGA_CAL_MAN_VAL, 0x0c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_VGA_CAL_CNTRL1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_GM_CAL, 0x0d),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_EQU_ADAPTOR_CNTRL4, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_SIGDET_ENABLES, 0x1c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_PHPRE_CTRL, 0x20),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_Q_PI_INTRINSIC_BIAS_RATE32, 0x39),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B0, 0xd4),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B1, 0x23),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B2, 0x58),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B3, 0x9a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B4, 0x38),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B5, 0xb6),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B6, 0xee),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B0, 0x1c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B1, 0xe4),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B2, 0x60),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B3, 0xdf),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B4, 0x69),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B5, 0x76),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B6, 0xff),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_TX_ADPT_CTRL, 0x10),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_rx_tbl[] = {
+	QMP_PHY_INIT_CFG_LANE(QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x3a, BIT(0)),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RXCLK_DIV2_CTRL, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_SUMMER_CAL_SPD_MODE, 0x5b),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_DFE_DAC_ENABLE1, 0x88),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH1, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH2, 0x0d),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B0, 0x12),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B1, 0x12),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B2, 0xdb),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B3, 0x9a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B4, 0x38),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B5, 0xb6),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B6, 0x64),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE210, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE210, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE210, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH4_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH5_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH6_RATE3, 0x1f),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_serdes_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0x26),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x03),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x0d),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x68),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0xab),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0xaa),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x12),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0xf8),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0d),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0xab),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xaa),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x62),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_POST_DIV_MUX, 0x40),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 0x1c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x90),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x82),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x46),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_CFG, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x34),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x20),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MISC_1, 0x88),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MODE, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_VCO_DC_LEVEL_CTRL, 0x0f),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_pcs_tbl[] = {
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_LOCK_DETECT_CONFIG2, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_G3S2_PRE_GAIN, 0x2e),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_RX_SIGDET_LVL, 0x99),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_ALIGN_DETECT_CONFIG7, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_EQ_CONFIG4, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_EQ_CONFIG5, 0x22),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_TX_RX_CONFIG, 0x04),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_TX_RX_CONFIG2, 0x02),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl[] = {
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_OSC_DTCT_ACTIONS, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_EQ_CONFIG1, 0x16),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_EQ_CONFIG5, 0x02),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_PRE_GAIN, 0x2e),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG1, 0x03),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG3, 0x28),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG5, 0x18),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G3_FOM_EQ_CONFIG5, 0x7a),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_FOM_EQ_CONFIG5, 0x8a),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G3_RXEQEVAL_TIME, 0x27),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_RXEQEVAL_TIME, 0x27),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_TX_RX_CONFIG, 0xc0),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_POWER_STATE_CONFIG2, 0x1d),
+
+};
+
 static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
@@ -2582,6 +2733,8 @@ struct qmp_pcie_offsets {
 	u16 rx;
 	u16 tx2;
 	u16 rx2;
+	u16 txz;
+	u16 rxz;
 	u16 ln_shrd;
 };
 
@@ -2592,6 +2745,10 @@ struct qmp_phy_cfg_tbls {
 	int tx_num;
 	const struct qmp_phy_init_tbl *rx;
 	int rx_num;
+	const struct qmp_phy_init_tbl *txz;
+	int txz_num;
+	const struct qmp_phy_init_tbl *rxz;
+	int rxz_num;
 	const struct qmp_phy_init_tbl *pcs;
 	int pcs_num;
 	const struct qmp_phy_init_tbl *pcs_misc;
@@ -2659,6 +2816,8 @@ struct qmp_pcie {
 	void __iomem *rx;
 	void __iomem *tx2;
 	void __iomem *rx2;
+	void __iomem *txz;
+	void __iomem *rxz;
 	void __iomem *ln_shrd;
 
 	void __iomem *port_b;
@@ -2826,6 +2985,17 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_20 = {
 	.ln_shrd	= 0x0e00,
 };
 
+static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_30 = {
+	.serdes		= 0x8800,
+	.pcs		= 0x9000,
+	.pcs_misc	= 0x9800,
+	.tx		= 0x0000,
+	.rx		= 0x0200,
+	.txz		= 0xe000,
+	.rxz		= 0xe200,
+	.ln_shrd	= 0x8000,
+};
+
 static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
 	.lanes			= 1,
 
@@ -3704,6 +3874,38 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x4_pciephy_cfg = {
 	.has_nocsr_reset	= true,
 };
 
+static const struct qmp_phy_cfg x1e80100_qmp_gen4x8_pciephy_cfg = {
+	.lanes = 8,
+
+	.offsets		= &qmp_pcie_offsets_v6_30,
+	.tbls = {
+		.serdes			= x1e80100_qmp_gen4x8_pcie_serdes_tbl,
+		.serdes_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_serdes_tbl),
+		.rx			= x1e80100_qmp_gen4x8_pcie_rx_tbl,
+		.rx_num			= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_rx_tbl),
+		.pcs			= x1e80100_qmp_gen4x8_pcie_pcs_tbl,
+		.pcs_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_pcs_tbl),
+		.pcs_misc		= x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl,
+		.pcs_misc_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl),
+		.ln_shrd		= x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl,
+		.ln_shrd_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl),
+		.txz			= x1e80100_qmp_gen4x8_pcie_txz_tbl,
+		.txz_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_txz_tbl),
+		.rxz			= x1e80100_qmp_gen4x8_pcie_rxz_tbl,
+		.rxz_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_rxz_tbl),
+	},
+
+	.reset_list		= sdm845_pciephy_reset_l,
+	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.vreg_list		= sm8550_qmp_phy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm8550_qmp_phy_vreg_l),
+	.regs			= pciephy_v6_regs_layout,
+
+	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,
+	.phy_status		= PHYSTATUS_4_20,
+	.has_nocsr_reset	= true,
+};
+
 static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
 {
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -3751,6 +3953,9 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
 
 	qmp_configure(qmp->dev, serdes, tbls->serdes, tbls->serdes_num);
 
+	qmp_configure(qmp->dev, qmp->txz, tbls->txz, tbls->txz_num);
+	qmp_configure(qmp->dev, qmp->rxz, tbls->rxz, tbls->rxz_num);
+
 	qmp_configure_lane(qmp->dev, tx, tbls->tx, tbls->tx_num, 1);
 	qmp_configure_lane(qmp->dev, rx, tbls->rx, tbls->rx_num, 1);
 
@@ -4293,6 +4498,9 @@ static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
 			return PTR_ERR(qmp->port_b);
 	}
 
+	qmp->txz = base + offs->txz;
+	qmp->rxz = base + offs->rxz;
+
 	if (cfg->tbls.ln_shrd)
 		qmp->ln_shrd = base + offs->ln_shrd;
 
@@ -4478,6 +4686,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
 	}, {
 		.compatible = "qcom,x1e80100-qmp-gen4x4-pcie-phy",
 		.data = &x1e80100_qmp_gen4x4_pciephy_cfg,
+	}, {
+		.compatible = "qcom,x1e80100-qmp-gen4x8-pcie-phy",
+		.data = &x1e80100_qmp_gen4x8_pciephy_cfg,
 	},
 	{ },
 };
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
new file mode 100644
index 000000000000..5a58ff197e6e
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_PCIE_V6_30_H_
+#define QCOM_PHY_QMP_PCS_PCIE_V6_30_H_
+
+/* Only for QMP V6_30 PHY - PCIE have different offsets than V6 */
+#define QPHY_PCIE_V6_30_PCS_POWER_STATE_CONFIG2		0x014
+#define QPHY_PCIE_V6_30_PCS_TX_RX_CONFIG		0x020
+#define QPHY_PCIE_V6_30_PCS_ENDPOINT_REFCLK_DRIVE	0x024
+#define QPHY_PCIE_V6_30_PCS_OSC_DTCT_ACTIONS		0x098
+#define QPHY_PCIE_V6_30_PCS_EQ_CONFIG1			0x0a8
+#define QPHY_PCIE_V6_30_PCS_G3_RXEQEVAL_TIME		0x0f8
+#define QPHY_PCIE_V6_30_PCS_G4_RXEQEVAL_TIME		0x0fc
+#define QPHY_PCIE_V6_30_PCS_G4_EQ_CONFIG5		0x110
+#define QPHY_PCIE_V6_30_PCS_G4_PRE_GAIN			0x164
+#define QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG1	0x184
+#define QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG3	0x18c
+#define QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG5	0x194
+#define QPHY_PCIE_V6_30_PCS_G3_FOM_EQ_CONFIG5		0x1b4
+#define QPHY_PCIE_V6_30_PCS_G4_FOM_EQ_CONFIG5		0x1c8
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h
new file mode 100644
index 000000000000..369120d88bc2
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_V6_30_H_
+#define QCOM_PHY_QMP_PCS_V6_30_H_
+
+/* Only for QMP V6_30 PHY - PCIe PCS registers */
+#define QPHY_V6_30_PCS_LOCK_DETECT_CONFIG2		0x0cc
+#define QPHY_V6_30_PCS_G3S2_PRE_GAIN			0x17c
+#define QPHY_V6_30_PCS_RX_SIGDET_LVL			0x194
+#define QPHY_V6_30_PCS_ALIGN_DETECT_CONFIG7		0x1dc
+#define QPHY_V6_30_PCS_TX_RX_CONFIG			0x1e0
+#define QPHY_V6_30_PCS_TX_RX_CONFIG2			0x1e4
+#define QPHY_V6_30_PCS_EQ_CONFIG4			0x1fc
+#define QPHY_V6_30_PCS_EQ_CONFIG5			0x200
+
+#endif
-- 
2.34.1



From quic_qianyu at quicinc.com  Mon Sep 23 05:57:13 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Mon, 23 Sep 2024 05:57:13 -0700
Subject: [PATCH v3 6/6] arm64: dts: qcom: x1e80100: Add support for PCIe3 on x1e80100
In-Reply-To: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
References: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
Message-ID: <20240923125713.3411487-7-quic_qianyu@quicinc.com>

Describe PCIe3 controller and PHY. Also add required system resources like
regulators, clocks, interrupts and registers configuration for PCIe3.

Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 arch/arm64/boot/dts/qcom/x1e80100.dtsi | 204 ++++++++++++++++++++++++-
 1 file changed, 203 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
index a36076e3c56b..c615c930cf0c 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
+++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
@@ -744,7 +744,7 @@ gcc: clock-controller at 100000 {
 
 			clocks = <&bi_tcxo_div2>,
 				 <&sleep_clk>,
-				 <0>,
+				 <&pcie3_phy>,
 				 <&pcie4_phy>,
 				 <&pcie5_phy>,
 				 <&pcie6a_phy>,
@@ -2907,6 +2907,208 @@ mmss_noc: interconnect at 1780000 {
 			#interconnect-cells = <2>;
 		};
 
+		pcie3: pcie at 1bd0000 {
+			device_type = "pci";
+			compatible = "qcom,pcie-x1e80100";
+			reg = <0x0 0x01bd0000 0x0 0x3000>,
+			      <0x0 0x78000000 0x0 0xf1d>,
+			      <0x0 0x78000f40 0x0 0xa8>,
+			      <0x0 0x78001000 0x0 0x1000>,
+			      <0x0 0x78100000 0x0 0x100000>,
+			      <0x0 0x01bd3000 0x0 0x1000>;
+			reg-names = "parf",
+				    "dbi",
+				    "elbi",
+				    "atu",
+				    "config",
+				    "mhi";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x78200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x78300000 0x0 0x78300000 0x0 0x3d00000>,
+				 <0x03000000 0x7 0x40000000 0x7 0x40000000 0x0 0x40000000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <3>;
+			num-lanes = <8>;
+
+			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 769 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 671 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi0",
+					  "msi1",
+					  "msi2",
+					  "msi3",
+					  "msi4",
+					  "msi5",
+					  "msi6",
+					  "msi7",
+					  "global";
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &intc 0 0 GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc 0 0 GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc 0 0 GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc 0 0 GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_3_AUX_CLK>,
+				 <&gcc GCC_PCIE_3_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_3_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_3_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_3_SLV_Q2A_AXI_CLK>,
+				 <&gcc GCC_CFG_NOC_PCIE_ANOC_NORTH_AHB_CLK>,
+				 <&gcc GCC_CNOC_PCIE_NORTH_SF_AXI_CLK>;
+			clock-names = "aux",
+				      "cfg",
+				      "bus_master",
+				      "bus_slave",
+				      "slave_q2a",
+				      "noc_aggr",
+				      "cnoc_sf_axi";
+
+			assigned-clocks = <&gcc GCC_PCIE_3_AUX_CLK>;
+			assigned-clock-rates = <19200000>;
+
+			interconnects = <&pcie_south_anoc MASTER_PCIE_3 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+					 &cnoc_main SLAVE_PCIE_3 QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "pcie-mem",
+					     "cpu-pcie";
+
+			resets = <&gcc GCC_PCIE_3_BCR>,
+				 <&gcc GCC_PCIE_3_LINK_DOWN_BCR>;
+			reset-names = "pci",
+				      "link_down";
+
+			power-domains = <&gcc GCC_PCIE_3_GDSC>;
+
+			phys = <&pcie3_phy>;
+			phy-names = "pciephy";
+
+			operating-points-v2 = <&pcie3_opp_table>;
+
+			status = "disabled";
+
+			pcie3_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				/* GEN 1 x1 */
+				opp-2500000 {
+					opp-hz = /bits/ 64 <2500000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <250000 1>;
+				};
+
+				/* GEN 1 x2 and GEN 2 x1 */
+				opp-5000000 {
+					opp-hz = /bits/ 64 <5000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <500000 1>;
+				};
+
+				/* GEN 1 x4 and GEN 2 x2 */
+				opp-10000000 {
+					opp-hz = /bits/ 64 <10000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1000000 1>;
+				};
+
+				/* GEN 1 x8 and GEN 2 x4 */
+				opp-20000000 {
+					opp-hz = /bits/ 64 <20000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <2000000 1>;
+				};
+
+				/* GEN 2 x8 */
+				opp-40000000 {
+					opp-hz = /bits/ 64 <40000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <4000000 1>;
+				};
+
+				/* GEN 3 x1 */
+				opp-8000000 {
+					opp-hz = /bits/ 64 <8000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <984500 1>;
+				};
+
+				/* GEN 3 x2 and GEN 4 x1 */
+				opp-16000000 {
+					opp-hz = /bits/ 64 <16000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <1969000 1>;
+				};
+
+				/* GEN 3 x4 and GEN 4 x2 */
+				opp-32000000 {
+					opp-hz = /bits/ 64 <32000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <3938000 1>;
+				};
+
+				/* GEN 3 x8 and GEN 4 x4 */
+				opp-64000000 {
+					opp-hz = /bits/ 64 <64000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <7876000 1>;
+				};
+
+				/* GEN 4 x8 */
+				opp-128000000 {
+					opp-hz = /bits/ 64 <128000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <15753000 1>;
+				};
+			};
+		};
+
+		pcie3_phy: phy at 1be0000 {
+			compatible = "qcom,x1e80100-qmp-gen4x8-pcie-phy";
+			reg = <0 0x01be0000 0 0x10000>;
+
+			clocks = <&gcc GCC_PCIE_3_PHY_AUX_CLK>,
+				 <&gcc GCC_PCIE_3_CFG_AHB_CLK>,
+				 <&tcsr TCSR_PCIE_8L_CLKREF_EN>,
+				 <&gcc GCC_PCIE_3_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_3_PIPE_CLK>,
+				 <&gcc GCC_PCIE_3_PIPEDIV2_CLK>;
+			clock-names = "aux",
+				      "cfg_ahb",
+				      "ref",
+				      "rchng",
+				      "pipe",
+				      "pipediv2";
+
+			resets = <&gcc GCC_PCIE_3_PHY_BCR>,
+				 <&gcc GCC_PCIE_3_NOCSR_COM_PHY_BCR>;
+			reset-names = "phy",
+				      "phy_nocsr";
+
+			assigned-clocks = <&gcc GCC_PCIE_3_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>;
+
+			power-domains = <&gcc GCC_PCIE_3_PHY_GDSC>;
+
+			#clock-cells = <0>;
+			clock-output-names = "pcie3_pipe_clk";
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
 		pcie6a: pci at 1bf8000 {
 			device_type = "pci";
 			compatible = "qcom,pcie-x1e80100";
-- 
2.34.1



From dmitry.baryshkov at linaro.org  Mon Sep 23 06:19:35 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Sep 2024 16:19:35 +0300
Subject: [PATCH v3 2/6] dt-bindings: PCI: qcom: Add OPP table for X1E80100
In-Reply-To: <20240923125713.3411487-3-quic_qianyu@quicinc.com>
References: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
 <20240923125713.3411487-3-quic_qianyu@quicinc.com>
Message-ID: <jz6eqbreus2hrhxadj643ibfy3ejr5tjhkerln6sh6bsvfhaw4@6uwpabq2d76a>

On Mon, Sep 23, 2024 at 05:57:09AM GMT, Qiang Yu wrote:
> Add OPP table so that PCIe is able to adjust power domain performance
> state and ICC peak bw according to PCIe gen speed and link width.
> 
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> ---
>  Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml
> index 704c0f58eea5..3c6430fe9331 100644
> --- a/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml
> +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml
> @@ -78,6 +78,10 @@ properties:
>      description: GPIO controlled connection to WAKE# signal
>      maxItems: 1
>  
> +  operating-points-v2: true
> +  opp-table:
> +    type: object
> +
>  required:
>    - reg
>    - reg-names

Please drop it from qcom,pcie-sm8450.yaml, it's redundant now.

> -- 
> 2.34.1
> 
> 
> -- 
> linux-phy mailing list
> linux-phy at lists.infradead.org
> https://lists.infradead.org/mailman/listinfo/linux-phy

-- 
With best wishes
Dmitry


From manivannan.sadhasivam at linaro.org  Mon Sep 23 07:00:25 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Mon, 23 Sep 2024 16:00:25 +0200
Subject: [PATCH v3 5/6] PCI: qcom: Add new cfg and ops without config_sid
 callback for X1E80100
In-Reply-To: <20240923125713.3411487-6-quic_qianyu@quicinc.com>
References: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
 <20240923125713.3411487-6-quic_qianyu@quicinc.com>
Message-ID: <20240923140025.4qhguusbhiajf3xa@thinkpad>

On Mon, Sep 23, 2024 at 05:57:12AM -0700, Qiang Yu wrote:

No need to mention the ops/cfg in subject. It is a detail for patch description.
So use:

"PCI: qcom: Add support for X1E80100 SoC"

Also add some information about the IP capability. Like what speed/gen version
it supports, lane width etc...

> Currently the ops_1_9_0 which is being used for X1E80100 has config_sid
> callback to config BDF to SID table. However, this callback is not
> required for X1E80100 because it has smmuv3 support and BDF to SID table
> will be not present.
> 
> Hence introduce cfg_1_38_0 and ops_1_38_0 with config_sid callback being
> NULL since X1E80100 has IP version 1.38.0.
> 

I'd rewrite the last sentence as below:

"Hence add support for X1E80100 by introducing a new ops and cfg structures that
don't require the config_sid callback. This could be reused by the future
platforms based on SMMUv3."

- Mani

> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> ---
>  drivers/pci/controller/dwc/pcie-qcom.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index 88a98be930e3..56ba8bc72f78 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1367,6 +1367,16 @@ static const struct qcom_pcie_ops ops_2_9_0 = {
>  	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
>  };
>  
> +/* Qcom IP rev.: 1.38.0 */
> +static const struct qcom_pcie_ops ops_1_38_0 = {
> +	.get_resources = qcom_pcie_get_resources_2_7_0,
> +	.init = qcom_pcie_init_2_7_0,
> +	.post_init = qcom_pcie_post_init_2_7_0,
> +	.host_post_init = qcom_pcie_host_post_init_2_7_0,
> +	.deinit = qcom_pcie_deinit_2_7_0,
> +	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
> +};
> +
>  static const struct qcom_pcie_cfg cfg_1_0_0 = {
>  	.ops = &ops_1_0_0,
>  };
> @@ -1409,6 +1419,10 @@ static const struct qcom_pcie_cfg cfg_sc8280xp = {
>  	.no_l0s = true,
>  };
>  
> +static const struct qcom_pcie_cfg cfg_1_38_0 = {
> +	.ops = &ops_1_38_0,
> +};
> +
>  static const struct dw_pcie_ops dw_pcie_ops = {
>  	.link_up = qcom_pcie_link_up,
>  	.start_link = qcom_pcie_start_link,
> @@ -1837,7 +1851,7 @@ static const struct of_device_id qcom_pcie_match[] = {
>  	{ .compatible = "qcom,pcie-sm8450-pcie0", .data = &cfg_1_9_0 },
>  	{ .compatible = "qcom,pcie-sm8450-pcie1", .data = &cfg_1_9_0 },
>  	{ .compatible = "qcom,pcie-sm8550", .data = &cfg_1_9_0 },
> -	{ .compatible = "qcom,pcie-x1e80100", .data = &cfg_1_9_0 },
> +	{ .compatible = "qcom,pcie-x1e80100", .data = &cfg_1_38_0 },
>  	{ }
>  };
>  
> -- 
> 2.34.1
> 

-- 
????????? ????????


From cristian.ciocaltea at collabora.com  Mon Sep 23 09:40:16 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 23 Sep 2024 19:40:16 +0300
Subject: [PATCH] phy: phy-rockchip-samsung-hdptx: Depend on
 CONFIG_COMMON_CLK
Message-ID: <20240923-sam-hdptx-link-fix-v1-1-8d10d7456305@collabora.com>

Ensure CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX depends on CONFIG_COMMON_CLK to
fix the following link errors when compile testing some random kernel
configurations:

  m68k-linux-ld: drivers/phy/rockchip/phy-rockchip-samsung-hdptx.o: in function `rk_hdptx_phy_clk_register':
  drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c:1031:(.text+0x470): undefined reference to `__clk_get_name'
  m68k-linux-ld: drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c:1036:(.text+0x4ba): undefined reference to `devm_clk_hw_register'
  m68k-linux-ld: drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c:1040:(.text+0x4d2): undefined reference to `of_clk_hw_simple_get'
  m68k-linux-ld: drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c:1040:(.text+0x4da): undefined reference to `devm_of_clk_add_hw_provider'

Fixes: c4b09c562086 ("phy: phy-rockchip-samsung-hdptx: Add clock provider support")
Reported-by: kernel test robot <lkp at intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202409180305.53PXymZn-lkp at intel.com/
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index 490263375057..2f7a05f21dc5 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -86,6 +86,7 @@ config PHY_ROCKCHIP_PCIE
 config PHY_ROCKCHIP_SAMSUNG_HDPTX
 	tristate "Rockchip Samsung HDMI/eDP Combo PHY driver"
 	depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
+	depends on COMMON_CLK
 	depends on HAS_IOMEM
 	select GENERIC_PHY
 	select MFD_SYSCON

---
base-commit: 5acd9952f95fb4b7da6d09a3be39195a80845eb6
change-id: 20240923-sam-hdptx-link-fix-c267877e3b1a



From Markus.Elfring at web.de  Mon Sep 23 13:04:25 2024
From: Markus.Elfring at web.de (Markus Elfring)
Date: Mon, 23 Sep 2024 22:04:25 +0200
Subject: [PATCH] phy: tegra: xusb: Call of_node_put(np) only once in
 tegra_xusb_padctl_get()
Message-ID: <86154518-3338-4370-8fa2-80a8b0e10302@web.de>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Mon, 23 Sep 2024 21:56:35 +0200

An of_node_put(np) call was immediately used after a pointer check
for a of_find_device_by_node() call in this function implementation.
Thus call such a function only once instead directly before the check.

This issue was transformed by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/phy/tegra/xusb.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index cfdb54b6070a..1a912ed52416 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -1345,12 +1345,9 @@ struct tegra_xusb_padctl *tegra_xusb_padctl_get(struct device *dev)
 	 * only ever be one per SoC that would be a little overkill.
 	 */
 	pdev = of_find_device_by_node(np);
-	if (!pdev) {
-		of_node_put(np);
-		return ERR_PTR(-ENODEV);
-	}
-
 	of_node_put(np);
+	if (!pdev)
+		return ERR_PTR(-ENODEV);

 	padctl = platform_get_drvdata(pdev);
 	if (!padctl) {
--
2.46.1



From frank.wang at rock-chips.com  Mon Sep 23 19:24:06 2024
From: frank.wang at rock-chips.com (Frank Wang)
Date: Tue, 24 Sep 2024 10:24:06 +0800
Subject: [RESEND PATCH 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <snccizbw6thn3lhwad4xppp7vqii4p56ttl2gufwc3ke7vfckf@e4b7nvwwtdfr>
References: <20240923025326.10467-1-frank.wang@rock-chips.com>
 <snccizbw6thn3lhwad4xppp7vqii4p56ttl2gufwc3ke7vfckf@e4b7nvwwtdfr>
Message-ID: <1f996322-e6f6-4dd5-a1d7-c2bde92c876b@rock-chips.com>

Hi Krzysztof,
On 2024/9/23 17:31, Krzysztof Kozlowski wrote:
> On Mon, Sep 23, 2024 at 10:53:25AM +0800, Frank Wang wrote:
>> Add compatible for the USB2 phy in the Rockchip RK3576 SoC.
>>
>> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
>> ---
>>   .../devicetree/bindings/phy/rockchip,inno-usb2phy.yaml | 10 +++++++++-
>>   1 file changed, 9 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>> index 5254413137c64..214917e55c0b6 100644
>> --- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>> +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>> @@ -20,6 +20,7 @@ properties:
>>         - rockchip,rk3366-usb2phy
>>         - rockchip,rk3399-usb2phy
>>         - rockchip,rk3568-usb2phy
>> +      - rockchip,rk3576-usb2phy
>>         - rockchip,rk3588-usb2phy
>>         - rockchip,rv1108-usb2phy
>>   
>> @@ -34,10 +35,16 @@ properties:
>>       const: 0
>>   
>>     clocks:
>> -    maxItems: 1
>> +    minItems: 1
>> +    items:
>> +      - description: phyclk - PHY input reference clocks.
>> +      - description: aclk and aclk_slv are optional and used for USB MMU.
>>   
>>     clock-names:
>> +    minItems: 1
>>       const: phyclk
>> +    const: aclk
>> +    const: aclk_slv
> Please test... Not sure what you wanted to achieve here, but maybe
> oneOf?

The "aclk" and "aclk_slv" clocks are new in RK3576, you mean the changes 
should be like the below?

@@ -34,10 +35,20 @@ properties:
 ???? const: 0

 ?? clocks:
-??? maxItems: 1
+??? minItems: 1
+??? maxItems: 3

 ?? clock-names:
-??? const: phyclk
+??? minItems: 1
+??? maxItems: 3
+??? items:
+????? oneOf:
+??????? - description: PHY input reference clocks.
+????????? const: phyclk
+??????? - description: aclk for USB MMU.
+????????? const: aclk
+??????? - description: aclk_slv for USB MMU.
+????????? const: aclk_slv


BR.
Frank

> Best regards,
> Krzysztof
>



From sandor.yu at nxp.com  Tue Sep 24 00:04:58 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 24 Sep 2024 07:04:58 +0000
Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501
 DP/HDMI driver
In-Reply-To: <CAA8EJpphegHmBFgH1-n9PEkrr-Ys+HCvekKGNYRp=xQxgmC0Cw@mail.gmail.com>
References: <cover.1719903904.git.Sandor.yu@nxp.com>
 <359914108b879e995d4a39de32a33310009f0fab.1719903904.git.Sandor.yu@nxp.com>
 <20240702-quartz-salamander-of-culture-eec264@houat>
 <PAXPR04MB94480AB0490BBF00D2BA17BBF4932@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <20240903-gay-capable-hound-3cbef2@houat>
 <PAXPR04MB9448EF507CB5C18A43239A80F49E2@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <20240912-zippy-mongoose-of-domination-2ebc1d@houat>
 <PAXPR04MB94484D86A71A7527ADD42EA4F4652@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <CAA8EJpphegHmBFgH1-n9PEkrr-Ys+HCvekKGNYRp=xQxgmC0Cw@mail.gmail.com>
Message-ID: <PAXPR04MB94481627922756E892C37B7DF4682@PAXPR04MB9448.eurprd04.prod.outlook.com>

 
> 
> On Fri, 13 Sept 2024 at 11:46, Sandor Yu <sandor.yu at nxp.com> wrote:
> >
> >
> > > Subject: Re: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add
> > > MHDP8501 DP/HDMI driver
> > >
> > > On Fri, Sep 06, 2024 at 02:50:08AM GMT, Sandor Yu wrote:
> > > > > On Tue, Sep 03, 2024 at 06:07:25AM GMT, Sandor Yu wrote:
> > > > > > > -----Original Message-----
> > > > > > > From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On
> > > > > > > Behalf Of Maxime Ripard
> > > > > > > Sent: 2024?7?2? 21:25
> > > > > > > To: Sandor Yu <sandor.yu at nxp.com>
> > > > > > > Cc: dmitry.baryshkov at linaro.org; andrzej.hajda at intel.com;
> > > > > > > neil.armstrong at linaro.org; Laurent Pinchart
> > > > > > > <laurent.pinchart at ideasonboard.com>; jonas at kwiboo.se;
> > > > > > > jernej.skrabec at gmail.com; airlied at gmail.com;
> > > > > > > daniel at ffwll.ch;
> > > > > > > robh+dt at kernel.org; krzysztof.kozlowski+dt at linaro.org;
> > > > > > > shawnguo at kernel.org; s.hauer at pengutronix.de;
> > > festevam at gmail.com;
> > > > > > > vkoul at kernel.org; dri-devel at lists.freedesktop.org;
> > > > > > > devicetree at vger.kernel.org;
> > > > > > > linux-arm-kernel at lists.infradead.org;
> > > > > > > linux-kernel at vger.kernel.org; linux-phy at lists.infradead.org;
> > > > > > > kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>;
> > > > > > > Oliver Brown <oliver.brown at nxp.com>;
> > > > > > > alexander.stein at ew.tq-group.com; sam at ravnborg.org
> > > > > > > Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add
> > > > > > > MHDP8501 DP/HDMI driver
> > > > > > >
> > > > > > > Hi,
> > > > > > >
> > > > > > > There's still the scrambler issue we discussed on v15, but I
> > > > > > > have some more comments.
> > > > > > >
> > > > > > > On Tue, Jul 02, 2024 at 08:22:36PM GMT, Sandor Yu wrote:
> > > > > > > > +enum drm_connector_status cdns_mhdp8501_detect(struct
> > > > > > > > +cdns_mhdp8501_device *mhdp) {
> > > > > > > > +   u8 hpd = 0xf;
> > > > > > > > +
> > > > > > > > +   hpd = cdns_mhdp8501_read_hpd(mhdp);
> > > > > > > > +   if (hpd == 1)
> > > > > > > > +           return connector_status_connected;
> > > > > > > > +   else if (hpd == 0)
> > > > > > > > +           return connector_status_disconnected;
> > > > > > > > +
> > > > > > > > +   dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n",
> > > hpd);
> > > > > > > > +   return connector_status_unknown; }
> > > > > > > > +
> > > > > > > > +static void hotplug_work_func(struct work_struct *work) {
> > > > > > > > +   struct cdns_mhdp8501_device *mhdp = container_of(work,
> > > > > > > > +                                                struct
> cdns_mhdp8501_device,
> > > > > > > > +
> hotplug_work.work);
> > > > > > > > +   enum drm_connector_status status =
> > > > > cdns_mhdp8501_detect(mhdp);
> > > > > > > > +
> > > > > > > > +   drm_bridge_hpd_notify(&mhdp->bridge, status);
> > > > > > > > +
> > > > > > > > +   if (status == connector_status_connected) {
> > > > > > > > +           /* Cable connected  */
> > > > > > > > +           DRM_INFO("HDMI/DP Cable Plug In\n");
> > > > > > > > +           enable_irq(mhdp->irq[IRQ_OUT]);
> > > > > > > > +   } else if (status == connector_status_disconnected) {
> > > > > > > > +           /* Cable Disconnected  */
> > > > > > > > +           DRM_INFO("HDMI/DP Cable Plug Out\n");
> > > > > > > > +           enable_irq(mhdp->irq[IRQ_IN]);
> > > > > > > > +   }
> > > > > > > > +}
> > > > > > >
> > > > > > > You shouldn't play with the interrupt being enabled here:
> > > > > > > hotplug interrupts should always enabled.
> > > > > > >
> > > > > > > If you can't for some reason, the reason should be
> > > > > > > documented in your
> > > > > driver.
> > > > > >
> > > > > > iMX8MQ have two HPD interrupters, one for plugout and the
> > > > > > other for plugin, because they could not be masked, so we have
> > > > > > to enable one and
> > > > > disable the other.
> > > > > > I will add more comments here.
> > > > >
> > > > > Right, but why do you need to enable and disable them? Do you
> > > > > get spurious interrupts?
> > > >
> > > > They don't have status registers and cannot be masked. If they are
> > > > not disabled, they will continuously generate interrupts.
> > > > Therefore, I have to
> > > disable one and enable the other.
> > >
> > > Sorry, I still don't get it. How can it be useful to detect hotplug
> > > interrupts if it constantly sends spurious interrupts when it's enabled?
> >
> > Yes, this interrupt is different from a normal one; it's likely a design flaw.
> > For instance, the plugin interrupt is continuously generated as long
> > as the cable is plugged in, only stopping when the cable is unplugged.
> > That's why two interrupts are used to detect cable plugout and plugin
> separately.
> > If interrupts aren't used, the only option is polling.
> 
> I think I've seen such strange design on other platforms, level interrupt for HPD,
> which needs to be disabled via disable_irq().
> 
> >
> > >
> > > > > > > > +   /* Mailbox protect for HDMI PHY access */
> > > > > > > > +   mutex_lock(&mhdp->mbox_mutex);
> > > > > > > > +   ret = phy_init(mhdp->phy);
> > > > > > > > +   mutex_unlock(&mhdp->mbox_mutex);
> > > > > > > > +   if (ret) {
> > > > > > > > +           dev_err(dev, "Failed to initialize PHY: %d\n", ret);
> > > > > > > > +           goto clk_disable;
> > > > > > > > +   }
> > > > > > > > +
> > > > > > > > +   /* Mailbox protect for HDMI PHY access */
> > > > > > > > +   mutex_lock(&mhdp->mbox_mutex);
> > > > > > > > +   ret = phy_set_mode(mhdp->phy, phy_mode);
> > > > > > > > +   mutex_unlock(&mhdp->mbox_mutex);
> > > > > > > > +   if (ret) {
> > > > > > > > +           dev_err(dev, "Failed to configure PHY: %d\n", ret);
> > > > > > > > +           goto clk_disable;
> > > > > > > > +   }
> > > > > > >
> > > > > > > Why do you need a shared mutex between the phy and HDMI
> > > controller?
> > > > > >
> > > > > > Both PHY and HDMI controller could access to the HDMI firmware
> > > > > > by mailbox, So add mutex to avoid race condition.
> > > > >
> > > > > That should be handled at either the phy or mailbox level, not
> > > > > in your hdmi driver.
> > > >
> > > > In both HDMI driver and PHY driver, every mailbox access had
> > > > protected by its owns mutex. However, this mutex can only protect
> > > > each mailbox access within their respective drivers, and it cannot
> > > > provide protection for access between the HDMI and PHY drivers.
> > > >
> > > > The PHY driver only provides two API functions, and these
> > > > functions are only called in the HDMI driver. Therefore, when
> > > > accessing these functions, we use a mutex to protect them. This
> > > > ensures that mailbox access is protected across different PHY and HDMI
> drivers.
> > >
> > > It's really about abstraction. You're using a publicly defined API,
> > > and change the semantics for your driver only, and that's not ok.
> > >
> > > Why can't the mailbox driver itself serialize the accesses from any
> > > user, HDMI and PHY drivers included?
> > >
> >
> > In the current code implementation, cdns-mhdp-helper.c isn't a standalone
> driver but rather a library.
> > It provides fundamental mailbox access functions and basic register
> read/write operations that rely on the mailbox.
> > These functions are highly reusable across MHDP8501 and MHDP8546 and
> can be leveraged by future MHDP versions.
> >
> > However, most MHDP firmware interactions involve a sequence of mailbox
> accesses, including sending commands and receiving firmware responses.
> > These commands constitute a significant portion of all firmware interactions,
> encompassing operations like EDID reading and DP link training.
> > Unfortunately, these commands cannot be reused between MHDP8501 and
> MHDP8546.
> >
> > Creating a dedicated mailbox driver with its own mutex would effectively
> address race conditions.
> > However, this would necessitate relocating all mailbox-related functions to
> this driver.
> > Including these non-reusable functions would defeat the purpose of code
> reuse.
> >
> > To strike a balance between code reusability and race condition mitigation,
> adding mutexes to PHY access functions seems like a reasonable solution.
> 
> You seem to have two kinds of scenarios when talking to MHDP: just
> cdns_mhdp_mailbox_send(), no response needed and then the
> cdns_mhdp_mailbox_send() /  cdns_mhdp_mailbox_recv_header() /
> cdns_mhdp_mailbox_recv_data() sequence. Extract those + the mutex access
> to separate functions, add a mutex to those sequences and use them as a
> high-level API for your HDMI and PHY drivers.
> 
> Adding mutexes around phy_foo() calls doesn't look like a proper solution _at_
> _all_.
> 
Because the sequence cdns_mhdp_mailbox_send() / cdns_mhdp_mailbox_recv_header() / cdns_mhdp_mailbox_recv_data() cannot be reused by different drivers, 
it's not suitable to abstract them into a separate function.
I've noticed some Linux kernel drivers use global mutexes, which can solve the current race conditions problem. 
I'll implement this in the next version.

> >
> > Sandor
> >
> > > > > > >
> > > > > > > > +static enum drm_mode_status
> > > > > > > > +cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge
> *bridge,
> > > > > > > > +                          const struct drm_display_mode
> *mode,
> > > > > > > > +                          unsigned long long tmds_rate) {
> > > > > > > > +   struct cdns_mhdp8501_device *mhdp =
> > > bridge->driver_private;
> > > > > > > > +   union phy_configure_opts phy_cfg;
> > > > > > > > +   int ret;
> > > > > > > > +
> > > > > > > > +   phy_cfg.hdmi.tmds_char_rate = tmds_rate;
> > > > > > > > +
> > > > > > > > +   /* Mailbox protect for HDMI PHY access */
> > > > > > > > +   mutex_lock(&mhdp->mbox_mutex);
> > > > > > > > +   ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0,
> > > &phy_cfg);
> > > > > > > > +   mutex_unlock(&mhdp->mbox_mutex);
> > > > > > > > +   if (ret < 0)
> > > > > > > > +           return MODE_CLOCK_RANGE;
> > > > > > > > +
> > > > > > > > +   return MODE_OK;
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +static enum drm_mode_status
> > > > > > > > +cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
> > > > > > > > +                       const struct drm_display_info *info,
> > > > > > > > +                       const struct drm_display_mode
> *mode) {
> > > > > > > > +   unsigned long long tmds_rate;
> > > > > > > > +
> > > > > > > > +   /* We don't support double-clocked and Interlaced modes */
> > > > > > > > +   if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
> > > > > > > > +       mode->flags & DRM_MODE_FLAG_INTERLACE)
> > > > > > > > +           return MODE_BAD;
> > > > > > > > +
> > > > > > > > +   /* MAX support pixel clock rate 594MHz */
> > > > > > > > +   if (mode->clock > 594000)
> > > > > > > > +           return MODE_CLOCK_HIGH;
> > > > > > >
> > > > > > > This needs to be in the tmds_char_rate_valid function
> > > > > > This clock rate check is covered by function
> > > > > > tmds_char_rate_valid() It could be removed if keep function
> > > > > > tmds_char_rate_valid() be called by
> > > > > mode_valid.
> > > > >
> > > > > Yeah, it's not something you should have to duplicate.
> > > > >
> > > > > > >
> > > > > > > > +   if (mode->hdisplay > 3840)
> > > > > > > > +           return MODE_BAD_HVALUE;
> > > > > > > > +
> > > > > > > > +   if (mode->vdisplay > 2160)
> > > > > > > > +           return MODE_BAD_VVALUE;
> > > > > > > > +
> > > > > > > > +   tmds_rate = mode->clock * 1000ULL;
> > > > > > > > +   return cdns_hdmi_tmds_char_rate_valid(bridge, mode,
> > > > > > > > +tmds_rate);
> > > > > > >
> > > > > > > It will already be called by the core so this is redundant.
> > > > > >
> > > > > > mode_valid function is use to filter the mode list in
> > > > > > drm_helper_probe_single_connector_modes(),
> > > > > > if function cdns_hdmi_tmds_char_rate_valid() is not called,
> > > > > > unsupported
> > > > > modes will in mode list.
> > > > >
> > > > > It's probably something we should deal with in the core somehow.
> > > > > I'm not entirely sure how to reconcile drm_bridge_connector and
> > > > > the hdmi framework there, but we should at the very least
> > > > > provide a mode_valid helper for bridges.
> > > >
> > > > I agree with that. In fact, I'm a bit confused about the current
> > > > mode_valid and tmds_char_rate_valid functions. Ideally, we should
> > > > find a way to make tmds_char_rate_valid also work for filtering
> > > > out the mode list, rather than just during atomic_check.
> > >
> > > Yeah, definitely. The way we did so on vc4 for example was to
> > > compute the rate for a 8bpc, RGB, output and try to validate that. I
> > > think it would be reasonable to start with that.
> 
> +1, please extract this code as a helper. You can even submit it
> separately, reworking sun4i and vc4 to use a new helper.
> 
OK, I would appreciate more time to carefully consider the implementation of this API.

B.R
Sandor

> --
> With best wishes
> Dmitry

From Sandor.yu at nxp.com  Tue Sep 24 00:36:45 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 24 Sep 2024 15:36:45 +0800
Subject: [PATCH v17 0/8] Initial support Cadence MHDP8501(HDMI/DP) for i.MX8MQ
Message-ID: <cover.1727159906.git.Sandor.yu@nxp.com>

The patch set initial support Cadence MHDP8501(HDMI/DP) DRM bridge
driver and Cadence HDP-TX PHY(HDMI/DP) driver for Freescale i.MX8MQ.

The patch set compose of DRM bridge drivers and PHY driver.

Both of them need by patch #1 and #2 to pass build.

DRM bridges driver patches:
  #1: drm: bridge: Cadence: Creat mhdp helper driver
  #2: phy: Add HDMI configuration options
  #3: dt-bindings: display: bridge: Add Cadence MHDP8501
  #4: drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver

PHY driver patches:
  #1: drm: bridge: Cadence: Creat mhdp helper driver
  #2: phy: Add HDMI configuration options
  #5: dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
  #6: phy: freescale: Add DisplayPort/HDMI Combo-PHY driver for i.MX8MQ

i.MX8M/TQMa8Mx DT patches:
  #7: Add DT nodes for DCSS/HDMI pipeline
  #8: Enable HDMI for TQMa8Mx/MBa8Mx

v16->v17:
Patch #1:
- Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex
Patch #2:
- remove hdmi.h
- add 2024 year to copyright
- Add r-b tag.
Patch #3:
- Add lane-mapping property.
Patch #4:
- Reset the HDMI/DP link when an HPD (Hot Plug Detect) event is detected
- Move the HDMI protocol settings from hdmi_ctrl_init() to a new function
  cdns_hdmi_set_hdmi_mode_type(), to align with the introduced link reset functionality.
- Implement logic to check the type of HDMI sink.
  If the sink is not a hdmi display, set the default mode to DVI.
- Implement hdmi_reset_infoframe function
- Reorder certain bit definitions in the header file to follow a descending order.
- Add "lane-mapping" property for both HDMI and DP, remove platform data from driver.
  lane-mapping should be setting in dts according different board layout.
- Remove variable mode in struct cdns_mhdp8501_device, video mode could get from struct drm_crtc_state
- Remove variable char_rate in  struct cdns_mhdp8501_device, it could get from struct struct drm_connector_state.hdmi
- Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex
- Remove mutext protect for phy_api access functions.
Patch #6:
- Remove mbox_mutex

v15->v16:
Patch #2:
- Remove pixel_clk_rate, bpc and color_space fields from struct
  phy_configure_opts_hdmi, they were replaced by
  unsigned long long tmds_char_rate.
- Remove r-b and a-c tags because this patch have important change.
Patch #4:
- Add DRM_BRIDGE_OP_HDMI flags for HDMI driver,
- Introduce the hdmi info frame helper functions,
  added hdmi_clear_infoframe(), hdmi_write_infoframe() and
  hdmi_tmds_char_rate_valid() according Dmitry's patch
  'make use of the HDMI connector infrastructure' patchset ([2]).
- mode_fixup() is replaced by atomic_check().
- Fix video mode 4Kp30 did not work on some displays that support
  LTE_340Mcsc_scramble.
- updated for tmds_char_rate added in patch #2. 
Patch #6:
- updated for tmds_char_rate added in patch #2. 

v14->v15:
Patch #6 + #7:
-  Merged PHY driver into a single combo PHY driver
Patch #7 + #8:
- Add DT patches for a running HDMI setup

v13->v14:
Patch #4:
- Rebase to next-20240219, replace get_edid function by edid_read
  function as commits d807ad80d811b ("drm/bridge: add ->edid_read
  hook and drm_bridge_edid_read()") and 27b8f91c08d99 ("drm/bridge:
  remove ->get_edid callback") had change the API.

v12->v13:
Patch #4:
- Explicitly include linux/platform_device.h for cdns-mhdp8501-core.c
- Fix build warning
- Order bit bpc and color_space in descending shit. 
Patch #7:
- Fix build warning

v11->v12:
Patch #1: 
- Move status initialize out of mbox_mutex.
- Reorder API functions in alphabetical.
- Add notes for malibox access functions.
- Add year 2024 to copyright.
Patch #4:
- Replace DRM_INFO with dev_info or dev_warn.
- Replace DRM_ERROR with dev_err.
- Return ret when cdns_mhdp_dpcd_read failed in function cdns_dp_aux_transferi().
- Remove unused parmeter in function cdns_dp_get_msa_misc
  and use two separate variables for color space and bpc.
- Add year 2024 to copyright.
Patch #6:
- Return error code to replace -1 for function wait_for_ack().
- Set cdns_phy->power_up = false in phy_power_down function.
- Remove "RATE_8_1 = 810000", it is not used in driver.
- Add year 2024 to copyright.
Patch #7:
- Adjust clk disable order.
- Return error code to replace -1 for function wait_for_ack().
- Use bool for variable pclk_in.
- Add year 2024 to copyright.

v10->v11:
- rewrite cdns_mhdp_set_firmware_active() in mhdp8546 core driver,
use cdns_mhdp_mailbox_send() to replace cdns_mhdp_mailbox_write()
same as the other mailbox access functions.
- use static for cdns_mhdp_mailbox_write() and cdns_mhdp_mailbox_read()
and remove them from EXPORT_SYMBOL_GPL().
- remove MODULE_ALIAS() from mhdp8501 driver.

v9->v10:
- Create mhdp helper driver to replace macro functions,
move all mhdp mailbox access functions and common functions
into the helper driver.
Patch #1:drm: bridge: Cadence: Creat mhdp helper driver
it is totaly different with v9.

v8->v9:
- Remove compatible string "cdns,mhdp8501" that had removed
  from dt-bindings file in v8.
- Add Dmitry's R-b tag to patch #2
- Add Krzysztof's R-b tag to patch #3

v7->v8:
MHDP8501 HDMI/DP:
- Correct DT node name to "display-bridge".
- Remove "cdns,mhdp8501" from mhdp8501 dt-binding doc.

HDMI/DP PHY:
- Introduced functions `wait_for_ack` and `wait_for_ack_clear` to handle
  waiting with acknowledgment bits set and cleared respectively.
- Use FIELD_PRE() to set bitfields for both HDMI and DP PHY.

v6->v7:
MHDP8501 HDMI/DP:
- Combine HDMI and DP driver into one mhdp8501 driver.
  Use the connector type to load the corresponding functions.
- Remove connector init functions.
- Add <linux/hdmi.h> in phy_hdmi.h to reuse 'enum hdmi_colorspace'.

HDMI/DP PHY:
- Lowercase hex values
- Fix parameters indent issue on some functions
- Replace 'udelay' with 'usleep_range'

v5->v6:
HDMI/DP bridge driver
- 8501 is the part number of Cadence MHDP on i.MX8MQ.
  Use MHDP8501 to name hdmi/dp drivers and files. 
- Add compatible "fsl,imx8mq-mhdp8501-dp" for i.MX8MQ DP driver
- Add compatible "fsl,imx8mq-mhdp8501-hdmi" for i.MX8MQ HDMI driver
- Combine HDMI and DP dt-bindings into one file cdns,mhdp8501.yaml
- Fix HDMI scrambling is not enable issue when driver working in 4Kp60
  mode.
- Add HDMI/DP PHY API mailbox protect.

HDMI/DP PHY driver:
- Rename DP and HDMI PHY files and move to folder phy/freescale/
- Remove properties num_lanes and link_rate from DP PHY driver.
- Combine HDMI and DP dt-bindings into one file fsl,imx8mq-dp-hdmi-phy.yaml
- Update compatible string to "fsl,imx8mq-dp-phy".
- Update compatible string to "fsl,imx8mq-hdmi-phy".

v4->v5:
- Drop "clk" suffix in clock name.
- Add output port property in the example of hdmi/dp.

v3->v4:
dt-bindings:
- Correct dt-bindings coding style and address review comments.
- Add apb_clk description.
- Add output port for HDMI/DP connector
PHY:
- Alphabetically sorted in Kconfig and Makefile for DP and HDMI PHY
- Remove unused registers define from HDMI and DP PHY drivers.
- More description in phy_hdmi.h.
- Add apb_clk to HDMI and DP phy driver.
HDMI/DP:
- Use get_unaligned_le32() to replace hardcode type conversion
  in HDMI AVI infoframe data fill function.
- Add mailbox mutex lock in HDMI/DP driver for phy functions
  to reslove race conditions between HDMI/DP and PHY drivers.
- Add apb_clk to both HDMI and DP driver.
- Rename some function names and add prefix with "cdns_hdmi/cdns_dp".
- Remove bpc 12 and 16 optional that not supported.

v2->v3:
Address comments for dt-bindings files.
- Correct dts-bindings file names 
  Rename phy-cadence-hdptx-dp.yaml to cdns,mhdp-imx8mq-dp.yaml
  Rename phy-cadence-hdptx-hdmi.yaml to cdns,mhdp-imx8mq-hdmi.yaml
- Drop redundant words and descriptions.
- Correct hdmi/dp node name.

v2 is a completely different version compared to v1.
Previous v1 can be available here [1].

v1->v2:
- Reuse Cadence mailbox access functions from mhdp8546 instead of
  rockchip DP.
- Mailbox access functions be convert to marco functions
  that will be referenced by HDP-TX PHY(HDMI/DP) driver too.
- Plain bridge instead of component driver.
- Standalone Cadence HDP-TX PHY(HDMI/DP) driver.
- Audio driver are removed from the patch set, it will be add in another
  patch set later.

[1] https://patchwork.kernel.org/project/linux-rockchip/cover/cover.1590982881.git.Sandor.yu at nxp.com/

Alexander Stein (2):
  arm64: dts: imx8mq: Add DCSS + HDMI/DP display pipeline
  arm64: dts: imx8mq: tqma8mq-mba8mx: Enable HDMI support

Sandor Yu (6):
  drm: bridge: Cadence: Create mhdp helper driver
  phy: Add HDMI configuration options
  dt-bindings: display: bridge: Add Cadence MHDP8501
  drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
  dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
  phy: freescale: Add DisplayPort/HDMI Combo-PHY driver for i.MX8MQ

 .../display/bridge/cdns,mhdp8501.yaml         |  109 ++
 .../bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml  |   51 +
 .../dts/freescale/imx8mq-tqma8mq-mba8mx.dts   |   20 +
 arch/arm64/boot/dts/freescale/imx8mq.dtsi     |   68 +
 arch/arm64/boot/dts/freescale/mba8mx.dtsi     |   11 +
 drivers/gpu/drm/bridge/cadence/Kconfig        |   20 +
 drivers/gpu/drm/bridge/cadence/Makefile       |    3 +
 .../gpu/drm/bridge/cadence/cdns-mhdp-helper.c |  307 ++++
 .../drm/bridge/cadence/cdns-mhdp8501-core.c   |  323 ++++
 .../drm/bridge/cadence/cdns-mhdp8501-core.h   |  359 +++++
 .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c |  737 +++++++++
 .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   |  692 +++++++++
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   |  425 +-----
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |   47 +-
 .../drm/bridge/cadence/cdns-mhdp8546-hdcp.c   |   36 +-
 drivers/phy/freescale/Kconfig                 |   10 +
 drivers/phy/freescale/Makefile                |    1 +
 drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c  | 1337 +++++++++++++++++
 include/drm/bridge/cdns-mhdp-helper.h         |   94 ++
 include/linux/phy/phy-hdmi.h                  |   19 +
 include/linux/phy/phy.h                       |    7 +-
 21 files changed, 4268 insertions(+), 408 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
 create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c
 create mode 100644 include/drm/bridge/cdns-mhdp-helper.h
 create mode 100644 include/linux/phy/phy-hdmi.h

-- 
2.34.1



From Sandor.yu at nxp.com  Tue Sep 24 00:36:46 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 24 Sep 2024 15:36:46 +0800
Subject: [PATCH v17 1/8] drm: bridge: Cadence: Create mhdp helper driver
In-Reply-To: <cover.1727159906.git.Sandor.yu@nxp.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <6e2e4951aa4c69eed68af231c2b0b2ce302b2358.1727159906.git.Sandor.yu@nxp.com>

MHDP8546 mailbox access functions will be share to other mhdp driver
and Cadence HDP-TX HDMI/DP PHY drivers.
Create a new mhdp helper driver and move all those functions into.

cdns_mhdp_reg_write() is renamed to cdns_mhdp_dp_reg_write(),
because it use the DPTX command ID DPTX_WRITE_REGISTER.

New cdns_mhdp_reg_write() is created with the general command ID
GENERAL_REGISTER_WRITE.

Rewrite cdns_mhdp_set_firmware_active() in mhdp8546 core driver,
use cdns_mhdp_mailbox_send() to replace cdns_mhdp_mailbox_write()
same as the other mailbox access functions.

Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex
to prevent race conditions in mailbox access by multi drivers.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
---
v16->v17:
- Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex

v12->v16:
 *No change.

V11->v12:
- Move status initialize out of mbox_mutex.
- Reorder API functions in alphabetical.
- Add notes for malibox access functions.
- Add year 2024 to copyright.

 drivers/gpu/drm/bridge/cadence/Kconfig        |   4 +
 drivers/gpu/drm/bridge/cadence/Makefile       |   1 +
 .../gpu/drm/bridge/cadence/cdns-mhdp-helper.c | 307 +++++++++++++
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 425 ++++--------------
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  47 +-
 .../drm/bridge/cadence/cdns-mhdp8546-hdcp.c   |  36 +-
 include/drm/bridge/cdns-mhdp-helper.h         |  94 ++++
 7 files changed, 507 insertions(+), 407 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
 create mode 100644 include/drm/bridge/cdns-mhdp-helper.h

diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig
index cced81633ddcd..e0973339e9e33 100644
--- a/drivers/gpu/drm/bridge/cadence/Kconfig
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -21,6 +21,9 @@ config DRM_CDNS_DSI_J721E
 	  the routing of the DSS DPI signal to the Cadence DSI.
 endif
 
+config CDNS_MHDP_HELPER
+	tristate
+
 config DRM_CDNS_MHDP8546
 	tristate "Cadence DPI/DP bridge"
 	select DRM_DISPLAY_DP_HELPER
@@ -28,6 +31,7 @@ config DRM_CDNS_MHDP8546
 	select DRM_DISPLAY_HELPER
 	select DRM_KMS_HELPER
 	select DRM_PANEL_BRIDGE
+	select CDNS_MHDP_HELPER
 	depends on OF
 	help
 	  Support Cadence DPI to DP bridge. This is an internal
diff --git a/drivers/gpu/drm/bridge/cadence/Makefile b/drivers/gpu/drm/bridge/cadence/Makefile
index c95fd5b81d137..087dc074820d7 100644
--- a/drivers/gpu/drm/bridge/cadence/Makefile
+++ b/drivers/gpu/drm/bridge/cadence/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
 cdns-dsi-y := cdns-dsi-core.o
 cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.o
+obj-$(CONFIG_CDNS_MHDP_HELPER) += cdns-mhdp-helper.o
 obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
 cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
 cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
new file mode 100644
index 0000000000000..c60a6b69a5343
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
@@ -0,0 +1,307 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, 2024 NXP Semiconductor, Inc.
+ *
+ */
+#include <drm/bridge/cdns-mhdp-helper.h>
+#include <linux/dev_printk.h>
+#include <linux/module.h>
+
+/* Protects mailbox communications with the firmware */
+DEFINE_MUTEX(mhdp_mailbox_mutex);
+
+/* Mailbox helper functions */
+static int cdns_mhdp_mailbox_read(struct cdns_mhdp_base *base)
+{
+	int ret, empty;
+
+	WARN_ON(!mutex_is_locked(&mhdp_mailbox_mutex));
+
+	ret = readx_poll_timeout(readl, base->regs + CDNS_MAILBOX_EMPTY,
+				 empty, !empty, MAILBOX_RETRY_US,
+				 MAILBOX_TIMEOUT_US);
+	if (ret < 0)
+		return ret;
+
+	return readl(base->regs + CDNS_MAILBOX_RX_DATA) & 0xff;
+}
+
+static int cdns_mhdp_mailbox_write(struct cdns_mhdp_base *base, u8 val)
+{
+	int ret, full;
+
+	WARN_ON(!mutex_is_locked(&mhdp_mailbox_mutex));
+
+	ret = readx_poll_timeout(readl, base->regs + CDNS_MAILBOX_FULL,
+				 full, !full, MAILBOX_RETRY_US,
+				 MAILBOX_TIMEOUT_US);
+	if (ret < 0)
+		return ret;
+
+	writel(val, base->regs + CDNS_MAILBOX_TX_DATA);
+
+	return 0;
+}
+
+int cdns_mhdp_mailbox_recv_header(struct cdns_mhdp_base *base,
+				  u8 module_id, u8 opcode,
+				  u16 req_size)
+{
+	u32 mbox_size, i;
+	u8 header[4];
+	int ret;
+
+	/* read the header of the message */
+	for (i = 0; i < sizeof(header); i++) {
+		ret = cdns_mhdp_mailbox_read(base);
+		if (ret < 0)
+			return ret;
+
+		header[i] = ret;
+	}
+
+	mbox_size = get_unaligned_be16(header + 2);
+
+	if (opcode != header[0] || module_id != header[1] ||
+	    req_size != mbox_size) {
+		/*
+		 * If the message in mailbox is not what we want, we need to
+		 * clear the mailbox by reading its contents.
+		 */
+		for (i = 0; i < mbox_size; i++)
+			if (cdns_mhdp_mailbox_read(base) < 0)
+				break;
+
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_recv_header);
+
+int cdns_mhdp_mailbox_recv_data(struct cdns_mhdp_base *base,
+				u8 *buff, u16 buff_size)
+{
+	u32 i;
+	int ret;
+
+	for (i = 0; i < buff_size; i++) {
+		ret = cdns_mhdp_mailbox_read(base);
+		if (ret < 0)
+			return ret;
+
+		buff[i] = ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_recv_data);
+
+int cdns_mhdp_mailbox_send(struct cdns_mhdp_base *base, u8 module_id,
+			   u8 opcode, u16 size, u8 *message)
+{
+	u8 header[4];
+	int ret, i;
+
+	header[0] = opcode;
+	header[1] = module_id;
+	put_unaligned_be16(size, header + 2);
+
+	for (i = 0; i < sizeof(header); i++) {
+		ret = cdns_mhdp_mailbox_write(base, header[i]);
+		if (ret)
+			return ret;
+	}
+
+	for (i = 0; i < size; i++) {
+		ret = cdns_mhdp_mailbox_write(base, message[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_send);
+
+/* General helper functions */
+int cdns_mhdp_reg_read(struct cdns_mhdp_base *base, u32 addr, u32 *value)
+{
+	u8 msg[4], resp[8];
+	int ret;
+
+	put_unaligned_be32(addr, msg);
+
+	mutex_lock(&mhdp_mailbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_GENERAL,
+				     GENERAL_REGISTER_READ,
+				     sizeof(msg), msg);
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_header(base, MB_MODULE_ID_GENERAL,
+					    GENERAL_REGISTER_READ,
+					    sizeof(resp));
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_data(base, resp, sizeof(resp));
+	if (ret)
+		goto out;
+
+	/* Returned address value should be the same as requested */
+	if (memcmp(msg, resp, sizeof(msg))) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	*value = get_unaligned_be32(resp + 4);
+
+out:
+	mutex_unlock(&mhdp_mailbox_mutex);
+	if (ret) {
+		dev_err(base->dev, "Failed to read register\n");
+		*value = 0;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_reg_read);
+
+int cdns_mhdp_reg_write(struct cdns_mhdp_base *base, u32 addr, u32 val)
+{
+	u8 msg[8];
+	int ret;
+
+	put_unaligned_be32(addr, msg);
+	put_unaligned_be32(val, msg + 4);
+
+	mutex_lock(&mhdp_mailbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_GENERAL,
+				     GENERAL_REGISTER_WRITE,
+				     sizeof(msg), msg);
+
+	mutex_unlock(&mhdp_mailbox_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_reg_write);
+
+/* DPTX helper functions */
+int cdns_mhdp_dp_reg_write(struct cdns_mhdp_base *base, u16 addr, u32 val)
+{
+	u8 msg[6];
+	int ret;
+
+	put_unaligned_be16(addr, msg);
+	put_unaligned_be32(val, msg + 2);
+
+	mutex_lock(&mhdp_mailbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_DP_TX,
+				     DPTX_WRITE_REGISTER, sizeof(msg), msg);
+
+	mutex_unlock(&mhdp_mailbox_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_dp_reg_write);
+
+int cdns_mhdp_dp_reg_write_bit(struct cdns_mhdp_base *base, u16 addr,
+			       u8 start_bit, u8 bits_no, u32 val)
+{
+	u8 field[8];
+	int ret;
+
+	put_unaligned_be16(addr, field);
+	field[2] = start_bit;
+	field[3] = bits_no;
+	put_unaligned_be32(val, field + 4);
+
+	mutex_lock(&mhdp_mailbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_DP_TX,
+				     DPTX_WRITE_FIELD, sizeof(field), field);
+
+	mutex_unlock(&mhdp_mailbox_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_dp_reg_write_bit);
+
+int cdns_mhdp_dpcd_read(struct cdns_mhdp_base *base,
+			u32 addr, u8 *data, u16 len)
+{
+	u8 msg[5], reg[5];
+	int ret;
+
+	put_unaligned_be16(len, msg);
+	put_unaligned_be24(addr, msg + 2);
+
+	mutex_lock(&mhdp_mailbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_DP_TX,
+				     DPTX_READ_DPCD, sizeof(msg), msg);
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_header(base, MB_MODULE_ID_DP_TX,
+					    DPTX_READ_DPCD,
+					    sizeof(reg) + len);
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_data(base, reg, sizeof(reg));
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_data(base, data, len);
+
+out:
+	mutex_unlock(&mhdp_mailbox_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_dpcd_read);
+
+int cdns_mhdp_dpcd_write(struct cdns_mhdp_base *base, u32 addr, u8 value)
+{
+	u8 msg[6], reg[5];
+	int ret;
+
+	put_unaligned_be16(1, msg);
+	put_unaligned_be24(addr, msg + 2);
+	msg[5] = value;
+
+	mutex_lock(&mhdp_mailbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_DP_TX,
+				     DPTX_WRITE_DPCD, sizeof(msg), msg);
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_header(base, MB_MODULE_ID_DP_TX,
+					    DPTX_WRITE_DPCD, sizeof(reg));
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_data(base, reg, sizeof(reg));
+	if (ret)
+		goto out;
+
+	if (addr != get_unaligned_be24(reg + 2))
+		ret = -EINVAL;
+
+out:
+	mutex_unlock(&mhdp_mailbox_mutex);
+
+	if (ret)
+		dev_err(base->dev, "dpcd write failed: %d\n", ret);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_dpcd_write);
+
+MODULE_DESCRIPTION("Cadence MHDP Helper driver");
+MODULE_AUTHOR("Sandor Yu <Sandor.yu at nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
index dee640ab1d3ad..3ceba90a682da 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -73,301 +73,31 @@ static void cdns_mhdp_bridge_hpd_disable(struct drm_bridge *bridge)
 	       mhdp->regs + CDNS_APB_INT_MASK);
 }
 
-static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp)
-{
-	int ret, empty;
-
-	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
-
-	ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_EMPTY,
-				 empty, !empty, MAILBOX_RETRY_US,
-				 MAILBOX_TIMEOUT_US);
-	if (ret < 0)
-		return ret;
-
-	return readl(mhdp->regs + CDNS_MAILBOX_RX_DATA) & 0xff;
-}
-
-static int cdns_mhdp_mailbox_write(struct cdns_mhdp_device *mhdp, u8 val)
-{
-	int ret, full;
-
-	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
-
-	ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_FULL,
-				 full, !full, MAILBOX_RETRY_US,
-				 MAILBOX_TIMEOUT_US);
-	if (ret < 0)
-		return ret;
-
-	writel(val, mhdp->regs + CDNS_MAILBOX_TX_DATA);
-
-	return 0;
-}
-
-static int cdns_mhdp_mailbox_recv_header(struct cdns_mhdp_device *mhdp,
-					 u8 module_id, u8 opcode,
-					 u16 req_size)
-{
-	u32 mbox_size, i;
-	u8 header[4];
-	int ret;
-
-	/* read the header of the message */
-	for (i = 0; i < sizeof(header); i++) {
-		ret = cdns_mhdp_mailbox_read(mhdp);
-		if (ret < 0)
-			return ret;
-
-		header[i] = ret;
-	}
-
-	mbox_size = get_unaligned_be16(header + 2);
-
-	if (opcode != header[0] || module_id != header[1] ||
-	    req_size != mbox_size) {
-		/*
-		 * If the message in mailbox is not what we want, we need to
-		 * clear the mailbox by reading its contents.
-		 */
-		for (i = 0; i < mbox_size; i++)
-			if (cdns_mhdp_mailbox_read(mhdp) < 0)
-				break;
-
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int cdns_mhdp_mailbox_recv_data(struct cdns_mhdp_device *mhdp,
-				       u8 *buff, u16 buff_size)
-{
-	u32 i;
-	int ret;
-
-	for (i = 0; i < buff_size; i++) {
-		ret = cdns_mhdp_mailbox_read(mhdp);
-		if (ret < 0)
-			return ret;
-
-		buff[i] = ret;
-	}
-
-	return 0;
-}
-
-static int cdns_mhdp_mailbox_send(struct cdns_mhdp_device *mhdp, u8 module_id,
-				  u8 opcode, u16 size, u8 *message)
-{
-	u8 header[4];
-	int ret, i;
-
-	header[0] = opcode;
-	header[1] = module_id;
-	put_unaligned_be16(size, header + 2);
-
-	for (i = 0; i < sizeof(header); i++) {
-		ret = cdns_mhdp_mailbox_write(mhdp, header[i]);
-		if (ret)
-			return ret;
-	}
-
-	for (i = 0; i < size; i++) {
-		ret = cdns_mhdp_mailbox_write(mhdp, message[i]);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-static
-int cdns_mhdp_reg_read(struct cdns_mhdp_device *mhdp, u32 addr, u32 *value)
-{
-	u8 msg[4], resp[8];
-	int ret;
-
-	put_unaligned_be32(addr, msg);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL,
-				     GENERAL_REGISTER_READ,
-				     sizeof(msg), msg);
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_GENERAL,
-					    GENERAL_REGISTER_READ,
-					    sizeof(resp));
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, resp, sizeof(resp));
-	if (ret)
-		goto out;
-
-	/* Returned address value should be the same as requested */
-	if (memcmp(msg, resp, sizeof(msg))) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	*value = get_unaligned_be32(resp + 4);
-
-out:
-	mutex_unlock(&mhdp->mbox_mutex);
-	if (ret) {
-		dev_err(mhdp->dev, "Failed to read register\n");
-		*value = 0;
-	}
-
-	return ret;
-}
-
-static
-int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u16 addr, u32 val)
-{
-	u8 msg[6];
-	int ret;
-
-	put_unaligned_be16(addr, msg);
-	put_unaligned_be32(val, msg + 2);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
-				     DPTX_WRITE_REGISTER, sizeof(msg), msg);
-
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
-}
-
-static
-int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr,
-			    u8 start_bit, u8 bits_no, u32 val)
-{
-	u8 field[8];
-	int ret;
-
-	put_unaligned_be16(addr, field);
-	field[2] = start_bit;
-	field[3] = bits_no;
-	put_unaligned_be32(val, field + 4);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
-				     DPTX_WRITE_FIELD, sizeof(field), field);
-
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
-}
-
-static
-int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp,
-			u32 addr, u8 *data, u16 len)
-{
-	u8 msg[5], reg[5];
-	int ret;
-
-	put_unaligned_be16(len, msg);
-	put_unaligned_be24(addr, msg + 2);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
-				     DPTX_READ_DPCD, sizeof(msg), msg);
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
-					    DPTX_READ_DPCD,
-					    sizeof(reg) + len);
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, data, len);
-
-out:
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
-}
-
 static
-int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value)
+int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable)
 {
-	u8 msg[6], reg[5];
+	u8 status;
 	int ret;
 
-	put_unaligned_be16(1, msg);
-	put_unaligned_be24(addr, msg + 2);
-	msg[5] = value;
-
-	mutex_lock(&mhdp->mbox_mutex);
+	status = enable ? FW_ACTIVE : FW_STANDBY;
 
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
-				     DPTX_WRITE_DPCD, sizeof(msg), msg);
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
-					    DPTX_WRITE_DPCD, sizeof(reg));
-	if (ret)
-		goto out;
+	mutex_lock(&mhdp_mailbox_mutex);
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_GENERAL,
+				     GENERAL_MAIN_CONTROL, sizeof(status), &status);
 	if (ret)
 		goto out;
 
-	if (addr != get_unaligned_be24(reg + 2))
-		ret = -EINVAL;
-
-out:
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	if (ret)
-		dev_err(mhdp->dev, "dpcd write failed: %d\n", ret);
-	return ret;
-}
-
-static
-int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable)
-{
-	u8 msg[5];
-	int ret, i;
-
-	msg[0] = GENERAL_MAIN_CONTROL;
-	msg[1] = MB_MODULE_ID_GENERAL;
-	msg[2] = 0;
-	msg[3] = 1;
-	msg[4] = enable ? FW_ACTIVE : FW_STANDBY;
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	for (i = 0; i < sizeof(msg); i++) {
-		ret = cdns_mhdp_mailbox_write(mhdp, msg[i]);
-		if (ret)
-			goto out;
-	}
-
-	/* read the firmware state */
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, msg, sizeof(msg));
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_GENERAL,
+					    GENERAL_MAIN_CONTROL,
+					    sizeof(status));
 	if (ret)
 		goto out;
 
-	ret = 0;
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &status, sizeof(status));
 
 out:
-	mutex_unlock(&mhdp->mbox_mutex);
+	mutex_unlock(&mhdp_mailbox_mutex);
 
 	if (ret < 0)
 		dev_err(mhdp->dev, "set firmware active failed\n");
@@ -380,24 +110,24 @@ int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp)
 	u8 status;
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
+	mutex_lock(&mhdp_mailbox_mutex);
 
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
 				     DPTX_HPD_STATE, 0, NULL);
 	if (ret)
 		goto err_get_hpd;
 
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
 					    DPTX_HPD_STATE,
 					    sizeof(status));
 	if (ret)
 		goto err_get_hpd;
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, &status, sizeof(status));
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &status, sizeof(status));
 	if (ret)
 		goto err_get_hpd;
 
-	mutex_unlock(&mhdp->mbox_mutex);
+	mutex_unlock(&mhdp_mailbox_mutex);
 
 	dev_dbg(mhdp->dev, "%s: HPD %splugged\n", __func__,
 		status ? "" : "un");
@@ -405,7 +135,7 @@ int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp)
 	return status;
 
 err_get_hpd:
-	mutex_unlock(&mhdp->mbox_mutex);
+	mutex_unlock(&mhdp_mailbox_mutex);
 
 	return ret;
 }
@@ -418,28 +148,28 @@ int cdns_mhdp_get_edid_block(void *data, u8 *edid,
 	u8 msg[2], reg[2], i;
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
+	mutex_lock(&mhdp_mailbox_mutex);
 
 	for (i = 0; i < 4; i++) {
 		msg[0] = block / 2;
 		msg[1] = block % 2;
 
-		ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
+		ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
 					     DPTX_GET_EDID, sizeof(msg), msg);
 		if (ret)
 			continue;
 
-		ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
+		ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
 						    DPTX_GET_EDID,
 						    sizeof(reg) + length);
 		if (ret)
 			continue;
 
-		ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg, sizeof(reg));
 		if (ret)
 			continue;
 
-		ret = cdns_mhdp_mailbox_recv_data(mhdp, edid, length);
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, edid, length);
 		if (ret)
 			continue;
 
@@ -447,7 +177,7 @@ int cdns_mhdp_get_edid_block(void *data, u8 *edid,
 			break;
 	}
 
-	mutex_unlock(&mhdp->mbox_mutex);
+	mutex_unlock(&mhdp_mailbox_mutex);
 
 	if (ret)
 		dev_err(mhdp->dev, "get block[%d] edid failed: %d\n",
@@ -462,21 +192,21 @@ int cdns_mhdp_read_hpd_event(struct cdns_mhdp_device *mhdp)
 	u8 event = 0;
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
+	mutex_lock(&mhdp_mailbox_mutex);
 
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
 				     DPTX_READ_EVENT, 0, NULL);
 	if (ret)
 		goto out;
 
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
 					    DPTX_READ_EVENT, sizeof(event));
 	if (ret < 0)
 		goto out;
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, &event, sizeof(event));
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &event, sizeof(event));
 out:
-	mutex_unlock(&mhdp->mbox_mutex);
+	mutex_unlock(&mhdp_mailbox_mutex);
 
 	if (ret < 0)
 		return ret;
@@ -510,22 +240,22 @@ int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, unsigned int nlanes,
 	put_unaligned_be16(udelay, payload + 1);
 	memcpy(payload + 3, lanes_data, nlanes);
 
-	mutex_lock(&mhdp->mbox_mutex);
+	mutex_lock(&mhdp_mailbox_mutex);
 
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
 				     DPTX_ADJUST_LT,
 				     sizeof(payload), payload);
 	if (ret)
 		goto out;
 
 	/* Yes, read the DPCD read command response */
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
 					    DPTX_READ_DPCD,
 					    sizeof(hdr) + DP_LINK_STATUS_SIZE);
 	if (ret)
 		goto out;
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, hdr, sizeof(hdr));
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, hdr, sizeof(hdr));
 	if (ret)
 		goto out;
 
@@ -533,11 +263,11 @@ int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, unsigned int nlanes,
 	if (addr != DP_LANE0_1_STATUS)
 		goto out;
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, link_status,
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, link_status,
 					  DP_LINK_STATUS_SIZE);
 
 out:
-	mutex_unlock(&mhdp->mbox_mutex);
+	mutex_unlock(&mhdp_mailbox_mutex);
 
 	if (ret)
 		dev_err(mhdp->dev, "Failed to adjust Link Training.\n");
@@ -847,7 +577,7 @@ static ssize_t cdns_mhdp_transfer(struct drm_dp_aux *aux,
 		unsigned int i;
 
 		for (i = 0; i < msg->size; ++i) {
-			ret = cdns_mhdp_dpcd_write(mhdp,
+			ret = cdns_mhdp_dpcd_write(&mhdp->base,
 						   msg->address + i, buf[i]);
 			if (!ret)
 				continue;
@@ -859,7 +589,7 @@ static ssize_t cdns_mhdp_transfer(struct drm_dp_aux *aux,
 			return ret;
 		}
 	} else {
-		ret = cdns_mhdp_dpcd_read(mhdp, msg->address,
+		ret = cdns_mhdp_dpcd_read(&mhdp->base, msg->address,
 					  msg->buffer, msg->size);
 		if (ret) {
 			dev_err(mhdp->dev,
@@ -887,12 +617,12 @@ static int cdns_mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
 	if (!mhdp->host.scrambler)
 		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32);
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_ENHNCD,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_ENHNCD,
 			    mhdp->sink.enhanced & mhdp->host.enhanced);
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_LANE_EN,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_LANE_EN,
 			    CDNS_DP_LANE_EN_LANES(mhdp->link.num_lanes));
 
 	cdns_mhdp_link_configure(&mhdp->aux, &mhdp->link);
@@ -913,7 +643,7 @@ static int cdns_mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
 		return ret;
 	}
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG,
 			    CDNS_PHY_COMMON_CONFIG |
 			    CDNS_PHY_TRAINING_EN |
 			    CDNS_PHY_TRAINING_TYPE(1) |
@@ -1058,7 +788,7 @@ static bool cdns_mhdp_link_training_channel_eq(struct cdns_mhdp_device *mhdp,
 		CDNS_PHY_TRAINING_TYPE(eq_tps);
 	if (eq_tps != 4)
 		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32);
 
 	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
 			   (eq_tps != 4) ? eq_tps | DP_LINK_SCRAMBLING_DISABLE :
@@ -1322,7 +1052,7 @@ static int cdns_mhdp_link_training(struct cdns_mhdp_device *mhdp,
 			   mhdp->host.scrambler ? 0 :
 			   DP_LINK_SCRAMBLING_DISABLE);
 
-	ret = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &reg32);
+	ret = cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &reg32);
 	if (ret < 0) {
 		dev_err(mhdp->dev,
 			"Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n",
@@ -1333,13 +1063,13 @@ static int cdns_mhdp_link_training(struct cdns_mhdp_device *mhdp,
 	reg32 |= CDNS_DP_NUM_LANES(mhdp->link.num_lanes);
 	reg32 |= CDNS_DP_WR_FAILING_EDGE_VSYNC;
 	reg32 |= CDNS_DP_FRAMER_EN;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, reg32);
 
 	/* Reset PHY config */
 	reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_TYPE(1);
 	if (!mhdp->host.scrambler)
 		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32);
 
 	return 0;
 err:
@@ -1347,7 +1077,7 @@ static int cdns_mhdp_link_training(struct cdns_mhdp_device *mhdp,
 	reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_TYPE(1);
 	if (!mhdp->host.scrambler)
 		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32);
 
 	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
 			   DP_TRAINING_PATTERN_DISABLE);
@@ -1461,7 +1191,7 @@ static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp)
 	mhdp->link.num_lanes = cdns_mhdp_max_num_lanes(mhdp);
 
 	/* Disable framer for link training */
-	err = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
+	err = cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
 	if (err < 0) {
 		dev_err(mhdp->dev,
 			"Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n",
@@ -1470,7 +1200,7 @@ static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp)
 	}
 
 	resp &= ~CDNS_DP_FRAMER_EN;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
 
 	/* Spread AMP if required, enable 8b/10b coding */
 	amp[0] = cdns_mhdp_get_ssc_supported(mhdp) ? DP_SPREAD_AMP_0_5 : 0;
@@ -1834,7 +1564,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 		bnd_hsync2vsync |= CDNS_IP_DET_INTERLACE_FORMAT;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_BND_HSYNC2VSYNC(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_BND_HSYNC2VSYNC(stream_id),
 			    bnd_hsync2vsync);
 
 	hsync2vsync_pol_ctrl = 0;
@@ -1842,10 +1572,10 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 		hsync2vsync_pol_ctrl |= CDNS_H2V_HSYNC_POL_ACTIVE_LOW;
 	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 		hsync2vsync_pol_ctrl |= CDNS_H2V_VSYNC_POL_ACTIVE_LOW;
-	cdns_mhdp_reg_write(mhdp, CDNS_HSYNC2VSYNC_POL_CTRL(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_HSYNC2VSYNC_POL_CTRL(stream_id),
 			    hsync2vsync_pol_ctrl);
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_PXL_REPR(stream_id), pxl_repr);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_PXL_REPR(stream_id), pxl_repr);
 
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 		dp_framer_sp |= CDNS_DP_FRAMER_INTERLACE;
@@ -1853,19 +1583,19 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 		dp_framer_sp |= CDNS_DP_FRAMER_HSYNC_POL_LOW;
 	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 		dp_framer_sp |= CDNS_DP_FRAMER_VSYNC_POL_LOW;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_SP(stream_id), dp_framer_sp);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_SP(stream_id), dp_framer_sp);
 
 	front_porch = mode->crtc_hsync_start - mode->crtc_hdisplay;
 	back_porch = mode->crtc_htotal - mode->crtc_hsync_end;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRONT_BACK_PORCH(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRONT_BACK_PORCH(stream_id),
 			    CDNS_DP_FRONT_PORCH(front_porch) |
 			    CDNS_DP_BACK_PORCH(back_porch));
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_BYTE_COUNT(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_BYTE_COUNT(stream_id),
 			    mode->crtc_hdisplay * bpp / 8);
 
 	msa_h0 = mode->crtc_htotal - mode->crtc_hsync_start;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_0(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_HORIZONTAL_0(stream_id),
 			    CDNS_DP_MSAH0_H_TOTAL(mode->crtc_htotal) |
 			    CDNS_DP_MSAH0_HSYNC_START(msa_h0));
 
@@ -1874,11 +1604,11 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 			   CDNS_DP_MSAH1_HDISP_WIDTH(mode->crtc_hdisplay);
 	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
 		msa_horizontal_1 |= CDNS_DP_MSAH1_HSYNC_POL_LOW;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_1(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_HORIZONTAL_1(stream_id),
 			    msa_horizontal_1);
 
 	msa_v0 = mode->crtc_vtotal - mode->crtc_vsync_start;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_VERTICAL_0(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_VERTICAL_0(stream_id),
 			    CDNS_DP_MSAV0_V_TOTAL(mode->crtc_vtotal) |
 			    CDNS_DP_MSAV0_VSYNC_START(msa_v0));
 
@@ -1887,7 +1617,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 			 CDNS_DP_MSAV1_VDISP_WIDTH(mode->crtc_vdisplay);
 	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 		msa_vertical_1 |= CDNS_DP_MSAV1_VSYNC_POL_LOW;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_VERTICAL_1(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_VERTICAL_1(stream_id),
 			    msa_vertical_1);
 
 	if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
@@ -1899,14 +1629,14 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 	if (pxlfmt == DRM_COLOR_FORMAT_YCBCR420)
 		misc1 = CDNS_DP_TEST_VSC_SDP;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_MISC(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_MISC(stream_id),
 			    misc0 | (misc1 << 8));
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_HORIZONTAL(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_HORIZONTAL(stream_id),
 			    CDNS_DP_H_HSYNC_WIDTH(hsync) |
 			    CDNS_DP_H_H_TOTAL(mode->crtc_hdisplay));
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_VERTICAL_0(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_VERTICAL_0(stream_id),
 			    CDNS_DP_V0_VHEIGHT(mode->crtc_vdisplay) |
 			    CDNS_DP_V0_VSTART(msa_v0));
 
@@ -1915,13 +1645,13 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 	    mode->crtc_vtotal % 2 == 0)
 		dp_vertical_1 |= CDNS_DP_V1_VTOTAL_EVEN;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_VERTICAL_1(stream_id), dp_vertical_1);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_VERTICAL_1(stream_id), dp_vertical_1);
 
-	cdns_mhdp_reg_write_bit(mhdp, CDNS_DP_VB_ID(stream_id), 2, 1,
-				(mode->flags & DRM_MODE_FLAG_INTERLACE) ?
-				CDNS_DP_VB_ID_INTERLACED : 0);
+	cdns_mhdp_dp_reg_write_bit(&mhdp->base, CDNS_DP_VB_ID(stream_id), 2, 1,
+				   (mode->flags & DRM_MODE_FLAG_INTERLACE) ?
+				   CDNS_DP_VB_ID_INTERLACED : 0);
 
-	ret = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &framer);
+	ret = cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &framer);
 	if (ret < 0) {
 		dev_err(mhdp->dev,
 			"Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n",
@@ -1930,7 +1660,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 	}
 	framer |= CDNS_DP_FRAMER_EN;
 	framer &= ~CDNS_DP_NO_VIDEO_MODE;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, framer);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, framer);
 }
 
 static void cdns_mhdp_sst_enable(struct cdns_mhdp_device *mhdp,
@@ -1963,15 +1693,15 @@ static void cdns_mhdp_sst_enable(struct cdns_mhdp_device *mhdp,
 
 	mhdp->stream_id = 0;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_TU,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_TU,
 			    CDNS_DP_FRAMER_TU_VS(vs) |
 			    CDNS_DP_FRAMER_TU_SIZE(tu_size) |
 			    CDNS_DP_FRAMER_TU_CNT_RST_EN);
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_LINE_THRESH(0),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_LINE_THRESH(0),
 			    line_thresh & GENMASK(5, 0));
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_STREAM_CONFIG_2(0),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_STREAM_CONFIG_2(0),
 			    CDNS_DP_SC2_TU_VS_DIFF((tu_size - vs > 3) ?
 						   0 : tu_size - vs));
 
@@ -2006,13 +1736,13 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,
 		mhdp->info->ops->enable(mhdp);
 
 	/* Enable VIF clock for stream 0 */
-	ret = cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp);
+	ret = cdns_mhdp_reg_read(&mhdp->base, CDNS_DPTX_CAR, &resp);
 	if (ret < 0) {
 		dev_err(mhdp->dev, "Failed to read CDNS_DPTX_CAR %d\n", ret);
 		goto out;
 	}
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_CAR,
 			    resp | CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN);
 
 	connector = drm_atomic_get_new_connector_for_encoder(state,
@@ -2083,16 +1813,16 @@ static void cdns_mhdp_atomic_disable(struct drm_bridge *bridge,
 		cdns_mhdp_hdcp_disable(mhdp);
 
 	mhdp->bridge_enabled = false;
-	cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
+	cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
 	resp &= ~CDNS_DP_FRAMER_EN;
 	resp |= CDNS_DP_NO_VIDEO_MODE;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
 
 	cdns_mhdp_link_down(mhdp);
 
 	/* Disable VIF clock for stream 0 */
-	cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp);
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR,
+	cdns_mhdp_reg_read(&mhdp->base, CDNS_DPTX_CAR, &resp);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_CAR,
 			    resp & ~(CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN));
 
 	if (mhdp->info && mhdp->info->ops && mhdp->info->ops->disable)
@@ -2471,7 +2201,6 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
 
 	mhdp->clk = clk;
 	mhdp->dev = dev;
-	mutex_init(&mhdp->mbox_mutex);
 	mutex_init(&mhdp->link_mutex);
 	spin_lock_init(&mhdp->start_lock);
 
@@ -2502,6 +2231,10 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, mhdp);
 
+	/* init base struct for access mailbox  */
+	mhdp->base.dev = mhdp->dev;
+	mhdp->base.regs = mhdp->regs;
+
 	mhdp->info = of_device_get_match_data(dev);
 
 	clk_prepare_enable(clk);
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
index bad2fc0c73066..d209c7b3bbfab 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
@@ -15,6 +15,7 @@
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 
+#include <drm/bridge/cdns-mhdp-helper.h>
 #include <drm/display/drm_dp_helper.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_connector.h>
@@ -27,10 +28,6 @@ struct phy;
 #define CDNS_APB_CTRL				0x00000
 #define CDNS_CPU_STALL				BIT(3)
 
-#define CDNS_MAILBOX_FULL			0x00008
-#define CDNS_MAILBOX_EMPTY			0x0000c
-#define CDNS_MAILBOX_TX_DATA			0x00010
-#define CDNS_MAILBOX_RX_DATA			0x00014
 #define CDNS_KEEP_ALIVE				0x00018
 #define CDNS_KEEP_ALIVE_MASK			GENMASK(7, 0)
 
@@ -198,45 +195,10 @@ struct phy;
 #define CDNS_DP_BYTE_COUNT(s)			(CDNS_DPTX_STREAM(s) + 0x7c)
 #define CDNS_DP_BYTE_COUNT_BYTES_IN_CHUNK_SHIFT	16
 
-/* mailbox */
-#define MAILBOX_RETRY_US			1000
-#define MAILBOX_TIMEOUT_US			2000000
-
-#define MB_OPCODE_ID				0
-#define MB_MODULE_ID				1
-#define MB_SIZE_MSB_ID				2
-#define MB_SIZE_LSB_ID				3
-#define MB_DATA_ID				4
-
-#define MB_MODULE_ID_DP_TX			0x01
-#define MB_MODULE_ID_HDCP_TX			0x07
-#define MB_MODULE_ID_HDCP_RX			0x08
-#define MB_MODULE_ID_HDCP_GENERAL		0x09
-#define MB_MODULE_ID_GENERAL			0x0a
-
-/* firmware and opcodes */
+/* firmware */
 #define FW_NAME					"cadence/mhdp8546.bin"
 #define CDNS_MHDP_IMEM				0x10000
 
-#define GENERAL_MAIN_CONTROL			0x01
-#define GENERAL_TEST_ECHO			0x02
-#define GENERAL_BUS_SETTINGS			0x03
-#define GENERAL_TEST_ACCESS			0x04
-#define GENERAL_REGISTER_READ			0x07
-
-#define DPTX_SET_POWER_MNG			0x00
-#define DPTX_GET_EDID				0x02
-#define DPTX_READ_DPCD				0x03
-#define DPTX_WRITE_DPCD				0x04
-#define DPTX_ENABLE_EVENT			0x05
-#define DPTX_WRITE_REGISTER			0x06
-#define DPTX_READ_REGISTER			0x07
-#define DPTX_WRITE_FIELD			0x08
-#define DPTX_READ_EVENT				0x0a
-#define DPTX_GET_LAST_AUX_STAUS			0x0e
-#define DPTX_HPD_STATE				0x11
-#define DPTX_ADJUST_LT				0x12
-
 #define FW_STANDBY				0
 #define FW_ACTIVE				1
 
@@ -352,6 +314,8 @@ struct cdns_mhdp_hdcp {
 };
 
 struct cdns_mhdp_device {
+	struct cdns_mhdp_base base;
+
 	void __iomem *regs;
 	void __iomem *sapb_regs;
 	void __iomem *j721e_regs;
@@ -362,9 +326,6 @@ struct cdns_mhdp_device {
 
 	const struct cdns_mhdp_platform_info *info;
 
-	/* This is to protect mailbox communications with the firmware */
-	struct mutex mbox_mutex;
-
 	/*
 	 * "link_mutex" protects the access to all the link parameters
 	 * including the link training process. Link training will be
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c
index 5e3b8edcf7948..21164ff78be23 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c
@@ -19,7 +19,7 @@ static int cdns_mhdp_secure_mailbox_read(struct cdns_mhdp_device *mhdp)
 {
 	int ret, empty;
 
-	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
+	WARN_ON(!mutex_is_locked(&mhdp_mailbox_mutex));
 
 	ret = readx_poll_timeout(readl, mhdp->sapb_regs + CDNS_MAILBOX_EMPTY,
 				 empty, !empty, MAILBOX_RETRY_US,
@@ -35,7 +35,7 @@ static int cdns_mhdp_secure_mailbox_write(struct cdns_mhdp_device *mhdp,
 {
 	int ret, full;
 
-	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
+	WARN_ON(!mutex_is_locked(&mhdp_mailbox_mutex));
 
 	ret = readx_poll_timeout(readl, mhdp->sapb_regs + CDNS_MAILBOX_FULL,
 				 full, !full, MAILBOX_RETRY_US,
@@ -131,7 +131,7 @@ static int cdns_mhdp_hdcp_get_status(struct cdns_mhdp_device *mhdp,
 	u8 hdcp_status[HDCP_STATUS_SIZE];
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
+	mutex_lock(&mhdp_mailbox_mutex);
 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
 					    HDCP_TRAN_STATUS_CHANGE, 0, NULL);
 	if (ret)
@@ -151,7 +151,7 @@ static int cdns_mhdp_hdcp_get_status(struct cdns_mhdp_device *mhdp,
 	*hdcp_port_status = ((u16)(hdcp_status[0] << 8) | hdcp_status[1]);
 
 err_get_hdcp_status:
-	mutex_unlock(&mhdp->mbox_mutex);
+	mutex_unlock(&mhdp_mailbox_mutex);
 
 	return ret;
 }
@@ -172,11 +172,11 @@ static int cdns_mhdp_hdcp_rx_id_valid_response(struct cdns_mhdp_device *mhdp,
 {
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
+	mutex_lock(&mhdp_mailbox_mutex);
 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
 					    HDCP_TRAN_RESPOND_RECEIVER_ID_VALID,
 					    1, &valid);
-	mutex_unlock(&mhdp->mbox_mutex);
+	mutex_unlock(&mhdp_mailbox_mutex);
 
 	return ret;
 }
@@ -188,7 +188,7 @@ static int cdns_mhdp_hdcp_rx_id_valid(struct cdns_mhdp_device *mhdp,
 	u8 status;
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
+	mutex_lock(&mhdp_mailbox_mutex);
 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
 					    HDCP_TRAN_IS_REC_ID_VALID, 0, NULL);
 	if (ret)
@@ -209,7 +209,7 @@ static int cdns_mhdp_hdcp_rx_id_valid(struct cdns_mhdp_device *mhdp,
 	ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, hdcp_rx_id, 5 * *recv_num);
 
 err_rx_id_valid:
-	mutex_unlock(&mhdp->mbox_mutex);
+	mutex_unlock(&mhdp_mailbox_mutex);
 
 	return ret;
 }
@@ -219,10 +219,10 @@ static int cdns_mhdp_hdcp_km_stored_resp(struct cdns_mhdp_device *mhdp,
 {
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
+	mutex_lock(&mhdp_mailbox_mutex);
 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
 					    HDCP2X_TX_RESPOND_KM, size, km);
-	mutex_unlock(&mhdp->mbox_mutex);
+	mutex_unlock(&mhdp_mailbox_mutex);
 
 	return ret;
 }
@@ -232,7 +232,7 @@ static int cdns_mhdp_hdcp_tx_is_km_stored(struct cdns_mhdp_device *mhdp,
 {
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
+	mutex_lock(&mhdp_mailbox_mutex);
 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
 					    HDCP2X_TX_IS_KM_STORED, 0, NULL);
 	if (ret)
@@ -246,7 +246,7 @@ static int cdns_mhdp_hdcp_tx_is_km_stored(struct cdns_mhdp_device *mhdp,
 
 	ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, resp, size);
 err_is_km_stored:
-	mutex_unlock(&mhdp->mbox_mutex);
+	mutex_unlock(&mhdp_mailbox_mutex);
 
 	return ret;
 }
@@ -256,10 +256,10 @@ static int cdns_mhdp_hdcp_tx_config(struct cdns_mhdp_device *mhdp,
 {
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
+	mutex_lock(&mhdp_mailbox_mutex);
 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
 					    HDCP_TRAN_CONFIGURATION, 1, &hdcp_cfg);
-	mutex_unlock(&mhdp->mbox_mutex);
+	mutex_unlock(&mhdp_mailbox_mutex);
 
 	return ret;
 }
@@ -504,11 +504,11 @@ int cdns_mhdp_hdcp_set_lc(struct cdns_mhdp_device *mhdp, u8 *val)
 {
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
+	mutex_lock(&mhdp_mailbox_mutex);
 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_GENERAL,
 					    HDCP_GENERAL_SET_LC_128,
 					    16, val);
-	mutex_unlock(&mhdp->mbox_mutex);
+	mutex_unlock(&mhdp_mailbox_mutex);
 
 	return ret;
 }
@@ -519,11 +519,11 @@ cdns_mhdp_hdcp_set_public_key_param(struct cdns_mhdp_device *mhdp,
 {
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
+	mutex_lock(&mhdp_mailbox_mutex);
 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
 					    HDCP2X_TX_SET_PUBLIC_KEY_PARAMS,
 					    sizeof(*val), (u8 *)val);
-	mutex_unlock(&mhdp->mbox_mutex);
+	mutex_unlock(&mhdp_mailbox_mutex);
 
 	return ret;
 }
diff --git a/include/drm/bridge/cdns-mhdp-helper.h b/include/drm/bridge/cdns-mhdp-helper.h
new file mode 100644
index 0000000000000..a0727cbbace55
--- /dev/null
+++ b/include/drm/bridge/cdns-mhdp-helper.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023-2024 NXP Semiconductor, Inc.
+ */
+#ifndef __CDNS_MHDP_HELPER_H__
+#define __CDNS_MHDP_HELPER_H__
+
+#include <asm/unaligned.h>
+#include <linux/iopoll.h>
+
+/* mailbox regs offset */
+#define CDNS_MAILBOX_FULL			0x00008
+#define CDNS_MAILBOX_EMPTY			0x0000c
+#define CDNS_MAILBOX_TX_DATA			0x00010
+#define CDNS_MAILBOX_RX_DATA			0x00014
+
+#define MAILBOX_RETRY_US			1000
+#define MAILBOX_TIMEOUT_US			2000000
+
+/* Module ID Code */
+#define MB_MODULE_ID_DP_TX			0x01
+#define MB_MODULE_ID_HDMI_TX			0x03
+#define MB_MODULE_ID_HDCP_TX			0x07
+#define MB_MODULE_ID_HDCP_RX			0x08
+#define MB_MODULE_ID_HDCP_GENERAL		0x09
+#define MB_MODULE_ID_GENERAL			0x0A
+
+/* General Commands */
+#define GENERAL_MAIN_CONTROL			0x01
+#define GENERAL_TEST_ECHO			0x02
+#define GENERAL_BUS_SETTINGS			0x03
+#define GENERAL_TEST_ACCESS			0x04
+#define GENERAL_REGISTER_WRITE			0x05
+#define GENERAL_WRITE_FIELD			0x06
+#define GENERAL_REGISTER_READ			0x07
+#define GENERAL_GET_HPD_STATE			0x11
+
+/* DPTX Commands */
+#define DPTX_SET_POWER_MNG			0x00
+#define DPTX_SET_HOST_CAPABILITIES		0x01
+#define DPTX_GET_EDID				0x02
+#define DPTX_READ_DPCD				0x03
+#define DPTX_WRITE_DPCD				0x04
+#define DPTX_ENABLE_EVENT			0x05
+#define DPTX_WRITE_REGISTER			0x06
+#define DPTX_READ_REGISTER			0x07
+#define DPTX_WRITE_FIELD			0x08
+#define DPTX_TRAINING_CONTROL			0x09
+#define DPTX_READ_EVENT				0x0a
+#define DPTX_READ_LINK_STAT			0x0b
+#define DPTX_SET_VIDEO				0x0c
+#define DPTX_SET_AUDIO				0x0d
+#define DPTX_GET_LAST_AUX_STAUS			0x0e
+#define DPTX_SET_LINK_BREAK_POINT		0x0f
+#define DPTX_FORCE_LANES			0x10
+#define DPTX_HPD_STATE				0x11
+#define DPTX_ADJUST_LT				0x12
+
+/* HDMI TX Commands */
+#define HDMI_TX_READ				0x00
+#define HDMI_TX_WRITE				0x01
+#define HDMI_TX_UPDATE_READ			0x02
+#define HDMI_TX_EDID				0x03
+#define HDMI_TX_EVENTS				0x04
+#define HDMI_TX_HPD_STATUS			0x05
+
+extern struct mutex mhdp_mailbox_mutex;
+
+struct cdns_mhdp_base {
+	struct device *dev;
+	void __iomem *regs;
+};
+
+/* Mailbox helper functions */
+int cdns_mhdp_mailbox_recv_data(struct cdns_mhdp_base *base,
+				u8 *buff, u16 buff_size);
+int cdns_mhdp_mailbox_recv_header(struct cdns_mhdp_base *base,
+				  u8 module_id, u8 opcode, u16 req_size);
+int cdns_mhdp_mailbox_send(struct cdns_mhdp_base *base, u8 module_id,
+			   u8 opcode, u16 size, u8 *message);
+
+/* General commands helper functions */
+int cdns_mhdp_reg_read(struct cdns_mhdp_base *base, u32 addr, u32 *value);
+int cdns_mhdp_reg_write(struct cdns_mhdp_base *base, u32 addr, u32 val);
+
+/* DPTX commands helper functions */
+int cdns_mhdp_dp_reg_write(struct cdns_mhdp_base *base, u16 addr, u32 val);
+int cdns_mhdp_dp_reg_write_bit(struct cdns_mhdp_base *base, u16 addr,
+			       u8 start_bit, u8 bits_no, u32 val);
+int cdns_mhdp_dpcd_read(struct cdns_mhdp_base *base,
+			u32 addr, u8 *data, u16 len);
+int cdns_mhdp_dpcd_write(struct cdns_mhdp_base *base, u32 addr, u8 value);
+
+#endif /* __CDNS_MHDP_HELPER_H__ */
-- 
2.34.1



From Sandor.yu at nxp.com  Tue Sep 24 00:36:47 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 24 Sep 2024 15:36:47 +0800
Subject: [PATCH v17 2/8] phy: Add HDMI configuration options
In-Reply-To: <cover.1727159906.git.Sandor.yu@nxp.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <c9c0c1c2e156731a46ffe0cfa3529e6f0e6a1e5f.1727159906.git.Sandor.yu@nxp.com>

Allow HDMI PHYs to be configured through the generic
functions through a custom structure added to the generic union.

The parameters added here are based on HDMI PHY
implementation practices.  The current set of parameters
should cover the potential users.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
v16->v17:
- remove headfile hdmi.h
- add 2024 year to copyright
- Add r-b tag.

v15->v16:
- Remove pixel_clk_rate, bpc and color_space fields from struct
  phy_configure_opts_hdmi, they were replaced by unsigned long long tmds_char_rate.
- Remove r-b and a-c tags because this patch have important change.

v9->v15:
 *No change.

 include/linux/phy/phy-hdmi.h | 19 +++++++++++++++++++
 include/linux/phy/phy.h      |  7 ++++++-
 2 files changed, 25 insertions(+), 1 deletion(-)
 create mode 100644 include/linux/phy/phy-hdmi.h

diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
new file mode 100644
index 0000000000000..6a696922bc7f2
--- /dev/null
+++ b/include/linux/phy/phy-hdmi.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2022,2024 NXP
+ */
+
+#ifndef __PHY_HDMI_H_
+#define __PHY_HDMI_H_
+
+/**
+ * struct phy_configure_opts_hdmi - HDMI configuration set
+ * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
+ *
+ * This structure is used to represent the configuration state of a HDMI phy.
+ */
+struct phy_configure_opts_hdmi {
+	unsigned long long tmds_char_rate;
+};
+
+#endif /* __PHY_HDMI_H_ */
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 03cd5bae92d3f..4ac486b101fe4 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -17,6 +17,7 @@
 #include <linux/regulator/consumer.h>
 
 #include <linux/phy/phy-dp.h>
+#include <linux/phy/phy-hdmi.h>
 #include <linux/phy/phy-lvds.h>
 #include <linux/phy/phy-mipi-dphy.h>
 
@@ -42,7 +43,8 @@ enum phy_mode {
 	PHY_MODE_MIPI_DPHY,
 	PHY_MODE_SATA,
 	PHY_MODE_LVDS,
-	PHY_MODE_DP
+	PHY_MODE_DP,
+	PHY_MODE_HDMI,
 };
 
 enum phy_media {
@@ -60,11 +62,14 @@ enum phy_media {
  *		the DisplayPort protocol.
  * @lvds:	Configuration set applicable for phys supporting
  *		the LVDS phy mode.
+ * @hdmi:	Configuration set applicable for phys supporting
+ *		the HDMI phy mode.
  */
 union phy_configure_opts {
 	struct phy_configure_opts_mipi_dphy	mipi_dphy;
 	struct phy_configure_opts_dp		dp;
 	struct phy_configure_opts_lvds		lvds;
+	struct phy_configure_opts_hdmi		hdmi;
 };
 
 /**
-- 
2.34.1



From Sandor.yu at nxp.com  Tue Sep 24 00:36:48 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 24 Sep 2024 15:36:48 +0800
Subject: [PATCH v17 3/8] dt-bindings: display: bridge: Add Cadence MHDP8501
In-Reply-To: <cover.1727159906.git.Sandor.yu@nxp.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <b2e1d26f964a03163ec7a1ba6ac8d7c88d6cb111.1727159906.git.Sandor.yu@nxp.com>

Add bindings for Cadence MHDP8501 DisplayPort/HDMI bridge.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
v16->v17:
- Add lane-mapping property

v9->v16:
 *No change

.../display/bridge/cdns,mhdp8501.yaml         | 109 ++++++++++++++++++
 1 file changed, 109 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml

diff --git a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
new file mode 100644
index 0000000000000..3f79f328c7425
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/cdns,mhdp8501.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cadence MHDP8501 DP/HDMI bridge
+
+maintainers:
+  - Sandor Yu <Sandor.yu at nxp.com>
+
+description:
+  Cadence MHDP8501 DisplayPort/HDMI interface.
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8mq-mhdp8501
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: MHDP8501 DP/HDMI APB clock.
+
+  phys:
+    maxItems: 1
+    description:
+      phandle to the DP/HDMI PHY
+
+  interrupts:
+    items:
+      - description: Hotplug cable plugin.
+      - description: Hotplug cable plugout.
+
+  interrupt-names:
+    items:
+      - const: plug_in
+      - const: plug_out
+
+  lane-mapping:
+    description: lane mapping for HDMI or DisplayPort interface.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Input port from display controller output.
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Output port to DisplayPort or HDMI connector.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+  - interrupt-names
+  - phys
+  - lane-mapping
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    mhdp: display-bridge at 32c00000 {
+        compatible = "fsl,imx8mq-mhdp8501";
+        reg = <0x32c00000 0x100000>;
+        interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "plug_in", "plug_out";
+        clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+        phys = <&mdhp_phy>;
+        lane-mapping = <0xe4>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port at 0 {
+                reg = <0>;
+
+                mhdp_in: endpoint {
+                    remote-endpoint = <&dcss_out>;
+                };
+            };
+
+            port at 1 {
+                reg = <1>;
+
+                mhdp_out: endpoint {
+                    remote-endpoint = <&dp_connector>;
+                };
+            };
+        };
+    };
-- 
2.34.1



From Sandor.yu at nxp.com  Tue Sep 24 00:36:49 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 24 Sep 2024 15:36:49 +0800
Subject: [PATCH v17 4/8] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <cover.1727159906.git.Sandor.yu@nxp.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <8bdf573bfd7e3feb45d7ccb53765a978a685ce2d.1727159906.git.Sandor.yu@nxp.com>

Add a new DRM DisplayPort and HDMI bridge driver for Candence MHDP8501
used in i.MX8MQ SOC. MHDP8501 could support HDMI or DisplayPort
standards according embedded Firmware running in the uCPU.

For iMX8MQ SOC, the DisplayPort/HDMI FW was loaded and activated by
SOC's ROM code. Bootload binary included respective specific firmware
is required.

Driver will check display connector type and
then load the corresponding driver.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
v16->v17:
- Reset the HDMI/DP link when an HPD (Hot Plug Detect) event is detected
- Move the HDMI protocol settings from hdmi_ctrl_init() to a new function
  cdns_hdmi_set_hdmi_mode_type(), to align with the introduced link reset functionality.
- Implement logic to check the type of HDMI sink.
  If the sink is not a hdmi display, set the default mode to DVI.
- Implement hdmi_reset_infoframe function
- Reorder certain bit definitions in the header file to follow a descending order.
- Add "lane-mapping" property for both HDMI and DP, remove platform data from driver.
  lane-mapping should be setting in dts according different board layout.
- Remove variable mode in struct cdns_mhdp8501_device, video mode could get from struct drm_crtc_state
- Remove variable char_rate in  struct cdns_mhdp8501_device, it could get from struct struct drm_connector_state.hdmi
- Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex
- Remove mutext protect for phy api access functions.

v15->v16:
- rebase the patchset sits on top Dmitry's
   'make use of the HDMI connector infrastructure' patchset ([2]).
- Add DRM_BRIDGE_OP_HDMI flags for HDMI driver,
- Introduce the hdmi info frame helper functions, added hdmi_clear_infoframe(),
  hdmi_write_infoframe() and hdmi_tmds_char_rate_valid().
- mode_fixup() was replaced by atomic_check().
- Fix video mode 4Kp30 did not work on some displays that support
  LTE_340Mcsc_scramble.
- updated for tmds_char_rate added in patch #2. 

v13->v14:
- Rebase to next-20240219, replace get_edid function by edid_read
  function.

v12->v13:
- Explicitly include linux/platform_device.h for cdns-mhdp8501-core.c
- Fix build warning
- Order bit bpc and color_space in descending shit. 

v11->v12:
- Replace DRM_INFO with dev_info or dev_warn.
- Replace DRM_ERROR with dev_err.
- Return ret when cdns_mhdp_dpcd_read failed in function cdns_dp_aux_transferi().
- Remove unused parmeter in function cdns_dp_get_msa_misc
  and use two separate variables for color space and bpc.
- Add year 2024 to copyright.

 drivers/gpu/drm/bridge/cadence/Kconfig        |  16 +
 drivers/gpu/drm/bridge/cadence/Makefile       |   2 +
 .../drm/bridge/cadence/cdns-mhdp8501-core.c   | 323 ++++++++
 .../drm/bridge/cadence/cdns-mhdp8501-core.h   | 359 +++++++++
 .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c | 737 ++++++++++++++++++
 .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   | 692 ++++++++++++++++
 6 files changed, 2129 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c

diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig
index e0973339e9e33..45848e741f5f4 100644
--- a/drivers/gpu/drm/bridge/cadence/Kconfig
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -51,3 +51,19 @@ config DRM_CDNS_MHDP8546_J721E
 	  initializes the J721E Display Port and sets up the
 	  clock and data muxes.
 endif
+
+config DRM_CDNS_MHDP8501
+	tristate "Cadence MHDP8501 DP/HDMI bridge"
+	select DRM_KMS_HELPER
+	select DRM_PANEL_BRIDGE
+	select DRM_DISPLAY_DP_HELPER
+	select DRM_DISPLAY_HELPER
+	select CDNS_MHDP_HELPER
+	select DRM_CDNS_AUDIO
+	depends on OF
+	help
+	  Support Cadence MHDP8501 DisplayPort/HDMI bridge.
+	  Cadence MHDP8501 support one or more protocols,
+	  including DisplayPort and HDMI.
+	  To use the DP and HDMI drivers, their respective
+	  specific firmware is required.
diff --git a/drivers/gpu/drm/bridge/cadence/Makefile b/drivers/gpu/drm/bridge/cadence/Makefile
index 087dc074820d7..02c1a9f3cf6fc 100644
--- a/drivers/gpu/drm/bridge/cadence/Makefile
+++ b/drivers/gpu/drm/bridge/cadence/Makefile
@@ -6,3 +6,5 @@ obj-$(CONFIG_CDNS_MHDP_HELPER) += cdns-mhdp-helper.o
 obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
 cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
 cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
+obj-$(CONFIG_DRM_CDNS_MHDP8501) += cdns-mhdp8501.o
+cdns-mhdp8501-y := cdns-mhdp8501-core.o cdns-mhdp8501-dp.o cdns-mhdp8501-hdmi.o
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
new file mode 100644
index 0000000000000..06256dbf99e7e
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
@@ -0,0 +1,323 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence Display Port Interface (DP) driver
+ *
+ * Copyright (C) 2023-2024 NXP Semiconductor, Inc.
+ *
+ */
+#include <drm/drm_of.h>
+#include <drm/drm_print.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+
+#include "cdns-mhdp8501-core.h"
+
+static int cdns_mhdp8501_read_hpd(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 status;
+	int ret;
+
+	mutex_lock(&mhdp_mailbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_GENERAL,
+				     GENERAL_GET_HPD_STATE, 0, NULL);
+	if (ret)
+		goto err_get_hpd;
+
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_GENERAL,
+					    GENERAL_GET_HPD_STATE,
+					    sizeof(status));
+	if (ret)
+		goto err_get_hpd;
+
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &status, sizeof(status));
+	if (ret)
+		goto err_get_hpd;
+
+	mutex_unlock(&mhdp_mailbox_mutex);
+
+	return status;
+
+err_get_hpd:
+	dev_err(mhdp->dev, "read hpd  failed: %d\n", ret);
+	mutex_unlock(&mhdp_mailbox_mutex);
+
+	return ret;
+}
+
+enum drm_connector_status cdns_mhdp8501_detect(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 hpd = 0xf;
+
+	hpd = cdns_mhdp8501_read_hpd(mhdp);
+	if (hpd == 1)
+		return connector_status_connected;
+	else if (hpd == 0)
+		return connector_status_disconnected;
+
+	dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n", hpd);
+	return connector_status_unknown;
+}
+
+static void hotplug_work_func(struct work_struct *work)
+{
+	struct cdns_mhdp8501_device *mhdp = container_of(work,
+						     struct cdns_mhdp8501_device,
+						     hotplug_work.work);
+	enum drm_connector_status status = cdns_mhdp8501_detect(mhdp);
+
+	drm_bridge_hpd_notify(&mhdp->bridge, status);
+
+	if (status == connector_status_connected) {
+		/* Cable connected  */
+		DRM_INFO("HDMI/DP Cable Plug In\n");
+		enable_irq(mhdp->irq[IRQ_OUT]);
+
+		/* Reset HDMI/DP link with sink */
+		if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA)
+			cdns_hdmi_reset_link(mhdp);
+		else
+			cdns_dp_check_link_state(mhdp);
+
+	} else if (status == connector_status_disconnected) {
+		/* Cable Disconnected  */
+		DRM_INFO("HDMI/DP Cable Plug Out\n");
+		enable_irq(mhdp->irq[IRQ_IN]);
+	}
+}
+
+static irqreturn_t cdns_mhdp8501_irq_thread(int irq, void *data)
+{
+	struct cdns_mhdp8501_device *mhdp = data;
+
+	disable_irq_nosync(irq);
+
+	mod_delayed_work(system_wq, &mhdp->hotplug_work,
+			 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
+
+	return IRQ_HANDLED;
+}
+
+static int cdns_mhdp8501_dt_parse(struct cdns_mhdp8501_device *mhdp,
+				  struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *remote;
+
+	remote = of_graph_get_remote_node(np, 1, 0);
+	if (!remote) {
+		dev_err(dev, "fail to get remote node\n");
+		of_node_put(remote);
+		return -EINVAL;
+	}
+
+	/* get connector type */
+	if (of_device_is_compatible(remote, "hdmi-connector")) {
+		mhdp->connector_type = DRM_MODE_CONNECTOR_HDMIA;
+
+	} else if (of_device_is_compatible(remote, "dp-connector")) {
+		mhdp->connector_type = DRM_MODE_CONNECTOR_DisplayPort;
+
+	} else {
+		dev_err(dev, "Unknown connector type\n");
+		of_node_put(remote);
+		return -EINVAL;
+	}
+
+	of_node_put(remote);
+
+	if (of_property_read_u32(np, "lane-mapping", &mhdp->lane_mapping)) {
+		dev_warn(dev, "Failed to get lane_mapping - using default\n");
+		mhdp->lane_mapping = LANE_MAPPING_FLIPPED;
+	}
+
+	return true;
+}
+
+static void cdns_mhdp8501_add_bridge(struct cdns_mhdp8501_device *mhdp)
+{
+	mhdp->bridge.type = mhdp->connector_type;
+	mhdp->bridge.driver_private = mhdp;
+	mhdp->bridge.of_node = mhdp->dev->of_node;
+	mhdp->bridge.vendor = "NXP";
+	mhdp->bridge.product = "i.MX8";
+	mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
+			   DRM_BRIDGE_OP_HPD;
+
+	if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA) {
+		mhdp->bridge.funcs = &cdns_hdmi_bridge_funcs;
+		mhdp->bridge.ops |= DRM_BRIDGE_OP_HDMI;
+	} else if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+		mhdp->bridge.funcs = &cdns_dp_bridge_funcs;
+	} else {
+		dev_err(mhdp->dev, "Unsupported connector type!\n");
+		return;
+	}
+
+	drm_bridge_add(&mhdp->bridge);
+}
+
+static int cdns_mhdp8501_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct cdns_mhdp8501_device *mhdp;
+	struct resource *res;
+	enum phy_mode phy_mode;
+	u32 reg;
+	int ret;
+
+	mhdp = devm_kzalloc(dev, sizeof(*mhdp), GFP_KERNEL);
+	if (!mhdp)
+		return -ENOMEM;
+
+	mutex_init(&mhdp_mailbox_mutex);
+	mhdp->dev = dev;
+
+	INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	mhdp->regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(mhdp->regs))
+		return PTR_ERR(mhdp->regs);
+
+	ret = cdns_mhdp8501_dt_parse(mhdp, pdev);
+	if (ret < 0)
+		return -EINVAL;
+
+	mhdp->phy = devm_of_phy_get_by_index(dev, pdev->dev.of_node, 0);
+	if (IS_ERR(mhdp->phy))
+		return dev_err_probe(dev, PTR_ERR(mhdp->phy), "no PHY configured\n");
+
+	mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
+	if (mhdp->irq[IRQ_IN] < 0)
+		return dev_err_probe(dev, mhdp->irq[IRQ_IN], "No plug_in irq number\n");
+
+	mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
+	if (mhdp->irq[IRQ_OUT] < 0)
+		return dev_err_probe(dev, mhdp->irq[IRQ_OUT], "No plug_out irq number\n");
+
+	irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN);
+	ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN],
+					NULL, cdns_mhdp8501_irq_thread,
+					IRQF_ONESHOT, dev_name(dev), mhdp);
+	if (ret < 0) {
+		dev_err(dev, "can't claim irq %d\n", mhdp->irq[IRQ_IN]);
+		return -EINVAL;
+	}
+
+	irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN);
+	ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT],
+					NULL, cdns_mhdp8501_irq_thread,
+					IRQF_ONESHOT, dev_name(dev), mhdp);
+	if (ret < 0) {
+		dev_err(dev, "can't claim irq %d\n", mhdp->irq[IRQ_OUT]);
+		return -EINVAL;
+	}
+
+	/* cdns_mhdp8501_dt_parse() ensures connector_type is valid */
+	if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
+		phy_mode = PHY_MODE_DP;
+	else if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA)
+		phy_mode = PHY_MODE_HDMI;
+
+	dev_set_drvdata(dev, mhdp);
+
+	/* init base struct for access mhdp mailbox */
+	mhdp->base.dev = mhdp->dev;
+	mhdp->base.regs = mhdp->regs;
+
+	if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+		drm_dp_aux_init(&mhdp->dp.aux);
+		mhdp->dp.aux.name = "mhdp8501_dp_aux";
+		mhdp->dp.aux.dev = dev;
+		mhdp->dp.aux.transfer = cdns_dp_aux_transfer;
+	}
+
+	/* Enable APB clock */
+	mhdp->apb_clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(mhdp->apb_clk))
+		return dev_err_probe(dev, PTR_ERR(mhdp->apb_clk),
+				     "couldn't get apb clk\n");
+
+	clk_prepare_enable(mhdp->apb_clk);
+
+	/*
+	 * Wait for the KEEP_ALIVE "message" on the first 8 bits.
+	 * Updated each sched "tick" (~2ms)
+	 */
+	ret = readl_poll_timeout(mhdp->regs + KEEP_ALIVE, reg,
+				 reg & CDNS_KEEP_ALIVE_MASK, 500,
+				 CDNS_KEEP_ALIVE_TIMEOUT);
+	if (ret) {
+		dev_err(dev, "device didn't give any life sign: reg %d\n", reg);
+		goto clk_disable;
+	}
+
+	ret = phy_init(mhdp->phy);
+	if (ret) {
+		dev_err(dev, "Failed to initialize PHY: %d\n", ret);
+		goto clk_disable;
+	}
+
+	ret = phy_set_mode(mhdp->phy, phy_mode);
+	if (ret) {
+		dev_err(dev, "Failed to configure PHY: %d\n", ret);
+		goto clk_disable;
+	}
+
+	/* Enable cable hotplug detect */
+	if (cdns_mhdp8501_read_hpd(mhdp))
+		enable_irq(mhdp->irq[IRQ_OUT]);
+	else
+		enable_irq(mhdp->irq[IRQ_IN]);
+
+	cdns_mhdp8501_add_bridge(mhdp);
+
+	return 0;
+
+clk_disable:
+	clk_disable_unprepare(mhdp->apb_clk);
+
+	return -EINVAL;
+}
+
+static void cdns_mhdp8501_remove(struct platform_device *pdev)
+{
+	struct cdns_mhdp8501_device *mhdp = platform_get_drvdata(pdev);
+
+	if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
+		cdns_dp_aux_destroy(mhdp);
+
+	drm_bridge_remove(&mhdp->bridge);
+	clk_disable_unprepare(mhdp->apb_clk);
+}
+
+static const struct of_device_id cdns_mhdp8501_dt_ids[] = {
+	{ .compatible = "fsl,imx8mq-mhdp8501",
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, cdns_mhdp8501_dt_ids);
+
+static struct platform_driver cdns_mhdp8501_driver = {
+	.probe = cdns_mhdp8501_probe,
+	.remove = cdns_mhdp8501_remove,
+	.driver = {
+		.name = "cdns-mhdp8501",
+		.of_match_table = cdns_mhdp8501_dt_ids,
+	},
+};
+
+module_platform_driver(cdns_mhdp8501_driver);
+
+MODULE_AUTHOR("Sandor Yu <sandor.yu at nxp.com>");
+MODULE_DESCRIPTION("Cadence MHDP8501 bridge driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
new file mode 100644
index 0000000000000..daa72470f9fec
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
@@ -0,0 +1,359 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Cadence MHDP 8501 Common head file
+ *
+ * Copyright (C) 2019-2024 NXP Semiconductor, Inc.
+ *
+ */
+
+#ifndef _CDNS_MHDP8501_CORE_H_
+#define _CDNS_MHDP8501_CORE_H_
+
+#include <drm/bridge/cdns-mhdp-helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_connector.h>
+#include <drm/display/drm_dp_helper.h>
+#include <linux/bitops.h>
+
+#define ADDR_IMEM			0x10000
+#define ADDR_DMEM			0x20000
+
+/* APB CFG addr */
+#define APB_CTRL			0
+#define XT_INT_CTRL			0x04
+#define MAILBOX_FULL_ADDR		0x08
+#define MAILBOX_EMPTY_ADDR		0x0c
+#define MAILBOX0_WR_DATA		0x10
+#define MAILBOX0_RD_DATA		0x14
+#define KEEP_ALIVE			0x18
+#define VER_L				0x1c
+#define VER_H				0x20
+#define VER_LIB_L_ADDR			0x24
+#define VER_LIB_H_ADDR			0x28
+#define SW_DEBUG_L			0x2c
+#define SW_DEBUG_H			0x30
+#define MAILBOX_INT_MASK		0x34
+#define MAILBOX_INT_STATUS		0x38
+#define SW_CLK_L			0x3c
+#define SW_CLK_H			0x40
+#define SW_EVENTS0			0x44
+#define SW_EVENTS1			0x48
+#define SW_EVENTS2			0x4c
+#define SW_EVENTS3			0x50
+#define XT_OCD_CTRL			0x60
+#define APB_INT_MASK			0x6c
+#define APB_STATUS_MASK			0x70
+
+/* Source phy comp */
+#define PHY_DATA_SEL			0x0818
+#define LANES_CONFIG			0x0814
+
+/* Source CAR Addr */
+#define SOURCE_HDTX_CAR			0x0900
+#define SOURCE_DPTX_CAR			0x0904
+#define SOURCE_PHY_CAR			0x0908
+#define SOURCE_CEC_CAR			0x090c
+#define SOURCE_CBUS_CAR			0x0910
+#define SOURCE_PKT_CAR			0x0918
+#define SOURCE_AIF_CAR			0x091c
+#define SOURCE_CIPHER_CAR		0x0920
+#define SOURCE_CRYPTO_CAR		0x0924
+
+/* clock meters addr */
+#define CM_CTRL				0x0a00
+#define CM_I2S_CTRL			0x0a04
+#define CM_SPDIF_CTRL			0x0a08
+#define CM_VID_CTRL			0x0a0c
+#define CM_LANE_CTRL			0x0a10
+#define I2S_NM_STABLE			0x0a14
+#define I2S_NCTS_STABLE			0x0a18
+#define SPDIF_NM_STABLE			0x0a1c
+#define SPDIF_NCTS_STABLE		0x0a20
+#define NMVID_MEAS_STABLE		0x0a24
+#define I2S_MEAS			0x0a40
+#define SPDIF_MEAS			0x0a80
+#define NMVID_MEAS			0x0ac0
+
+/* source vif addr */
+#define BND_HSYNC2VSYNC			0x0b00
+#define HSYNC2VSYNC_F1_L1		0x0b04
+#define HSYNC2VSYNC_STATUS		0x0b0c
+#define HSYNC2VSYNC_POL_CTRL		0x0b10
+
+/* MHDP TX_top_comp */
+#define SCHEDULER_H_SIZE		0x1000
+#define SCHEDULER_V_SIZE		0x1004
+#define HDTX_SIGNAL_FRONT_WIDTH		0x100c
+#define HDTX_SIGNAL_SYNC_WIDTH		0x1010
+#define HDTX_SIGNAL_BACK_WIDTH		0x1014
+#define HDTX_CONTROLLER			0x1018
+#define HDTX_HPD			0x1020
+#define HDTX_CLOCK_REG_0		0x1024
+#define HDTX_CLOCK_REG_1		0x1028
+
+/* DPTX hpd addr */
+#define HPD_IRQ_DET_MIN_TIMER		0x2100
+#define HPD_IRQ_DET_MAX_TIMER		0x2104
+#define HPD_UNPLGED_DET_MIN_TIMER	0x2108
+#define HPD_STABLE_TIMER		0x210c
+#define HPD_FILTER_TIMER		0x2110
+#define HPD_EVENT_MASK			0x211c
+#define HPD_EVENT_DET			0x2120
+
+/* DPTX framer addr */
+#define DP_FRAMER_GLOBAL_CONFIG		0x2200
+#define DP_SW_RESET			0x2204
+#define DP_FRAMER_TU			0x2208
+#define DP_FRAMER_PXL_REPR		0x220c
+#define DP_FRAMER_SP			0x2210
+#define AUDIO_PACK_CONTROL		0x2214
+#define DP_VC_TABLE(x)			(0x2218 + ((x) << 2))
+#define DP_VB_ID			0x2258
+#define DP_MTPH_LVP_CONTROL		0x225c
+#define DP_MTPH_SYMBOL_VALUES		0x2260
+#define DP_MTPH_ECF_CONTROL		0x2264
+#define DP_MTPH_ACT_CONTROL		0x2268
+#define DP_MTPH_STATUS			0x226c
+#define DP_INTERRUPT_SOURCE		0x2270
+#define DP_INTERRUPT_MASK		0x2274
+#define DP_FRONT_BACK_PORCH		0x2278
+#define DP_BYTE_COUNT			0x227c
+
+/* DPTX stream addr */
+#define MSA_HORIZONTAL_0		0x2280
+#define MSA_HORIZONTAL_1		0x2284
+#define MSA_VERTICAL_0			0x2288
+#define MSA_VERTICAL_1			0x228c
+#define MSA_MISC			0x2290
+#define STREAM_CONFIG			0x2294
+#define AUDIO_PACK_STATUS		0x2298
+#define VIF_STATUS			0x229c
+#define PCK_STUFF_STATUS_0		0x22a0
+#define PCK_STUFF_STATUS_1		0x22a4
+#define INFO_PACK_STATUS		0x22a8
+#define RATE_GOVERNOR_STATUS		0x22ac
+#define DP_HORIZONTAL			0x22b0
+#define DP_VERTICAL_0			0x22b4
+#define DP_VERTICAL_1			0x22b8
+#define DP_BLOCK_SDP			0x22bc
+
+/* DPTX glbl addr */
+#define DPTX_LANE_EN			0x2300
+#define DPTX_ENHNCD			0x2304
+#define DPTX_INT_MASK			0x2308
+#define DPTX_INT_STATUS			0x230c
+
+/* DP AUX Addr */
+#define DP_AUX_HOST_CONTROL		0x2800
+#define DP_AUX_INTERRUPT_SOURCE		0x2804
+#define DP_AUX_INTERRUPT_MASK		0x2808
+#define DP_AUX_SWAP_INVERSION_CONTROL	0x280c
+#define DP_AUX_SEND_NACK_TRANSACTION	0x2810
+#define DP_AUX_CLEAR_RX			0x2814
+#define DP_AUX_CLEAR_TX			0x2818
+#define DP_AUX_TIMER_STOP		0x281c
+#define DP_AUX_TIMER_CLEAR		0x2820
+#define DP_AUX_RESET_SW			0x2824
+#define DP_AUX_DIVIDE_2M		0x2828
+#define DP_AUX_TX_PREACHARGE_LENGTH	0x282c
+#define DP_AUX_FREQUENCY_1M_MAX		0x2830
+#define DP_AUX_FREQUENCY_1M_MIN		0x2834
+#define DP_AUX_RX_PRE_MIN		0x2838
+#define DP_AUX_RX_PRE_MAX		0x283c
+#define DP_AUX_TIMER_PRESET		0x2840
+#define DP_AUX_NACK_FORMAT		0x2844
+#define DP_AUX_TX_DATA			0x2848
+#define DP_AUX_RX_DATA			0x284c
+#define DP_AUX_TX_STATUS		0x2850
+#define DP_AUX_RX_STATUS		0x2854
+#define DP_AUX_RX_CYCLE_COUNTER		0x2858
+#define DP_AUX_MAIN_STATES		0x285c
+#define DP_AUX_MAIN_TIMER		0x2860
+#define DP_AUX_AFE_OUT			0x2864
+
+/* source pif addr */
+#define SOURCE_PIF_WR_ADDR		0x30800
+#define SOURCE_PIF_WR_REQ		0x30804
+#define SOURCE_PIF_RD_ADDR		0x30808
+#define SOURCE_PIF_RD_REQ		0x3080c
+#define SOURCE_PIF_DATA_WR		0x30810
+#define SOURCE_PIF_DATA_RD		0x30814
+#define SOURCE_PIF_FIFO1_FLUSH		0x30818
+#define SOURCE_PIF_FIFO2_FLUSH		0x3081c
+#define SOURCE_PIF_STATUS		0x30820
+#define SOURCE_PIF_INTERRUPT_SOURCE	0x30824
+#define SOURCE_PIF_INTERRUPT_MASK	0x30828
+#define SOURCE_PIF_PKT_ALLOC_REG	0x3082c
+#define SOURCE_PIF_PKT_ALLOC_WR_EN	0x30830
+#define SOURCE_PIF_SW_RESET		0x30834
+
+#define LINK_TRAINING_NOT_ACTIV		0
+#define LINK_TRAINING_RUN		1
+#define LINK_TRAINING_RESTART		2
+
+#define CONTROL_VIDEO_IDLE		0
+#define CONTROL_VIDEO_VALID		1
+
+#define INTERLACE_FMT_DET		BIT(12)
+#define VIF_BYPASS_INTERLACE		BIT(13)
+#define TU_CNT_RST_EN			BIT(15)
+#define INTERLACE_DTCT_WIN		0x20
+
+#define DP_FRAMER_SP_INTERLACE_EN	BIT(2)
+#define DP_FRAMER_SP_HSP		BIT(1)
+#define DP_FRAMER_SP_VSP		BIT(0)
+
+/* Capability */
+#define AUX_HOST_INVERT			3
+#define FAST_LT_SUPPORT			1
+#define FAST_LT_NOT_SUPPORT		0
+#define LANE_MAPPING_FLIPPED		0xe4
+#define ENHANCED			1
+#define SCRAMBLER_EN			BIT(4)
+
+#define FULL_LT_STARTED			BIT(0)
+#define FASE_LT_STARTED			BIT(1)
+#define CLK_RECOVERY_FINISHED		BIT(2)
+#define EQ_PHASE_FINISHED		BIT(3)
+#define FASE_LT_START_FINISHED		BIT(4)
+#define CLK_RECOVERY_FAILED		BIT(5)
+#define EQ_PHASE_FAILED			BIT(6)
+#define FASE_LT_FAILED			BIT(7)
+
+#define TU_SIZE				30
+#define CDNS_DP_MAX_LINK_RATE		540000
+
+#define F_HDMI2_CTRL_IL_MODE(x)		(((x) & ((1 << 1) - 1)) << 19)
+#define F_HDMI2_PREAMBLE_EN(x)		(((x) & ((1 << 1) - 1)) << 18)
+#define F_HDMI_ENCODING(x)		(((x) & ((1 << 2) - 1)) << 16)
+#define F_DATA_EN(x)			(((x) & ((1 << 1) - 1)) << 15)
+#define F_CLEAR_AVMUTE(x)		(((x) & ((1 << 1) - 1)) << 14)
+#define F_SET_AVMUTE(x)			(((x) & ((1 << 1) - 1)) << 13)
+#define F_GCP_EN(x)			(((x) & ((1 << 1) - 1)) << 12)
+#define F_BCH_EN(x)			(((x) & ((1 << 1) - 1)) << 11)
+#define F_PIC_3D(x)			(((x) & ((1 << 4) - 1)) << 7)
+#define F_VIF_DATA_WIDTH(x)		(((x) & ((1 << 2) - 1)) << 2)
+#define F_HDMI_MODE(x)			(((x) & ((1 << 2) - 1)) << 0)
+
+#define F_SOURCE_PHY_MHDP_SEL(x)	(((x) & ((1 << 2) - 1)) << 3)
+
+#define F_HPD_GLITCH_WIDTH(x)		(((x) & ((1 << 8) - 1)) << 12)
+#define F_PACKET_TYPE(x)		(((x) & ((1 << 8) - 1)) << 8)
+#define F_HPD_VALID_WIDTH(x)		(((x) & ((1 << 12) - 1)) << 0)
+
+#define F_SOURCE_PHY_LANE3_SWAP(x)	(((x) & ((1 << 2) - 1)) << 6)
+#define F_SOURCE_PHY_LANE2_SWAP(x)	(((x) & ((1 << 2) - 1)) << 4)
+#define F_SOURCE_PHY_LANE1_SWAP(x)	(((x) & ((1 << 2) - 1)) << 2)
+#define F_SOURCE_PHY_LANE0_SWAP(x)	(((x) & ((1 << 2) - 1)) << 0)
+
+#define F_ACTIVE_IDLE_TYPE(x)		(((x) & ((1 << 1) - 1)) << 17)
+#define F_TYPE_VALID(x)			(((x) & ((1 << 1) - 1)) << 16)
+#define F_PKT_ALLOC_ADDRESS(x)		(((x) & ((1 << 4) - 1)) << 0)
+
+#define F_FIFO1_FLUSH(x)		(((x) & ((1 << 1) - 1)) << 0)
+#define F_PKT_ALLOC_WR_EN(x)		(((x) & ((1 << 1) - 1)) << 0)
+#define F_DATA_WR(x)			(x)
+#define F_WR_ADDR(x)			(((x) & ((1 << 4) - 1)) << 0)
+#define F_HOST_WR(x)			(((x) & ((1 << 1) - 1)) << 0)
+
+/* Reference cycles when using lane clock as reference */
+#define LANE_REF_CYC			0x8000
+
+/* HPD Debounce */
+#define HOTPLUG_DEBOUNCE_MS		200
+
+/* HPD IRQ Index */
+#define IRQ_IN    0
+#define IRQ_OUT   1
+#define IRQ_NUM   2
+
+/* FW check alive timeout */
+#define CDNS_KEEP_ALIVE_TIMEOUT		2000
+#define CDNS_KEEP_ALIVE_MASK		GENMASK(7, 0)
+
+enum voltage_swing_level {
+	VOLTAGE_LEVEL_0,
+	VOLTAGE_LEVEL_1,
+	VOLTAGE_LEVEL_2,
+	VOLTAGE_LEVEL_3,
+};
+
+enum pre_emphasis_level {
+	PRE_EMPHASIS_LEVEL_0,
+	PRE_EMPHASIS_LEVEL_1,
+	PRE_EMPHASIS_LEVEL_2,
+	PRE_EMPHASIS_LEVEL_3,
+};
+
+enum pattern_set {
+	PTS1 = BIT(0),
+	PTS2 = BIT(1),
+	PTS3 = BIT(2),
+	PTS4 = BIT(3),
+	DP_NONE	= BIT(4)
+};
+
+enum vic_color_depth {
+	BCS_6 = 0x1,
+	BCS_8 = 0x2,
+	BCS_10 = 0x4,
+	BCS_12 = 0x8,
+	BCS_16 = 0x10,
+};
+
+enum vic_bt_type {
+	BT_601 = 0x0,
+	BT_709 = 0x1,
+};
+
+enum {
+	MODE_DVI,
+	MODE_HDMI_1_4,
+	MODE_HDMI_2_0,
+};
+
+struct video_info {
+	int bpc;
+	int color_fmt;
+};
+
+struct cdns_mhdp8501_device {
+	struct cdns_mhdp_base base;
+
+	struct device *dev;
+	void __iomem *regs;
+	struct drm_connector *curr_conn;
+	struct drm_bridge bridge;
+	struct clk *apb_clk;
+	struct phy *phy;
+
+	struct video_info video_info;
+
+	int irq[IRQ_NUM];
+	struct delayed_work hotplug_work;
+	int connector_type;
+	u32 lane_mapping;
+
+	union {
+		struct _dp_data {
+			u32 rate;
+			u8 num_lanes;
+			struct drm_dp_aux aux;
+			u8 dpcd[DP_RECEIVER_CAP_SIZE];
+		} dp;
+		struct _hdmi_data {
+			u32 hdmi_type;
+		} hdmi;
+	};
+};
+
+extern const struct drm_bridge_funcs cdns_dp_bridge_funcs;
+extern const struct drm_bridge_funcs cdns_hdmi_bridge_funcs;
+
+enum drm_connector_status
+cdns_mhdp8501_detect(struct cdns_mhdp8501_device *mhdp);
+ssize_t cdns_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg);
+int cdns_dp_aux_destroy(struct cdns_mhdp8501_device *mhdp);
+void cdns_dp_check_link_state(struct cdns_mhdp8501_device *mhdp);
+void cdns_hdmi_reset_link(struct cdns_mhdp8501_device *mhdp);
+#endif
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
new file mode 100644
index 0000000000000..bd2e8fae88335
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
@@ -0,0 +1,737 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence MHDP8501 DisplayPort(DP) bridge driver
+ *
+ * Copyright (C) 2019-2024 NXP Semiconductor, Inc.
+ *
+ */
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_print.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-dp.h>
+
+#include "cdns-mhdp8501-core.h"
+
+#define LINK_TRAINING_TIMEOUT_MS	500
+#define LINK_TRAINING_RETRY_MS		20
+
+ssize_t cdns_dp_aux_transfer(struct drm_dp_aux *aux,
+			     struct drm_dp_aux_msg *msg)
+{
+	struct cdns_mhdp8501_device *mhdp = dev_get_drvdata(aux->dev);
+	bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
+	int ret;
+
+	/* Ignore address only message */
+	if (!msg->size || !msg->buffer) {
+		msg->reply = native ?
+			DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
+		return msg->size;
+	}
+
+	if (!native) {
+		dev_err(mhdp->dev, "%s: only native messages supported\n", __func__);
+		return -EINVAL;
+	}
+
+	/* msg sanity check */
+	if (msg->size > DP_AUX_MAX_PAYLOAD_BYTES) {
+		dev_err(mhdp->dev, "%s: invalid msg: size(%zu), request(%x)\n",
+			__func__, msg->size, (unsigned int)msg->request);
+		return -EINVAL;
+	}
+
+	if (msg->request == DP_AUX_NATIVE_WRITE) {
+		const u8 *buf = msg->buffer;
+		int i;
+
+		for (i = 0; i < msg->size; ++i) {
+			ret = cdns_mhdp_dpcd_write(&mhdp->base,
+						   msg->address + i, buf[i]);
+			if (ret < 0) {
+				dev_err(mhdp->dev, "Failed to write DPCD\n");
+				return ret;
+			}
+		}
+		msg->reply = DP_AUX_NATIVE_REPLY_ACK;
+		return msg->size;
+	}
+
+	if (msg->request == DP_AUX_NATIVE_READ) {
+		ret = cdns_mhdp_dpcd_read(&mhdp->base, msg->address,
+					  msg->buffer, msg->size);
+		if (ret < 0)
+			return ret;
+		msg->reply = DP_AUX_NATIVE_REPLY_ACK;
+		return msg->size;
+	}
+	return 0;
+}
+
+int cdns_dp_aux_destroy(struct cdns_mhdp8501_device *mhdp)
+{
+	drm_dp_aux_unregister(&mhdp->dp.aux);
+
+	return 0;
+}
+
+static int cdns_dp_get_msa_misc(struct video_info *video)
+{
+	u32 msa_misc;
+	u8 color_space = 0;
+	u8 bpc = 0;
+
+	switch (video->color_fmt) {
+	/* set YUV default color space conversion to BT601 */
+	case DRM_COLOR_FORMAT_YCBCR444:
+		color_space = 6 + BT_601 * 8;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		color_space = 5 + BT_601 * 8;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		color_space = 5;
+		break;
+	case DRM_COLOR_FORMAT_RGB444:
+	default:
+		color_space = 0;
+		break;
+	};
+
+	switch (video->bpc) {
+	case 6:
+		bpc = 0;
+		break;
+	case 10:
+		bpc = 2;
+		break;
+	case 12:
+		bpc = 3;
+		break;
+	case 16:
+		bpc = 4;
+		break;
+	case 8:
+	default:
+		bpc = 1;
+		break;
+	};
+
+	msa_misc = (bpc << 5) | (color_space << 1);
+
+	return msa_misc;
+}
+
+static int cdns_dp_config_video(struct cdns_mhdp8501_device *mhdp,
+				const struct drm_display_mode *mode)
+{
+	struct video_info *video = &mhdp->video_info;
+	bool h_sync_polarity, v_sync_polarity;
+	u64 symbol;
+	u32 val, link_rate, rem;
+	u8 bit_per_pix, tu_size_reg = TU_SIZE;
+	int ret;
+
+	bit_per_pix = (video->color_fmt == DRM_COLOR_FORMAT_YCBCR422) ?
+		      (video->bpc * 2) : (video->bpc * 3);
+
+	link_rate = mhdp->dp.rate / 1000;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE);
+	if (ret)
+		goto err_config_video;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HSYNC2VSYNC_POL_CTRL, 0);
+	if (ret)
+		goto err_config_video;
+
+	/*
+	 * get a best tu_size and valid symbol:
+	 * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32
+	 * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes)
+	 * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set
+	 *    TU += 2 and repeat 2nd step.
+	 */
+	do {
+		tu_size_reg += 2;
+		symbol = tu_size_reg * mode->clock * bit_per_pix;
+		do_div(symbol, mhdp->dp.num_lanes * link_rate * 8);
+		rem = do_div(symbol, 1000);
+		if (tu_size_reg > 64) {
+			ret = -EINVAL;
+			dev_err(mhdp->dev, "tu error, clk:%d, lanes:%d, rate:%d\n",
+				mode->clock, mhdp->dp.num_lanes, link_rate);
+			goto err_config_video;
+		}
+	} while ((symbol <= 1) || (tu_size_reg - symbol < 4) ||
+		 (rem > 850) || (rem < 100));
+
+	val = symbol + (tu_size_reg << 8);
+	val |= TU_CNT_RST_EN;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_TU, val);
+	if (ret)
+		goto err_config_video;
+
+	/* set the FIFO Buffer size */
+	val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate;
+	val /= (mhdp->dp.num_lanes * link_rate);
+	val = div_u64(8 * (symbol + 1), bit_per_pix) - val;
+	val += 2;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_VC_TABLE(15), val);
+
+	switch (video->bpc) {
+	case 6:
+		val = BCS_6;
+		break;
+	case 10:
+		val = BCS_10;
+		break;
+	case 12:
+		val = BCS_12;
+		break;
+	case 16:
+		val = BCS_16;
+		break;
+	case 8:
+	default:
+		val = BCS_8;
+		break;
+	};
+
+	val += video->color_fmt << 8;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_PXL_REPR, val);
+	if (ret)
+		goto err_config_video;
+
+	v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
+	h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
+
+	val = h_sync_polarity ? DP_FRAMER_SP_HSP : 0;
+	val |= v_sync_polarity ? DP_FRAMER_SP_VSP : 0;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_SP, val);
+	if (ret)
+		goto err_config_video;
+
+	val = (mode->hsync_start - mode->hdisplay) << 16;
+	val |= mode->htotal - mode->hsync_end;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRONT_BACK_PORCH, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->hdisplay * bit_per_pix / 8;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_BYTE_COUNT, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16);
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_HORIZONTAL_0, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->hsync_end - mode->hsync_start;
+	val |= (mode->hdisplay << 16) | (h_sync_polarity << 15);
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_HORIZONTAL_1, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->vtotal;
+	val |= (mode->vtotal - mode->vsync_start) << 16;
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_VERTICAL_0, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->vsync_end - mode->vsync_start;
+	val |= (mode->vdisplay << 16) | (v_sync_polarity << 15);
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_VERTICAL_1, val);
+	if (ret)
+		goto err_config_video;
+
+	val = cdns_dp_get_msa_misc(video);
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_MISC, val);
+	if (ret)
+		goto err_config_video;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, STREAM_CONFIG, 1);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->hsync_end - mode->hsync_start;
+	val |= mode->hdisplay << 16;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_HORIZONTAL, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->vdisplay;
+	val |= (mode->vtotal - mode->vsync_start) << 16;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_VERTICAL_0, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->vtotal;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_VERTICAL_1, val);
+	if (ret)
+		goto err_config_video;
+
+	ret = cdns_mhdp_dp_reg_write_bit(&mhdp->base, DP_VB_ID, 2, 1, 0);
+
+err_config_video:
+	if (ret)
+		dev_err(mhdp->dev, "config video failed: %d\n", ret);
+	return ret;
+}
+
+static void cdns_dp_pixel_clk_reset(struct cdns_mhdp8501_device *mhdp)
+{
+	u32 val;
+
+	/* reset pixel clk */
+	cdns_mhdp_reg_read(&mhdp->base, SOURCE_HDTX_CAR, &val);
+	cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR, val & 0xFD);
+	cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR, val);
+}
+
+static int cdns_dp_set_video_status(struct cdns_mhdp8501_device *mhdp, int active)
+{
+	u8 msg;
+	int ret;
+
+	msg = !!active;
+
+	mutex_lock(&mhdp_mailbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO,
+				     sizeof(msg), &msg);
+	if (ret)
+		dev_err(mhdp->dev, "set video status failed: %d\n", ret);
+
+	mutex_unlock(&mhdp_mailbox_mutex);
+
+	return ret;
+}
+
+static int cdns_dp_training_start(struct cdns_mhdp8501_device *mhdp)
+{
+	unsigned long timeout;
+	u8 msg, event[2];
+	int ret;
+
+	msg = LINK_TRAINING_RUN;
+
+	mutex_lock(&mhdp_mailbox_mutex);
+
+	/* start training */
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+				     DPTX_TRAINING_CONTROL, sizeof(msg), &msg);
+	if (ret)
+		goto err_training_start;
+
+	timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS);
+	while (time_before(jiffies, timeout)) {
+		msleep(LINK_TRAINING_RETRY_MS);
+		ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+					     DPTX_READ_EVENT, 0, NULL);
+		if (ret)
+			goto err_training_start;
+
+		ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
+						    DPTX_READ_EVENT, sizeof(event));
+		if (ret)
+			goto err_training_start;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, event, sizeof(event));
+		if (ret)
+			goto err_training_start;
+
+		if (event[1] & CLK_RECOVERY_FAILED) {
+			dev_err(mhdp->dev, "clock recovery failed\n");
+		} else if (event[1] & EQ_PHASE_FINISHED) {
+			mutex_unlock(&mhdp_mailbox_mutex);
+			return 0;
+		}
+	}
+
+	ret = -ETIMEDOUT;
+
+err_training_start:
+	mutex_unlock(&mhdp_mailbox_mutex);
+
+	dev_err(mhdp->dev, "training failed: %d\n", ret);
+	return ret;
+}
+
+static int cdns_dp_get_training_status(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 status[13];
+	int ret;
+
+	mutex_lock(&mhdp_mailbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+				     DPTX_READ_LINK_STAT, 0, NULL);
+	if (ret)
+		goto err_get_training_status;
+
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
+					    DPTX_READ_LINK_STAT,
+					    sizeof(status));
+	if (ret)
+		goto err_get_training_status;
+
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, status, sizeof(status));
+	if (ret)
+		goto err_get_training_status;
+
+	mhdp->dp.rate = drm_dp_bw_code_to_link_rate(status[0]);
+	mhdp->dp.num_lanes = status[1];
+
+err_get_training_status:
+	mutex_unlock(&mhdp_mailbox_mutex);
+
+	if (ret)
+		dev_err(mhdp->dev, "get training status failed: %d\n", ret);
+	return ret;
+}
+
+static int cdns_dp_train_link(struct cdns_mhdp8501_device *mhdp)
+{
+	int ret;
+
+	ret = cdns_dp_training_start(mhdp);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to start training %d\n", ret);
+		return ret;
+	}
+
+	ret = cdns_dp_get_training_status(mhdp);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to get training stat %d\n", ret);
+		return ret;
+	}
+
+	dev_dbg(mhdp->dev, "rate:0x%x, lanes:%d\n", mhdp->dp.rate,
+		mhdp->dp.num_lanes);
+	return ret;
+}
+
+static int cdns_dp_set_host_cap(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 msg[8];
+	int ret;
+
+	msg[0] = drm_dp_link_rate_to_bw_code(mhdp->dp.rate);
+	msg[1] = mhdp->dp.num_lanes | SCRAMBLER_EN;
+	msg[2] = VOLTAGE_LEVEL_2;
+	msg[3] = PRE_EMPHASIS_LEVEL_3;
+	msg[4] = PTS1 | PTS2 | PTS3 | PTS4;
+	msg[5] = FAST_LT_NOT_SUPPORT;
+	msg[6] = mhdp->lane_mapping;
+	msg[7] = ENHANCED;
+
+	mutex_lock(&mhdp_mailbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+				     DPTX_SET_HOST_CAPABILITIES,
+				     sizeof(msg), msg);
+
+	mutex_unlock(&mhdp_mailbox_mutex);
+
+	if (ret)
+		dev_err(mhdp->dev, "set host cap failed: %d\n", ret);
+
+	return ret;
+}
+
+static int cdns_dp_get_edid_block(void *data, u8 *edid,
+				  unsigned int block, size_t length)
+{
+	struct cdns_mhdp8501_device *mhdp = data;
+	u8 msg[2], reg[2], i;
+	int ret;
+
+	mutex_lock(&mhdp_mailbox_mutex);
+
+	for (i = 0; i < 4; i++) {
+		msg[0] = block / 2;
+		msg[1] = block % 2;
+
+		ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+					     DPTX_GET_EDID, sizeof(msg), msg);
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
+						    DPTX_GET_EDID,
+						    sizeof(reg) + length);
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg, sizeof(reg));
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, edid, length);
+		if (ret)
+			continue;
+
+		if (reg[0] == length && reg[1] == block / 2)
+			break;
+	}
+
+	if (ret)
+		dev_err(mhdp->dev, "get block[%d] edid failed: %d\n", block, ret);
+
+	mutex_unlock(&mhdp_mailbox_mutex);
+	return ret;
+}
+
+static void cdns_dp_mode_set(struct cdns_mhdp8501_device *mhdp,
+			     const struct drm_display_mode *mode)
+{
+	union phy_configure_opts phy_cfg;
+	int ret;
+
+	cdns_dp_pixel_clk_reset(mhdp);
+
+	/* Get DP Caps  */
+	ret = drm_dp_dpcd_read(&mhdp->dp.aux, DP_DPCD_REV, mhdp->dp.dpcd,
+			       DP_RECEIVER_CAP_SIZE);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "Failed to get caps %d\n", ret);
+		return;
+	}
+
+	mhdp->dp.rate = drm_dp_max_link_rate(mhdp->dp.dpcd);
+	mhdp->dp.num_lanes = drm_dp_max_lane_count(mhdp->dp.dpcd);
+
+	/* check the max link rate */
+	if (mhdp->dp.rate > CDNS_DP_MAX_LINK_RATE)
+		mhdp->dp.rate = CDNS_DP_MAX_LINK_RATE;
+
+	phy_cfg.dp.lanes = mhdp->dp.num_lanes;
+	phy_cfg.dp.link_rate = mhdp->dp.rate;
+	phy_cfg.dp.set_lanes = false;
+	phy_cfg.dp.set_rate = false;
+	phy_cfg.dp.set_voltages = true;
+
+	ret = phy_configure(mhdp->phy, &phy_cfg);
+	if (ret) {
+		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
+			__func__, ret);
+		return;
+	}
+
+	/* Video off */
+	ret = cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_IDLE);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to valid video %d\n", ret);
+		return;
+	}
+
+	/* Line swapping */
+	cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping);
+
+	/* Set DP host capability */
+	ret = cdns_dp_set_host_cap(mhdp);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to set host cap %d\n", ret);
+		return;
+	}
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_AUX_SWAP_INVERSION_CONTROL,
+				  AUX_HOST_INVERT);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to set host invert %d\n", ret);
+		return;
+	}
+
+	ret = cdns_dp_config_video(mhdp, mode);
+	if (ret)
+		dev_err(mhdp->dev, "Failed to config video %d\n", ret);
+}
+
+static bool
+cdns_dp_needs_link_retrain(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 link_status[DP_LINK_STATUS_SIZE];
+
+	if (drm_dp_dpcd_read_phy_link_status(&mhdp->dp.aux, DP_PHY_DPRX,
+					     link_status) < 0)
+		return false;
+
+	/* Retrain if link not ok */
+	return !drm_dp_channel_eq_ok(link_status, mhdp->dp.num_lanes);
+}
+
+void cdns_dp_check_link_state(struct cdns_mhdp8501_device *mhdp)
+{
+	struct drm_connector *connector = mhdp->curr_conn;
+	const struct drm_edid *drm_edid;
+	struct drm_connector_state *conn_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc *crtc;
+
+	if (!connector)
+		return;
+
+	drm_edid = drm_edid_read_custom(connector, cdns_dp_get_edid_block, mhdp);
+	drm_edid_connector_update(connector, drm_edid);
+
+	if (!drm_edid)
+		return;
+
+	drm_edid_free(drm_edid);
+
+	conn_state = connector->state;
+	crtc = conn_state->crtc;
+	if (!crtc)
+		return;
+
+	crtc_state = crtc->state;
+	if (!crtc_state->active)
+		return;
+
+	if (!cdns_dp_needs_link_retrain(mhdp))
+		return;
+
+	/* DP link retrain */
+	if (cdns_dp_train_link(mhdp))
+		dev_err(mhdp->dev, "Failed link train\n");
+}
+
+static int cdns_dp_bridge_attach(struct drm_bridge *bridge,
+				 enum drm_bridge_attach_flags flags)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		dev_err(mhdp->dev, "do not support creating a drm_connector\n");
+		return -EINVAL;
+	}
+
+	mhdp->dp.aux.drm_dev = bridge->dev;
+
+	return drm_dp_aux_register(&mhdp->dp.aux);
+}
+
+static enum drm_mode_status
+cdns_dp_bridge_mode_valid(struct drm_bridge *bridge,
+			  const struct drm_display_info *info,
+			  const struct drm_display_mode *mode)
+{
+	enum drm_mode_status mode_status = MODE_OK;
+
+	/* We don't support double-clocked modes */
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
+	    mode->flags & DRM_MODE_FLAG_INTERLACE)
+		return MODE_BAD;
+
+	/* MAX support pixel clock rate 594MHz */
+	if (mode->clock > 594000)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->hdisplay > 3840)
+		return MODE_BAD_HVALUE;
+
+	if (mode->vdisplay > 2160)
+		return MODE_BAD_VVALUE;
+
+	return mode_status;
+}
+
+static enum drm_connector_status
+cdns_dp_bridge_detect(struct drm_bridge *bridge)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	return cdns_mhdp8501_detect(mhdp);
+}
+
+static const struct drm_edid
+*cdns_dp_bridge_edid_read(struct drm_bridge *bridge,
+			  struct drm_connector *connector)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	return drm_edid_read_custom(connector, cdns_dp_get_edid_block, mhdp);
+}
+
+static void cdns_dp_bridge_atomic_disable(struct drm_bridge *bridge,
+					  struct drm_bridge_state *old_state)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_IDLE);
+	mhdp->curr_conn = NULL;
+
+	phy_power_off(mhdp->phy);
+}
+
+static void cdns_dp_bridge_atomic_enable(struct drm_bridge *bridge,
+					 struct drm_bridge_state *old_state)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+	struct drm_atomic_state *state = old_state->base.state;
+	struct drm_connector *connector;
+	struct video_info *video = &mhdp->video_info;
+	struct drm_crtc_state *crtc_state;
+	struct drm_connector_state *conn_state;
+	int ret;
+
+	connector = drm_atomic_get_new_connector_for_encoder(state,
+							     bridge->encoder);
+	if (WARN_ON(!connector))
+		return;
+
+	mhdp->curr_conn = connector;
+
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (WARN_ON(!conn_state))
+		return;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+	if (WARN_ON(!crtc_state))
+		return;
+
+	switch (connector->display_info.bpc) {
+	case 10:
+		video->bpc = 10;
+		break;
+	case 6:
+		video->bpc = 6;
+		break;
+	default:
+		video->bpc = 8;
+		break;
+	}
+
+	/* The only currently supported format */
+	video->color_fmt = DRM_COLOR_FORMAT_RGB444;
+
+	cdns_dp_mode_set(mhdp, &crtc_state->adjusted_mode);
+
+	/* Link trainning */
+	ret = cdns_dp_train_link(mhdp);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed link train %d\n", ret);
+		return;
+	}
+
+	ret = cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_VALID);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to valid video %d\n", ret);
+		return;
+	}
+}
+
+const struct drm_bridge_funcs cdns_dp_bridge_funcs = {
+	.attach = cdns_dp_bridge_attach,
+	.detect = cdns_dp_bridge_detect,
+	.edid_read = cdns_dp_bridge_edid_read,
+	.mode_valid = cdns_dp_bridge_mode_valid,
+	.atomic_enable = cdns_dp_bridge_atomic_enable,
+	.atomic_disable = cdns_dp_bridge_atomic_disable,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+};
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
new file mode 100644
index 0000000000000..f94a8d0204825
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
@@ -0,0 +1,692 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence MHDP8501 HDMI bridge driver
+ *
+ * Copyright (C) 2019-2024 NXP Semiconductor, Inc.
+ *
+ */
+#include <drm/display/drm_hdmi_helper.h>
+#include <drm/display/drm_hdmi_state_helper.h>
+#include <drm/display/drm_scdc_helper.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_print.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-hdmi.h>
+
+#include "cdns-mhdp8501-core.h"
+
+/**
+ * cdns_hdmi_config_infoframe() - fill the HDMI infoframe
+ * @mhdp: phandle to mhdp device.
+ * @entry_id: The packet memory address in which the data is written.
+ * @len: length of infoframe.
+ * @buf: point to InfoFrame Packet.
+ * @type: Packet Type of InfoFrame in HDMI Specification.
+ *
+ */
+static void cdns_hdmi_config_infoframe(struct cdns_mhdp8501_device *mhdp,
+				       u8 entry_id, u8 len,
+				       const u8 *buf, u8 type)
+{
+	u8 packet[32], packet_len = 32;
+	u32 packet32, len32;
+	u32 val, i;
+
+	/*
+	 * only support 32 bytes now
+	 * packet[0] = 0
+	 * packet[1-3] = HB[0-2]  InfoFrame Packet Header
+	 * packet[4-31 = PB[0-27] InfoFrame Packet Contents
+	 */
+	if (len >= (packet_len - 1))
+		return;
+	packet[0] = 0;
+	memcpy(packet + 1, buf, len);
+
+	/* invalidate entry */
+	val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id);
+	writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG);
+	writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs + SOURCE_PIF_PKT_ALLOC_WR_EN);
+
+	/* flush fifo 1 */
+	writel(F_FIFO1_FLUSH(1), mhdp->regs + SOURCE_PIF_FIFO1_FLUSH);
+
+	/* write packet into memory */
+	len32 = packet_len / 4;
+	for (i = 0; i < len32; i++) {
+		packet32 = get_unaligned_le32(packet + 4 * i);
+		writel(F_DATA_WR(packet32), mhdp->regs + SOURCE_PIF_DATA_WR);
+	}
+
+	/* write entry id */
+	writel(F_WR_ADDR(entry_id), mhdp->regs + SOURCE_PIF_WR_ADDR);
+
+	/* write request */
+	writel(F_HOST_WR(1), mhdp->regs + SOURCE_PIF_WR_REQ);
+
+	/* update entry */
+	val = F_ACTIVE_IDLE_TYPE(1) | F_TYPE_VALID(1) |
+		F_PACKET_TYPE(type) | F_PKT_ALLOC_ADDRESS(entry_id);
+	writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG);
+
+	writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs + SOURCE_PIF_PKT_ALLOC_WR_EN);
+}
+
+static void cdns_hdmi_reset_infoframe(struct cdns_mhdp8501_device *mhdp, u8 entry_id)
+{
+	u32 val;
+
+	/* invalidate entry */
+	val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id);
+	writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG);
+	writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs + SOURCE_PIF_PKT_ALLOC_WR_EN);
+}
+
+static int cdns_hdmi_get_edid_block(void *data, u8 *edid,
+				    u32 block, size_t length)
+{
+	struct cdns_mhdp8501_device *mhdp = data;
+	u8 msg[2], reg[5], i;
+	int ret;
+
+	mutex_lock(&mhdp_mailbox_mutex);
+
+	for (i = 0; i < 4; i++) {
+		msg[0] = block / 2;
+		msg[1] = block % 2;
+
+		ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_HDMI_TX, HDMI_TX_EDID,
+					     sizeof(msg), msg);
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_HDMI_TX,
+						    HDMI_TX_EDID, sizeof(reg) + length);
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg, sizeof(reg));
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, edid, length);
+		if (ret)
+			continue;
+
+		if ((reg[3] << 8 | reg[4]) == length)
+			break;
+	}
+
+	mutex_unlock(&mhdp_mailbox_mutex);
+
+	if (ret)
+		dev_err(mhdp->dev, "get block[%d] edid failed: %d\n", block, ret);
+	return ret;
+}
+
+static int cdns_hdmi_scdc_write(struct cdns_mhdp8501_device *mhdp, u8 addr, u8 value)
+{
+	u8 msg[5], reg[5];
+	int ret;
+
+	msg[0] = 0x54;
+	msg[1] = addr;
+	msg[2] = 0;
+	msg[3] = 1;
+	msg[4] = value;
+
+	mutex_lock(&mhdp_mailbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_HDMI_TX, HDMI_TX_WRITE,
+				     sizeof(msg), msg);
+	if (ret)
+		goto err_scdc_write;
+
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_HDMI_TX,
+					    HDMI_TX_WRITE, sizeof(reg));
+	if (ret)
+		goto err_scdc_write;
+
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg, sizeof(reg));
+	if (ret)
+		goto err_scdc_write;
+
+	if (reg[0] != 0)
+		ret = -EINVAL;
+
+err_scdc_write:
+
+	mutex_unlock(&mhdp_mailbox_mutex);
+
+	if (ret)
+		dev_err(mhdp->dev, "scdc write failed: %d\n", ret);
+	return ret;
+}
+
+static int cdns_hdmi_set_hdmi_mode_type(struct cdns_mhdp8501_device *mhdp)
+{
+	struct drm_connector_state *conn_state = mhdp->curr_conn->state;
+	u32 protocol = mhdp->hdmi.hdmi_type;
+	u32 val;
+
+	if (protocol == MODE_HDMI_2_0 &&
+	    conn_state->hdmi.tmds_char_rate >= 340000000) {
+		cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_0, 0);
+		cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_1, 0xFFFFF);
+	}
+
+	cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
+
+	/* set HDMI mode and preemble mode data enable */
+	val |= F_HDMI_MODE(protocol) | F_HDMI2_PREAMBLE_EN(1) |
+	       F_HDMI2_CTRL_IL_MODE(1);
+	return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+}
+
+static int cdns_hdmi_ctrl_init(struct cdns_mhdp8501_device *mhdp)
+{
+	u32 val;
+	int ret;
+
+	/* Set PHY to HDMI data */
+	ret = cdns_mhdp_reg_write(&mhdp->base, PHY_DATA_SEL, F_SOURCE_PHY_MHDP_SEL(1));
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_HPD,
+				  F_HPD_VALID_WIDTH(4) | F_HPD_GLITCH_WIDTH(0));
+	if (ret < 0)
+		return ret;
+
+	/* open CARS */
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_PHY_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR, 0xFF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_PKT_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_AIF_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CIPHER_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CRYPTO_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CEC_CAR, 3);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_0, 0x7c1f);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_1, 0x7c1f);
+	if (ret < 0)
+		return ret;
+
+	/* init HDMI Controller */
+	val = F_BCH_EN(1) | F_PIC_3D(0xF) | F_CLEAR_AVMUTE(1);
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+	if (ret < 0)
+		return ret;
+
+	return cdns_hdmi_set_hdmi_mode_type(mhdp);
+}
+
+static int cdns_hdmi_mode_config(struct cdns_mhdp8501_device *mhdp,
+				 struct drm_display_mode *mode,
+				 struct video_info *video_info)
+{
+	u32 vsync_lines = mode->vsync_end - mode->vsync_start;
+	u32 eof_lines = mode->vsync_start - mode->vdisplay;
+	u32 sof_lines = mode->vtotal - mode->vsync_end;
+	u32 hblank = mode->htotal - mode->hdisplay;
+	u32 hactive = mode->hdisplay;
+	u32 vblank = mode->vtotal - mode->vdisplay;
+	u32 vactive = mode->vdisplay;
+	u32 hfront = mode->hsync_start - mode->hdisplay;
+	u32 hback = mode->htotal - mode->hsync_end;
+	u32 vfront = eof_lines;
+	u32 hsync = hblank - hfront - hback;
+	u32 vsync = vsync_lines;
+	u32 vback = sof_lines;
+	u32 v_h_polarity = ((mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1) +
+			   ((mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : 2);
+	int ret;
+	u32 val;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, SCHEDULER_H_SIZE, (hactive << 16) + hblank);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, SCHEDULER_V_SIZE, (vactive << 16) + vblank);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_SIGNAL_FRONT_WIDTH, (vfront << 16) + hfront);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_SIGNAL_SYNC_WIDTH, (vsync << 16) + hsync);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_SIGNAL_BACK_WIDTH, (vback << 16) + hback);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HSYNC2VSYNC_POL_CTRL, v_h_polarity);
+	if (ret < 0)
+		return ret;
+
+	/* Reset Data Enable */
+	cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
+	val &= ~F_DATA_EN(1);
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+	if (ret < 0)
+		return ret;
+
+	/* Set bpc */
+	val &= ~F_VIF_DATA_WIDTH(3);
+	switch (video_info->bpc) {
+	case 10:
+		val |= F_VIF_DATA_WIDTH(1);
+		break;
+	case 12:
+		val |= F_VIF_DATA_WIDTH(2);
+		break;
+	case 16:
+		val |= F_VIF_DATA_WIDTH(3);
+		break;
+	case 8:
+	default:
+		val |= F_VIF_DATA_WIDTH(0);
+		break;
+	}
+
+	/* select color encoding */
+	val &= ~F_HDMI_ENCODING(3);
+	switch (video_info->color_fmt) {
+	case HDMI_COLORSPACE_YUV444:
+		val |= F_HDMI_ENCODING(2);
+		break;
+	case HDMI_COLORSPACE_YUV422:
+		val |= F_HDMI_ENCODING(1);
+		break;
+	case HDMI_COLORSPACE_YUV420:
+		val |= F_HDMI_ENCODING(3);
+		break;
+	case HDMI_COLORSPACE_RGB:
+	default:
+		val |= F_HDMI_ENCODING(0);
+		break;
+	}
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+	if (ret < 0)
+		return ret;
+
+	/* set data enable */
+	val |= F_DATA_EN(1);
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+
+	return ret;
+}
+
+static int cdns_hdmi_disable_gcp(struct cdns_mhdp8501_device *mhdp)
+{
+	u32 val;
+
+	cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
+	val &= ~F_GCP_EN(1);
+
+	return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+}
+
+static int cdns_hdmi_enable_gcp(struct cdns_mhdp8501_device *mhdp)
+{
+	u32 val;
+
+	cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
+	val |= F_GCP_EN(1);
+
+	return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+}
+
+static void cdns_hdmi_sink_config(struct cdns_mhdp8501_device *mhdp)
+{
+	struct drm_display_info *display = &mhdp->curr_conn->display_info;
+	struct drm_connector_state *conn_state = mhdp->curr_conn->state;
+	struct drm_scdc *scdc = &mhdp->curr_conn->display_info.hdmi.scdc;
+	u8 buff = 0;
+
+	/* check sink type (HDMI or DVI) */
+	if (!display->is_hdmi) {
+		mhdp->hdmi.hdmi_type = MODE_DVI;
+		return;
+	}
+
+	/* Default work in HDMI1.4 */
+	mhdp->hdmi.hdmi_type = MODE_HDMI_1_4;
+
+	/* check sink support SCDC or not */
+	if (!scdc->supported) {
+		dev_info(mhdp->dev, "Sink Not Support SCDC\n");
+		return;
+	}
+
+	if (conn_state->hdmi.tmds_char_rate > 340000000) {
+		/*
+		 * TMDS Character Rate above 340MHz should working in HDMI2.0
+		 * Enable scrambling and TMDS_Bit_Clock_Ratio
+		 */
+		buff = SCDC_TMDS_BIT_CLOCK_RATIO_BY_40 | SCDC_SCRAMBLING_ENABLE;
+		mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
+	} else if (scdc->scrambling.low_rates) {
+		/*
+		 * Enable scrambling and HDMI2.0 when scrambling capability of sink
+		 * be indicated in the HF-VSDB LTE_340Mcsc_scramble bit
+		 */
+		buff = SCDC_SCRAMBLING_ENABLE;
+		mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
+	}
+
+	/* TMDS config */
+	cdns_hdmi_scdc_write(mhdp, SCDC_TMDS_CONFIG, buff);
+}
+
+static int cdns_hdmi_bridge_attach(struct drm_bridge *bridge,
+				   enum drm_bridge_attach_flags flags)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		dev_err(mhdp->dev, "do not support creating a drm_connector\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int reset_pipe(struct drm_crtc *crtc)
+{
+	struct drm_atomic_state *state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_modeset_acquire_ctx ctx;
+	int ret;
+
+	state = drm_atomic_state_alloc(crtc->dev);
+	if (!state)
+		return -ENOMEM;
+
+	drm_modeset_acquire_init(&ctx, 0);
+
+	state->acquire_ctx = &ctx;
+
+	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	if (IS_ERR(crtc_state)) {
+		ret = PTR_ERR(crtc_state);
+		goto out;
+	}
+
+	crtc_state->connectors_changed = true;
+
+	ret = drm_atomic_commit(state);
+out:
+	drm_atomic_state_put(state);
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+
+	return ret;
+}
+
+void cdns_hdmi_reset_link(struct cdns_mhdp8501_device *mhdp)
+{
+	struct drm_connector *connector = mhdp->curr_conn;
+	const struct drm_edid *drm_edid;
+	struct drm_connector_state *conn_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc *crtc;
+
+	if (!connector)
+		return;
+
+	drm_edid = drm_edid_read_custom(connector, cdns_hdmi_get_edid_block, mhdp);
+	drm_edid_connector_update(connector, drm_edid);
+
+	if (!drm_edid)
+		return;
+
+	drm_edid_free(drm_edid);
+
+	conn_state = connector->state;
+	crtc = conn_state->crtc;
+	if (!crtc)
+		return;
+
+	crtc_state = crtc->state;
+	if (!crtc_state->active)
+		return;
+
+	cdns_hdmi_sink_config(mhdp);
+	cdns_hdmi_set_hdmi_mode_type(mhdp);
+
+	/*
+	 * HDMI 2.0 says that one should not send scrambled data
+	 * prior to configuring the sink scrambling, and that
+	 * TMDS clock/data transmission should be suspended when
+	 * changing the TMDS clock rate in the sink. So let's
+	 * just do a full modeset here, even though some sinks
+	 * would be perfectly happy if were to just reconfigure
+	 * the SCDC settings on the fly.
+	 */
+	reset_pipe(crtc);
+}
+
+static enum drm_mode_status
+cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
+			       const struct drm_display_mode *mode,
+			       unsigned long long tmds_rate)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+	union phy_configure_opts phy_cfg;
+	int ret;
+
+	phy_cfg.hdmi.tmds_char_rate = tmds_rate;
+
+	ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
+	if (ret < 0)
+		return MODE_CLOCK_RANGE;
+
+	return MODE_OK;
+}
+
+static enum drm_mode_status
+cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
+			    const struct drm_display_info *info,
+			    const struct drm_display_mode *mode)
+{
+	unsigned long long tmds_rate;
+
+	/* We don't support double-clocked and Interlaced modes */
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
+	    mode->flags & DRM_MODE_FLAG_INTERLACE)
+		return MODE_BAD;
+
+	if (mode->hdisplay > 3840)
+		return MODE_BAD_HVALUE;
+
+	if (mode->vdisplay > 2160)
+		return MODE_BAD_VVALUE;
+
+	tmds_rate = mode->clock * 1000ULL;
+	return cdns_hdmi_tmds_char_rate_valid(bridge, mode, tmds_rate);
+}
+
+static enum drm_connector_status
+cdns_hdmi_bridge_detect(struct drm_bridge *bridge)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	return cdns_mhdp8501_detect(mhdp);
+}
+
+static const struct drm_edid
+*cdns_hdmi_bridge_edid_read(struct drm_bridge *bridge,
+			    struct drm_connector *connector)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	return drm_edid_read_custom(connector, cdns_hdmi_get_edid_block, mhdp);
+}
+
+static void cdns_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
+					    struct drm_bridge_state *old_state)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	mhdp->curr_conn = NULL;
+
+	phy_power_off(mhdp->phy);
+}
+
+static void cdns_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
+					   struct drm_bridge_state *old_state)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+	struct drm_atomic_state *state = old_state->base.state;
+	struct drm_connector *connector;
+	struct video_info *video_info = &mhdp->video_info;
+	struct drm_crtc_state *crtc_state;
+	struct drm_connector_state *conn_state;
+	union phy_configure_opts phy_cfg;
+	int ret;
+
+	connector = drm_atomic_get_new_connector_for_encoder(state,
+							     bridge->encoder);
+	if (WARN_ON(!connector))
+		return;
+
+	mhdp->curr_conn = connector;
+
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (WARN_ON(!conn_state))
+		return;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+	if (WARN_ON(!crtc_state))
+		return;
+
+	video_info->color_fmt = conn_state->hdmi.output_format;
+	video_info->bpc = conn_state->hdmi.output_bpc;
+
+	drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
+
+	/* Line swapping */
+	cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping);
+
+	phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate;
+
+	ret = phy_configure(mhdp->phy, &phy_cfg);
+	if (ret) {
+		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
+			__func__, ret);
+		return;
+	}
+
+	cdns_hdmi_sink_config(mhdp);
+
+	ret = cdns_hdmi_ctrl_init(mhdp);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "hdmi ctrl init failed = %d\n",  ret);
+		return;
+	}
+
+	/* Config GCP */
+	if (video_info->bpc == 8)
+		cdns_hdmi_disable_gcp(mhdp);
+	else
+		cdns_hdmi_enable_gcp(mhdp);
+
+	ret = cdns_hdmi_mode_config(mhdp, &crtc_state->adjusted_mode, video_info);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret);
+		return;
+	}
+
+	phy_power_on(mhdp->phy);
+}
+
+static int cdns_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge,
+					    enum hdmi_infoframe_type type)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AVI:
+		cdns_hdmi_reset_infoframe(mhdp, 0);
+		break;
+	case HDMI_INFOFRAME_TYPE_SPD:
+		cdns_hdmi_reset_infoframe(mhdp, 1);
+		break;
+	case HDMI_INFOFRAME_TYPE_VENDOR:
+		cdns_hdmi_reset_infoframe(mhdp, 2);
+		break;
+	default:
+		dev_dbg(mhdp->dev, "Unsupported infoframe type %x\n", type);
+	}
+
+	return 0;
+}
+
+static int cdns_hdmi_bridge_write_infoframe(struct drm_bridge *bridge,
+					    enum hdmi_infoframe_type type,
+					    const u8 *buffer, size_t len)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AVI:
+		cdns_hdmi_config_infoframe(mhdp, 0, len, buffer, HDMI_INFOFRAME_TYPE_AVI);
+		break;
+	case HDMI_INFOFRAME_TYPE_SPD:
+		cdns_hdmi_config_infoframe(mhdp, 1, len, buffer, HDMI_INFOFRAME_TYPE_SPD);
+		break;
+	case HDMI_INFOFRAME_TYPE_VENDOR:
+		cdns_hdmi_config_infoframe(mhdp, 2, len, buffer, HDMI_INFOFRAME_TYPE_VENDOR);
+		break;
+	default:
+		dev_dbg(mhdp->dev, "Unsupported infoframe type %x\n", type);
+	}
+
+	return 0;
+}
+
+static int cdns_hdmi_bridge_atomic_check(struct drm_bridge *bridge,
+					 struct drm_bridge_state *bridge_state,
+					 struct drm_crtc_state *crtc_state,
+					 struct drm_connector_state *conn_state)
+{
+	return drm_atomic_helper_connector_hdmi_check(conn_state->connector, conn_state->state);
+}
+
+const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = {
+	.attach = cdns_hdmi_bridge_attach,
+	.detect = cdns_hdmi_bridge_detect,
+	.edid_read = cdns_hdmi_bridge_edid_read,
+	.mode_valid = cdns_hdmi_bridge_mode_valid,
+	.atomic_enable = cdns_hdmi_bridge_atomic_enable,
+	.atomic_disable = cdns_hdmi_bridge_atomic_disable,
+	.atomic_check = cdns_hdmi_bridge_atomic_check,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+	.hdmi_clear_infoframe = cdns_hdmi_bridge_clear_infoframe,
+	.hdmi_write_infoframe = cdns_hdmi_bridge_write_infoframe,
+	.hdmi_tmds_char_rate_valid = cdns_hdmi_tmds_char_rate_valid,
+};
-- 
2.34.1



From Sandor.yu at nxp.com  Tue Sep 24 00:36:50 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 24 Sep 2024 15:36:50 +0800
Subject: [PATCH v17 5/8] dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
In-Reply-To: <cover.1727159906.git.Sandor.yu@nxp.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <b125ac1fdd7d0cd3eff0852b81365f3e5d43a798.1727159906.git.Sandor.yu@nxp.com>

Add bindings for Freescale iMX8MQ DP and HDMI PHY.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
v9->v17:
 *No change.

 .../bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml  | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
new file mode 100644
index 0000000000000..c17a645e71bad
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/fsl,imx8mq-dp-hdmi-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cadence HDP-TX DP/HDMI PHY for Freescale i.MX8MQ SoC
+
+maintainers:
+  - Sandor Yu <sandor.yu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8mq-hdptx-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: PHY reference clock.
+      - description: APB clock.
+
+  clock-names:
+    items:
+      - const: ref
+      - const: apb
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/phy/phy.h>
+    dp_phy: phy at 32c00000 {
+        compatible = "fsl,imx8mq-hdptx-phy";
+        reg = <0x32c00000 0x100000>;
+        #phy-cells = <0>;
+        clocks = <&hdmi_phy_27m>, <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+        clock-names = "ref", "apb";
+    };
-- 
2.34.1



From Sandor.yu at nxp.com  Tue Sep 24 00:36:51 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 24 Sep 2024 15:36:51 +0800
Subject: [PATCH v17 6/8] phy: freescale: Add DisplayPort/HDMI Combo-PHY driver for i.MX8MQ
In-Reply-To: <cover.1727159906.git.Sandor.yu@nxp.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <18505d1811ed5f743c06852d2542d71e9be73f95.1727159906.git.Sandor.yu@nxp.com>

Add Cadence HDP-TX DisplayPort and HDMI PHY driver for i.MX8MQ.

Cadence HDP-TX PHY could be put in either DP mode or
HDMI mode base on the configuration chosen.
DisplayPort or HDMI PHY mode is configured in the driver.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
v16->v17:
- Remove mbox_mutex, it had replaced with a global mutex mhdp_mailbox_mutex

v15->v16:
- updated for tmds_char_rate added to struct phy_configure_opts_hdmi in patch #2.

v14->v15:
- Merged DP and HDMI PHY driver into a single combo PHY driver

 drivers/phy/freescale/Kconfig                |   10 +
 drivers/phy/freescale/Makefile               |    1 +
 drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c | 1337 ++++++++++++++++++
 3 files changed, 1348 insertions(+)
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c

diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index dcd9acff6d01a..2b1210367b31c 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -35,6 +35,16 @@ config PHY_FSL_IMX8M_PCIE
 	  Enable this to add support for the PCIE PHY as found on
 	  i.MX8M family of SOCs.
 
+config PHY_FSL_IMX8MQ_HDPTX
+	tristate "Freescale i.MX8MQ DP/HDMI PHY support"
+	depends on OF && HAS_IOMEM
+	depends on COMMON_CLK
+	select GENERIC_PHY
+	select CDNS_MHDP_HELPER
+	help
+	  Enable this to support the Cadence HDPTX DP/HDMI PHY driver
+	  on i.MX8MQ SOC.
+
 config PHY_FSL_IMX8QM_HSIO
 	tristate "Freescale i.MX8QM HSIO PHY"
 	depends on OF && HAS_IOMEM
diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
index 658eac7d0a622..a946b87905498 100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_PHY_FSL_IMX8MQ_HDPTX)	+= phy-fsl-imx8mq-hdptx.o
 obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)	+= phy-fsl-imx8mq-usb.o
 obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)	+= phy-fsl-imx8qm-lvds-phy.o
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)	+= phy-fsl-imx8-mipi-dphy.o
diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c b/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c
new file mode 100644
index 0000000000000..7da05e1573e76
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c
@@ -0,0 +1,1337 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence DP/HDMI PHY driver
+ *
+ * Copyright (C) 2022-2024 NXP Semiconductor, Inc.
+ */
+#include <asm/unaligned.h>
+#include <drm/bridge/cdns-mhdp-helper.h>
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#define ADDR_PHY_AFE	0x80000
+
+/* PHY registers */
+#define CMN_SSM_BIAS_TMR			0x0022
+#define CMN_PLLSM0_PLLEN_TMR			0x0029
+#define CMN_PLLSM0_PLLPRE_TMR			0x002a
+#define CMN_PLLSM0_PLLVREF_TMR			0x002b
+#define CMN_PLLSM0_PLLLOCK_TMR			0x002c
+#define CMN_PLLSM0_USER_DEF_CTRL		0x002f
+#define CMN_PSM_CLK_CTRL			0x0061
+#define CMN_CDIAG_REFCLK_CTRL			0x0062
+#define CMN_PLL0_VCOCAL_START			0x0081
+#define CMN_PLL0_VCOCAL_INIT_TMR		0x0084
+#define CMN_PLL0_VCOCAL_ITER_TMR		0x0085
+#define CMN_PLL0_INTDIV				0x0094
+#define CMN_PLL0_FRACDIV			0x0095
+#define CMN_PLL0_HIGH_THR			0x0096
+#define CMN_PLL0_DSM_DIAG			0x0097
+#define CMN_PLL0_SS_CTRL2			0x0099
+#define CMN_ICAL_INIT_TMR			0x00c4
+#define CMN_ICAL_ITER_TMR			0x00c5
+#define CMN_RXCAL_INIT_TMR			0x00d4
+#define CMN_RXCAL_ITER_TMR			0x00d5
+#define CMN_TXPUCAL_CTRL			0x00e0
+#define CMN_TXPUCAL_INIT_TMR			0x00e4
+#define CMN_TXPUCAL_ITER_TMR			0x00e5
+#define CMN_TXPDCAL_CTRL			0x00f0
+#define CMN_TXPDCAL_INIT_TMR			0x00f4
+#define CMN_TXPDCAL_ITER_TMR			0x00f5
+#define CMN_ICAL_ADJ_INIT_TMR			0x0102
+#define CMN_ICAL_ADJ_ITER_TMR			0x0103
+#define CMN_RX_ADJ_INIT_TMR			0x0106
+#define CMN_RX_ADJ_ITER_TMR			0x0107
+#define CMN_TXPU_ADJ_CTRL			0x0108
+#define CMN_TXPU_ADJ_INIT_TMR			0x010a
+#define CMN_TXPU_ADJ_ITER_TMR			0x010b
+#define CMN_TXPD_ADJ_CTRL			0x010c
+#define CMN_TXPD_ADJ_INIT_TMR			0x010e
+#define CMN_TXPD_ADJ_ITER_TMR			0x010f
+#define CMN_DIAG_PLL0_FBH_OVRD			0x01c0
+#define CMN_DIAG_PLL0_FBL_OVRD			0x01c1
+#define CMN_DIAG_PLL0_OVRD			0x01c2
+#define CMN_DIAG_PLL0_TEST_MODE			0x01c4
+#define CMN_DIAG_PLL0_V2I_TUNE			0x01c5
+#define CMN_DIAG_PLL0_CP_TUNE			0x01c6
+#define CMN_DIAG_PLL0_LF_PROG			0x01c7
+#define CMN_DIAG_PLL0_PTATIS_TUNE1		0x01c8
+#define CMN_DIAG_PLL0_PTATIS_TUNE2		0x01c9
+#define CMN_DIAG_PLL0_INCLK_CTRL		0x01ca
+#define CMN_DIAG_PLL0_PXL_DIVH			0x01cb
+#define CMN_DIAG_PLL0_PXL_DIVL			0x01cc
+#define CMN_DIAG_HSCLK_SEL			0x01e0
+#define CMN_DIAG_PER_CAL_ADJ			0x01ec
+#define CMN_DIAG_CAL_CTRL			0x01ed
+#define CMN_DIAG_ACYA				0x01ff
+#define XCVR_PSM_RCTRL				0x4001
+#define XCVR_PSM_CAL_TMR			0x4002
+#define XCVR_PSM_A0IN_TMR			0x4003
+#define TX_TXCC_CAL_SCLR_MULT_0			0x4047
+#define TX_TXCC_CPOST_MULT_00_0			0x404c
+#define XCVR_DIAG_PLLDRC_CTRL			0x40e0
+#define XCVR_DIAG_HSCLK_SEL			0x40e1
+#define XCVR_DIAG_BIDI_CTRL			0x40e8
+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR		0x40f2
+#define TX_PSC_A0				0x4100
+#define TX_PSC_A1				0x4101
+#define TX_PSC_A2				0x4102
+#define TX_PSC_A3				0x4103
+#define TX_RCVDET_EN_TMR			0x4122
+#define TX_RCVDET_ST_TMR			0x4123
+#define TX_DIAG_TX_CTRL				0x41e0
+#define TX_DIAG_TX_DRV				0x41e1
+#define TX_DIAG_BGREF_PREDRV_DELAY		0x41e7
+#define TX_DIAG_ACYA_0				0x41ff
+#define TX_DIAG_ACYA_1				0x43ff
+#define TX_DIAG_ACYA_2				0x45ff
+#define TX_DIAG_ACYA_3				0x47ff
+#define TX_ANA_CTRL_REG_1			0x5020
+#define TX_ANA_CTRL_REG_2			0x5021
+#define TX_DIG_CTRL_REG_1			0x5023
+#define TX_DIG_CTRL_REG_2			0x5024
+#define TXDA_CYA_AUXDA_CYA			0x5025
+#define TX_ANA_CTRL_REG_3			0x5026
+#define TX_ANA_CTRL_REG_4			0x5027
+#define TX_ANA_CTRL_REG_5			0x5029
+#define RX_PSC_A0				0x8000
+#define RX_PSC_CAL				0x8006
+#define PHY_HDP_MODE_CTRL			0xc008
+#define PHY_HDP_CLK_CTL				0xc009
+#define PHY_ISO_CMN_CTRL			0xc010
+#define PHY_PMA_CMN_CTRL1			0xc800
+#define PHY_PMA_ISO_CMN_CTRL			0xc810
+#define PHY_PMA_ISO_PLL_CTRL1			0xc812
+#define PHY_PMA_ISOLATION_CTRL			0xc81f
+
+/* PHY_HDP_CLK_CTL */
+#define PLL_DATA_RATE_CLK_DIV_MASK		GENMASK(15, 8)
+#define PLL_DATA_RATE_CLK_DIV_HBR		0x24
+#define PLL_DATA_RATE_CLK_DIV_HBR2		0x12
+#define PLL_CLK_EN_ACK				BIT(3)
+#define PLL_CLK_EN				BIT(2)
+#define PLL_READY				BIT(1)
+#define PLL_EN					BIT(0)
+
+/* PHY_PMA_CMN_CTRL1 */
+#define CMA_REF_CLK_DIG_DIV_MASK		GENMASK(13, 12)
+#define CMA_REF_CLK_SEL_MASK			GENMASK(6, 4)
+#define CMA_REF_CLK_RCV_EN_MASK			BIT(3)
+#define CMA_REF_CLK_RCV_EN			1
+#define CMN_READY				BIT(0)
+
+/* PHY_PMA_ISO_PLL_CTRL1 */
+#define CMN_PLL0_CLK_DATART_DIV_MASK		GENMASK(7, 0)
+
+/* TX_DIAG_TX_DRV */
+#define TX_DRIVER_PROG_BOOST_ENABLE		BIT(10)
+#define TX_DRIVER_PROG_BOOST_LEVEL_MASK		GENMASK(9, 8)
+#define TX_DRIVER_LDO_BG_DEPENDENT_REF_ENABLE	BIT(7)
+#define TX_DRIVER_LDO_BANDGAP_REF_ENABLE	BIT(6)
+
+/* TX_TXCC_CAL_SCLR_MULT_0 */
+#define SCALED_RESISTOR_CALIBRATION_CODE_ADD	BIT(8)
+#define RESISTOR_CAL_MULT_VAL_32_128		BIT(5)
+
+/* CMN_CDIAG_REFCLK_CTRL */
+#define DIG_REF_CLK_DIV_SCALER_MASK		GENMASK(14, 12)
+#define REFCLK_TERMINATION_EN_OVERRIDE_EN	BIT(7)
+#define REFCLK_TERMINATION_EN_OVERRIDE		BIT(6)
+
+/* CMN_DIAG_HSCLK_SEL */
+#define HSCLK1_SEL_MASK				GENMASK(5, 4)
+#define HSCLK0_SEL_MASK				GENMASK(1, 0)
+#define HSCLK_PLL0_DIV2				1
+
+/* XCVR_DIAG_HSCLK_SEL */
+#define HSCLK_SEL_MODE3_MASK			GENMASK(13, 12)
+#define HSCLK_SEL_MODE3_HSCLK1			1
+
+/* CMN_PLL0_VCOCAL_START */
+#define VCO_CALIB_CODE_START_POINT_VAL_MASK	GENMASK(8, 0)
+
+/* CMN_DIAG_PLL0_FBH_OVRD */
+#define PLL_FEEDBACK_DIV_HI_OVERRIDE_EN		BIT(15)
+
+/* CMN_DIAG_PLL0_FBL_OVRD */
+#define PLL_FEEDBACK_DIV_LO_OVERRIDE_EN		BIT(15)
+
+/* CMN_DIAG_PLL0_PXL_DIVH */
+#define PLL_PCLK_DIV_EN				BIT(15)
+
+/* XCVR_DIAG_PLLDRC_CTRL */
+#define DPLL_CLK_SEL_MODE3			BIT(14)
+#define DPLL_DATA_RATE_DIV_MODE3_MASK		GENMASK(13, 12)
+
+/* TX_DIAG_TX_CTRL */
+#define TX_IF_SUBRATE_MODE3_MASK		GENMASK(7, 6)
+
+/* PHY_HDP_MODE_CTRL */
+#define POWER_STATE_A3_ACK			BIT(7)
+#define POWER_STATE_A2_ACK			BIT(6)
+#define POWER_STATE_A1_ACK			BIT(5)
+#define POWER_STATE_A0_ACK			BIT(4)
+#define POWER_STATE_A3				BIT(3)
+#define POWER_STATE_A2				BIT(2)
+#define POWER_STATE_A1				BIT(1)
+#define POWER_STATE_A0				BIT(0)
+
+/* PHY_PMA_ISO_CMN_CTRL */
+#define CMN_MACRO_PWR_EN_ACK			BIT(5)
+
+#define KEEP_ALIVE		0x18
+
+#define REF_CLK_27MHZ		27000000
+
+/* HDMI TX clock control settings */
+struct hdptx_hdmi_ctrl {
+	u32 pixel_clk_freq_min;
+	u32 pixel_clk_freq_max;
+	u32 feedback_factor;
+	u32 data_range_kbps_min;
+	u32 data_range_kbps_max;
+	u32 cmnda_pll0_ip_div;
+	u32 cmn_ref_clk_dig_div;
+	u32 ref_clk_divider_scaler;
+	u32 pll_fb_div_total;
+	u32 cmnda_pll0_fb_div_low;
+	u32 cmnda_pll0_fb_div_high;
+	u32 pixel_div_total;
+	u32 cmnda_pll0_pxdiv_low;
+	u32 cmnda_pll0_pxdiv_high;
+	u32 vco_freq_min;
+	u32 vco_freq_max;
+	u32 vco_ring_select;
+	u32 cmnda_hs_clk_0_sel;
+	u32 cmnda_hs_clk_1_sel;
+	u32 hsclk_div_at_xcvr;
+	u32 hsclk_div_tx_sub_rate;
+	u32 cmnda_pll0_hs_sym_div_sel;
+	u32 cmnda_pll0_clk_freq_min;
+	u32 cmnda_pll0_clk_freq_max;
+};
+
+struct cdns_hdptx_phy {
+	struct cdns_mhdp_base base;
+
+	void __iomem *regs;	/* DPTX registers base */
+	struct device *dev;
+	struct phy *phy;
+	struct clk *ref_clk, *apb_clk;
+	u32 ref_clk_rate;
+	bool power_up;
+	union {
+		struct phy_configure_opts_hdmi hdmi;
+		struct phy_configure_opts_dp dp;
+	};
+};
+
+/* HDMI TX clock control settings, pixel clock is output */
+static const struct hdptx_hdmi_ctrl pixel_clk_output_ctrl_table[] = {
+/*Minclk  Maxclk Fdbak  DR_min   DR_max  ip_d  dig  DS    Totl */
+{ 27000,  27000, 1000,  270000,  270000, 0x03, 0x1, 0x1,  240, 0x0bc, 0x030,  80, 0x026, 0x026, 2160000, 2160000, 0, 2, 2, 2, 4, 0x3,  27000,  27000},
+{ 27000,  27000, 1250,  337500,  337500, 0x03, 0x1, 0x1,  300, 0x0ec, 0x03c, 100, 0x030, 0x030, 2700000, 2700000, 0, 2, 2, 2, 4, 0x3,  33750,  33750},
+{ 27000,  27000, 1500,  405000,  405000, 0x03, 0x1, 0x1,  360, 0x11c, 0x048, 120, 0x03a, 0x03a, 3240000, 3240000, 0, 2, 2, 2, 4, 0x3,  40500,  40500},
+{ 27000,  27000, 2000,  540000,  540000, 0x03, 0x1, 0x1,  240, 0x0bc, 0x030,  80, 0x026, 0x026, 2160000, 2160000, 0, 2, 2, 2, 4, 0x2,  54000,  54000},
+{ 54000,  54000, 1000,  540000,  540000, 0x03, 0x1, 0x1,  480, 0x17c, 0x060,  80, 0x026, 0x026, 4320000, 4320000, 1, 2, 2, 2, 4, 0x3,  54000,  54000},
+{ 54000,  54000, 1250,  675000,  675000, 0x04, 0x1, 0x1,  400, 0x13c, 0x050,  50, 0x017, 0x017, 2700000, 2700000, 0, 1, 1, 2, 4, 0x2,  67500,  67500},
+{ 54000,  54000, 1500,  810000,  810000, 0x04, 0x1, 0x1,  480, 0x17c, 0x060,  60, 0x01c, 0x01c, 3240000, 3240000, 0, 2, 2, 2, 2, 0x2,  81000,  81000},
+{ 54000,  54000, 2000, 1080000, 1080000, 0x03, 0x1, 0x1,  240, 0x0bc, 0x030,  40, 0x012, 0x012, 2160000, 2160000, 0, 2, 2, 2, 1, 0x1, 108000, 108000},
+{ 74250,  74250, 1000,  742500,  742500, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  80, 0x026, 0x026, 5940000, 5940000, 1, 2, 2, 2, 4, 0x3,  74250,  74250},
+{ 74250,  74250, 1250,  928125,  928125, 0x04, 0x1, 0x1,  550, 0x1b4, 0x06e,  50, 0x017, 0x017, 3712500, 3712500, 1, 1, 1, 2, 4, 0x2,  92812,  92812},
+{ 74250,  74250, 1500, 1113750, 1113750, 0x04, 0x1, 0x1,  660, 0x20c, 0x084,  60, 0x01c, 0x01c, 4455000, 4455000, 1, 2, 2, 2, 2, 0x2, 111375, 111375},
+{ 74250,  74250, 2000, 1485000, 1485000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  40, 0x012, 0x012, 2970000, 2970000, 0, 2, 2, 2, 1, 0x1, 148500, 148500},
+{ 99000,  99000, 1000,  990000,  990000, 0x03, 0x1, 0x1,  440, 0x15c, 0x058,  40, 0x012, 0x012, 3960000, 3960000, 1, 2, 2, 2, 2, 0x2,  99000,  99000},
+{ 99000,  99000, 1250, 1237500, 1237500, 0x03, 0x1, 0x1,  275, 0x0d8, 0x037,  25, 0x00b, 0x00a, 2475000, 2475000, 0, 1, 1, 2, 2, 0x1, 123750, 123750},
+{ 99000,  99000, 1500, 1485000, 1485000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  30, 0x00d, 0x00d, 2970000, 2970000, 0, 2, 2, 2, 1, 0x1, 148500, 148500},
+{ 99000,  99000, 2000, 1980000, 1980000, 0x03, 0x1, 0x1,  440, 0x15c, 0x058,  40, 0x012, 0x012, 3960000, 3960000, 1, 2, 2, 2, 1, 0x1, 198000, 198000},
+{148500, 148500, 1000, 1485000, 1485000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  40, 0x012, 0x012, 5940000, 5940000, 1, 2, 2, 2, 2, 0x2, 148500, 148500},
+{148500, 148500, 1250, 1856250, 1856250, 0x04, 0x1, 0x1,  550, 0x1b4, 0x06e,  25, 0x00b, 0x00a, 3712500, 3712500, 1, 1, 1, 2, 2, 0x1, 185625, 185625},
+{148500, 148500, 1500, 2227500, 2227500, 0x03, 0x1, 0x1,  495, 0x188, 0x063,  30, 0x00d, 0x00d, 4455000, 4455000, 1, 1, 1, 2, 2, 0x1, 222750, 222750},
+{148500, 148500, 2000, 2970000, 2970000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  40, 0x012, 0x012, 5940000, 5940000, 1, 2, 2, 2, 1, 0x1, 297000, 297000},
+{198000, 198000, 1000, 1980000, 1980000, 0x03, 0x1, 0x1,  220, 0x0ac, 0x02c,  10, 0x003, 0x003, 1980000, 1980000, 0, 1, 1, 2, 1, 0x0, 198000, 198000},
+{198000, 198000, 1250, 2475000, 2475000, 0x03, 0x1, 0x1,  550, 0x1b4, 0x06e,  25, 0x00b, 0x00a, 4950000, 4950000, 1, 1, 1, 2, 2, 0x1, 247500, 247500},
+{198000, 198000, 1500, 2970000, 2970000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  15, 0x006, 0x005, 2970000, 2970000, 0, 1, 1, 2, 1, 0x0, 297000, 297000},
+{198000, 198000, 2000, 3960000, 3960000, 0x03, 0x1, 0x1,  440, 0x15c, 0x058,  20, 0x008, 0x008, 3960000, 3960000, 1, 1, 1, 2, 1, 0x0, 396000, 396000},
+{297000, 297000, 1000, 2970000, 2970000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  10, 0x003, 0x003, 2970000, 2970000, 0, 1, 1, 2, 1, 0x0, 297000, 297000},
+{297000, 297000, 1500, 4455000, 4455000, 0x03, 0x1, 0x1,  495, 0x188, 0x063,  15, 0x006, 0x005, 4455000, 4455000, 1, 1, 1, 2, 1, 0x0, 445500, 445500},
+{297000, 297000, 2000, 5940000, 5940000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  20, 0x008, 0x008, 5940000, 5940000, 1, 1, 1, 2, 1, 0x0, 594000, 594000},
+{594000, 594000, 1000, 5940000, 5940000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  10, 0x003, 0x003, 5940000, 5940000, 1, 1, 1, 2, 1, 0x0, 594000, 594000},
+{594000, 594000,  750, 4455000, 4455000, 0x03, 0x1, 0x1,  495, 0x188, 0x063,  10, 0x003, 0x003, 4455000, 4455000, 1, 1, 1, 2, 1, 0x0, 445500, 445500},
+{594000, 594000,  625, 3712500, 3712500, 0x04, 0x1, 0x1,  550, 0x1b4, 0x06e,  10, 0x003, 0x003, 3712500, 3712500, 1, 1, 1, 2, 1, 0x0, 371250, 371250},
+{594000, 594000,  500, 2970000, 2970000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  10, 0x003, 0x003, 5940000, 5940000, 1, 1, 1, 2, 2, 0x1, 297000, 297000},
+};
+
+/* HDMI TX PLL tuning settings */
+struct hdptx_hdmi_pll_tuning {
+	u32 vco_freq_bin;
+	u32 vco_freq_min;
+	u32 vco_freq_max;
+	u32 volt_to_current_coarse;
+	u32 volt_to_current;
+	u32 ndac_ctrl;
+	u32 pmos_ctrl;
+	u32 ptat_ndac_ctrl;
+	u32 feedback_div_total;
+	u32 charge_pump_gain;
+	u32 coarse_code;
+	u32 v2i_code;
+	u32 vco_cal_code;
+};
+
+/* HDMI TX PLL tuning settings, pixel clock is output */
+static const struct hdptx_hdmi_pll_tuning pixel_clk_output_pll_table[] = {
+/*bin VCO_freq min/max  coar  cod NDAC  PMOS PTAT div-T P-Gain Coa V2I CAL */
+{  1, 1980000, 1980000, 0x4, 0x3, 0x0, 0x09, 0x09, 220, 0x42, 160, 5, 183 },
+{  2, 2160000, 2160000, 0x4, 0x3, 0x0, 0x09, 0x09, 240, 0x42, 166, 6, 208 },
+{  3, 2475000, 2475000, 0x5, 0x3, 0x1, 0x00, 0x07, 275, 0x42, 167, 6, 209 },
+{  4, 2700000, 2700000, 0x5, 0x3, 0x1, 0x00, 0x07, 300, 0x42, 188, 6, 230 },
+{  4, 2700000, 2700000, 0x5, 0x3, 0x1, 0x00, 0x07, 400, 0x4c, 188, 6, 230 },
+{  5, 2970000, 2970000, 0x6, 0x3, 0x1, 0x00, 0x07, 330, 0x42, 183, 6, 225 },
+{  6, 3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 360, 0x42, 203, 7, 256 },
+{  6, 3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 480, 0x4c, 203, 7, 256 },
+{  7, 3712500, 3712500, 0x4, 0x3, 0x0, 0x07, 0x0F, 550, 0x4c, 212, 7, 257 },
+{  8, 3960000, 3960000, 0x5, 0x3, 0x0, 0x07, 0x0F, 440, 0x42, 184, 6, 226 },
+{  9, 4320000, 4320000, 0x5, 0x3, 0x1, 0x07, 0x0F, 480, 0x42, 205, 7, 258 },
+{ 10, 4455000, 4455000, 0x5, 0x3, 0x0, 0x07, 0x0F, 495, 0x42, 219, 7, 272 },
+{ 10, 4455000, 4455000, 0x5, 0x3, 0x0, 0x07, 0x0F, 660, 0x4c, 219, 7, 272 },
+{ 11, 4950000, 4950000, 0x6, 0x3, 0x1, 0x00, 0x07, 550, 0x42, 213, 7, 258 },
+{ 12, 5940000, 5940000, 0x7, 0x3, 0x1, 0x00, 0x07, 660, 0x42, 244, 8, 292 },
+};
+
+enum dp_link_rate {
+	RATE_1_6 = 162000,
+	RATE_2_1 = 216000,
+	RATE_2_4 = 243000,
+	RATE_2_7 = 270000,
+	RATE_3_2 = 324000,
+	RATE_4_3 = 432000,
+	RATE_5_4 = 540000,
+};
+
+#define MAX_LINK_RATE RATE_5_4
+
+struct phy_pll_reg {
+	u16 val[7];
+	u32 addr;
+};
+
+static const struct phy_pll_reg phy_pll_27m_cfg[] = {
+	/*  1.62    2.16    2.43    2.7     3.24    4.32    5.4      register address */
+	{{ 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e }, CMN_PLL0_VCOCAL_INIT_TMR },
+	{{ 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b }, CMN_PLL0_VCOCAL_ITER_TMR },
+	{{ 0x30b9, 0x3087, 0x3096, 0x30b4, 0x30b9, 0x3087, 0x30b4 }, CMN_PLL0_VCOCAL_START },
+	{{ 0x0077, 0x009f, 0x00b3, 0x00c7, 0x0077, 0x009f, 0x00c7 }, CMN_PLL0_INTDIV },
+	{{ 0xf9da, 0xf7cd, 0xf6c7, 0xf5c1, 0xf9da, 0xf7cd, 0xf5c1 }, CMN_PLL0_FRACDIV },
+	{{ 0x001e, 0x0028, 0x002d, 0x0032, 0x001e, 0x0028, 0x0032 }, CMN_PLL0_HIGH_THR },
+	{{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_PLL0_DSM_DIAG },
+	{{ 0x0000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x1000 }, CMN_PLLSM0_USER_DEF_CTRL },
+	{{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_OVRD },
+	{{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBH_OVRD },
+	{{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBL_OVRD },
+	{{ 0x0006, 0x0007, 0x0007, 0x0007, 0x0006, 0x0007, 0x0007 }, CMN_DIAG_PLL0_V2I_TUNE },
+	{{ 0x0043, 0x0043, 0x0043, 0x0042, 0x0043, 0x0043, 0x0042 }, CMN_DIAG_PLL0_CP_TUNE },
+	{{ 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008 }, CMN_DIAG_PLL0_LF_PROG },
+	{{ 0x0100, 0x0001, 0x0001, 0x0001, 0x0100, 0x0001, 0x0001 }, CMN_DIAG_PLL0_PTATIS_TUNE1 },
+	{{ 0x0007, 0x0001, 0x0001, 0x0001, 0x0007, 0x0001, 0x0001 }, CMN_DIAG_PLL0_PTATIS_TUNE2 },
+	{{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_DIAG_PLL0_TEST_MODE},
+	{{ 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016 }, CMN_PSM_CLK_CTRL }
+};
+
+static int dp_link_rate_index(u32 rate)
+{
+	switch (rate) {
+	case RATE_1_6:
+		return 0;
+	case RATE_2_1:
+		return 1;
+	case RATE_2_4:
+		return 2;
+	case RATE_2_7:
+		return 3;
+	case RATE_3_2:
+		return 4;
+	case RATE_4_3:
+		return 5;
+	case RATE_5_4:
+	default:
+		return 6;
+	}
+}
+
+static int cdns_phy_reg_write(struct cdns_hdptx_phy *cdns_phy, u32 addr, u32 val)
+{
+	return cdns_mhdp_reg_write(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), val);
+}
+
+static u32 cdns_phy_reg_read(struct cdns_hdptx_phy *cdns_phy, u32 addr)
+{
+	u32 reg32;
+
+	cdns_mhdp_reg_read(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), &reg32);
+
+	return reg32;
+}
+
+static void hdptx_dp_aux_cfg(struct cdns_hdptx_phy *cdns_phy)
+{
+	/* Power up Aux */
+	cdns_phy_reg_write(cdns_phy, TXDA_CYA_AUXDA_CYA, 1);
+
+	cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_1, 0x3);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_2, 36);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0100);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0300);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_3, 0x0000);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2008);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2018);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa018);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030c);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_5, 0x0000);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_4, 0x1001);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa098);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa198);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030d);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030f);
+}
+
+/* PMA common configuration for 27MHz */
+static void hdptx_dp_phy_pma_cmn_cfg_27mhz(struct cdns_hdptx_phy *cdns_phy)
+{
+	u32 num_lanes = cdns_phy->dp.lanes;
+	u16 val;
+	int k;
+
+	/* Enable PMA input ref clk(CMN_REF_CLK_RCV_EN) */
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_RCV_EN_MASK;
+	val |= FIELD_PREP(CMA_REF_CLK_RCV_EN_MASK, CMA_REF_CLK_RCV_EN);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+
+	/* Startup state machine registers */
+	cdns_phy_reg_write(cdns_phy, CMN_SSM_BIAS_TMR, 0x0087);
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLEN_TMR, 0x001b);
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLPRE_TMR, 0x0036);
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLVREF_TMR, 0x001b);
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLLOCK_TMR, 0x006c);
+
+	/* Current calibration registers */
+	cdns_phy_reg_write(cdns_phy, CMN_ICAL_INIT_TMR, 0x0044);
+	cdns_phy_reg_write(cdns_phy, CMN_ICAL_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_ICAL_ADJ_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_ICAL_ADJ_ITER_TMR, 0x0006);
+
+	/* Resistor calibration registers */
+	cdns_phy_reg_write(cdns_phy, CMN_TXPUCAL_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPUCAL_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPU_ADJ_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPU_ADJ_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPDCAL_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPDCAL_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPD_ADJ_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPD_ADJ_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_RXCAL_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_RXCAL_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_RX_ADJ_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_RX_ADJ_ITER_TMR, 0x0006);
+
+	for (k = 0; k < num_lanes; k = k + 1) {
+		/* Power state machine registers */
+		cdns_phy_reg_write(cdns_phy, XCVR_PSM_CAL_TMR  | (k << 9), 0x016d);
+		cdns_phy_reg_write(cdns_phy, XCVR_PSM_A0IN_TMR | (k << 9), 0x016d);
+		/* Transceiver control and diagnostic registers */
+		cdns_phy_reg_write(cdns_phy, XCVR_DIAG_LANE_FCM_EN_MGN_TMR | (k << 9), 0x00a2);
+		cdns_phy_reg_write(cdns_phy, TX_DIAG_BGREF_PREDRV_DELAY | (k << 9), 0x0097);
+		/* Transmitter receiver detect registers */
+		cdns_phy_reg_write(cdns_phy, TX_RCVDET_EN_TMR | (k << 9), 0x0a8c);
+		cdns_phy_reg_write(cdns_phy, TX_RCVDET_ST_TMR | (k << 9), 0x0036);
+	}
+
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_0, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_1, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_2, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_3, 1);
+}
+
+static void hdptx_dp_phy_pma_cmn_pll0_27mhz(struct cdns_hdptx_phy *cdns_phy)
+{
+	u32 num_lanes = cdns_phy->dp.lanes;
+	u32 link_rate = cdns_phy->dp.link_rate;
+	u16 val;
+	int index, i, k;
+
+	/* DP PLL data rate 0/1 clock divider value */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val &= ~PLL_DATA_RATE_CLK_DIV_MASK;
+	if (link_rate <= RATE_2_7)
+		val |= FIELD_PREP(PLL_DATA_RATE_CLK_DIV_MASK,
+				  PLL_DATA_RATE_CLK_DIV_HBR);
+	else
+		val |= FIELD_PREP(PLL_DATA_RATE_CLK_DIV_MASK,
+				  PLL_DATA_RATE_CLK_DIV_HBR2);
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+
+	/* High speed clock 0/1 div */
+	val = cdns_phy_reg_read(cdns_phy, CMN_DIAG_HSCLK_SEL);
+	val &= ~(HSCLK1_SEL_MASK | HSCLK0_SEL_MASK);
+	if (link_rate <= RATE_2_7) {
+		val |= FIELD_PREP(HSCLK1_SEL_MASK, HSCLK_PLL0_DIV2);
+		val |= FIELD_PREP(HSCLK0_SEL_MASK, HSCLK_PLL0_DIV2);
+	}
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_HSCLK_SEL, val);
+
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)));
+		val &= ~HSCLK_SEL_MODE3_MASK;
+		if (link_rate <= RATE_2_7)
+			val |= FIELD_PREP(HSCLK_SEL_MODE3_MASK, HSCLK_SEL_MODE3_HSCLK1);
+		cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)), val);
+	}
+
+	/* DP PHY PLL 27MHz configuration */
+	index = dp_link_rate_index(link_rate);
+	for (i = 0; i < ARRAY_SIZE(phy_pll_27m_cfg); i++)
+		cdns_phy_reg_write(cdns_phy, phy_pll_27m_cfg[i].addr,
+				   phy_pll_27m_cfg[i].val[index]);
+
+	/* Transceiver control and diagnostic registers */
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)));
+		val &= ~(DPLL_DATA_RATE_DIV_MODE3_MASK | DPLL_CLK_SEL_MODE3);
+		if (link_rate <= RATE_2_7)
+			val |= FIELD_PREP(DPLL_DATA_RATE_DIV_MODE3_MASK, 2);
+		else
+			val |= FIELD_PREP(DPLL_DATA_RATE_DIV_MODE3_MASK, 1);
+		cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val);
+	}
+
+	for (k = 0; k < num_lanes; k = k + 1) {
+		/* Power state machine registers */
+		cdns_phy_reg_write(cdns_phy, (XCVR_PSM_RCTRL | (k << 9)), 0xbefc);
+		cdns_phy_reg_write(cdns_phy, (TX_PSC_A0 | (k << 9)), 0x6799);
+		cdns_phy_reg_write(cdns_phy, (TX_PSC_A1 | (k << 9)), 0x6798);
+		cdns_phy_reg_write(cdns_phy, (TX_PSC_A2 | (k << 9)), 0x0098);
+		cdns_phy_reg_write(cdns_phy, (TX_PSC_A3 | (k << 9)), 0x0098);
+		/* Receiver calibration power state definition register */
+		val = cdns_phy_reg_read(cdns_phy, RX_PSC_CAL | (k << 9));
+		val &= 0xffbb;
+		cdns_phy_reg_write(cdns_phy, (RX_PSC_CAL | (k << 9)), val);
+		val = cdns_phy_reg_read(cdns_phy, RX_PSC_A0 | (k << 9));
+		val &= 0xffbb;
+		cdns_phy_reg_write(cdns_phy, (RX_PSC_A0 | (k << 9)), val);
+	}
+}
+
+static void hdptx_dp_phy_ref_clock_type(struct cdns_hdptx_phy *cdns_phy)
+{
+	u32 val;
+
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_SEL_MASK;
+	/*
+	 * single ended reference clock (val |= 0x0030);
+	 * differential clock  (val |= 0x0000);
+	 *
+	 * for differential clock on the refclk_p and
+	 * refclk_m off chip pins: CMN_DIAG_ACYA[8]=1'b1
+	 * cdns_phy_reg_write(cdns_phy, CMN_DIAG_ACYA, 0x0100);
+	 */
+	val |= FIELD_PREP(CMA_REF_CLK_SEL_MASK, 3);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+}
+
+static int wait_for_ack(struct cdns_hdptx_phy *cdns_phy, u32 reg, u32 mask,
+			const char *err_msg)
+{
+	u32 val, i;
+
+	for (i = 0; i < 10; i++) {
+		val = cdns_phy_reg_read(cdns_phy, reg);
+		if (val & mask)
+			return 0;
+		msleep(20);
+	}
+
+	dev_err(cdns_phy->dev, "%s\n", err_msg);
+	return -ETIMEDOUT;
+}
+
+static int wait_for_ack_clear(struct cdns_hdptx_phy *cdns_phy, u32 reg, u32 mask,
+			      const char *err_msg)
+{
+	u32 val, i;
+
+	for (i = 0; i < 10; i++) {
+		val = cdns_phy_reg_read(cdns_phy, reg);
+		if (!(val & mask))
+			return 0;
+		msleep(20);
+	}
+
+	dev_err(cdns_phy->dev, "%s\n", err_msg);
+	return -ETIMEDOUT;
+}
+
+static int hdptx_dp_phy_power_up(struct cdns_hdptx_phy *cdns_phy)
+{
+	u32 val;
+	int ret;
+
+	/* Enable HDP PLL's for high speed clocks */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val |= PLL_EN;
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+	ret = wait_for_ack(cdns_phy, PHY_HDP_CLK_CTL, PLL_READY,
+			   "Wait PLL Ack failed");
+	if (ret < 0)
+		return ret;
+
+	/* Enable HDP PLL's data rate and full rate clocks out of PMA. */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val |= PLL_CLK_EN;
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+	ret = wait_for_ack(cdns_phy, PHY_HDP_CLK_CTL, PLL_CLK_EN_ACK,
+			   "Wait PLL clock enable ACK failed");
+	if (ret < 0)
+		return ret;
+
+	/* Configure PHY in A2 Mode */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2);
+	ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2_ACK,
+			   "Wait A2 Ack failed");
+	if (ret < 0)
+		return ret;
+
+	/* Configure PHY in A0 mode (PHY must be in the A0 power
+	 * state in order to transmit data)
+	 */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0);
+	ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0_ACK,
+			   "Wait A0 Ack failed");
+	if (ret < 0)
+		return ret;
+
+	cdns_phy->power_up = true;
+
+	return ret;
+}
+
+static int hdptx_dp_phy_power_down(struct cdns_hdptx_phy *cdns_phy)
+{
+	u16 val;
+	int ret;
+
+	if (!cdns_phy->power_up)
+		return 0;
+
+	/* Place the PHY lanes in the A3 power state. */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3);
+	ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3_ACK,
+			   "Wait A3 Ack failed");
+	if (ret)
+		return ret;
+
+	/* Disable HDP PLL's data rate and full rate clocks out of PMA. */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val &= ~PLL_CLK_EN;
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+	ret = wait_for_ack_clear(cdns_phy, PHY_HDP_CLK_CTL, PLL_CLK_EN_ACK,
+				 "Wait PLL clock Ack clear failed");
+	if (ret)
+		return ret;
+
+	/* Disable HDP PLL's for high speed clocks */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val &= ~PLL_EN;
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+	ret = wait_for_ack_clear(cdns_phy, PHY_HDP_CLK_CTL, PLL_READY,
+				 "Wait PLL Ack clear failed");
+	if (ret)
+		return ret;
+
+	cdns_phy->power_up = false;
+	return 0;
+}
+
+static int cdns_hdptx_dp_configure(struct phy *phy,
+				   union phy_configure_opts *opts)
+{
+	struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
+
+	cdns_phy->dp.link_rate = opts->dp.link_rate;
+	cdns_phy->dp.lanes = opts->dp.lanes;
+
+	if (cdns_phy->dp.link_rate > MAX_LINK_RATE) {
+		dev_err(cdns_phy->dev, "Link Rate(%d) Not supported\n", cdns_phy->dp.link_rate);
+		return false;
+	}
+
+	/* Disable phy clock if PHY in power up state */
+	hdptx_dp_phy_power_down(cdns_phy);
+
+	if (cdns_phy->ref_clk_rate == REF_CLK_27MHZ) {
+		hdptx_dp_phy_pma_cmn_cfg_27mhz(cdns_phy);
+		hdptx_dp_phy_pma_cmn_pll0_27mhz(cdns_phy);
+	} else {
+		dev_err(cdns_phy->dev, "Not support ref clock rate\n");
+	}
+
+	/* PHY power up */
+	return hdptx_dp_phy_power_up(cdns_phy);
+}
+
+static bool hdptx_phy_check_alive(struct cdns_hdptx_phy *cdns_phy)
+{
+	u32  alive, newalive;
+	u8 retries_left = 50;
+
+	alive = readl(cdns_phy->regs + KEEP_ALIVE);
+
+	while (retries_left--) {
+		udelay(2);
+
+		newalive = readl(cdns_phy->regs + KEEP_ALIVE);
+		if (alive == newalive)
+			continue;
+		return true;
+	}
+	return false;
+}
+
+static int hdptx_clk_enable(struct cdns_hdptx_phy *cdns_phy)
+{
+	struct device *dev = cdns_phy->dev;
+	u32 ref_clk_rate;
+	int ret;
+
+	cdns_phy->ref_clk = devm_clk_get(dev, "ref");
+	if (IS_ERR(cdns_phy->ref_clk)) {
+		dev_err(dev, "phy ref clock not found\n");
+		return PTR_ERR(cdns_phy->ref_clk);
+	}
+
+	cdns_phy->apb_clk = devm_clk_get(dev, "apb");
+	if (IS_ERR(cdns_phy->apb_clk)) {
+		dev_err(dev, "phy apb clock not found\n");
+		return PTR_ERR(cdns_phy->apb_clk);
+	}
+
+	ret = clk_prepare_enable(cdns_phy->ref_clk);
+	if (ret) {
+		dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
+		return ret;
+	}
+
+	ref_clk_rate = clk_get_rate(cdns_phy->ref_clk);
+	if (!ref_clk_rate) {
+		dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
+		goto err_ref_clk;
+	}
+
+	if (ref_clk_rate == REF_CLK_27MHZ) {
+		cdns_phy->ref_clk_rate = ref_clk_rate;
+	} else {
+		dev_err(cdns_phy->dev, "Not support Ref Clock Rate(%dHz)\n", ref_clk_rate);
+		goto err_ref_clk;
+	}
+
+	ret = clk_prepare_enable(cdns_phy->apb_clk);
+	if (ret) {
+		dev_err(cdns_phy->dev, "Failed to prepare apb clock\n");
+		goto err_ref_clk;
+	}
+
+	return 0;
+
+err_ref_clk:
+	clk_disable_unprepare(cdns_phy->ref_clk);
+	return -EINVAL;
+}
+
+static void hdptx_clk_disable(struct cdns_hdptx_phy *cdns_phy)
+{
+	clk_disable_unprepare(cdns_phy->apb_clk);
+	clk_disable_unprepare(cdns_phy->ref_clk);
+}
+
+static void hdptx_hdmi_arc_config(struct cdns_hdptx_phy *cdns_phy)
+{
+	u16 txpu_calib_code;
+	u16 txpd_calib_code;
+	u16 txpu_adj_calib_code;
+	u16 txpd_adj_calib_code;
+	u16 prev_calib_code;
+	u16 new_calib_code;
+	u16 rdata;
+
+	/* Power ARC */
+	cdns_phy_reg_write(cdns_phy, TXDA_CYA_AUXDA_CYA, 0x0001);
+
+	prev_calib_code = cdns_phy_reg_read(cdns_phy, TX_DIG_CTRL_REG_2);
+	txpu_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPUCAL_CTRL);
+	txpd_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPDCAL_CTRL);
+	txpu_adj_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPU_ADJ_CTRL);
+	txpd_adj_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPD_ADJ_CTRL);
+
+	new_calib_code = ((txpu_calib_code + txpd_calib_code) / 2)
+		+ txpu_adj_calib_code + txpd_adj_calib_code;
+
+	if (new_calib_code != prev_calib_code) {
+		rdata = cdns_phy_reg_read(cdns_phy, TX_ANA_CTRL_REG_1);
+		rdata &= 0xdfff;
+		cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, rdata);
+		cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_2, new_calib_code);
+		mdelay(10);
+		rdata |= 0x2000;
+		cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, rdata);
+		usleep_range(150, 250);
+	}
+
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0100);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0300);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_3, 0x0000);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2008);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2018);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2098);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030c);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_5, 0x0010);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_4, 0x4001);
+	mdelay(5);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2198);
+	mdelay(5);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030d);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030f);
+}
+
+static void hdptx_hdmi_phy_set_vswing(struct cdns_hdptx_phy *cdns_phy)
+{
+	u32 k;
+	const u32 num_lanes = 4;
+
+	for (k = 0; k < num_lanes; k++) {
+		cdns_phy_reg_write(cdns_phy, (TX_DIAG_TX_DRV | (k << 9)),
+				   TX_DRIVER_PROG_BOOST_ENABLE |
+				   FIELD_PREP(TX_DRIVER_PROG_BOOST_LEVEL_MASK, 3) |
+				   TX_DRIVER_LDO_BG_DEPENDENT_REF_ENABLE |
+				   TX_DRIVER_LDO_BANDGAP_REF_ENABLE);
+		cdns_phy_reg_write(cdns_phy, (TX_TXCC_CPOST_MULT_00_0 | (k << 9)), 0x0);
+		cdns_phy_reg_write(cdns_phy, (TX_TXCC_CAL_SCLR_MULT_0 | (k << 9)),
+				   SCALED_RESISTOR_CALIBRATION_CODE_ADD |
+				   RESISTOR_CAL_MULT_VAL_32_128);
+	}
+}
+
+static int hdptx_hdmi_phy_config(struct cdns_hdptx_phy *cdns_phy,
+				 const struct hdptx_hdmi_ctrl *p_ctrl_table,
+				 const struct hdptx_hdmi_pll_tuning *p_pll_table,
+				 bool pclk_in)
+{
+	const u32 num_lanes = 4;
+	u32 val, k;
+	int ret;
+
+	/* enable PHY isolation mode only for CMN */
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISOLATION_CTRL, 0xd000);
+
+	/* set cmn_pll0_clk_datart1_div/cmn_pll0_clk_datart0_div dividers */
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_ISO_PLL_CTRL1);
+	val &= ~CMN_PLL0_CLK_DATART_DIV_MASK;
+	val |= FIELD_PREP(CMN_PLL0_CLK_DATART_DIV_MASK, 0x12);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_PLL_CTRL1, val);
+
+	/* assert PHY reset from isolation register */
+	cdns_phy_reg_write(cdns_phy, PHY_ISO_CMN_CTRL, 0x0000);
+	/* assert PMA CMN reset */
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0000);
+
+	/* register XCVR_DIAG_BIDI_CTRL */
+	for (k = 0; k < num_lanes; k++)
+		cdns_phy_reg_write(cdns_phy, XCVR_DIAG_BIDI_CTRL | (k << 9), 0x00ff);
+
+	/* Describing Task phy_cfg_hdp */
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_RCV_EN_MASK;
+	val |= FIELD_PREP(CMA_REF_CLK_RCV_EN_MASK, CMA_REF_CLK_RCV_EN);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+
+	/* PHY Registers */
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_DIG_DIV_MASK;
+	val |= FIELD_PREP(CMA_REF_CLK_DIG_DIV_MASK, p_ctrl_table->cmn_ref_clk_dig_div);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val &= ~PLL_DATA_RATE_CLK_DIV_MASK;
+	val |= FIELD_PREP(PLL_DATA_RATE_CLK_DIV_MASK,
+			  PLL_DATA_RATE_CLK_DIV_HBR2);
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+
+	/* Common control module control and diagnostic registers */
+	val = cdns_phy_reg_read(cdns_phy, CMN_CDIAG_REFCLK_CTRL);
+	val &= ~DIG_REF_CLK_DIV_SCALER_MASK;
+	val |= FIELD_PREP(DIG_REF_CLK_DIV_SCALER_MASK, p_ctrl_table->ref_clk_divider_scaler);
+	val |= REFCLK_TERMINATION_EN_OVERRIDE_EN | REFCLK_TERMINATION_EN_OVERRIDE;
+	cdns_phy_reg_write(cdns_phy, CMN_CDIAG_REFCLK_CTRL, val);
+
+	/* High speed clock used */
+	val = cdns_phy_reg_read(cdns_phy, CMN_DIAG_HSCLK_SEL);
+	val &= ~(HSCLK1_SEL_MASK | HSCLK0_SEL_MASK);
+	val |= FIELD_PREP(HSCLK1_SEL_MASK, (p_ctrl_table->cmnda_hs_clk_1_sel >> 1));
+	val |= FIELD_PREP(HSCLK0_SEL_MASK, (p_ctrl_table->cmnda_hs_clk_0_sel >> 1));
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_HSCLK_SEL, val);
+
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)));
+		val &= ~HSCLK_SEL_MODE3_MASK;
+		val |= FIELD_PREP(HSCLK_SEL_MODE3_MASK,
+				  (p_ctrl_table->cmnda_hs_clk_0_sel >> 1));
+		cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)), val);
+	}
+
+	/* PLL 0 control state machine registers */
+	val = p_ctrl_table->vco_ring_select << 12;
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_USER_DEF_CTRL, val);
+
+	if (pclk_in) {
+		val = 0x30a0;
+	} else {
+		val = cdns_phy_reg_read(cdns_phy, CMN_PLL0_VCOCAL_START);
+		val &= ~VCO_CALIB_CODE_START_POINT_VAL_MASK;
+		val |= FIELD_PREP(VCO_CALIB_CODE_START_POINT_VAL_MASK,
+				  p_pll_table->vco_cal_code);
+	}
+	cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_START, val);
+
+	cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_INIT_TMR, 0x0064);
+	cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_ITER_TMR, 0x000a);
+
+	/* Common functions control and diagnostics registers */
+	val = p_ctrl_table->cmnda_pll0_hs_sym_div_sel << 8;
+	val |= p_ctrl_table->cmnda_pll0_ip_div;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_INCLK_CTRL, val);
+
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_OVRD, 0x0000);
+
+	val = p_ctrl_table->cmnda_pll0_fb_div_high;
+	val |= PLL_FEEDBACK_DIV_HI_OVERRIDE_EN;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_FBH_OVRD, val);
+
+	val = p_ctrl_table->cmnda_pll0_fb_div_low;
+	val |= PLL_FEEDBACK_DIV_LO_OVERRIDE_EN;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_FBL_OVRD, val);
+
+	if (!pclk_in) {
+		val = p_ctrl_table->cmnda_pll0_pxdiv_low;
+		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PXL_DIVL, val);
+
+		val = p_ctrl_table->cmnda_pll0_pxdiv_high;
+		val |= PLL_PCLK_DIV_EN;
+		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PXL_DIVH, val);
+	}
+
+	val = p_pll_table->volt_to_current_coarse;
+	val |= (p_pll_table->volt_to_current) << 4;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_V2I_TUNE, val);
+
+	val = p_pll_table->charge_pump_gain;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_CP_TUNE, val);
+
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_LF_PROG, 0x0008);
+
+	val = p_pll_table->pmos_ctrl;
+	val |= (p_pll_table->ndac_ctrl) << 8;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PTATIS_TUNE1, val);
+
+	val = p_pll_table->ptat_ndac_ctrl;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PTATIS_TUNE2, val);
+
+	if (pclk_in)
+		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_TEST_MODE, 0x0022);
+	else
+		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_TEST_MODE, 0x0020);
+
+	cdns_phy_reg_write(cdns_phy, CMN_PSM_CLK_CTRL, 0x0016);
+
+	/* Transceiver control and diagnostic registers */
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)));
+		val &= ~DPLL_CLK_SEL_MODE3;
+		cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val);
+	}
+
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (TX_DIAG_TX_CTRL | (k << 9)));
+		val &= ~TX_IF_SUBRATE_MODE3_MASK;
+		val |= FIELD_PREP(TX_IF_SUBRATE_MODE3_MASK,
+				  (p_ctrl_table->hsclk_div_tx_sub_rate >> 1));
+		cdns_phy_reg_write(cdns_phy, (TX_DIAG_TX_CTRL | (k << 9)), val);
+	}
+
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_SEL_MASK;
+	/*
+	 * single ended reference clock (val |= 0x0030);
+	 * differential clock  (val |= 0x0000);
+	 * for differential clock on the refclk_p and
+	 * refclk_m off chip pins: CMN_DIAG_ACYA[8]=1'b1
+	 * cdns_phy_reg_write(cdns_phy, CMN_DIAG_ACYA, 0x0100);
+	 */
+	val |= FIELD_PREP(CMA_REF_CLK_SEL_MASK, 3);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+
+	/* Deassert PHY reset */
+	cdns_phy_reg_write(cdns_phy, PHY_ISO_CMN_CTRL, 0x0001);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0003);
+
+	/* Power state machine registers */
+	for (k = 0; k < num_lanes; k++)
+		cdns_phy_reg_write(cdns_phy, XCVR_PSM_RCTRL | (k << 9), 0xfefc);
+
+	/* Assert cmn_macro_pwr_en */
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0013);
+
+	/* wait for cmn_macro_pwr_en_ack */
+	ret = wait_for_ack(cdns_phy, PHY_PMA_ISO_CMN_CTRL, CMN_MACRO_PWR_EN_ACK,
+			   "MA output macro power up failed");
+	if (ret < 0)
+		return ret;
+
+	/* wait for cmn_ready */
+	ret = wait_for_ack(cdns_phy, PHY_PMA_CMN_CTRL1, CMN_READY,
+			   "PMA output ready failed");
+	if (ret < 0)
+		return ret;
+
+	for (k = 0; k < num_lanes; k++) {
+		cdns_phy_reg_write(cdns_phy, TX_PSC_A0 | (k << 9), 0x6791);
+		cdns_phy_reg_write(cdns_phy, TX_PSC_A1 | (k << 9), 0x6790);
+		cdns_phy_reg_write(cdns_phy, TX_PSC_A2 | (k << 9), 0x0090);
+		cdns_phy_reg_write(cdns_phy, TX_PSC_A3 | (k << 9), 0x0090);
+
+		val = cdns_phy_reg_read(cdns_phy, RX_PSC_CAL | (k << 9));
+		val &= 0xffbb;
+		cdns_phy_reg_write(cdns_phy, RX_PSC_CAL | (k << 9), val);
+
+		val = cdns_phy_reg_read(cdns_phy, RX_PSC_A0 | (k << 9));
+		val &= 0xffbb;
+		cdns_phy_reg_write(cdns_phy, RX_PSC_A0 | (k << 9), val);
+	}
+
+	return 0;
+}
+
+static int hdptx_hdmi_phy_cfg(struct cdns_hdptx_phy *cdns_phy, unsigned long long char_rate)
+{
+	const struct hdptx_hdmi_ctrl *p_ctrl_table;
+	const struct hdptx_hdmi_pll_tuning *p_pll_table;
+	const u32 refclk_freq_khz = cdns_phy->ref_clk_rate / 1000;
+	const bool pclk_in = false;
+	u32 char_rate_khz = char_rate / 1000;
+	u32 vco_freq, rate;
+	u32 div_total, i;
+
+	dev_dbg(cdns_phy->dev, "character clock: %d KHz\n ", char_rate_khz);
+
+	/* Get right row from the ctrl_table table.
+	 * check the character rate.
+	 */
+	for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++) {
+		rate = pixel_clk_output_ctrl_table[i].feedback_factor *
+		       pixel_clk_output_ctrl_table[i].pixel_clk_freq_min / 1000;
+		if (char_rate_khz == rate) {
+			p_ctrl_table = &pixel_clk_output_ctrl_table[i];
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(pixel_clk_output_ctrl_table)) {
+		dev_warn(cdns_phy->dev,
+			 "char clk (%d KHz) not supported\n", char_rate_khz);
+		return -EINVAL;
+	}
+
+	div_total = p_ctrl_table->pll_fb_div_total;
+	vco_freq = refclk_freq_khz * div_total / p_ctrl_table->cmnda_pll0_ip_div;
+
+	/* Get right row from the pixel_clk_output_pll_table table.
+	 * Check if vco_freq_khz and feedback_div_total
+	 * column matching with pixel_clk_output_pll_table.
+	 */
+	for (i = 0; i < ARRAY_SIZE(pixel_clk_output_pll_table); i++) {
+		if (vco_freq == pixel_clk_output_pll_table[i].vco_freq_min &&
+		    div_total == pixel_clk_output_pll_table[i].feedback_div_total) {
+			p_pll_table = &pixel_clk_output_pll_table[i];
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(pixel_clk_output_pll_table)) {
+		dev_warn(cdns_phy->dev, "VCO (%d KHz) not supported\n", vco_freq);
+		return -EINVAL;
+	}
+	dev_dbg(cdns_phy->dev, "VCO frequency is (%d KHz)\n", vco_freq);
+
+	return hdptx_hdmi_phy_config(cdns_phy, p_ctrl_table, p_pll_table, pclk_in);
+}
+
+static int hdptx_hdmi_phy_power_up(struct cdns_hdptx_phy *cdns_phy)
+{
+	int ret;
+
+	/* set Power State to A2 */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2);
+
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_0, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_1, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_2, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_3, 1);
+
+	ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2_ACK,
+			   "Wait A2 Ack failed");
+	if (ret < 0)
+		return ret;
+
+	/* Power up ARC */
+	hdptx_hdmi_arc_config(cdns_phy);
+
+	/* Configure PHY in A0 mode (PHY must be in the A0 power
+	 * state in order to transmit data)
+	 */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0);
+
+	return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0_ACK,
+			    "Wait A0 Ack failed");
+}
+
+static int hdptx_hdmi_phy_power_down(struct cdns_hdptx_phy *cdns_phy)
+{
+	u32 val;
+
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_MODE_CTRL);
+	val &= ~(POWER_STATE_A0 | POWER_STATE_A1 | POWER_STATE_A2 | POWER_STATE_A3);
+	/* PHY_DP_MODE_CTL set to A3 power state */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, val | POWER_STATE_A3);
+
+	return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3_ACK,
+			    "Wait A3 Ack failed");
+}
+
+static int cdns_hdptx_phy_on(struct phy *phy)
+{
+	struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
+
+	if (phy->attrs.mode == PHY_MODE_DP)
+		return hdptx_dp_phy_power_up(cdns_phy);
+	else
+		return hdptx_hdmi_phy_power_up(cdns_phy);
+}
+
+static int cdns_hdptx_phy_off(struct phy *phy)
+{
+	struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
+
+	if (phy->attrs.mode == PHY_MODE_DP)
+		return hdptx_dp_phy_power_down(cdns_phy);
+	else
+		return hdptx_hdmi_phy_power_down(cdns_phy);
+	return 0;
+}
+
+static int
+cdns_hdptx_phy_valid(struct phy *phy, enum phy_mode mode,
+		     int submode, union phy_configure_opts *opts)
+{
+	u32 rate = opts->hdmi.tmds_char_rate / 1000;
+	int i;
+
+	if (mode == PHY_MODE_DP)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++)
+		if (rate == pixel_clk_output_ctrl_table[i].pixel_clk_freq_min)
+			return 0;
+
+	return -EINVAL;
+}
+
+static int cdns_hdptx_phy_init(struct phy *phy)
+{
+	return 0;
+}
+
+static int cdns_hdptx_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+	struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
+	int ret = 0;
+
+	if (mode == PHY_MODE_DP) {
+		hdptx_dp_phy_ref_clock_type(cdns_phy);
+
+		/* PHY power up */
+		ret = hdptx_dp_phy_power_up(cdns_phy);
+		if (ret < 0)
+			return ret;
+
+		hdptx_dp_aux_cfg(cdns_phy);
+	} else if (mode != PHY_MODE_HDMI) {
+		dev_err(&phy->dev, "Invalid PHY mode: %u\n", mode);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static int cdns_hdptx_hdmi_configure(struct phy *phy,
+				     union phy_configure_opts *opts)
+{
+	struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
+	int ret;
+
+	cdns_phy->hdmi.tmds_char_rate = opts->hdmi.tmds_char_rate;
+
+	/* Check HDMI FW alive before HDMI PHY init */
+	ret = hdptx_phy_check_alive(cdns_phy);
+	if (!ret) {
+		dev_err(cdns_phy->dev, "NO HDMI FW running\n");
+		return -ENXIO;
+	}
+
+	/* Configure PHY */
+	if (hdptx_hdmi_phy_cfg(cdns_phy, cdns_phy->hdmi.tmds_char_rate) < 0) {
+		dev_err(cdns_phy->dev, "failed to set phy pclock\n");
+		return -EINVAL;
+	}
+
+	ret = hdptx_hdmi_phy_power_up(cdns_phy);
+	if (ret < 0)
+		return ret;
+
+	hdptx_hdmi_phy_set_vswing(cdns_phy);
+
+	return 0;
+}
+
+static int cdns_hdptx_configure(struct phy *phy,
+				union phy_configure_opts *opts)
+{
+	if (phy->attrs.mode == PHY_MODE_DP)
+		return cdns_hdptx_dp_configure(phy, opts);
+	else
+		return cdns_hdptx_hdmi_configure(phy, opts);
+}
+
+static const struct phy_ops cdns_hdptx_phy_ops = {
+	.init = cdns_hdptx_phy_init,
+	.set_mode = cdns_hdptx_phy_set_mode,
+	.configure = cdns_hdptx_configure,
+	.power_on = cdns_hdptx_phy_on,
+	.power_off = cdns_hdptx_phy_off,
+	.validate = cdns_hdptx_phy_valid,
+	.owner = THIS_MODULE,
+};
+
+static int cdns_hdptx_phy_probe(struct platform_device *pdev)
+{
+	struct cdns_hdptx_phy *cdns_phy;
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct phy_provider *phy_provider;
+	struct resource *res;
+	struct phy *phy;
+	int ret;
+
+	cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL);
+	if (!cdns_phy)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, cdns_phy);
+	cdns_phy->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+	cdns_phy->regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(cdns_phy->regs))
+		return PTR_ERR(cdns_phy->regs);
+
+	phy = devm_phy_create(dev, node, &cdns_hdptx_phy_ops);
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	cdns_phy->phy = phy;
+	phy_set_drvdata(phy, cdns_phy);
+
+	/* init base struct for access mhdp mailbox */
+	cdns_phy->base.dev = cdns_phy->dev;
+	cdns_phy->base.regs = cdns_phy->regs;
+
+	ret = hdptx_clk_enable(cdns_phy);
+	if (ret) {
+		dev_err(dev, "Init clk fail\n");
+		return -EINVAL;
+	}
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(phy_provider)) {
+		ret = PTR_ERR(phy_provider);
+		goto clk_disable;
+	}
+
+	dev_dbg(dev, "probe success!\n");
+
+	return 0;
+
+clk_disable:
+	hdptx_clk_disable(cdns_phy);
+
+	return -EINVAL;
+}
+
+static void cdns_hdptx_phy_remove(struct platform_device *pdev)
+{
+	struct cdns_hdptx_phy *cdns_phy = platform_get_drvdata(pdev);
+
+	hdptx_clk_disable(cdns_phy);
+}
+
+static const struct of_device_id cdns_hdptx_phy_of_match[] = {
+	{.compatible = "fsl,imx8mq-hdptx-phy" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, cdns_hdptx_phy_of_match);
+
+static struct platform_driver cdns_hdptx_phy_driver = {
+	.probe = cdns_hdptx_phy_probe,
+	.remove = cdns_hdptx_phy_remove,
+	.driver = {
+		.name	= "cdns-hdptx-phy",
+		.of_match_table	= cdns_hdptx_phy_of_match,
+	}
+};
+module_platform_driver(cdns_hdptx_phy_driver);
+
+MODULE_AUTHOR("Sandor Yu <sandor.yu at nxp.com>");
+MODULE_DESCRIPTION("Cadence HDP-TX DP/HDMI PHY driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From Sandor.yu at nxp.com  Tue Sep 24 00:36:52 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 24 Sep 2024 15:36:52 +0800
Subject: [PATCH v17 7/8] arm64: dts: imx8mq: Add DCSS + HDMI/DP display pipeline
In-Reply-To: <cover.1727159906.git.Sandor.yu@nxp.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <856a715c0ba66b42f215357653d46b254c289ea2.1727159906.git.Sandor.yu@nxp.com>

From: Alexander Stein <alexander.stein at ew.tq-group.com>

This adds DCSS + MHDP + MHDP PHY nodes. PHY mode (DP/HDMI) is selected
by the connector type connected to mhdp port at 1 endpoint.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 68 +++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index e03186bbc4152..6bd7d2b2aba2f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1602,6 +1602,74 @@ aips4: bus at 32c00000 { /* AIPS4 */
 			#size-cells = <1>;
 			ranges = <0x32c00000 0x32c00000 0x400000>;
 
+			mdhp_phy: phy at 32c00000 {
+				compatible = "fsl,imx8mq-hdptx-phy";
+				reg = <0x32c00000 0x100000>;
+				#phy-cells = <0>;
+				clocks = <&hdmi_phy_27m>, <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+				clock-names = "ref", "apb";
+			};
+
+			mhdp: bridge at 32c00000 {
+				compatible = "fsl,imx8mq-mhdp8501";
+				reg = <0x32c00000 0x100000>;
+				interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "plug_in", "plug_out";
+				clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+				phys = <&mdhp_phy>;
+				status = "disabled";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port at 0 {
+						reg = <0>;
+
+						mhdp_in: endpoint {
+							remote-endpoint = <&dcss_out>;
+						};
+					};
+
+					port at 1 {
+						reg = <1>;
+
+						mhdp_out: endpoint {
+						};
+					};
+				};
+			};
+
+			dcss: display-controller at 32e00000 {
+				compatible = "nxp,imx8mq-dcss";
+				reg = <0x32e00000 0x2d000>, <0x32e2f000 0x1000>;
+				interrupt-parent = <&irqsteer>;
+				interrupts = <6>, <8>, <9>;
+				interrupt-names = "ctxld", "ctxld_kick", "vblank";
+				clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>,
+					 <&clk IMX8MQ_CLK_DISP_AXI_ROOT>,
+					 <&clk IMX8MQ_CLK_DISP_RTRM_ROOT>,
+					 <&clk IMX8MQ_VIDEO2_PLL_OUT>,
+					 <&clk IMX8MQ_CLK_DISP_DTRC>;
+				clock-names = "apb", "axi", "rtrm", "pix", "dtrc";
+				assigned-clocks = <&clk IMX8MQ_CLK_DISP_AXI>,
+						  <&clk IMX8MQ_CLK_DISP_RTRM>,
+						  <&clk IMX8MQ_VIDEO2_PLL1_REF_SEL>;
+				assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_800M>,
+							 <&clk IMX8MQ_SYS1_PLL_800M>,
+							 <&clk IMX8MQ_CLK_27M>;
+				assigned-clock-rates = <800000000>,
+						       <400000000>;
+				status = "disabled";
+
+				port {
+					dcss_out: endpoint {
+						remote-endpoint = <&mhdp_in>;
+					};
+				};
+			};
+
 			irqsteer: interrupt-controller at 32e2d000 {
 				compatible = "fsl,imx8m-irqsteer", "fsl,imx-irqsteer";
 				reg = <0x32e2d000 0x1000>;
-- 
2.34.1



From Sandor.yu at nxp.com  Tue Sep 24 00:36:53 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 24 Sep 2024 15:36:53 +0800
Subject: [PATCH v17 8/8] arm64: dts: imx8mq: tqma8mq-mba8mx: Enable HDMI support
In-Reply-To: <cover.1727159906.git.Sandor.yu@nxp.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <8a0b928a420f86537b7eed9c708a3808992c9724.1727159906.git.Sandor.yu@nxp.com>

From: Alexander Stein <alexander.stein at ew.tq-group.com>

Add HDMI connector and connect it to MHDP output. Enable peripherals
for HDMI output.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 .../dts/freescale/imx8mq-tqma8mq-mba8mx.dts   | 20 +++++++++++++++++++
 arch/arm64/boot/dts/freescale/mba8mx.dtsi     | 11 ++++++++++
 2 files changed, 31 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
index 0165f3a259853..406c8229097cb 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
@@ -53,6 +53,10 @@ &btn2 {
 	gpios = <&gpio3 17 GPIO_ACTIVE_LOW>;
 };
 
+&dcss {
+	status = "okay";
+};
+
 &gpio_leds {
 	led3 {
 		label = "led3";
@@ -60,6 +64,14 @@ led3 {
 	};
 };
 
+&hdmi_connector {
+	port {
+		hdmi_connector_in: endpoint {
+			remote-endpoint = <&mhdp_out>;
+		};
+	};
+};
+
 &i2c1 {
 	expander2: gpio at 25 {
 		compatible = "nxp,pca9555";
@@ -91,6 +103,14 @@ &led2 {
 	gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>;
 };
 
+&mhdp {
+	status = "okay";
+};
+
+&mhdp_out {
+	remote-endpoint = <&hdmi_connector_in>;
+};
+
 /* PCIe slot on X36 */
 &pcie0 {
 	reset-gpio = <&expander0 14 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm64/boot/dts/freescale/mba8mx.dtsi b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
index c60c7a9e54aff..fedc284ebb506 100644
--- a/arch/arm64/boot/dts/freescale/mba8mx.dtsi
+++ b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
@@ -89,6 +89,17 @@ gpio_delays: gpio-delays {
 		gpio-line-names = "LVDS_BRIDGE_EN_1V8";
 	};
 
+	hdmi_connector: connector {
+		compatible = "hdmi-connector";
+		label = "X11";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+			};
+		};
+	};
+
 	panel: panel-lvds {
 		/*
 		 * Display is not fixed, so compatible has to be added from
-- 
2.34.1



From krzk at kernel.org  Tue Sep 24 00:56:41 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 24 Sep 2024 09:56:41 +0200
Subject: [RESEND PATCH 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <1f996322-e6f6-4dd5-a1d7-c2bde92c876b@rock-chips.com>
References: <20240923025326.10467-1-frank.wang@rock-chips.com>
 <snccizbw6thn3lhwad4xppp7vqii4p56ttl2gufwc3ke7vfckf@e4b7nvwwtdfr>
 <1f996322-e6f6-4dd5-a1d7-c2bde92c876b@rock-chips.com>
Message-ID: <e77cab18-155a-4174-bca0-5ff1ce1d2b6f@kernel.org>

On 24/09/2024 04:24, Frank Wang wrote:
> Hi Krzysztof,
> On 2024/9/23 17:31, Krzysztof Kozlowski wrote:
>> On Mon, Sep 23, 2024 at 10:53:25AM +0800, Frank Wang wrote:
>>> Add compatible for the USB2 phy in the Rockchip RK3576 SoC.
>>>
>>> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
>>> ---
>>>   .../devicetree/bindings/phy/rockchip,inno-usb2phy.yaml | 10 +++++++++-
>>>   1 file changed, 9 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>>> index 5254413137c64..214917e55c0b6 100644
>>> --- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>>> +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>>> @@ -20,6 +20,7 @@ properties:
>>>         - rockchip,rk3366-usb2phy
>>>         - rockchip,rk3399-usb2phy
>>>         - rockchip,rk3568-usb2phy
>>> +      - rockchip,rk3576-usb2phy
>>>         - rockchip,rk3588-usb2phy
>>>         - rockchip,rv1108-usb2phy
>>>   
>>> @@ -34,10 +35,16 @@ properties:
>>>       const: 0
>>>   
>>>     clocks:
>>> -    maxItems: 1
>>> +    minItems: 1
>>> +    items:
>>> +      - description: phyclk - PHY input reference clocks.
>>> +      - description: aclk and aclk_slv are optional and used for USB MMU.
>>>   
>>>     clock-names:
>>> +    minItems: 1
>>>       const: phyclk
>>> +    const: aclk
>>> +    const: aclk_slv
>> Please test... Not sure what you wanted to achieve here, but maybe
>> oneOf?
> 
> The "aclk" and "aclk_slv" clocks are new in RK3576, you mean the changes 
> should be like the below?
> 
> @@ -34,10 +35,20 @@ properties:
>  ???? const: 0
> 
>  ?? clocks:
> -??? maxItems: 1
> +??? minItems: 1
> +??? maxItems: 3
> 
>  ?? clock-names:
> -??? const: phyclk
> +??? minItems: 1
> +??? maxItems: 3
> +??? items:
> +????? oneOf:
> +??????? - description: PHY input reference clocks.
> +????????? const: phyclk
> +??????? - description: aclk for USB MMU.
> +????????? const: aclk
> +??????? - description: aclk_slv for USB MMU.
> +????????? const: aclk_slv

Nope, you just messed the order. Order is strict.

Best regards,
Krzysztof



From krzk at kernel.org  Tue Sep 24 01:18:17 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 24 Sep 2024 10:18:17 +0200
Subject: [PATCH v3 1/5] dt-bindings: phy: Add eDP PHY compatible for
 sa8775p
In-Reply-To: <20240923113150.24711-2-quic_mukhopad@quicinc.com>
References: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
 <20240923113150.24711-2-quic_mukhopad@quicinc.com>
Message-ID: <vxyvyfab3m3yp4s6lraympgukmpxo2zjmh4irxu3lwxzve7mrn@jykursrajsrd>

On Mon, Sep 23, 2024 at 05:01:46PM +0530, Soutrik Mukhopadhyay wrote:
> Add compatible string for the supported eDP PHY on sa8775p platform.
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

As explained in reply to Konrad in v2, reviewed-by was given by mistake.
Please drop on next submit.

> Acked-by: Krzysztof Kozlowski <krzk at kernel.org>
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
> v2: No change
> 
> v3: No change

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Tue Sep 24 01:26:39 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 24 Sep 2024 10:26:39 +0200
Subject: [PATCH v17 3/8] dt-bindings: display: bridge: Add Cadence
 MHDP8501
In-Reply-To: <b2e1d26f964a03163ec7a1ba6ac8d7c88d6cb111.1727159906.git.Sandor.yu@nxp.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
 <b2e1d26f964a03163ec7a1ba6ac8d7c88d6cb111.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <wfdanj6ibwybx2puqvi6xjy6h5t4yagnb2mod7ln3zca4dl5wz@4mvbe6wjavb6>

On Tue, Sep 24, 2024 at 03:36:48PM +0800, Sandor Yu wrote:
> Add bindings for Cadence MHDP8501 DisplayPort/HDMI bridge.
> 
> Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Drop

> ---
> v16->v17:
> - Add lane-mapping property

That's a significant change.

> 
> v9->v16:
>  *No change
> 
> .../display/bridge/cdns,mhdp8501.yaml         | 109 ++++++++++++++++++
>  1 file changed, 109 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
> new file mode 100644
> index 0000000000000..3f79f328c7425
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml

> @@ -0,0 +1,109 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/bridge/cdns,mhdp8501.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Cadence MHDP8501 DP/HDMI bridge
> +
> +maintainers:
> +  - Sandor Yu <Sandor.yu at nxp.com>
> +
> +description:
> +  Cadence MHDP8501 DisplayPort/HDMI interface.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - fsl,imx8mq-mhdp8501
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +    description: MHDP8501 DP/HDMI APB clock.
> +
> +  phys:
> +    maxItems: 1
> +    description:
> +      phandle to the DP/HDMI PHY
> +
> +  interrupts:
> +    items:
> +      - description: Hotplug cable plugin.
> +      - description: Hotplug cable plugout.
> +
> +  interrupt-names:
> +    items:
> +      - const: plug_in
> +      - const: plug_out
> +
> +  lane-mapping:
> +    description: lane mapping for HDMI or DisplayPort interface.

Where is the definition of this property? I do not see any $ref here, so
did you add it to dtschema?

Best regards,
Krzysztof



From alexander.stein at ew.tq-group.com  Tue Sep 24 01:41:26 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 24 Sep 2024 10:41:26 +0200
Subject: [PATCH v17 1/8] drm: bridge: Cadence: Create mhdp helper driver
In-Reply-To: <6e2e4951aa4c69eed68af231c2b0b2ce302b2358.1727159906.git.Sandor.yu@nxp.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com> <6e2e4951aa4c69eed68af231c2b0b2ce302b2358.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <2773403.mvXUDI8C0e@steina-w>

Hi Sandor,

Am Dienstag, 24. September 2024, 09:36:46 CEST schrieb Sandor Yu:
> MHDP8546 mailbox access functions will be share to other mhdp driver
> and Cadence HDP-TX HDMI/DP PHY drivers.
> Create a new mhdp helper driver and move all those functions into.
> 
> cdns_mhdp_reg_write() is renamed to cdns_mhdp_dp_reg_write(),
> because it use the DPTX command ID DPTX_WRITE_REGISTER.
> 
> New cdns_mhdp_reg_write() is created with the general command ID
> GENERAL_REGISTER_WRITE.
> 
> Rewrite cdns_mhdp_set_firmware_active() in mhdp8546 core driver,
> use cdns_mhdp_mailbox_send() to replace cdns_mhdp_mailbox_write()
> same as the other mailbox access functions.
> 
> Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex
> to prevent race conditions in mailbox access by multi drivers.
> 
> Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> ---
> v16->v17:
> - Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex
> 
> v12->v16:
>  *No change.
> 
> V11->v12:
> - Move status initialize out of mbox_mutex.
> - Reorder API functions in alphabetical.
> - Add notes for malibox access functions.
> - Add year 2024 to copyright.
> 
>  drivers/gpu/drm/bridge/cadence/Kconfig        |   4 +
>  drivers/gpu/drm/bridge/cadence/Makefile       |   1 +
>  .../gpu/drm/bridge/cadence/cdns-mhdp-helper.c | 307 +++++++++++++
>  .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 425 ++++--------------
>  .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  47 +-
>  .../drm/bridge/cadence/cdns-mhdp8546-hdcp.c   |  36 +-
>  include/drm/bridge/cdns-mhdp-helper.h         |  94 ++++
>  7 files changed, 507 insertions(+), 407 deletions(-)
>  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
>  create mode 100644 include/drm/bridge/cdns-mhdp-helper.h
> 
> diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig
> index cced81633ddcd..e0973339e9e33 100644
> --- a/drivers/gpu/drm/bridge/cadence/Kconfig
> +++ b/drivers/gpu/drm/bridge/cadence/Kconfig
> @@ -21,6 +21,9 @@ config DRM_CDNS_DSI_J721E
>  	  the routing of the DSS DPI signal to the Cadence DSI.
>  endif
>  
> +config CDNS_MHDP_HELPER
> +	tristate
> +
>  config DRM_CDNS_MHDP8546
>  	tristate "Cadence DPI/DP bridge"
>  	select DRM_DISPLAY_DP_HELPER
> @@ -28,6 +31,7 @@ config DRM_CDNS_MHDP8546
>  	select DRM_DISPLAY_HELPER
>  	select DRM_KMS_HELPER
>  	select DRM_PANEL_BRIDGE
> +	select CDNS_MHDP_HELPER
>  	depends on OF
>  	help
>  	  Support Cadence DPI to DP bridge. This is an internal
> diff --git a/drivers/gpu/drm/bridge/cadence/Makefile b/drivers/gpu/drm/bridge/cadence/Makefile
> index c95fd5b81d137..087dc074820d7 100644
> --- a/drivers/gpu/drm/bridge/cadence/Makefile
> +++ b/drivers/gpu/drm/bridge/cadence/Makefile
> @@ -2,6 +2,7 @@
>  obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
>  cdns-dsi-y := cdns-dsi-core.o
>  cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.o
> +obj-$(CONFIG_CDNS_MHDP_HELPER) += cdns-mhdp-helper.o
>  obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
>  cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
>  cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
> diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
> new file mode 100644
> index 0000000000000..c60a6b69a5343
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
> @@ -0,0 +1,307 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2023, 2024 NXP Semiconductor, Inc.
> + *
> + */
> +#include <drm/bridge/cdns-mhdp-helper.h>
> +#include <linux/dev_printk.h>
> +#include <linux/module.h>
> +
> +/* Protects mailbox communications with the firmware */
> +DEFINE_MUTEX(mhdp_mailbox_mutex);

This is not enough if the driver is built as a module:

> ERROR: modpost: "mhdp_mailbox_mutex"
> [drivers/gpu/drm/bridge/cadence/cdns-mhdp8546.ko] undefined! ERROR:
> modpost: "mhdp_mailbox_mutex"
> [drivers/gpu/drm/bridge/cadence/cdns-mhdp8501.ko] undefined!

Not sure if EXPORT_SYMBOL_GPL() on a mutex is considered good style.

Best regards,
Alexander

> [snip]
-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From angelogioacchino.delregno at collabora.com  Tue Sep 24 01:41:41 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 24 Sep 2024 10:41:41 +0200
Subject: [PATCH] phy: phy-rockchip-samsung-hdptx: Depend on
 CONFIG_COMMON_CLK
In-Reply-To: <20240923-sam-hdptx-link-fix-v1-1-8d10d7456305@collabora.com>
References: <20240923-sam-hdptx-link-fix-v1-1-8d10d7456305@collabora.com>
Message-ID: <9a7b67a4-f4aa-44df-8933-876396e873d9@collabora.com>

Il 23/09/24 18:40, Cristian Ciocaltea ha scritto:
> Ensure CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX depends on CONFIG_COMMON_CLK to
> fix the following link errors when compile testing some random kernel
> configurations:
> 
>    m68k-linux-ld: drivers/phy/rockchip/phy-rockchip-samsung-hdptx.o: in function `rk_hdptx_phy_clk_register':
>    drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c:1031:(.text+0x470): undefined reference to `__clk_get_name'
>    m68k-linux-ld: drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c:1036:(.text+0x4ba): undefined reference to `devm_clk_hw_register'
>    m68k-linux-ld: drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c:1040:(.text+0x4d2): undefined reference to `of_clk_hw_simple_get'
>    m68k-linux-ld: drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c:1040:(.text+0x4da): undefined reference to `devm_of_clk_add_hw_provider'
> 
> Fixes: c4b09c562086 ("phy: phy-rockchip-samsung-hdptx: Add clock provider support")
> Reported-by: kernel test robot <lkp at intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202409180305.53PXymZn-lkp at intel.com/
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From krzk at kernel.org  Tue Sep 24 01:43:02 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 24 Sep 2024 10:43:02 +0200
Subject: [PATCH v3 4/5] dt-bindings: display: msm: dp-controller:
 document SA8775P compatible
In-Reply-To: <20240923113150.24711-5-quic_mukhopad@quicinc.com>
References: <20240923113150.24711-1-quic_mukhopad@quicinc.com>
 <20240923113150.24711-5-quic_mukhopad@quicinc.com>
Message-ID: <6v3wtdxcooi6qfolj5bfbgeru4uyawj6bsbfcnxu3lspuuhsi6@ysmb435njcul>

On Mon, Sep 23, 2024 at 05:01:49PM +0530, Soutrik Mukhopadhyay wrote:
> Add compatible string for the DisplayPort controller found on the
> Qualcomm SA8775P platform.
> 
> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad at quicinc.com>
> ---
> v2: No change
> 
> v3: No change

Acked-by: Krzysztof Kozlowski <krzk at kernel.org>

Best regards,
Krzysztof



From krzk at kernel.org  Tue Sep 24 01:43:29 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 24 Sep 2024 10:43:29 +0200
Subject: [PATCH v3 1/6] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document the X1E80100 QMP PCIe PHY Gen4 x8
In-Reply-To: <20240923125713.3411487-2-quic_qianyu@quicinc.com>
References: <20240923125713.3411487-1-quic_qianyu@quicinc.com>
 <20240923125713.3411487-2-quic_qianyu@quicinc.com>
Message-ID: <znnzcqujrz4cc3uimwymwizf4yvhsos3ky5vwhkxmopootmu2d@3yglev5si6fn>

On Mon, Sep 23, 2024 at 05:57:08AM -0700, Qiang Yu wrote:
> PCIe 3rd instance of X1E80100 supports Gen 4 x8 which needs different
> 8 lane capable QMP PCIe PHY with hardware revision v6.30. Document Gen
> 4 x8 PHY as separate module.
> 
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> ---
>  .../devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml    | 3 +++
>  1 file changed, 3 insertions(+)

Reviewed-by: Krzysztof Kozlowski <krzk at kernel.org>

Best regards,
Krzysztof



From frawang.cn at gmail.com  Tue Sep 24 01:55:09 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Tue, 24 Sep 2024 16:55:09 +0800
Subject: [PATCH v2 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add rk3576
Message-ID: <20240924085510.20863-1-frawang.cn@gmail.com>

From: Frank Wang <frank.wang at rock-chips.com>

Add compatible for the USB2 phy in the Rockchip RK3576 SoC.

Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
---
Changelog:
v2:
 - Categorize clock names by oneOf keyword.

v1:
 - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-1-frank.wang at rock-chips.com/

 .../bindings/phy/rockchip,inno-usb2phy.yaml      | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
index 5254413137c64..8af4e0f8637fc 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
@@ -20,6 +20,7 @@ properties:
       - rockchip,rk3366-usb2phy
       - rockchip,rk3399-usb2phy
       - rockchip,rk3568-usb2phy
+      - rockchip,rk3576-usb2phy
       - rockchip,rk3588-usb2phy
       - rockchip,rv1108-usb2phy
 
@@ -34,10 +35,20 @@ properties:
     const: 0
 
   clocks:
-    maxItems: 1
+    minItems: 1
+    maxItems: 3
 
   clock-names:
-    const: phyclk
+    minItems: 1
+    maxItems: 3
+    items:
+      oneOf:
+        - description: aclk for USB MMU.
+          const: aclk
+        - description: aclk_slv for USB MMU.
+          const: aclk_slv
+        - description: PHY input reference clocks.
+          const: phyclk
 
   assigned-clocks:
     description:
@@ -143,6 +154,7 @@ allOf:
           contains:
             enum:
               - rockchip,rk3568-usb2phy
+              - rockchip,rk3576-usb2phy
               - rockchip,rk3588-usb2phy
 
     then:
-- 
2.45.2



From dmitry.baryshkov at linaro.org  Tue Sep 24 01:55:17 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 24 Sep 2024 11:55:17 +0300
Subject: [PATCH v17 3/8] dt-bindings: display: bridge: Add Cadence
 MHDP8501
In-Reply-To: <b2e1d26f964a03163ec7a1ba6ac8d7c88d6cb111.1727159906.git.Sandor.yu@nxp.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
 <b2e1d26f964a03163ec7a1ba6ac8d7c88d6cb111.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <w72m4bxymngdadhp4x3mxyvv4j6k3mgtoqg3tcw4p3xdmhfpmx@wbkmfj3zmwcv>

On Tue, Sep 24, 2024 at 03:36:48PM GMT, Sandor Yu wrote:
> Add bindings for Cadence MHDP8501 DisplayPort/HDMI bridge.
> 
> Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
> v16->v17:
> - Add lane-mapping property
> 
> v9->v16:
>  *No change
> 
> .../display/bridge/cdns,mhdp8501.yaml         | 109 ++++++++++++++++++
>  1 file changed, 109 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
> new file mode 100644
> index 0000000000000..3f79f328c7425
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
> @@ -0,0 +1,109 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/bridge/cdns,mhdp8501.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Cadence MHDP8501 DP/HDMI bridge
> +
> +maintainers:
> +  - Sandor Yu <Sandor.yu at nxp.com>
> +
> +description:
> +  Cadence MHDP8501 DisplayPort/HDMI interface.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - fsl,imx8mq-mhdp8501
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +    description: MHDP8501 DP/HDMI APB clock.
> +
> +  phys:
> +    maxItems: 1
> +    description:
> +      phandle to the DP/HDMI PHY
> +
> +  interrupts:
> +    items:
> +      - description: Hotplug cable plugin.
> +      - description: Hotplug cable plugout.
> +
> +  interrupt-names:
> +    items:
> +      - const: plug_in
> +      - const: plug_out
> +
> +  lane-mapping:
> +    description: lane mapping for HDMI or DisplayPort interface.
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description:
> +          Input port from display controller output.
> +      port at 1:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description:
> +          Output port to DisplayPort or HDMI connector.
> +
> +    required:
> +      - port at 0
> +      - port at 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - interrupts
> +  - interrupt-names
> +  - phys
> +  - lane-mapping
> +  - ports
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/imx8mq-clock.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    mhdp: display-bridge at 32c00000 {
> +        compatible = "fsl,imx8mq-mhdp8501";
> +        reg = <0x32c00000 0x100000>;
> +        interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
> +                     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
> +        interrupt-names = "plug_in", "plug_out";
> +        clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
> +        phys = <&mdhp_phy>;
> +        lane-mapping = <0xe4>;

What does this value mean? The DT should be describing the hardware, not
the register values. Can it be expressed as the data-lanes property of
the corresponding port?

> +
> +        ports {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            port at 0 {
> +                reg = <0>;
> +
> +                mhdp_in: endpoint {
> +                    remote-endpoint = <&dcss_out>;
> +                };
> +            };
> +
> +            port at 1 {
> +                reg = <1>;
> +
> +                mhdp_out: endpoint {
> +                    remote-endpoint = <&dp_connector>;
> +                };
> +            };
> +        };
> +    };
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From frawang.cn at gmail.com  Tue Sep 24 01:55:10 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Tue, 24 Sep 2024 16:55:10 +0800
Subject: [PATCH v2 2/2] phy: rockchip: inno-usb2: Add usb2 phys support for rk3576
In-Reply-To: <20240924085510.20863-1-frawang.cn@gmail.com>
References: <20240924085510.20863-1-frawang.cn@gmail.com>
Message-ID: <20240924085510.20863-2-frawang.cn@gmail.com>

From: William Wu <william.wu at rock-chips.com>

The RK3576 SoC has two independent USB2.0 PHYs, and
each PHY has one port.

Signed-off-by: William Wu <william.wu at rock-chips.com>
Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
---
Changelog:
v2:
 - no changes.

v1:
 - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-2-frank.wang at rock-chips.com/

 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 131 ++++++++++++++++--
 1 file changed, 123 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 4f71373ae6e1a..51ca16cbb86cb 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -229,9 +229,10 @@ struct rockchip_usb2phy_port {
  * @dev: pointer to device.
  * @grf: General Register Files regmap.
  * @usbgrf: USB General Register Files regmap.
- * @clk: clock struct of phy input clk.
+ * @clks: array of phy input clocks.
  * @clk480m: clock struct of phy output clk.
  * @clk480m_hw: clock struct of phy output clk management.
+ * @num_clks: number of phy input clocks.
  * @phy_reset: phy reset control.
  * @chg_state: states involved in USB charger detection.
  * @chg_type: USB charger types.
@@ -246,9 +247,10 @@ struct rockchip_usb2phy {
 	struct device	*dev;
 	struct regmap	*grf;
 	struct regmap	*usbgrf;
-	struct clk	*clk;
+	struct clk_bulk_data	*clks;
 	struct clk	*clk480m;
 	struct clk_hw	clk480m_hw;
+	int			num_clks;
 	struct reset_control	*phy_reset;
 	enum usb_chg_state	chg_state;
 	enum power_supply_type	chg_type;
@@ -376,6 +378,7 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
 {
 	struct device_node *node = rphy->dev->of_node;
 	struct clk_init_data init;
+	struct clk *refclk = of_clk_get_by_name(node, "phyclk");
 	const char *clk_name;
 	int ret = 0;
 
@@ -386,8 +389,8 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
 	/* optional override of the clockname */
 	of_property_read_string(node, "clock-output-names", &init.name);
 
-	if (rphy->clk) {
-		clk_name = __clk_get_name(rphy->clk);
+	if (!IS_ERR(refclk)) {
+		clk_name = __clk_get_name(refclk);
 		init.parent_names = &clk_name;
 		init.num_parents = 1;
 	} else {
@@ -1406,22 +1409,29 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 	if (IS_ERR(rphy->phy_reset))
 		return PTR_ERR(rphy->phy_reset);
 
-	rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk");
-	if (IS_ERR(rphy->clk)) {
-		return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk),
+	ret = devm_clk_bulk_get_all(dev, &rphy->clks);
+	if (ret == -EPROBE_DEFER) {
+		return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
 				     "failed to get phyclk\n");
 	}
 
+	/* Clocks are optional */
+	rphy->num_clks = ret < 0 ? 0 : ret;
+
 	ret = rockchip_usb2phy_clk480m_register(rphy);
 	if (ret) {
 		dev_err(dev, "failed to register 480m output clock\n");
 		return ret;
 	}
 
+	ret = clk_bulk_prepare_enable(rphy->num_clks, rphy->clks);
+	if (ret)
+		return ret;
+
 	if (rphy->phy_cfg->phy_tuning) {
 		ret = rphy->phy_cfg->phy_tuning(rphy);
 		if (ret)
-			return ret;
+			goto disable_clks;
 	}
 
 	index = 0;
@@ -1484,6 +1494,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 
 put_child:
 	of_node_put(child_np);
+disable_clks:
+	clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks);
 	return ret;
 }
 
@@ -1495,6 +1507,30 @@ static int rk3128_usb2phy_tuning(struct rockchip_usb2phy *rphy)
 				BIT(2) << BIT_WRITEABLE_SHIFT | 0);
 }
 
+static int rk3576_usb2phy_tuning(struct rockchip_usb2phy *rphy)
+{
+	int ret;
+	u32 reg = rphy->phy_cfg->reg;
+
+	/* Deassert SIDDQ to power on analog block */
+	ret = regmap_write(rphy->grf, reg + 0x0010, GENMASK(29, 29) | 0x0000);
+	if (ret)
+		return ret;
+
+	/* Do reset after exit IDDQ mode */
+	ret = rockchip_usb2phy_reset(rphy);
+	if (ret)
+		return ret;
+
+	/* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */
+	ret |= regmap_write(rphy->grf, reg + 0x000c, GENMASK(27, 24) | 0x0900);
+
+	/* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
+	ret |= regmap_write(rphy->grf, reg + 0x0010, GENMASK(20, 19) | 0x0010);
+
+	return ret;
+}
+
 static int rk3588_usb2phy_tuning(struct rockchip_usb2phy *rphy)
 {
 	int ret;
@@ -1923,6 +1959,84 @@ static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
 	{ /* sentinel */ }
 };
 
+static const struct rockchip_usb2phy_cfg rk3576_phy_cfgs[] = {
+	{
+		.reg = 0x0,
+		.num_ports	= 1,
+		.phy_tuning	= rk3576_usb2phy_tuning,
+		.clkout_ctl	= { 0x0008, 0, 0, 1, 0 },
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x0000, 8, 0, 0, 0x1d1 },
+				.bvalid_det_en	= { 0x00c0, 1, 1, 0, 1 },
+				.bvalid_det_st	= { 0x00c4, 1, 1, 0, 1 },
+				.bvalid_det_clr = { 0x00c8, 1, 1, 0, 1 },
+				.ls_det_en	= { 0x00c0, 0, 0, 0, 1 },
+				.ls_det_st	= { 0x00c4, 0, 0, 0, 1 },
+				.ls_det_clr	= { 0x00c8, 0, 0, 0, 1 },
+				.disfall_en	= { 0x00c0, 6, 6, 0, 1 },
+				.disfall_st	= { 0x00c4, 6, 6, 0, 1 },
+				.disfall_clr	= { 0x00c8, 6, 6, 0, 1 },
+				.disrise_en	= { 0x00c0, 5, 5, 0, 1 },
+				.disrise_st	= { 0x00c4, 5, 5, 0, 1 },
+				.disrise_clr	= { 0x00c8, 5, 5, 0, 1 },
+				.utmi_avalid	= { 0x0080, 1, 1, 0, 1 },
+				.utmi_bvalid	= { 0x0080, 0, 0, 0, 1 },
+				.utmi_ls	= { 0x0080, 5, 4, 0, 1 },
+			}
+		},
+		.chg_det = {
+			.cp_det		= { 0x0080, 8, 8, 0, 1 },
+			.dcp_det	= { 0x0080, 8, 8, 0, 1 },
+			.dp_det		= { 0x0080, 9, 9, 1, 0 },
+			.idm_sink_en	= { 0x0010, 5, 5, 1, 0 },
+			.idp_sink_en	= { 0x0010, 5, 5, 0, 1 },
+			.idp_src_en	= { 0x0010, 14, 14, 0, 1 },
+			.rdm_pdwn_en	= { 0x0010, 14, 14, 0, 1 },
+			.vdm_src_en	= { 0x0010, 7, 6, 0, 3 },
+			.vdp_src_en	= { 0x0010, 7, 6, 0, 3 },
+		},
+	},
+	{
+		.reg = 0x2000,
+		.num_ports	= 1,
+		.phy_tuning	= rk3576_usb2phy_tuning,
+		.clkout_ctl	= { 0x2008, 0, 0, 1, 0 },
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x2000, 8, 0, 0, 0x1d1 },
+				.bvalid_det_en	= { 0x20c0, 1, 1, 0, 1 },
+				.bvalid_det_st	= { 0x20c4, 1, 1, 0, 1 },
+				.bvalid_det_clr = { 0x20c8, 1, 1, 0, 1 },
+				.ls_det_en	= { 0x20c0, 0, 0, 0, 1 },
+				.ls_det_st	= { 0x20c4, 0, 0, 0, 1 },
+				.ls_det_clr	= { 0x20c8, 0, 0, 0, 1 },
+				.disfall_en	= { 0x20c0, 6, 6, 0, 1 },
+				.disfall_st	= { 0x20c4, 6, 6, 0, 1 },
+				.disfall_clr	= { 0x20c8, 6, 6, 0, 1 },
+				.disrise_en	= { 0x20c0, 5, 5, 0, 1 },
+				.disrise_st	= { 0x20c4, 5, 5, 0, 1 },
+				.disrise_clr	= { 0x20c8, 5, 5, 0, 1 },
+				.utmi_avalid	= { 0x2080, 1, 1, 0, 1 },
+				.utmi_bvalid	= { 0x2080, 0, 0, 0, 1 },
+				.utmi_ls	= { 0x2080, 5, 4, 0, 1 },
+			}
+		},
+		.chg_det = {
+			.cp_det		= { 0x2080, 8, 8, 0, 1 },
+			.dcp_det	= { 0x2080, 8, 8, 0, 1 },
+			.dp_det		= { 0x2080, 9, 9, 1, 0 },
+			.idm_sink_en	= { 0x2010, 5, 5, 1, 0 },
+			.idp_sink_en	= { 0x2010, 5, 5, 0, 1 },
+			.idp_src_en	= { 0x2010, 14, 14, 0, 1 },
+			.rdm_pdwn_en	= { 0x2010, 14, 14, 0, 1 },
+			.vdm_src_en	= { 0x2010, 7, 6, 0, 3 },
+			.vdp_src_en	= { 0x2010, 7, 6, 0, 3 },
+		},
+	},
+	{ /* sentinel */ }
+};
+
 static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
 	{
 		.reg = 0x0000,
@@ -2094,6 +2208,7 @@ static const struct of_device_id rockchip_usb2phy_dt_match[] = {
 	{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
 	{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
 	{ .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
+	{ .compatible = "rockchip,rk3576-usb2phy", .data = &rk3576_phy_cfgs },
 	{ .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs },
 	{ .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
 	{}
-- 
2.45.2



From dmitry.baryshkov at linaro.org  Tue Sep 24 02:31:02 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 24 Sep 2024 12:31:02 +0300
Subject: [PATCH v17 1/8] drm: bridge: Cadence: Create mhdp helper driver
In-Reply-To: <2773403.mvXUDI8C0e@steina-w>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
 <6e2e4951aa4c69eed68af231c2b0b2ce302b2358.1727159906.git.Sandor.yu@nxp.com>
 <2773403.mvXUDI8C0e@steina-w>
Message-ID: <vlqcv7pdhyf6rjmkm2ccyvg3fv64gcp536zppns6nc3xpzuew6@j3qrwextsp33>

On Tue, Sep 24, 2024 at 10:41:26AM GMT, Alexander Stein wrote:
> Hi Sandor,
> 
> Am Dienstag, 24. September 2024, 09:36:46 CEST schrieb Sandor Yu:
> > MHDP8546 mailbox access functions will be share to other mhdp driver
> > and Cadence HDP-TX HDMI/DP PHY drivers.
> > Create a new mhdp helper driver and move all those functions into.
> > 
> > cdns_mhdp_reg_write() is renamed to cdns_mhdp_dp_reg_write(),
> > because it use the DPTX command ID DPTX_WRITE_REGISTER.
> > 
> > New cdns_mhdp_reg_write() is created with the general command ID
> > GENERAL_REGISTER_WRITE.
> > 
> > Rewrite cdns_mhdp_set_firmware_active() in mhdp8546 core driver,
> > use cdns_mhdp_mailbox_send() to replace cdns_mhdp_mailbox_write()
> > same as the other mailbox access functions.
> > 
> > Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex
> > to prevent race conditions in mailbox access by multi drivers.
> > 
> > Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> > ---
> > v16->v17:
> > - Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex
> > 
> > v12->v16:
> >  *No change.
> > 
> > V11->v12:
> > - Move status initialize out of mbox_mutex.
> > - Reorder API functions in alphabetical.
> > - Add notes for malibox access functions.
> > - Add year 2024 to copyright.
> > 
> >  drivers/gpu/drm/bridge/cadence/Kconfig        |   4 +
> >  drivers/gpu/drm/bridge/cadence/Makefile       |   1 +
> >  .../gpu/drm/bridge/cadence/cdns-mhdp-helper.c | 307 +++++++++++++
> >  .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 425 ++++--------------
> >  .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  47 +-
> >  .../drm/bridge/cadence/cdns-mhdp8546-hdcp.c   |  36 +-
> >  include/drm/bridge/cdns-mhdp-helper.h         |  94 ++++
> >  7 files changed, 507 insertions(+), 407 deletions(-)
> >  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
> >  create mode 100644 include/drm/bridge/cdns-mhdp-helper.h
> > 
> > diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig
> > index cced81633ddcd..e0973339e9e33 100644
> > --- a/drivers/gpu/drm/bridge/cadence/Kconfig
> > +++ b/drivers/gpu/drm/bridge/cadence/Kconfig
> > @@ -21,6 +21,9 @@ config DRM_CDNS_DSI_J721E
> >  	  the routing of the DSS DPI signal to the Cadence DSI.
> >  endif
> >  
> > +config CDNS_MHDP_HELPER
> > +	tristate
> > +
> >  config DRM_CDNS_MHDP8546
> >  	tristate "Cadence DPI/DP bridge"
> >  	select DRM_DISPLAY_DP_HELPER
> > @@ -28,6 +31,7 @@ config DRM_CDNS_MHDP8546
> >  	select DRM_DISPLAY_HELPER
> >  	select DRM_KMS_HELPER
> >  	select DRM_PANEL_BRIDGE
> > +	select CDNS_MHDP_HELPER
> >  	depends on OF
> >  	help
> >  	  Support Cadence DPI to DP bridge. This is an internal
> > diff --git a/drivers/gpu/drm/bridge/cadence/Makefile b/drivers/gpu/drm/bridge/cadence/Makefile
> > index c95fd5b81d137..087dc074820d7 100644
> > --- a/drivers/gpu/drm/bridge/cadence/Makefile
> > +++ b/drivers/gpu/drm/bridge/cadence/Makefile
> > @@ -2,6 +2,7 @@
> >  obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
> >  cdns-dsi-y := cdns-dsi-core.o
> >  cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.o
> > +obj-$(CONFIG_CDNS_MHDP_HELPER) += cdns-mhdp-helper.o
> >  obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
> >  cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
> >  cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
> > diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
> > new file mode 100644
> > index 0000000000000..c60a6b69a5343
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
> > @@ -0,0 +1,307 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (C) 2023, 2024 NXP Semiconductor, Inc.
> > + *
> > + */
> > +#include <drm/bridge/cdns-mhdp-helper.h>
> > +#include <linux/dev_printk.h>
> > +#include <linux/module.h>
> > +
> > +/* Protects mailbox communications with the firmware */
> > +DEFINE_MUTEX(mhdp_mailbox_mutex);
> 
> This is not enough if the driver is built as a module:
> 
> > ERROR: modpost: "mhdp_mailbox_mutex"
> > [drivers/gpu/drm/bridge/cadence/cdns-mhdp8546.ko] undefined! ERROR:
> > modpost: "mhdp_mailbox_mutex"
> > [drivers/gpu/drm/bridge/cadence/cdns-mhdp8501.ko] undefined!
> 
> Not sure if EXPORT_SYMBOL_GPL() on a mutex is considered good style.

Absolutely no. The API should wrap register access, using the mutex
whether required, rather than exporting the mutex for everybody else to
use.

> 
> Best regards,
> Alexander
> 
> > [snip]
> -- 
> TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
> Amtsgericht M?nchen, HRB 105018
> Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
> http://www.tq-group.com/
> 
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Tue Sep 24 02:38:26 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 24 Sep 2024 12:38:26 +0300
Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501
 DP/HDMI driver
In-Reply-To: <PAXPR04MB94481627922756E892C37B7DF4682@PAXPR04MB9448.eurprd04.prod.outlook.com>
References: <cover.1719903904.git.Sandor.yu@nxp.com>
 <359914108b879e995d4a39de32a33310009f0fab.1719903904.git.Sandor.yu@nxp.com>
 <20240702-quartz-salamander-of-culture-eec264@houat>
 <PAXPR04MB94480AB0490BBF00D2BA17BBF4932@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <20240903-gay-capable-hound-3cbef2@houat>
 <PAXPR04MB9448EF507CB5C18A43239A80F49E2@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <20240912-zippy-mongoose-of-domination-2ebc1d@houat>
 <PAXPR04MB94484D86A71A7527ADD42EA4F4652@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <CAA8EJpphegHmBFgH1-n9PEkrr-Ys+HCvekKGNYRp=xQxgmC0Cw@mail.gmail.com>
 <PAXPR04MB94481627922756E892C37B7DF4682@PAXPR04MB9448.eurprd04.prod.outlook.com>
Message-ID: <3z53w7kzwnsn3pg5elp5fbueid323t47yyhub67muidd6k47me@assca4bckdt5>

On Tue, Sep 24, 2024 at 07:04:58AM GMT, Sandor Yu wrote:
>  
> > 
> > On Fri, 13 Sept 2024 at 11:46, Sandor Yu <sandor.yu at nxp.com> wrote:
> > >
> > >
> > > > Subject: Re: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add
> > > > MHDP8501 DP/HDMI driver
> > > >
> > > > On Fri, Sep 06, 2024 at 02:50:08AM GMT, Sandor Yu wrote:
> > > > > > On Tue, Sep 03, 2024 at 06:07:25AM GMT, Sandor Yu wrote:
> > > > > > > > -----Original Message-----
> > > > > > > > From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On
> > > > > > > > Behalf Of Maxime Ripard
> > > > > > > > Sent: 2024?7?2? 21:25
> > > > > > > > To: Sandor Yu <sandor.yu at nxp.com>
> > > > > > > > Cc: dmitry.baryshkov at linaro.org; andrzej.hajda at intel.com;
> > > > > > > > neil.armstrong at linaro.org; Laurent Pinchart
> > > > > > > > <laurent.pinchart at ideasonboard.com>; jonas at kwiboo.se;
> > > > > > > > jernej.skrabec at gmail.com; airlied at gmail.com;
> > > > > > > > daniel at ffwll.ch;
> > > > > > > > robh+dt at kernel.org; krzysztof.kozlowski+dt at linaro.org;
> > > > > > > > shawnguo at kernel.org; s.hauer at pengutronix.de;
> > > > festevam at gmail.com;
> > > > > > > > vkoul at kernel.org; dri-devel at lists.freedesktop.org;
> > > > > > > > devicetree at vger.kernel.org;
> > > > > > > > linux-arm-kernel at lists.infradead.org;
> > > > > > > > linux-kernel at vger.kernel.org; linux-phy at lists.infradead.org;
> > > > > > > > kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>;
> > > > > > > > Oliver Brown <oliver.brown at nxp.com>;
> > > > > > > > alexander.stein at ew.tq-group.com; sam at ravnborg.org
> > > > > > > > Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add
> > > > > > > > MHDP8501 DP/HDMI driver
> > > > > > > >
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > There's still the scrambler issue we discussed on v15, but I
> > > > > > > > have some more comments.
> > > > > > > >
> > > > > > > > On Tue, Jul 02, 2024 at 08:22:36PM GMT, Sandor Yu wrote:
> > > > > > > > > +enum drm_connector_status cdns_mhdp8501_detect(struct
> > > > > > > > > +cdns_mhdp8501_device *mhdp) {
> > > > > > > > > +   u8 hpd = 0xf;
> > > > > > > > > +
> > > > > > > > > +   hpd = cdns_mhdp8501_read_hpd(mhdp);
> > > > > > > > > +   if (hpd == 1)
> > > > > > > > > +           return connector_status_connected;
> > > > > > > > > +   else if (hpd == 0)
> > > > > > > > > +           return connector_status_disconnected;
> > > > > > > > > +
> > > > > > > > > +   dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n",
> > > > hpd);
> > > > > > > > > +   return connector_status_unknown; }
> > > > > > > > > +
> > > > > > > > > +static void hotplug_work_func(struct work_struct *work) {
> > > > > > > > > +   struct cdns_mhdp8501_device *mhdp = container_of(work,
> > > > > > > > > +                                                struct
> > cdns_mhdp8501_device,
> > > > > > > > > +
> > hotplug_work.work);
> > > > > > > > > +   enum drm_connector_status status =
> > > > > > cdns_mhdp8501_detect(mhdp);
> > > > > > > > > +
> > > > > > > > > +   drm_bridge_hpd_notify(&mhdp->bridge, status);
> > > > > > > > > +
> > > > > > > > > +   if (status == connector_status_connected) {
> > > > > > > > > +           /* Cable connected  */
> > > > > > > > > +           DRM_INFO("HDMI/DP Cable Plug In\n");
> > > > > > > > > +           enable_irq(mhdp->irq[IRQ_OUT]);
> > > > > > > > > +   } else if (status == connector_status_disconnected) {
> > > > > > > > > +           /* Cable Disconnected  */
> > > > > > > > > +           DRM_INFO("HDMI/DP Cable Plug Out\n");
> > > > > > > > > +           enable_irq(mhdp->irq[IRQ_IN]);
> > > > > > > > > +   }
> > > > > > > > > +}
> > > > > > > >
> > > > > > > > You shouldn't play with the interrupt being enabled here:
> > > > > > > > hotplug interrupts should always enabled.
> > > > > > > >
> > > > > > > > If you can't for some reason, the reason should be
> > > > > > > > documented in your
> > > > > > driver.
> > > > > > >
> > > > > > > iMX8MQ have two HPD interrupters, one for plugout and the
> > > > > > > other for plugin, because they could not be masked, so we have
> > > > > > > to enable one and
> > > > > > disable the other.
> > > > > > > I will add more comments here.
> > > > > >
> > > > > > Right, but why do you need to enable and disable them? Do you
> > > > > > get spurious interrupts?
> > > > >
> > > > > They don't have status registers and cannot be masked. If they are
> > > > > not disabled, they will continuously generate interrupts.
> > > > > Therefore, I have to
> > > > disable one and enable the other.
> > > >
> > > > Sorry, I still don't get it. How can it be useful to detect hotplug
> > > > interrupts if it constantly sends spurious interrupts when it's enabled?
> > >
> > > Yes, this interrupt is different from a normal one; it's likely a design flaw.
> > > For instance, the plugin interrupt is continuously generated as long
> > > as the cable is plugged in, only stopping when the cable is unplugged.
> > > That's why two interrupts are used to detect cable plugout and plugin
> > separately.
> > > If interrupts aren't used, the only option is polling.
> > 
> > I think I've seen such strange design on other platforms, level interrupt for HPD,
> > which needs to be disabled via disable_irq().
> > 
> > >
> > > >
> > > > > > > > > +   /* Mailbox protect for HDMI PHY access */
> > > > > > > > > +   mutex_lock(&mhdp->mbox_mutex);
> > > > > > > > > +   ret = phy_init(mhdp->phy);
> > > > > > > > > +   mutex_unlock(&mhdp->mbox_mutex);
> > > > > > > > > +   if (ret) {
> > > > > > > > > +           dev_err(dev, "Failed to initialize PHY: %d\n", ret);
> > > > > > > > > +           goto clk_disable;
> > > > > > > > > +   }
> > > > > > > > > +
> > > > > > > > > +   /* Mailbox protect for HDMI PHY access */
> > > > > > > > > +   mutex_lock(&mhdp->mbox_mutex);
> > > > > > > > > +   ret = phy_set_mode(mhdp->phy, phy_mode);
> > > > > > > > > +   mutex_unlock(&mhdp->mbox_mutex);
> > > > > > > > > +   if (ret) {
> > > > > > > > > +           dev_err(dev, "Failed to configure PHY: %d\n", ret);
> > > > > > > > > +           goto clk_disable;
> > > > > > > > > +   }
> > > > > > > >
> > > > > > > > Why do you need a shared mutex between the phy and HDMI
> > > > controller?
> > > > > > >
> > > > > > > Both PHY and HDMI controller could access to the HDMI firmware
> > > > > > > by mailbox, So add mutex to avoid race condition.
> > > > > >
> > > > > > That should be handled at either the phy or mailbox level, not
> > > > > > in your hdmi driver.
> > > > >
> > > > > In both HDMI driver and PHY driver, every mailbox access had
> > > > > protected by its owns mutex. However, this mutex can only protect
> > > > > each mailbox access within their respective drivers, and it cannot
> > > > > provide protection for access between the HDMI and PHY drivers.
> > > > >
> > > > > The PHY driver only provides two API functions, and these
> > > > > functions are only called in the HDMI driver. Therefore, when
> > > > > accessing these functions, we use a mutex to protect them. This
> > > > > ensures that mailbox access is protected across different PHY and HDMI
> > drivers.
> > > >
> > > > It's really about abstraction. You're using a publicly defined API,
> > > > and change the semantics for your driver only, and that's not ok.
> > > >
> > > > Why can't the mailbox driver itself serialize the accesses from any
> > > > user, HDMI and PHY drivers included?
> > > >
> > >
> > > In the current code implementation, cdns-mhdp-helper.c isn't a standalone
> > driver but rather a library.
> > > It provides fundamental mailbox access functions and basic register
> > read/write operations that rely on the mailbox.
> > > These functions are highly reusable across MHDP8501 and MHDP8546 and
> > can be leveraged by future MHDP versions.
> > >
> > > However, most MHDP firmware interactions involve a sequence of mailbox
> > accesses, including sending commands and receiving firmware responses.
> > > These commands constitute a significant portion of all firmware interactions,
> > encompassing operations like EDID reading and DP link training.
> > > Unfortunately, these commands cannot be reused between MHDP8501 and
> > MHDP8546.
> > >
> > > Creating a dedicated mailbox driver with its own mutex would effectively
> > address race conditions.
> > > However, this would necessitate relocating all mailbox-related functions to
> > this driver.
> > > Including these non-reusable functions would defeat the purpose of code
> > reuse.
> > >
> > > To strike a balance between code reusability and race condition mitigation,
> > adding mutexes to PHY access functions seems like a reasonable solution.
> > 
> > You seem to have two kinds of scenarios when talking to MHDP: just
> > cdns_mhdp_mailbox_send(), no response needed and then the
> > cdns_mhdp_mailbox_send() /  cdns_mhdp_mailbox_recv_header() /
> > cdns_mhdp_mailbox_recv_data() sequence. Extract those + the mutex access
> > to separate functions, add a mutex to those sequences and use them as a
> > high-level API for your HDMI and PHY drivers.
> > 
> > Adding mutexes around phy_foo() calls doesn't look like a proper solution _at_
> > _all_.
> > 
> Because the sequence cdns_mhdp_mailbox_send() / cdns_mhdp_mailbox_recv_header() / cdns_mhdp_mailbox_recv_data() cannot be reused by different drivers, 
> it's not suitable to abstract them into a separate function.

Why is it so? In the end, even if one driver uses it and another driver
uses other functions (while holding the mutex), please move generic
versions of those functions to your helper code. It should abstract
_types_ of hardware access (and send/recv_header/recv_data is such an
abstraction).

> I've noticed some Linux kernel drivers use global mutexes, which can solve the current race conditions problem. 
> I'll implement this in the next version.

-- 
With best wishes
Dmitry


From mripard at kernel.org  Tue Sep 24 02:41:04 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 24 Sep 2024 09:41:04 +0000
Subject: [PATCH v17 2/8] phy: Add HDMI configuration options
In-Reply-To: <c9c0c1c2e156731a46ffe0cfa3529e6f0e6a1e5f.1727159906.git.Sandor.yu@nxp.com>
References: <c9c0c1c2e156731a46ffe0cfa3529e6f0e6a1e5f.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <5c67dc9b6c0ef3942e933b4a0f7bb605@kernel.org>

On Tue, 24 Sep 2024 15:36:47 +0800, Sandor Yu wrote:
> Allow HDMI PHYs to be configured through the generic
> functions through a custom structure added to the generic union.
> 
> The parameters added here are based on HDMI PHY
> implementation practices.  The current set of parameters
> 
> [ ... ]

Reviewed-by: Maxime Ripard <mripard at kernel.org>

Thanks!
Maxime


From mripard at kernel.org  Tue Sep 24 02:51:27 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 24 Sep 2024 11:51:27 +0200
Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501
 DP/HDMI driver
In-Reply-To: <PAXPR04MB94484D86A71A7527ADD42EA4F4652@PAXPR04MB9448.eurprd04.prod.outlook.com>
References: <cover.1719903904.git.Sandor.yu@nxp.com>
 <359914108b879e995d4a39de32a33310009f0fab.1719903904.git.Sandor.yu@nxp.com>
 <20240702-quartz-salamander-of-culture-eec264@houat>
 <PAXPR04MB94480AB0490BBF00D2BA17BBF4932@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <20240903-gay-capable-hound-3cbef2@houat>
 <PAXPR04MB9448EF507CB5C18A43239A80F49E2@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <20240912-zippy-mongoose-of-domination-2ebc1d@houat>
 <PAXPR04MB94484D86A71A7527ADD42EA4F4652@PAXPR04MB9448.eurprd04.prod.outlook.com>
Message-ID: <20240924-miniature-jade-gibbon-c9a226@houat>

On Fri, Sep 13, 2024 at 09:46:12AM GMT, Sandor Yu wrote:
> > Subject: Re: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add MHDP8501
> > DP/HDMI driver
> > 
> > On Fri, Sep 06, 2024 at 02:50:08AM GMT, Sandor Yu wrote:
> > > > On Tue, Sep 03, 2024 at 06:07:25AM GMT, Sandor Yu wrote:
> > > > > > -----Original Message-----
> > > > > > From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On
> > > > > > Behalf Of Maxime Ripard
> > > > > > Sent: 2024?7?2? 21:25
> > > > > > To: Sandor Yu <sandor.yu at nxp.com>
> > > > > > Cc: dmitry.baryshkov at linaro.org; andrzej.hajda at intel.com;
> > > > > > neil.armstrong at linaro.org; Laurent Pinchart
> > > > > > <laurent.pinchart at ideasonboard.com>; jonas at kwiboo.se;
> > > > > > jernej.skrabec at gmail.com; airlied at gmail.com; daniel at ffwll.ch;
> > > > > > robh+dt at kernel.org; krzysztof.kozlowski+dt at linaro.org;
> > > > > > shawnguo at kernel.org; s.hauer at pengutronix.de;
> > festevam at gmail.com;
> > > > > > vkoul at kernel.org; dri-devel at lists.freedesktop.org;
> > > > > > devicetree at vger.kernel.org;
> > > > > > linux-arm-kernel at lists.infradead.org;
> > > > > > linux-kernel at vger.kernel.org; linux-phy at lists.infradead.org;
> > > > > > kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>; Oliver
> > > > > > Brown <oliver.brown at nxp.com>; alexander.stein at ew.tq-group.com;
> > > > > > sam at ravnborg.org
> > > > > > Subject: [EXT] Re: [PATCH v16 4/8] drm: bridge: Cadence: Add
> > > > > > MHDP8501 DP/HDMI driver
> > > > > >
> > > > > > Hi,
> > > > > >
> > > > > > There's still the scrambler issue we discussed on v15, but I
> > > > > > have some more comments.
> > > > > >
> > > > > > On Tue, Jul 02, 2024 at 08:22:36PM GMT, Sandor Yu wrote:
> > > > > > > +enum drm_connector_status cdns_mhdp8501_detect(struct
> > > > > > > +cdns_mhdp8501_device *mhdp) {
> > > > > > > +	u8 hpd = 0xf;
> > > > > > > +
> > > > > > > +	hpd = cdns_mhdp8501_read_hpd(mhdp);
> > > > > > > +	if (hpd == 1)
> > > > > > > +		return connector_status_connected;
> > > > > > > +	else if (hpd == 0)
> > > > > > > +		return connector_status_disconnected;
> > > > > > > +
> > > > > > > +	dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n",
> > hpd);
> > > > > > > +	return connector_status_unknown; }
> > > > > > > +
> > > > > > > +static void hotplug_work_func(struct work_struct *work) {
> > > > > > > +	struct cdns_mhdp8501_device *mhdp = container_of(work,
> > > > > > > +						     struct cdns_mhdp8501_device,
> > > > > > > +						     hotplug_work.work);
> > > > > > > +	enum drm_connector_status status =
> > > > cdns_mhdp8501_detect(mhdp);
> > > > > > > +
> > > > > > > +	drm_bridge_hpd_notify(&mhdp->bridge, status);
> > > > > > > +
> > > > > > > +	if (status == connector_status_connected) {
> > > > > > > +		/* Cable connected  */
> > > > > > > +		DRM_INFO("HDMI/DP Cable Plug In\n");
> > > > > > > +		enable_irq(mhdp->irq[IRQ_OUT]);
> > > > > > > +	} else if (status == connector_status_disconnected) {
> > > > > > > +		/* Cable Disconnected  */
> > > > > > > +		DRM_INFO("HDMI/DP Cable Plug Out\n");
> > > > > > > +		enable_irq(mhdp->irq[IRQ_IN]);
> > > > > > > +	}
> > > > > > > +}
> > > > > >
> > > > > > You shouldn't play with the interrupt being enabled here:
> > > > > > hotplug interrupts should always enabled.
> > > > > >
> > > > > > If you can't for some reason, the reason should be documented in
> > > > > > your
> > > > driver.
> > > > >
> > > > > iMX8MQ have two HPD interrupters, one for plugout and the other
> > > > > for plugin, because they could not be masked, so we have to enable
> > > > > one and
> > > > disable the other.
> > > > > I will add more comments here.
> > > >
> > > > Right, but why do you need to enable and disable them? Do you get
> > > > spurious interrupts?
> > >
> > > They don't have status registers and cannot be masked. If they are not
> > > disabled, they will continuously generate interrupts. Therefore, I have to
> > disable one and enable the other.
> > 
> > Sorry, I still don't get it. How can it be useful to detect hotplug interrupts if it
> > constantly sends spurious interrupts when it's enabled?
> 
> Yes, this interrupt is different from a normal one; it's likely a design flaw. 
> For instance, the plugin interrupt is continuously generated as long as the cable is plugged in,
> only stopping when the cable is unplugged.
>
> That's why two interrupts are used to detect cable plugout and plugin
> separately. If interrupts aren't used, the only option is polling.

Urgh. Ok. At least, you should document that in your code then.

> > > > > > > +	/* Mailbox protect for HDMI PHY access */
> > > > > > > +	mutex_lock(&mhdp->mbox_mutex);
> > > > > > > +	ret = phy_init(mhdp->phy);
> > > > > > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > > > > > +	if (ret) {
> > > > > > > +		dev_err(dev, "Failed to initialize PHY: %d\n", ret);
> > > > > > > +		goto clk_disable;
> > > > > > > +	}
> > > > > > > +
> > > > > > > +	/* Mailbox protect for HDMI PHY access */
> > > > > > > +	mutex_lock(&mhdp->mbox_mutex);
> > > > > > > +	ret = phy_set_mode(mhdp->phy, phy_mode);
> > > > > > > +	mutex_unlock(&mhdp->mbox_mutex);
> > > > > > > +	if (ret) {
> > > > > > > +		dev_err(dev, "Failed to configure PHY: %d\n", ret);
> > > > > > > +		goto clk_disable;
> > > > > > > +	}
> > > > > >
> > > > > > Why do you need a shared mutex between the phy and HDMI
> > controller?
> > > > >
> > > > > Both PHY and HDMI controller could access to the HDMI firmware by
> > > > > mailbox, So add mutex to avoid race condition.
> > > >
> > > > That should be handled at either the phy or mailbox level, not in
> > > > your hdmi driver.
> > >
> > > In both HDMI driver and PHY driver, every mailbox access had protected
> > > by its owns mutex. However, this mutex can only protect each mailbox
> > > access within their respective drivers, and it cannot provide
> > > protection for access between the HDMI and PHY drivers.
> > >
> > > The PHY driver only provides two API functions, and these functions
> > > are only called in the HDMI driver. Therefore, when accessing these
> > > functions, we use a mutex to protect them. This ensures that mailbox
> > > access is protected across different PHY and HDMI drivers.
> > 
> > It's really about abstraction. You're using a publicly defined API, and change
> > the semantics for your driver only, and that's not ok.
> > 
> > Why can't the mailbox driver itself serialize the accesses from any user, HDMI
> > and PHY drivers included?
>
> In the current code implementation, cdns-mhdp-helper.c isn't a
> standalone driver but rather a library. It provides fundamental
> mailbox access functions and basic register read/write operations that
> rely on the mailbox. These functions are highly reusable across
> MHDP8501 and MHDP8546 and can be leveraged by future MHDP versions.
> 
> However, most MHDP firmware interactions involve a sequence of mailbox
> accesses, including sending commands and receiving firmware responses.
> These commands constitute a significant portion of all firmware
> interactions, encompassing operations like EDID reading and DP link
> training. Unfortunately, these commands cannot be reused between
> MHDP8501 and MHDP8546.
> 
> Creating a dedicated mailbox driver with its own mutex would
> effectively address race conditions. However, this would necessitate
> relocating all mailbox-related functions to this driver. Including
> these non-reusable functions would defeat the purpose of code reuse.
> 
> To strike a balance between code reusability and race condition
> mitigation, adding mutexes to PHY access functions seems like a
> reasonable solution.

No, it's really not. You need to address this in some other way. Why
can't you put the mutex in cdns-mhdp-helper.c calls?

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 273 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20240924/509865b4/attachment-0001.sig>

From heiko at sntech.de  Tue Sep 24 03:01:23 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 24 Sep 2024 12:01:23 +0200
Subject: [PATCH v2 2/2] phy: rockchip: inno-usb2: Add usb2 phys support for rk3576
In-Reply-To: <20240924085510.20863-2-frawang.cn@gmail.com>
References: <20240924085510.20863-1-frawang.cn@gmail.com>
 <20240924085510.20863-2-frawang.cn@gmail.com>
Message-ID: <15288441.JCcGWNJJiE@phil>

Am Dienstag, 24. September 2024, 10:55:10 CEST schrieb Frank Wang:
> From: William Wu <william.wu at rock-chips.com>
> 
> The RK3576 SoC has two independent USB2.0 PHYs, and
> each PHY has one port.

Can you please split the content into "converting to clk_bulk" (see
additional comment below) and "add rk3576" please?

That would make the patch a lot cleaner.


> @@ -376,6 +378,7 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
>  {
>  	struct device_node *node = rphy->dev->of_node;
>  	struct clk_init_data init;
> +	struct clk *refclk = of_clk_get_by_name(node, "phyclk");

Doesn't this create an imbalance - with the missing put?
I think ideally just define clk_bulk_data structs for the
1-clock and 3-clock variant, attach that to the device-data
and then use the regular devm_clk_bulk_get ?

That way you can then retrieve the clock from that struct?


Thanks
Heiko




From heiko at sntech.de  Tue Sep 24 03:01:51 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 24 Sep 2024 12:01:51 +0200
Subject: [PATCH v2 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add rk3576
In-Reply-To: <20240924085510.20863-1-frawang.cn@gmail.com>
References: <20240924085510.20863-1-frawang.cn@gmail.com>
Message-ID: <11146778.5MRjnR8RnV@phil>

Hi Frank,

Am Dienstag, 24. September 2024, 10:55:09 CEST schrieb Frank Wang:
> From: Frank Wang <frank.wang at rock-chips.com>
> 
> Add compatible for the USB2 phy in the Rockchip RK3576 SoC.

can you please add some details to the commit message, about those
new clocks. I.e. what they do.

Thanks
Heiko

> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
> ---
> Changelog:
> v2:
>  - Categorize clock names by oneOf keyword.
> 
> v1:
>  - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-1-frank.wang at rock-chips.com/
> 
>  .../bindings/phy/rockchip,inno-usb2phy.yaml      | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
> index 5254413137c64..8af4e0f8637fc 100644
> --- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
> @@ -20,6 +20,7 @@ properties:
>        - rockchip,rk3366-usb2phy
>        - rockchip,rk3399-usb2phy
>        - rockchip,rk3568-usb2phy
> +      - rockchip,rk3576-usb2phy
>        - rockchip,rk3588-usb2phy
>        - rockchip,rv1108-usb2phy
>  
> @@ -34,10 +35,20 @@ properties:
>      const: 0
>  
>    clocks:
> -    maxItems: 1
> +    minItems: 1
> +    maxItems: 3
>  
>    clock-names:
> -    const: phyclk
> +    minItems: 1
> +    maxItems: 3
> +    items:
> +      oneOf:
> +        - description: aclk for USB MMU.
> +          const: aclk
> +        - description: aclk_slv for USB MMU.
> +          const: aclk_slv
> +        - description: PHY input reference clocks.
> +          const: phyclk
>  
>    assigned-clocks:
>      description:
> @@ -143,6 +154,7 @@ allOf:
>            contains:
>              enum:
>                - rockchip,rk3568-usb2phy
> +              - rockchip,rk3576-usb2phy
>                - rockchip,rk3588-usb2phy
>  
>      then:
> 






From heiko at sntech.de  Tue Sep 24 03:03:56 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 24 Sep 2024 12:03:56 +0200
Subject: [PATCH] phy: phy-rockchip-samsung-hdptx: Depend on CONFIG_COMMON_CLK
In-Reply-To: <20240923-sam-hdptx-link-fix-v1-1-8d10d7456305@collabora.com>
References: <20240923-sam-hdptx-link-fix-v1-1-8d10d7456305@collabora.com>
Message-ID: <2000463.jZfb76A358@phil>

Am Montag, 23. September 2024, 18:40:16 CEST schrieb Cristian Ciocaltea:
> Ensure CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX depends on CONFIG_COMMON_CLK to
> fix the following link errors when compile testing some random kernel
> configurations:
> 
>   m68k-linux-ld: drivers/phy/rockchip/phy-rockchip-samsung-hdptx.o: in function `rk_hdptx_phy_clk_register':
>   drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c:1031:(.text+0x470): undefined reference to `__clk_get_name'
>   m68k-linux-ld: drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c:1036:(.text+0x4ba): undefined reference to `devm_clk_hw_register'
>   m68k-linux-ld: drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c:1040:(.text+0x4d2): undefined reference to `of_clk_hw_simple_get'
>   m68k-linux-ld: drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c:1040:(.text+0x4da): undefined reference to `devm_of_clk_add_hw_provider'
> 
> Fixes: c4b09c562086 ("phy: phy-rockchip-samsung-hdptx: Add clock provider support")
> Reported-by: kernel test robot <lkp at intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202409180305.53PXymZn-lkp at intel.com/
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>

Reviewed-by: Heiko Stuebner <heiko at sntech.de>




From quic_qianyu at quicinc.com  Tue Sep 24 03:14:39 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Tue, 24 Sep 2024 03:14:39 -0700
Subject: [PATCH v4 1/6] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the X1E80100 QMP PCIe PHY Gen4 x8
In-Reply-To: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
Message-ID: <20240924101444.3933828-2-quic_qianyu@quicinc.com>

PCIe 3rd instance of X1E80100 supports Gen 4 x8 which needs different
8 lane capable QMP PCIe PHY with hardware revision v6.30. Document Gen
4 x8 PHY as separate module.

Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
Reviewed-by: Krzysztof Kozlowski <krzk at kernel.org>
---
 .../devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml    | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
index dcf4fa55fbba..680ec3113c2b 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -41,6 +41,7 @@ properties:
       - qcom,x1e80100-qmp-gen3x2-pcie-phy
       - qcom,x1e80100-qmp-gen4x2-pcie-phy
       - qcom,x1e80100-qmp-gen4x4-pcie-phy
+      - qcom,x1e80100-qmp-gen4x8-pcie-phy
 
   reg:
     minItems: 1
@@ -172,6 +173,7 @@ allOf:
               - qcom,sc8280xp-qmp-gen3x2-pcie-phy
               - qcom,sc8280xp-qmp-gen3x4-pcie-phy
               - qcom,x1e80100-qmp-gen4x4-pcie-phy
+              - qcom,x1e80100-qmp-gen4x8-pcie-phy
     then:
       properties:
         clocks:
@@ -201,6 +203,7 @@ allOf:
               - qcom,sm8550-qmp-gen4x2-pcie-phy
               - qcom,sm8650-qmp-gen4x2-pcie-phy
               - qcom,x1e80100-qmp-gen4x2-pcie-phy
+              - qcom,x1e80100-qmp-gen4x8-pcie-phy
     then:
       properties:
         resets:
-- 
2.34.1



From quic_qianyu at quicinc.com  Tue Sep 24 03:14:40 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Tue, 24 Sep 2024 03:14:40 -0700
Subject: [PATCH v4 2/6] dt-bindings: PCI: qcom: Move OPP table to qcom,pcie-common.yaml
In-Reply-To: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
Message-ID: <20240924101444.3933828-3-quic_qianyu@quicinc.com>

OPP table is a generic property that is also required by other qcom
platforms. Hence move this property to qcom,pcie-common.yaml so that PCIe
on other qcom platforms is able to adjust power domain performance state
and ICC peak bw according to PCIe gen speed and link width.

Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
---
 Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml | 4 ++++
 Documentation/devicetree/bindings/pci/qcom,pcie-sm8450.yaml | 4 ----
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml
index 704c0f58eea5..3c6430fe9331 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml
@@ -78,6 +78,10 @@ properties:
     description: GPIO controlled connection to WAKE# signal
     maxItems: 1
 
+  operating-points-v2: true
+  opp-table:
+    type: object
+
 required:
   - reg
   - reg-names
diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8450.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8450.yaml
index 46bd59eefadb..6e0a6d8f0ed0 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8450.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8450.yaml
@@ -70,10 +70,6 @@ properties:
       - const: msi7
       - const: global
 
-  operating-points-v2: true
-  opp-table:
-    type: object
-
   resets:
     maxItems: 1
 
-- 
2.34.1



From quic_qianyu at quicinc.com  Tue Sep 24 03:14:44 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Tue, 24 Sep 2024 03:14:44 -0700
Subject: [PATCH v4 6/6] arm64: dts: qcom: x1e80100: Add support for PCIe3 on x1e80100
In-Reply-To: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
Message-ID: <20240924101444.3933828-7-quic_qianyu@quicinc.com>

Describe PCIe3 controller and PHY. Also add required system resources like
regulators, clocks, interrupts and registers configuration for PCIe3.

Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 arch/arm64/boot/dts/qcom/x1e80100.dtsi | 204 ++++++++++++++++++++++++-
 1 file changed, 203 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
index a36076e3c56b..c615c930cf0c 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
+++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
@@ -744,7 +744,7 @@ gcc: clock-controller at 100000 {
 
 			clocks = <&bi_tcxo_div2>,
 				 <&sleep_clk>,
-				 <0>,
+				 <&pcie3_phy>,
 				 <&pcie4_phy>,
 				 <&pcie5_phy>,
 				 <&pcie6a_phy>,
@@ -2907,6 +2907,208 @@ mmss_noc: interconnect at 1780000 {
 			#interconnect-cells = <2>;
 		};
 
+		pcie3: pcie at 1bd0000 {
+			device_type = "pci";
+			compatible = "qcom,pcie-x1e80100";
+			reg = <0x0 0x01bd0000 0x0 0x3000>,
+			      <0x0 0x78000000 0x0 0xf1d>,
+			      <0x0 0x78000f40 0x0 0xa8>,
+			      <0x0 0x78001000 0x0 0x1000>,
+			      <0x0 0x78100000 0x0 0x100000>,
+			      <0x0 0x01bd3000 0x0 0x1000>;
+			reg-names = "parf",
+				    "dbi",
+				    "elbi",
+				    "atu",
+				    "config",
+				    "mhi";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x78200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x78300000 0x0 0x78300000 0x0 0x3d00000>,
+				 <0x03000000 0x7 0x40000000 0x7 0x40000000 0x0 0x40000000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <3>;
+			num-lanes = <8>;
+
+			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 769 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 671 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi0",
+					  "msi1",
+					  "msi2",
+					  "msi3",
+					  "msi4",
+					  "msi5",
+					  "msi6",
+					  "msi7",
+					  "global";
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &intc 0 0 GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc 0 0 GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc 0 0 GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc 0 0 GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_3_AUX_CLK>,
+				 <&gcc GCC_PCIE_3_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_3_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_3_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_3_SLV_Q2A_AXI_CLK>,
+				 <&gcc GCC_CFG_NOC_PCIE_ANOC_NORTH_AHB_CLK>,
+				 <&gcc GCC_CNOC_PCIE_NORTH_SF_AXI_CLK>;
+			clock-names = "aux",
+				      "cfg",
+				      "bus_master",
+				      "bus_slave",
+				      "slave_q2a",
+				      "noc_aggr",
+				      "cnoc_sf_axi";
+
+			assigned-clocks = <&gcc GCC_PCIE_3_AUX_CLK>;
+			assigned-clock-rates = <19200000>;
+
+			interconnects = <&pcie_south_anoc MASTER_PCIE_3 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+					 &cnoc_main SLAVE_PCIE_3 QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "pcie-mem",
+					     "cpu-pcie";
+
+			resets = <&gcc GCC_PCIE_3_BCR>,
+				 <&gcc GCC_PCIE_3_LINK_DOWN_BCR>;
+			reset-names = "pci",
+				      "link_down";
+
+			power-domains = <&gcc GCC_PCIE_3_GDSC>;
+
+			phys = <&pcie3_phy>;
+			phy-names = "pciephy";
+
+			operating-points-v2 = <&pcie3_opp_table>;
+
+			status = "disabled";
+
+			pcie3_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				/* GEN 1 x1 */
+				opp-2500000 {
+					opp-hz = /bits/ 64 <2500000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <250000 1>;
+				};
+
+				/* GEN 1 x2 and GEN 2 x1 */
+				opp-5000000 {
+					opp-hz = /bits/ 64 <5000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <500000 1>;
+				};
+
+				/* GEN 1 x4 and GEN 2 x2 */
+				opp-10000000 {
+					opp-hz = /bits/ 64 <10000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1000000 1>;
+				};
+
+				/* GEN 1 x8 and GEN 2 x4 */
+				opp-20000000 {
+					opp-hz = /bits/ 64 <20000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <2000000 1>;
+				};
+
+				/* GEN 2 x8 */
+				opp-40000000 {
+					opp-hz = /bits/ 64 <40000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <4000000 1>;
+				};
+
+				/* GEN 3 x1 */
+				opp-8000000 {
+					opp-hz = /bits/ 64 <8000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <984500 1>;
+				};
+
+				/* GEN 3 x2 and GEN 4 x1 */
+				opp-16000000 {
+					opp-hz = /bits/ 64 <16000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <1969000 1>;
+				};
+
+				/* GEN 3 x4 and GEN 4 x2 */
+				opp-32000000 {
+					opp-hz = /bits/ 64 <32000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <3938000 1>;
+				};
+
+				/* GEN 3 x8 and GEN 4 x4 */
+				opp-64000000 {
+					opp-hz = /bits/ 64 <64000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <7876000 1>;
+				};
+
+				/* GEN 4 x8 */
+				opp-128000000 {
+					opp-hz = /bits/ 64 <128000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+					opp-peak-kBps = <15753000 1>;
+				};
+			};
+		};
+
+		pcie3_phy: phy at 1be0000 {
+			compatible = "qcom,x1e80100-qmp-gen4x8-pcie-phy";
+			reg = <0 0x01be0000 0 0x10000>;
+
+			clocks = <&gcc GCC_PCIE_3_PHY_AUX_CLK>,
+				 <&gcc GCC_PCIE_3_CFG_AHB_CLK>,
+				 <&tcsr TCSR_PCIE_8L_CLKREF_EN>,
+				 <&gcc GCC_PCIE_3_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_3_PIPE_CLK>,
+				 <&gcc GCC_PCIE_3_PIPEDIV2_CLK>;
+			clock-names = "aux",
+				      "cfg_ahb",
+				      "ref",
+				      "rchng",
+				      "pipe",
+				      "pipediv2";
+
+			resets = <&gcc GCC_PCIE_3_PHY_BCR>,
+				 <&gcc GCC_PCIE_3_NOCSR_COM_PHY_BCR>;
+			reset-names = "phy",
+				      "phy_nocsr";
+
+			assigned-clocks = <&gcc GCC_PCIE_3_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>;
+
+			power-domains = <&gcc GCC_PCIE_3_PHY_GDSC>;
+
+			#clock-cells = <0>;
+			clock-output-names = "pcie3_pipe_clk";
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
 		pcie6a: pci at 1bf8000 {
 			device_type = "pci";
 			compatible = "qcom,pcie-x1e80100";
-- 
2.34.1



From quic_qianyu at quicinc.com  Tue Sep 24 03:14:38 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Tue, 24 Sep 2024 03:14:38 -0700
Subject: [PATCH v4 0/6] Add support for PCIe3 on x1e80100
Message-ID: <20240924101444.3933828-1-quic_qianyu@quicinc.com>

This series add support for PCIe3 on x1e80100.

PCIe3 needs additional set of clocks, regulators and new set of PCIe QMP
PHY configuration compare other PCIe instances on x1e80100. Hence add
required resource configuration and usage for PCIe3.

v3->v4:
1. Reword commit msg of [PATCH v3 5/6]
2. Drop opp-table property from qcom,pcie-sm8450.yaml
3. Add Reviewed-by tag

v2->v3:
1. Use 'Gen 4 x8' in commit msg
2. Move opp-table property to qcom,pcie-common.yaml
3. Add Reviewed-by tag
4. Add global interrupt and use GIC_SPI for the parent interrupt specifier
5. Use 0x0 in reg property and use pcie@ for pcie3 device node
6. Show different IP version v6.30 in commit msg
7. Add logic in controller driver to have new ops for x1e80100

v2->v1:
1. Squash [PATCH 1/8], [PATCH 2/8],[PATCH 3/8] into one patch and make the
   indentation consistent.
2. Put dts patch at the end of the patchset.
3. Put dt-binding patch at the first of the patchset.
4. Add a new patch where opp-table is added in dt-binding to avoid dtbs
   checking error.
5. Remove GCC_PCIE_3_AUX_CLK, RPMH_CXO_CLK, put in TCSR_PCIE_8L_CLKREF_EN
   as ref.
6. Remove lane_broadcasting.
7. Add 64 bit bar, Remove GCC_PCIE_3_PIPE_CLK_SRC, 
   GCC_CFG_NOC_PCIE_ANOC_SOUTH_AHB_CLK is changed to
   GCC_CFG_NOC_PCIE_ANOC_NORTH_AHB_CLK.
8. Add Reviewed-by tag.
9. Remove [PATCH 7/8], [PATCH 8/8].

Qiang Yu (6):
  dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the X1E80100
    QMP PCIe PHY Gen4 x8
  dt-bindings: PCI: qcom: Move OPP table to qcom,pcie-common.yaml
  phy: qcom: qmp: Add phy register and clk setting for x1e80100 PCIe3
  clk: qcom: gcc-x1e80100: Fix halt_check for pipediv2 clocks
  PCI: qcom: Add support for X1E80100 SoC
  arm64: dts: qcom: x1e80100: Add support for PCIe3 on x1e80100

 .../bindings/pci/qcom,pcie-common.yaml        |   4 +
 .../bindings/pci/qcom,pcie-sm8450.yaml        |   4 -
 .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml       |   3 +
 arch/arm64/boot/dts/qcom/x1e80100.dtsi        | 204 ++++++++++++++++-
 drivers/clk/qcom/gcc-x1e80100.c               |  10 +-
 drivers/pci/controller/dwc/pcie-qcom.c        |  16 +-
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c      | 211 ++++++++++++++++++
 .../qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h    |  25 +++
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h |  19 ++
 9 files changed, 485 insertions(+), 11 deletions(-)
 create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
 create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h

-- 
2.34.1



From quic_qianyu at quicinc.com  Tue Sep 24 03:14:42 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Tue, 24 Sep 2024 03:14:42 -0700
Subject: [PATCH v4 4/6] clk: qcom: gcc-x1e80100: Fix halt_check for pipediv2 clocks
In-Reply-To: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
Message-ID: <20240924101444.3933828-5-quic_qianyu@quicinc.com>

The pipediv2_clk's source from the same mux as pipe clock. So they have
same limitation, which is that the PHY sequence requires to enable these
local CBCs before the PHY is actually outputting a clock to them. This
means the clock won't actually turn on when we vote them. Hence, let's
skip the halt bit check of the pipediv2_clk, otherwise pipediv2_clk may
stuck at off state during bootup.

Suggested-by: Mike Tipton <quic_mdtipton at quicinc.com>
Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
Reviewed-by: Konrad Dybcio <konradybcio at kernel.org>
---
 drivers/clk/qcom/gcc-x1e80100.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c
index 0f578771071f..81ba5ceab342 100644
--- a/drivers/clk/qcom/gcc-x1e80100.c
+++ b/drivers/clk/qcom/gcc-x1e80100.c
@@ -3123,7 +3123,7 @@ static struct clk_branch gcc_pcie_3_pipe_clk = {
 
 static struct clk_branch gcc_pcie_3_pipediv2_clk = {
 	.halt_reg = 0x58060,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52020,
 		.enable_mask = BIT(5),
@@ -3248,7 +3248,7 @@ static struct clk_branch gcc_pcie_4_pipe_clk = {
 
 static struct clk_branch gcc_pcie_4_pipediv2_clk = {
 	.halt_reg = 0x6b054,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52010,
 		.enable_mask = BIT(27),
@@ -3373,7 +3373,7 @@ static struct clk_branch gcc_pcie_5_pipe_clk = {
 
 static struct clk_branch gcc_pcie_5_pipediv2_clk = {
 	.halt_reg = 0x2f054,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52018,
 		.enable_mask = BIT(19),
@@ -3511,7 +3511,7 @@ static struct clk_branch gcc_pcie_6a_pipe_clk = {
 
 static struct clk_branch gcc_pcie_6a_pipediv2_clk = {
 	.halt_reg = 0x31060,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52018,
 		.enable_mask = BIT(28),
@@ -3649,7 +3649,7 @@ static struct clk_branch gcc_pcie_6b_pipe_clk = {
 
 static struct clk_branch gcc_pcie_6b_pipediv2_clk = {
 	.halt_reg = 0x8d060,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52010,
 		.enable_mask = BIT(28),
-- 
2.34.1



From quic_qianyu at quicinc.com  Tue Sep 24 03:14:41 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Tue, 24 Sep 2024 03:14:41 -0700
Subject: [PATCH v4 3/6] phy: qcom: qmp: Add phy register and clk setting for x1e80100 PCIe3
In-Reply-To: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
Message-ID: <20240924101444.3933828-4-quic_qianyu@quicinc.com>

Currently driver supports only x4 lane based functionality using tx/rx and
tx2/rx2 pair of register sets. To support 8 lane functionality with PCIe3,
PCIe3 related QMP PHY provides additional programming which are available
as txz and rxz based register set. Hence adds txz and rxz based registers
usage and programming sequences. Phy register setting for txz and rxz will
be applied to all 8 lanes. Some lanes may have different settings on
several registers than txz/rxz, these registers should be programmed after
txz/rxz programming sequences completing.

Besides, x1e80100 SoC uses QMP phy with version v6.30 for PCIe Gen4 x8.
Add the new register offsets in a dedicated header file.

Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Reviewed-by: Konrad Dybcio <konradybcio at kernel.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c      | 211 ++++++++++++++++++
 .../qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h    |  25 +++
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h |  19 ++
 3 files changed, 255 insertions(+)
 create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
 create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index f71787fb4d7e..d7bbd9df11d7 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -34,6 +34,8 @@
 #include "phy-qcom-qmp-pcs-pcie-v5_20.h"
 #include "phy-qcom-qmp-pcs-pcie-v6.h"
 #include "phy-qcom-qmp-pcs-pcie-v6_20.h"
+#include "phy-qcom-qmp-pcs-pcie-v6_30.h"
+#include "phy-qcom-qmp-pcs-v6_30.h"
 #include "phy-qcom-qmp-pcie-qhp.h"
 
 #define PHY_INIT_COMPLETE_TIMEOUT		10000
@@ -1344,6 +1346,155 @@ static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
 	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_FOM_EQ_CONFIG5, 0x8a),
 };
 
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_txz_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_TX, 0x1a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_RX, 0x05),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_1, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_2, 0x10),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_3, 0x51),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_TRAN_DRVR_EMP_EN, 0x34),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_rxz_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_2, 0x0c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_GAIN_RATE_2, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_3, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_PI_CONTROLS, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_ACC_DEFAULT_VAL_RATE3, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_CAL_CTRL2, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_POSTCAL_OFFSET, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_BKUP_CTRL1, 0x15),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_3, 0x45),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_VGA_CAL_MAN_VAL, 0x0c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_VGA_CAL_CNTRL1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_GM_CAL, 0x0d),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_EQU_ADAPTOR_CNTRL4, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_SIGDET_ENABLES, 0x1c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_PHPRE_CTRL, 0x20),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_Q_PI_INTRINSIC_BIAS_RATE32, 0x39),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B0, 0xd4),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B1, 0x23),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B2, 0x58),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B3, 0x9a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B4, 0x38),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B5, 0xb6),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B6, 0xee),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B0, 0x1c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B1, 0xe4),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B2, 0x60),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B3, 0xdf),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B4, 0x69),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B5, 0x76),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B6, 0xff),
+	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_TX_ADPT_CTRL, 0x10),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_rx_tbl[] = {
+	QMP_PHY_INIT_CFG_LANE(QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x3a, BIT(0)),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RXCLK_DIV2_CTRL, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_SUMMER_CAL_SPD_MODE, 0x5b),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_DFE_DAC_ENABLE1, 0x88),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH1, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH2, 0x0d),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B0, 0x12),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B1, 0x12),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B2, 0xdb),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B3, 0x9a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B4, 0x38),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B5, 0xb6),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B6, 0x64),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE210, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE210, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE210, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH4_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH5_RATE3, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH6_RATE3, 0x1f),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_serdes_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0x26),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x03),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x0d),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x68),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0xab),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0xaa),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x12),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0xf8),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0d),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0xab),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xaa),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x62),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_POST_DIV_MUX, 0x40),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 0x1c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x90),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x82),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x46),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_CFG, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x34),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x20),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MISC_1, 0x88),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MODE, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_VCO_DC_LEVEL_CTRL, 0x0f),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_pcs_tbl[] = {
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_LOCK_DETECT_CONFIG2, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_G3S2_PRE_GAIN, 0x2e),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_RX_SIGDET_LVL, 0x99),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_ALIGN_DETECT_CONFIG7, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_EQ_CONFIG4, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_EQ_CONFIG5, 0x22),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_TX_RX_CONFIG, 0x04),
+	QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_TX_RX_CONFIG2, 0x02),
+};
+
+static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl[] = {
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_OSC_DTCT_ACTIONS, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_EQ_CONFIG1, 0x16),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_EQ_CONFIG5, 0x02),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_PRE_GAIN, 0x2e),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG1, 0x03),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG3, 0x28),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG5, 0x18),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G3_FOM_EQ_CONFIG5, 0x7a),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_FOM_EQ_CONFIG5, 0x8a),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G3_RXEQEVAL_TIME, 0x27),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_RXEQEVAL_TIME, 0x27),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_TX_RX_CONFIG, 0xc0),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_POWER_STATE_CONFIG2, 0x1d),
+
+};
+
 static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
@@ -2582,6 +2733,8 @@ struct qmp_pcie_offsets {
 	u16 rx;
 	u16 tx2;
 	u16 rx2;
+	u16 txz;
+	u16 rxz;
 	u16 ln_shrd;
 };
 
@@ -2592,6 +2745,10 @@ struct qmp_phy_cfg_tbls {
 	int tx_num;
 	const struct qmp_phy_init_tbl *rx;
 	int rx_num;
+	const struct qmp_phy_init_tbl *txz;
+	int txz_num;
+	const struct qmp_phy_init_tbl *rxz;
+	int rxz_num;
 	const struct qmp_phy_init_tbl *pcs;
 	int pcs_num;
 	const struct qmp_phy_init_tbl *pcs_misc;
@@ -2659,6 +2816,8 @@ struct qmp_pcie {
 	void __iomem *rx;
 	void __iomem *tx2;
 	void __iomem *rx2;
+	void __iomem *txz;
+	void __iomem *rxz;
 	void __iomem *ln_shrd;
 
 	void __iomem *port_b;
@@ -2826,6 +2985,17 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_20 = {
 	.ln_shrd	= 0x0e00,
 };
 
+static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_30 = {
+	.serdes		= 0x8800,
+	.pcs		= 0x9000,
+	.pcs_misc	= 0x9800,
+	.tx		= 0x0000,
+	.rx		= 0x0200,
+	.txz		= 0xe000,
+	.rxz		= 0xe200,
+	.ln_shrd	= 0x8000,
+};
+
 static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
 	.lanes			= 1,
 
@@ -3704,6 +3874,38 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x4_pciephy_cfg = {
 	.has_nocsr_reset	= true,
 };
 
+static const struct qmp_phy_cfg x1e80100_qmp_gen4x8_pciephy_cfg = {
+	.lanes = 8,
+
+	.offsets		= &qmp_pcie_offsets_v6_30,
+	.tbls = {
+		.serdes			= x1e80100_qmp_gen4x8_pcie_serdes_tbl,
+		.serdes_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_serdes_tbl),
+		.rx			= x1e80100_qmp_gen4x8_pcie_rx_tbl,
+		.rx_num			= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_rx_tbl),
+		.pcs			= x1e80100_qmp_gen4x8_pcie_pcs_tbl,
+		.pcs_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_pcs_tbl),
+		.pcs_misc		= x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl,
+		.pcs_misc_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl),
+		.ln_shrd		= x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl,
+		.ln_shrd_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl),
+		.txz			= x1e80100_qmp_gen4x8_pcie_txz_tbl,
+		.txz_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_txz_tbl),
+		.rxz			= x1e80100_qmp_gen4x8_pcie_rxz_tbl,
+		.rxz_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_rxz_tbl),
+	},
+
+	.reset_list		= sdm845_pciephy_reset_l,
+	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.vreg_list		= sm8550_qmp_phy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm8550_qmp_phy_vreg_l),
+	.regs			= pciephy_v6_regs_layout,
+
+	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,
+	.phy_status		= PHYSTATUS_4_20,
+	.has_nocsr_reset	= true,
+};
+
 static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
 {
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -3751,6 +3953,9 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
 
 	qmp_configure(qmp->dev, serdes, tbls->serdes, tbls->serdes_num);
 
+	qmp_configure(qmp->dev, qmp->txz, tbls->txz, tbls->txz_num);
+	qmp_configure(qmp->dev, qmp->rxz, tbls->rxz, tbls->rxz_num);
+
 	qmp_configure_lane(qmp->dev, tx, tbls->tx, tbls->tx_num, 1);
 	qmp_configure_lane(qmp->dev, rx, tbls->rx, tbls->rx_num, 1);
 
@@ -4293,6 +4498,9 @@ static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
 			return PTR_ERR(qmp->port_b);
 	}
 
+	qmp->txz = base + offs->txz;
+	qmp->rxz = base + offs->rxz;
+
 	if (cfg->tbls.ln_shrd)
 		qmp->ln_shrd = base + offs->ln_shrd;
 
@@ -4478,6 +4686,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
 	}, {
 		.compatible = "qcom,x1e80100-qmp-gen4x4-pcie-phy",
 		.data = &x1e80100_qmp_gen4x4_pciephy_cfg,
+	}, {
+		.compatible = "qcom,x1e80100-qmp-gen4x8-pcie-phy",
+		.data = &x1e80100_qmp_gen4x8_pciephy_cfg,
 	},
 	{ },
 };
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
new file mode 100644
index 000000000000..5a58ff197e6e
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_PCIE_V6_30_H_
+#define QCOM_PHY_QMP_PCS_PCIE_V6_30_H_
+
+/* Only for QMP V6_30 PHY - PCIE have different offsets than V6 */
+#define QPHY_PCIE_V6_30_PCS_POWER_STATE_CONFIG2		0x014
+#define QPHY_PCIE_V6_30_PCS_TX_RX_CONFIG		0x020
+#define QPHY_PCIE_V6_30_PCS_ENDPOINT_REFCLK_DRIVE	0x024
+#define QPHY_PCIE_V6_30_PCS_OSC_DTCT_ACTIONS		0x098
+#define QPHY_PCIE_V6_30_PCS_EQ_CONFIG1			0x0a8
+#define QPHY_PCIE_V6_30_PCS_G3_RXEQEVAL_TIME		0x0f8
+#define QPHY_PCIE_V6_30_PCS_G4_RXEQEVAL_TIME		0x0fc
+#define QPHY_PCIE_V6_30_PCS_G4_EQ_CONFIG5		0x110
+#define QPHY_PCIE_V6_30_PCS_G4_PRE_GAIN			0x164
+#define QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG1	0x184
+#define QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG3	0x18c
+#define QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG5	0x194
+#define QPHY_PCIE_V6_30_PCS_G3_FOM_EQ_CONFIG5		0x1b4
+#define QPHY_PCIE_V6_30_PCS_G4_FOM_EQ_CONFIG5		0x1c8
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h
new file mode 100644
index 000000000000..369120d88bc2
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_V6_30_H_
+#define QCOM_PHY_QMP_PCS_V6_30_H_
+
+/* Only for QMP V6_30 PHY - PCIe PCS registers */
+#define QPHY_V6_30_PCS_LOCK_DETECT_CONFIG2		0x0cc
+#define QPHY_V6_30_PCS_G3S2_PRE_GAIN			0x17c
+#define QPHY_V6_30_PCS_RX_SIGDET_LVL			0x194
+#define QPHY_V6_30_PCS_ALIGN_DETECT_CONFIG7		0x1dc
+#define QPHY_V6_30_PCS_TX_RX_CONFIG			0x1e0
+#define QPHY_V6_30_PCS_TX_RX_CONFIG2			0x1e4
+#define QPHY_V6_30_PCS_EQ_CONFIG4			0x1fc
+#define QPHY_V6_30_PCS_EQ_CONFIG5			0x200
+
+#endif
-- 
2.34.1



From quic_qianyu at quicinc.com  Tue Sep 24 03:14:43 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Tue, 24 Sep 2024 03:14:43 -0700
Subject: [PATCH v4 5/6] PCI: qcom: Add support for X1E80100 SoC
In-Reply-To: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
Message-ID: <20240924101444.3933828-6-quic_qianyu@quicinc.com>

X1E80100 has PCIe ports that support up to Gen4 x8 based on hardware IP
version 1.38.0.

Currently the ops_1_9_0 which is being used for X1E80100 has config_sid
callback to config BDF to SID table. However, this callback is not
required for X1E80100 because it has smmuv3 support and BDF to SID table
will be not present.

Hence add support for X1E80100 by introducing a new ops and cfg structures
that don't require the config_sid callback. This could be reused by the
future platforms based on SMMUv3.

Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
---
 drivers/pci/controller/dwc/pcie-qcom.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 88a98be930e3..56ba8bc72f78 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1367,6 +1367,16 @@ static const struct qcom_pcie_ops ops_2_9_0 = {
 	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
 };
 
+/* Qcom IP rev.: 1.38.0 */
+static const struct qcom_pcie_ops ops_1_38_0 = {
+	.get_resources = qcom_pcie_get_resources_2_7_0,
+	.init = qcom_pcie_init_2_7_0,
+	.post_init = qcom_pcie_post_init_2_7_0,
+	.host_post_init = qcom_pcie_host_post_init_2_7_0,
+	.deinit = qcom_pcie_deinit_2_7_0,
+	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
+};
+
 static const struct qcom_pcie_cfg cfg_1_0_0 = {
 	.ops = &ops_1_0_0,
 };
@@ -1409,6 +1419,10 @@ static const struct qcom_pcie_cfg cfg_sc8280xp = {
 	.no_l0s = true,
 };
 
+static const struct qcom_pcie_cfg cfg_1_38_0 = {
+	.ops = &ops_1_38_0,
+};
+
 static const struct dw_pcie_ops dw_pcie_ops = {
 	.link_up = qcom_pcie_link_up,
 	.start_link = qcom_pcie_start_link,
@@ -1837,7 +1851,7 @@ static const struct of_device_id qcom_pcie_match[] = {
 	{ .compatible = "qcom,pcie-sm8450-pcie0", .data = &cfg_1_9_0 },
 	{ .compatible = "qcom,pcie-sm8450-pcie1", .data = &cfg_1_9_0 },
 	{ .compatible = "qcom,pcie-sm8550", .data = &cfg_1_9_0 },
-	{ .compatible = "qcom,pcie-x1e80100", .data = &cfg_1_9_0 },
+	{ .compatible = "qcom,pcie-x1e80100", .data = &cfg_1_38_0 },
 	{ }
 };
 
-- 
2.34.1



From mripard at kernel.org  Tue Sep 24 03:16:27 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 24 Sep 2024 12:16:27 +0200
Subject: [PATCH v17 4/8] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <8bdf573bfd7e3feb45d7ccb53765a978a685ce2d.1727159906.git.Sandor.yu@nxp.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
 <8bdf573bfd7e3feb45d7ccb53765a978a685ce2d.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <20240924-mottled-psychedelic-lorikeet-ef8f4c@houat>

On Tue, Sep 24, 2024 at 03:36:49PM GMT, Sandor Yu wrote:
> +static int cdns_mhdp8501_read_hpd(struct cdns_mhdp8501_device *mhdp)
> +{
> +	u8 status;
> +	int ret;
> +
> +	mutex_lock(&mhdp_mailbox_mutex);
> +
> +	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_GENERAL,
> +				     GENERAL_GET_HPD_STATE, 0, NULL);
> +	if (ret)
> +		goto err_get_hpd;
> +
> +	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_GENERAL,
> +					    GENERAL_GET_HPD_STATE,
> +					    sizeof(status));
> +	if (ret)
> +		goto err_get_hpd;
> +
> +	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &status, sizeof(status));
> +	if (ret)
> +		goto err_get_hpd;
> +
> +	mutex_unlock(&mhdp_mailbox_mutex);

That's better I guess, but it's still not a good API design. If you
can't have concurrent accesses, then cdns_mhdp_mailbox_send et al.
should take the mutex themselves.

> +	return status;
> +
> +err_get_hpd:
> +	dev_err(mhdp->dev, "read hpd  failed: %d\n", ret);
> +	mutex_unlock(&mhdp_mailbox_mutex);
> +
> +	return ret;
> +}
> +
> +enum drm_connector_status cdns_mhdp8501_detect(struct cdns_mhdp8501_device *mhdp)
> +{
> +	u8 hpd = 0xf;
> +
> +	hpd = cdns_mhdp8501_read_hpd(mhdp);
> +	if (hpd == 1)
> +		return connector_status_connected;
> +	else if (hpd == 0)
> +		return connector_status_disconnected;
> +
> +	dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n", hpd);

This is already logged, there's no need to add a message there.

> +	return connector_status_unknown;
> +}
> +
> +static void hotplug_work_func(struct work_struct *work)
> +{
> +	struct cdns_mhdp8501_device *mhdp = container_of(work,
> +						     struct cdns_mhdp8501_device,
> +						     hotplug_work.work);
> +	enum drm_connector_status status = cdns_mhdp8501_detect(mhdp);
> +
> +	drm_bridge_hpd_notify(&mhdp->bridge, status);
> +
> +	if (status == connector_status_connected) {
> +		/* Cable connected  */
> +		DRM_INFO("HDMI/DP Cable Plug In\n");

You might want to log it using drm_dev_debug, but anything else is a big
stretch.

> +		enable_irq(mhdp->irq[IRQ_OUT]);
> +
> +		/* Reset HDMI/DP link with sink */
> +		if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA)
> +			cdns_hdmi_reset_link(mhdp);
> +		else
> +			cdns_dp_check_link_state(mhdp);
> +
> +	} else if (status == connector_status_disconnected) {
> +		/* Cable Disconnected  */
> +		DRM_INFO("HDMI/DP Cable Plug Out\n");
> +		enable_irq(mhdp->irq[IRQ_IN]);
> +	}
> +}
> +
> +static irqreturn_t cdns_mhdp8501_irq_thread(int irq, void *data)
> +{
> +	struct cdns_mhdp8501_device *mhdp = data;
> +
> +	disable_irq_nosync(irq);
> +
> +	mod_delayed_work(system_wq, &mhdp->hotplug_work,
> +			 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
> +
> +	return IRQ_HANDLED;
> +}

disable_irq_nosync doesn't guarantee that you won't be called before
interrupts are reenabled. What will happen if this handler is called
multiple times?

> +
> +static int cdns_mhdp8501_dt_parse(struct cdns_mhdp8501_device *mhdp,
> +				  struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	struct device_node *remote;
> +
> +	remote = of_graph_get_remote_node(np, 1, 0);
> +	if (!remote) {
> +		dev_err(dev, "fail to get remote node\n");
> +		of_node_put(remote);
> +		return -EINVAL;
> +	}
> +
> +	/* get connector type */
> +	if (of_device_is_compatible(remote, "hdmi-connector")) {
> +		mhdp->connector_type = DRM_MODE_CONNECTOR_HDMIA;
> +
> +	} else if (of_device_is_compatible(remote, "dp-connector")) {
> +		mhdp->connector_type = DRM_MODE_CONNECTOR_DisplayPort;
> +
> +	} else {
> +		dev_err(dev, "Unknown connector type\n");
> +		of_node_put(remote);
> +		return -EINVAL;
> +	}
> +
> +	of_node_put(remote);
> +
> +	if (of_property_read_u32(np, "lane-mapping", &mhdp->lane_mapping)) {
> +		dev_warn(dev, "Failed to get lane_mapping - using default\n");

debug logging as well.

> +		mhdp->lane_mapping = LANE_MAPPING_FLIPPED;
> +	}
> +
> +	return true;
> +}
> +
> +static void cdns_mhdp8501_add_bridge(struct cdns_mhdp8501_device *mhdp)
> +{
> +	mhdp->bridge.type = mhdp->connector_type;
> +	mhdp->bridge.driver_private = mhdp;
> +	mhdp->bridge.of_node = mhdp->dev->of_node;
> +	mhdp->bridge.vendor = "NXP";
> +	mhdp->bridge.product = "i.MX8";
> +	mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
> +			   DRM_BRIDGE_OP_HPD;
> +
> +	if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA) {
> +		mhdp->bridge.funcs = &cdns_hdmi_bridge_funcs;
> +		mhdp->bridge.ops |= DRM_BRIDGE_OP_HDMI;
> +	} else if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
> +		mhdp->bridge.funcs = &cdns_dp_bridge_funcs;
> +	} else {
> +		dev_err(mhdp->dev, "Unsupported connector type!\n");
> +		return;
> +	}

If this function can error out, then it should return an error code.

> +static int cdns_hdmi_scdc_write(struct cdns_mhdp8501_device *mhdp, u8 addr, u8 value)
> +{
> +	u8 msg[5], reg[5];
> +	int ret;
> +
> +	msg[0] = 0x54;
> +	msg[1] = addr;
> +	msg[2] = 0;
> +	msg[3] = 1;
> +	msg[4] = value;
> +
> +	mutex_lock(&mhdp_mailbox_mutex);
> +
> +	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_HDMI_TX, HDMI_TX_WRITE,
> +				     sizeof(msg), msg);
> +	if (ret)
> +		goto err_scdc_write;
> +
> +	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_HDMI_TX,
> +					    HDMI_TX_WRITE, sizeof(reg));
> +	if (ret)
> +		goto err_scdc_write;
> +
> +	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg, sizeof(reg));
> +	if (ret)
> +		goto err_scdc_write;
> +
> +	if (reg[0] != 0)
> +		ret = -EINVAL;
> +
> +err_scdc_write:
> +
> +	mutex_unlock(&mhdp_mailbox_mutex);
> +
> +	if (ret)
> +		dev_err(mhdp->dev, "scdc write failed: %d\n", ret);
> +	return ret;
> +}

You should be using SCDC helpers there instead of hand crafting your
messages.

> +static void cdns_hdmi_sink_config(struct cdns_mhdp8501_device *mhdp)
> +{
> +	struct drm_display_info *display = &mhdp->curr_conn->display_info;
> +	struct drm_connector_state *conn_state = mhdp->curr_conn->state;

That looks a bit hackish to me. We should probably provide a helper to
get the connector state the bridge is attached to.

> +	struct drm_scdc *scdc = &mhdp->curr_conn->display_info.hdmi.scdc;
> +	u8 buff = 0;
> +
> +	/* check sink type (HDMI or DVI) */
> +	if (!display->is_hdmi) {
> +		mhdp->hdmi.hdmi_type = MODE_DVI;
> +		return;
> +	}
> +
> +	/* Default work in HDMI1.4 */
> +	mhdp->hdmi.hdmi_type = MODE_HDMI_1_4;
> +
> +	/* check sink support SCDC or not */
> +	if (!scdc->supported) {
> +		dev_info(mhdp->dev, "Sink Not Support SCDC\n");

drm_dev_debug

> +static enum drm_mode_status
> +cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
> +			       const struct drm_display_mode *mode,
> +			       unsigned long long tmds_rate)
> +{
> +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> +	union phy_configure_opts phy_cfg;
> +	int ret;
> +
> +	phy_cfg.hdmi.tmds_char_rate = tmds_rate;
> +
> +	ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
> +	if (ret < 0)
> +		return MODE_CLOCK_RANGE;
> +
> +	return MODE_OK;
> +}
> +
> +static enum drm_mode_status
> +cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
> +			    const struct drm_display_info *info,
> +			    const struct drm_display_mode *mode)
> +{
> +	unsigned long long tmds_rate;
> +
> +	/* We don't support double-clocked and Interlaced modes */
> +	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
> +	    mode->flags & DRM_MODE_FLAG_INTERLACE)
> +		return MODE_BAD;
> +
> +	if (mode->hdisplay > 3840)
> +		return MODE_BAD_HVALUE;
> +
> +	if (mode->vdisplay > 2160)
> +		return MODE_BAD_VVALUE;
> +
> +	tmds_rate = mode->clock * 1000ULL;
> +	return cdns_hdmi_tmds_char_rate_valid(bridge, mode, tmds_rate);
> +}

Didn't we agree on creating a mode_valid helper?

> +static void cdns_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
> +					   struct drm_bridge_state *old_state)
> +{
> +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> +	struct drm_atomic_state *state = old_state->base.state;
> +	struct drm_connector *connector;
> +	struct video_info *video_info = &mhdp->video_info;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_connector_state *conn_state;
> +	union phy_configure_opts phy_cfg;
> +	int ret;
> +
> +	connector = drm_atomic_get_new_connector_for_encoder(state,
> +							     bridge->encoder);
> +	if (WARN_ON(!connector))
> +		return;
> +
> +	mhdp->curr_conn = connector;
> +
> +	conn_state = drm_atomic_get_new_connector_state(state, connector);
> +	if (WARN_ON(!conn_state))
> +		return;
> +
> +	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
> +	if (WARN_ON(!crtc_state))
> +		return;
> +
> +	video_info->color_fmt = conn_state->hdmi.output_format;
> +	video_info->bpc = conn_state->hdmi.output_bpc;
> +
> +	drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
> +
> +	/* Line swapping */
> +	cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping);
> +
> +	phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate;
> +
> +	ret = phy_configure(mhdp->phy, &phy_cfg);
> +	if (ret) {
> +		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
> +			__func__, ret);
> +		return;
> +	}
> +
> +	cdns_hdmi_sink_config(mhdp);
> +
> +	ret = cdns_hdmi_ctrl_init(mhdp);
> +	if (ret < 0) {
> +		dev_err(mhdp->dev, "hdmi ctrl init failed = %d\n",  ret);
> +		return;
> +	}
> +
> +	/* Config GCP */
> +	if (video_info->bpc == 8)
> +		cdns_hdmi_disable_gcp(mhdp);
> +	else
> +		cdns_hdmi_enable_gcp(mhdp);
> +
> +	ret = cdns_hdmi_mode_config(mhdp, &crtc_state->adjusted_mode, video_info);
> +	if (ret < 0) {
> +		dev_err(mhdp->dev, "CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret);
> +		return;
> +	}

If the only thing you're doing is filling video_info and passing it
there, why do you need that structure at all? Just pass the
connector_state pointer.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 273 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20240924/d96cd667/attachment.sig>

From geert at linux-m68k.org  Tue Sep 24 04:32:04 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 24 Sep 2024 13:32:04 +0200
Subject: [PATCH 04/16] soc: renesas: Add SYSC driver for Renesas RZ/G3S
In-Reply-To: <20240822152801.602318-5-claudiu.beznea.uj@bp.renesas.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com> <20240822152801.602318-5-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <CAMuHMdVQsHx0nC3xwQWVRWyWMnbXd1=RokNn8rkJv3bfG_0p-A@mail.gmail.com>

Hi Claudiu,

On Thu, Aug 22, 2024 at 5:28?PM Claudiu <claudiu.beznea at tuxon.dev> wrote:
> From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>
> The RZ/G3S SYS Controller has 2 registers (one for PCIE one for USB) that
> need to be configured before/after powering off/on the PCI or USB
> ares. The bits in these registers control signals to PCIE and USB that
> need to be de-asserted/asserted after/before power on/off event. For this
> add SYSC controller driver that registers a reset controller driver on
> auxiliary bus which allows USB, PCIE drivers to control these signals.
>
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>

Thanks for your patch!

> --- /dev/null
> +++ b/drivers/reset/reset-rzg3s-sysc.c
> @@ -0,0 +1,140 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Renesas RZ/G3S SYSC reset driver
> + *
> + * Copyright (C) 2024 Renesas Electronics Corp.
> + */
> +
> +#include <linux/auxiliary_bus.h>

Using the Auxiliary Bus requires selecting AUXILIARY_BUS.
Elsse you might run into build failures:

aarch64-linux-gnu-ld: drivers/soc/renesas/rzg3s-sysc.o: in function
`rzg3s_sysc_probe':
rzg3s-sysc.c:(.text+0x21c): undefined reference to `auxiliary_device_init'
aarch64-linux-gnu-ld: rzg3s-sysc.c:(.text+0x264): undefined reference
to `__auxiliary_device_add'
aarch64-linux-gnu-ld: drivers/reset/reset-rzg3s-sysc.o: in function
`rzg3s_sysc_reset_driver_init':
reset-rzg3s-sysc.c:(.init.text+0x1c): undefined reference to
`__auxiliary_driver_register'
aarch64-linux-gnu-ld: drivers/reset/reset-rzg3s-sysc.o: in function
`rzg3s_sysc_reset_driver_exit':
reset-rzg3s-sysc.c:(.exit.text+0x10): undefined reference to
`auxiliary_driver_unregister'

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From dmitry.baryshkov at linaro.org  Tue Sep 24 06:47:45 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 24 Sep 2024 16:47:45 +0300
Subject: [PATCH v17 4/8] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <20240924-mottled-psychedelic-lorikeet-ef8f4c@houat>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
 <8bdf573bfd7e3feb45d7ccb53765a978a685ce2d.1727159906.git.Sandor.yu@nxp.com>
 <20240924-mottled-psychedelic-lorikeet-ef8f4c@houat>
Message-ID: <2mug3ii2vi735sk7nwwu2rcj63d3mlgazlhg4sydcxb6uf5nsc@qi5ut5pmajsv>

On Tue, Sep 24, 2024 at 12:16:27PM GMT, Maxime Ripard wrote:
> On Tue, Sep 24, 2024 at 03:36:49PM GMT, Sandor Yu wrote:
> > +static int cdns_mhdp8501_read_hpd(struct cdns_mhdp8501_device *mhdp)
> > +{
> > +	u8 status;
> > +	int ret;
> > +
> > +	mutex_lock(&mhdp_mailbox_mutex);
> > +
> > +	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_GENERAL,
> > +				     GENERAL_GET_HPD_STATE, 0, NULL);
> > +	if (ret)
> > +		goto err_get_hpd;
> > +
> > +	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_GENERAL,
> > +					    GENERAL_GET_HPD_STATE,
> > +					    sizeof(status));
> > +	if (ret)
> > +		goto err_get_hpd;
> > +
> > +	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &status, sizeof(status));
> > +	if (ret)
> > +		goto err_get_hpd;
> > +
> > +	mutex_unlock(&mhdp_mailbox_mutex);
> 
> That's better I guess, but it's still not a good API design. If you
> can't have concurrent accesses, then cdns_mhdp_mailbox_send et al.
> should take the mutex themselves.

I think that a proper API might be:

int cdns_mhdp_mailbox_send_recv(struct cdns_mhdp_device *mhdp,
			u8 module_id, u8 opcode,
			u16 size, const u8 *message,
			u16 buf_size, u8 *buf);

Internally it should take the lock, exchange the data, then return.

-- 
With best wishes
Dmitry


From manivannan.sadhasivam at linaro.org  Tue Sep 24 06:50:21 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Tue, 24 Sep 2024 15:50:21 +0200
Subject: [PATCH v4 5/6] PCI: qcom: Add support for X1E80100 SoC
In-Reply-To: <20240924101444.3933828-6-quic_qianyu@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-6-quic_qianyu@quicinc.com>
Message-ID: <20240924135021.ybpyoahlpuvedma5@thinkpad>

On Tue, Sep 24, 2024 at 03:14:43AM -0700, Qiang Yu wrote:
> X1E80100 has PCIe ports that support up to Gen4 x8 based on hardware IP
> version 1.38.0.
> 
> Currently the ops_1_9_0 which is being used for X1E80100 has config_sid
> callback to config BDF to SID table. However, this callback is not
> required for X1E80100 because it has smmuv3 support and BDF to SID table
> will be not present.
> 
> Hence add support for X1E80100 by introducing a new ops and cfg structures
> that don't require the config_sid callback. This could be reused by the
> future platforms based on SMMUv3.
> 

Oops... I completely overlooked that you are not adding the SoC support but
fixing the existing one :( Sorry for suggesting a commit message that changed
the context.

For this, you can have something like:

"PCI: qcom: Fix the ops for X1E80100 SoC

X1E80100 SoC is based on SMMUv3, hence it doesn't need the BDF2SID mapping
present in the existing cfg_1_9_0 ops. This is fixed by introducing new ops
'ops_1_38_0' and cfg 'cfg_1_38_0' structures. These are exactly same as the
1_9_0 ones, but they don't have the 'config_sid()' callback that handles the
BDF2SID mapping in the hardware. These new structures could also be used by the
future SoCs making use of SMMUv3."

- Mani

> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> ---
>  drivers/pci/controller/dwc/pcie-qcom.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index 88a98be930e3..56ba8bc72f78 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1367,6 +1367,16 @@ static const struct qcom_pcie_ops ops_2_9_0 = {
>  	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
>  };
>  
> +/* Qcom IP rev.: 1.38.0 */
> +static const struct qcom_pcie_ops ops_1_38_0 = {
> +	.get_resources = qcom_pcie_get_resources_2_7_0,
> +	.init = qcom_pcie_init_2_7_0,
> +	.post_init = qcom_pcie_post_init_2_7_0,
> +	.host_post_init = qcom_pcie_host_post_init_2_7_0,
> +	.deinit = qcom_pcie_deinit_2_7_0,
> +	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
> +};
> +
>  static const struct qcom_pcie_cfg cfg_1_0_0 = {
>  	.ops = &ops_1_0_0,
>  };
> @@ -1409,6 +1419,10 @@ static const struct qcom_pcie_cfg cfg_sc8280xp = {
>  	.no_l0s = true,
>  };
>  
> +static const struct qcom_pcie_cfg cfg_1_38_0 = {
> +	.ops = &ops_1_38_0,
> +};
> +
>  static const struct dw_pcie_ops dw_pcie_ops = {
>  	.link_up = qcom_pcie_link_up,
>  	.start_link = qcom_pcie_start_link,
> @@ -1837,7 +1851,7 @@ static const struct of_device_id qcom_pcie_match[] = {
>  	{ .compatible = "qcom,pcie-sm8450-pcie0", .data = &cfg_1_9_0 },
>  	{ .compatible = "qcom,pcie-sm8450-pcie1", .data = &cfg_1_9_0 },
>  	{ .compatible = "qcom,pcie-sm8550", .data = &cfg_1_9_0 },
> -	{ .compatible = "qcom,pcie-x1e80100", .data = &cfg_1_9_0 },
> +	{ .compatible = "qcom,pcie-x1e80100", .data = &cfg_1_38_0 },
>  	{ }
>  };
>  
> -- 
> 2.34.1
> 

-- 
????????? ????????


From manivannan.sadhasivam at linaro.org  Tue Sep 24 07:06:18 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Tue, 24 Sep 2024 16:06:18 +0200
Subject: [PATCH v4 6/6] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <20240924101444.3933828-7-quic_qianyu@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-7-quic_qianyu@quicinc.com>
Message-ID: <20240924140618.dgaiisihyuqf4vrr@thinkpad>

On Tue, Sep 24, 2024 at 03:14:44AM -0700, Qiang Yu wrote:
> Describe PCIe3 controller and PHY. Also add required system resources like
> regulators, clocks, interrupts and registers configuration for PCIe3.
> 
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>

- Mani

> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/x1e80100.dtsi | 204 ++++++++++++++++++++++++-
>  1 file changed, 203 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> index a36076e3c56b..c615c930cf0c 100644
> --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> +++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> @@ -744,7 +744,7 @@ gcc: clock-controller at 100000 {
>  
>  			clocks = <&bi_tcxo_div2>,
>  				 <&sleep_clk>,
> -				 <0>,
> +				 <&pcie3_phy>,
>  				 <&pcie4_phy>,
>  				 <&pcie5_phy>,
>  				 <&pcie6a_phy>,
> @@ -2907,6 +2907,208 @@ mmss_noc: interconnect at 1780000 {
>  			#interconnect-cells = <2>;
>  		};
>  
> +		pcie3: pcie at 1bd0000 {
> +			device_type = "pci";
> +			compatible = "qcom,pcie-x1e80100";
> +			reg = <0x0 0x01bd0000 0x0 0x3000>,
> +			      <0x0 0x78000000 0x0 0xf1d>,
> +			      <0x0 0x78000f40 0x0 0xa8>,
> +			      <0x0 0x78001000 0x0 0x1000>,
> +			      <0x0 0x78100000 0x0 0x100000>,
> +			      <0x0 0x01bd3000 0x0 0x1000>;
> +			reg-names = "parf",
> +				    "dbi",
> +				    "elbi",
> +				    "atu",
> +				    "config",
> +				    "mhi";
> +			#address-cells = <3>;
> +			#size-cells = <2>;
> +			ranges = <0x01000000 0x0 0x00000000 0x0 0x78200000 0x0 0x100000>,
> +				 <0x02000000 0x0 0x78300000 0x0 0x78300000 0x0 0x3d00000>,
> +				 <0x03000000 0x7 0x40000000 0x7 0x40000000 0x0 0x40000000>;
> +			bus-range = <0x00 0xff>;
> +
> +			dma-coherent;
> +
> +			linux,pci-domain = <3>;
> +			num-lanes = <8>;
> +
> +			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 769 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 671 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
> +			interrupt-names = "msi0",
> +					  "msi1",
> +					  "msi2",
> +					  "msi3",
> +					  "msi4",
> +					  "msi5",
> +					  "msi6",
> +					  "msi7",
> +					  "global";
> +
> +			#interrupt-cells = <1>;
> +			interrupt-map-mask = <0 0 0 0x7>;
> +			interrupt-map = <0 0 0 1 &intc 0 0 GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>,
> +					<0 0 0 2 &intc 0 0 GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>,
> +					<0 0 0 3 &intc 0 0 GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>,
> +					<0 0 0 4 &intc 0 0 GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
> +
> +			clocks = <&gcc GCC_PCIE_3_AUX_CLK>,
> +				 <&gcc GCC_PCIE_3_CFG_AHB_CLK>,
> +				 <&gcc GCC_PCIE_3_MSTR_AXI_CLK>,
> +				 <&gcc GCC_PCIE_3_SLV_AXI_CLK>,
> +				 <&gcc GCC_PCIE_3_SLV_Q2A_AXI_CLK>,
> +				 <&gcc GCC_CFG_NOC_PCIE_ANOC_NORTH_AHB_CLK>,
> +				 <&gcc GCC_CNOC_PCIE_NORTH_SF_AXI_CLK>;
> +			clock-names = "aux",
> +				      "cfg",
> +				      "bus_master",
> +				      "bus_slave",
> +				      "slave_q2a",
> +				      "noc_aggr",
> +				      "cnoc_sf_axi";
> +
> +			assigned-clocks = <&gcc GCC_PCIE_3_AUX_CLK>;
> +			assigned-clock-rates = <19200000>;
> +
> +			interconnects = <&pcie_south_anoc MASTER_PCIE_3 QCOM_ICC_TAG_ALWAYS
> +					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
> +					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
> +					 &cnoc_main SLAVE_PCIE_3 QCOM_ICC_TAG_ALWAYS>;
> +			interconnect-names = "pcie-mem",
> +					     "cpu-pcie";
> +
> +			resets = <&gcc GCC_PCIE_3_BCR>,
> +				 <&gcc GCC_PCIE_3_LINK_DOWN_BCR>;
> +			reset-names = "pci",
> +				      "link_down";
> +
> +			power-domains = <&gcc GCC_PCIE_3_GDSC>;
> +
> +			phys = <&pcie3_phy>;
> +			phy-names = "pciephy";
> +
> +			operating-points-v2 = <&pcie3_opp_table>;
> +
> +			status = "disabled";
> +
> +			pcie3_opp_table: opp-table {
> +				compatible = "operating-points-v2";
> +
> +				/* GEN 1 x1 */
> +				opp-2500000 {
> +					opp-hz = /bits/ 64 <2500000>;
> +					required-opps = <&rpmhpd_opp_low_svs>;
> +					opp-peak-kBps = <250000 1>;
> +				};
> +
> +				/* GEN 1 x2 and GEN 2 x1 */
> +				opp-5000000 {
> +					opp-hz = /bits/ 64 <5000000>;
> +					required-opps = <&rpmhpd_opp_low_svs>;
> +					opp-peak-kBps = <500000 1>;
> +				};
> +
> +				/* GEN 1 x4 and GEN 2 x2 */
> +				opp-10000000 {
> +					opp-hz = /bits/ 64 <10000000>;
> +					required-opps = <&rpmhpd_opp_low_svs>;
> +					opp-peak-kBps = <1000000 1>;
> +				};
> +
> +				/* GEN 1 x8 and GEN 2 x4 */
> +				opp-20000000 {
> +					opp-hz = /bits/ 64 <20000000>;
> +					required-opps = <&rpmhpd_opp_low_svs>;
> +					opp-peak-kBps = <2000000 1>;
> +				};
> +
> +				/* GEN 2 x8 */
> +				opp-40000000 {
> +					opp-hz = /bits/ 64 <40000000>;
> +					required-opps = <&rpmhpd_opp_low_svs>;
> +					opp-peak-kBps = <4000000 1>;
> +				};
> +
> +				/* GEN 3 x1 */
> +				opp-8000000 {
> +					opp-hz = /bits/ 64 <8000000>;
> +					required-opps = <&rpmhpd_opp_svs>;
> +					opp-peak-kBps = <984500 1>;
> +				};
> +
> +				/* GEN 3 x2 and GEN 4 x1 */
> +				opp-16000000 {
> +					opp-hz = /bits/ 64 <16000000>;
> +					required-opps = <&rpmhpd_opp_svs>;
> +					opp-peak-kBps = <1969000 1>;
> +				};
> +
> +				/* GEN 3 x4 and GEN 4 x2 */
> +				opp-32000000 {
> +					opp-hz = /bits/ 64 <32000000>;
> +					required-opps = <&rpmhpd_opp_svs>;
> +					opp-peak-kBps = <3938000 1>;
> +				};
> +
> +				/* GEN 3 x8 and GEN 4 x4 */
> +				opp-64000000 {
> +					opp-hz = /bits/ 64 <64000000>;
> +					required-opps = <&rpmhpd_opp_svs>;
> +					opp-peak-kBps = <7876000 1>;
> +				};
> +
> +				/* GEN 4 x8 */
> +				opp-128000000 {
> +					opp-hz = /bits/ 64 <128000000>;
> +					required-opps = <&rpmhpd_opp_svs>;
> +					opp-peak-kBps = <15753000 1>;
> +				};
> +			};
> +		};
> +
> +		pcie3_phy: phy at 1be0000 {
> +			compatible = "qcom,x1e80100-qmp-gen4x8-pcie-phy";
> +			reg = <0 0x01be0000 0 0x10000>;
> +
> +			clocks = <&gcc GCC_PCIE_3_PHY_AUX_CLK>,
> +				 <&gcc GCC_PCIE_3_CFG_AHB_CLK>,
> +				 <&tcsr TCSR_PCIE_8L_CLKREF_EN>,
> +				 <&gcc GCC_PCIE_3_PHY_RCHNG_CLK>,
> +				 <&gcc GCC_PCIE_3_PIPE_CLK>,
> +				 <&gcc GCC_PCIE_3_PIPEDIV2_CLK>;
> +			clock-names = "aux",
> +				      "cfg_ahb",
> +				      "ref",
> +				      "rchng",
> +				      "pipe",
> +				      "pipediv2";
> +
> +			resets = <&gcc GCC_PCIE_3_PHY_BCR>,
> +				 <&gcc GCC_PCIE_3_NOCSR_COM_PHY_BCR>;
> +			reset-names = "phy",
> +				      "phy_nocsr";
> +
> +			assigned-clocks = <&gcc GCC_PCIE_3_PHY_RCHNG_CLK>;
> +			assigned-clock-rates = <100000000>;
> +
> +			power-domains = <&gcc GCC_PCIE_3_PHY_GDSC>;
> +
> +			#clock-cells = <0>;
> +			clock-output-names = "pcie3_pipe_clk";
> +
> +			#phy-cells = <0>;
> +
> +			status = "disabled";
> +		};
> +
>  		pcie6a: pci at 1bf8000 {
>  			device_type = "pci";
>  			compatible = "qcom,pcie-x1e80100";
> -- 
> 2.34.1
> 

-- 
????????? ????????


From manivannan.sadhasivam at linaro.org  Tue Sep 24 07:08:28 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Tue, 24 Sep 2024 16:08:28 +0200
Subject: [PATCH v4 2/6] dt-bindings: PCI: qcom: Move OPP table to
 qcom,pcie-common.yaml
In-Reply-To: <20240924101444.3933828-3-quic_qianyu@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-3-quic_qianyu@quicinc.com>
Message-ID: <20240924140828.mz5vjcicygsj4eb4@thinkpad>

On Tue, Sep 24, 2024 at 03:14:40AM -0700, Qiang Yu wrote:

> OPP table is a generic property that is also required by other qcom
> platforms. Hence move this property to qcom,pcie-common.yaml so that PCIe
> on other qcom platforms is able to adjust power domain performance state
> and ICC peak bw according to PCIe gen speed and link width.
> 
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>

- Mani

> ---
>  Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml | 4 ++++
>  Documentation/devicetree/bindings/pci/qcom,pcie-sm8450.yaml | 4 ----
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml
> index 704c0f58eea5..3c6430fe9331 100644
> --- a/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml
> +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml
> @@ -78,6 +78,10 @@ properties:
>      description: GPIO controlled connection to WAKE# signal
>      maxItems: 1
>  
> +  operating-points-v2: true
> +  opp-table:
> +    type: object
> +
>  required:
>    - reg
>    - reg-names
> diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8450.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8450.yaml
> index 46bd59eefadb..6e0a6d8f0ed0 100644
> --- a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8450.yaml
> +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8450.yaml
> @@ -70,10 +70,6 @@ properties:
>        - const: msi7
>        - const: global
>  
> -  operating-points-v2: true
> -  opp-table:
> -    type: object
> -
>    resets:
>      maxItems: 1
>  
> -- 
> 2.34.1
> 

-- 
????????? ????????


From konradybcio at kernel.org  Tue Sep 24 07:26:34 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Tue, 24 Sep 2024 16:26:34 +0200
Subject: [PATCH v4 6/6] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <20240924101444.3933828-7-quic_qianyu@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-7-quic_qianyu@quicinc.com>
Message-ID: <9a692c98-eb0a-4d86-b642-ea655981ff53@kernel.org>

On 24.09.2024 12:14 PM, Qiang Yu wrote:
> Describe PCIe3 controller and PHY. Also add required system resources like
> regulators, clocks, interrupts and registers configuration for PCIe3.
> 
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---

Qiang, Mani

I have a RTS5261 mmc chip on PCIe3 on the Surface Laptop.
Adding the global irq breaks sdcard detection (the chip still comes
up fine) somehow. Removing the irq makes it work again :|

I've confirmed that the irq number is correct

Konrad


From johan at kernel.org  Tue Sep 24 07:31:16 2024
From: johan at kernel.org (Johan Hovold)
Date: Tue, 24 Sep 2024 16:31:16 +0200
Subject: [PATCH v4 4/6] clk: qcom: gcc-x1e80100: Fix halt_check for
 pipediv2 clocks
In-Reply-To: <20240924101444.3933828-5-quic_qianyu@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-5-quic_qianyu@quicinc.com>
Message-ID: <ZvLNNDCOy68nK2B5@hovoldconsulting.com>

On Tue, Sep 24, 2024 at 03:14:42AM -0700, Qiang Yu wrote:
> The pipediv2_clk's source from the same mux as pipe clock. So they have
> same limitation, which is that the PHY sequence requires to enable these
> local CBCs before the PHY is actually outputting a clock to them. This
> means the clock won't actually turn on when we vote them. Hence, let's
> skip the halt bit check of the pipediv2_clk, otherwise pipediv2_clk may
> stuck at off state during bootup.
> 
> Suggested-by: Mike Tipton <quic_mdtipton at quicinc.com>
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> Reviewed-by: Konrad Dybcio <konradybcio at kernel.org>

Looks like this one is missing a Fixes and CC stable tag. With that
added:

Reviewed-by: Johan Hovold <johan+linaro at kernel.org>

Johan


From johan at kernel.org  Tue Sep 24 07:43:33 2024
From: johan at kernel.org (Johan Hovold)
Date: Tue, 24 Sep 2024 16:43:33 +0200
Subject: [PATCH v4 6/6] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <20240924101444.3933828-7-quic_qianyu@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-7-quic_qianyu@quicinc.com>
Message-ID: <ZvLQFSjwR-TvHbm_@hovoldconsulting.com>

On Tue, Sep 24, 2024 at 03:14:44AM -0700, Qiang Yu wrote:
> Describe PCIe3 controller and PHY. Also add required system resources like
> regulators, clocks, interrupts and registers configuration for PCIe3.

> @@ -2907,6 +2907,208 @@ mmss_noc: interconnect at 1780000 {
>  			#interconnect-cells = <2>;
>  		};
>  
> +		pcie3: pcie at 1bd0000 {
> +			device_type = "pci";
> +			compatible = "qcom,pcie-x1e80100";

> +			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 769 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 671 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
> +			interrupt-names = "msi0",
> +					  "msi1",
> +					  "msi2",
> +					  "msi3",
> +					  "msi4",
> +					  "msi5",
> +					  "msi6",
> +					  "msi7",
> +					  "global";

This ninth "global" interrupt is not described by the bindings, which
would also need to be updated. What is it used for?

Johan


From johan at kernel.org  Tue Sep 24 08:15:25 2024
From: johan at kernel.org (Johan Hovold)
Date: Tue, 24 Sep 2024 17:15:25 +0200
Subject: [PATCH v4 3/6] phy: qcom: qmp: Add phy register and clk setting
 for x1e80100 PCIe3
In-Reply-To: <20240924101444.3933828-4-quic_qianyu@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-4-quic_qianyu@quicinc.com>
Message-ID: <ZvLXjdpBpUS3lLn-@hovoldconsulting.com>

On Tue, Sep 24, 2024 at 03:14:41AM -0700, Qiang Yu wrote:
> Currently driver supports only x4 lane based functionality using tx/rx and
> tx2/rx2 pair of register sets. To support 8 lane functionality with PCIe3,
> PCIe3 related QMP PHY provides additional programming which are available
> as txz and rxz based register set. Hence adds txz and rxz based registers
> usage and programming sequences.

> Phy register setting for txz and rxz will
> be applied to all 8 lanes. Some lanes may have different settings on
> several registers than txz/rxz, these registers should be programmed after
> txz/rxz programming sequences completing.

Please expand and clarify what you mean by this.
 
> Besides, x1e80100 SoC uses QMP phy with version v6.30 for PCIe Gen4 x8.
> Add the new register offsets in a dedicated header file.
> 
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Reviewed-by: Konrad Dybcio <konradybcio at kernel.org>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c      | 211 ++++++++++++++++++
>  .../qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h    |  25 +++
>  drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h |  19 ++
>  3 files changed, 255 insertions(+)
>  create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
>  create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> index f71787fb4d7e..d7bbd9df11d7 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c

> @@ -1344,6 +1346,155 @@ static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
>  	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_FOM_EQ_CONFIG5, 0x8a),
>  };
>  
> +static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_txz_tbl[] = {

Please try to follow the sort order used for the other platforms for
these tables (e.g.  serdes, tx, rx, pcr, pcr_misc).

> +static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl[] = {
> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1),
> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_OSC_DTCT_ACTIONS, 0x00),
> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_EQ_CONFIG1, 0x16),
> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_EQ_CONFIG5, 0x02),
> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_PRE_GAIN, 0x2e),
> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG1, 0x03),
> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG3, 0x28),
> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG5, 0x18),
> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G3_FOM_EQ_CONFIG5, 0x7a),
> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_FOM_EQ_CONFIG5, 0x8a),
> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G3_RXEQEVAL_TIME, 0x27),
> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_RXEQEVAL_TIME, 0x27),
> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_TX_RX_CONFIG, 0xc0),
> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_POWER_STATE_CONFIG2, 0x1d),
> +

Stray newline.

> +};
> +

> +static const struct qmp_phy_cfg x1e80100_qmp_gen4x8_pciephy_cfg = {
> +	.lanes = 8,
> +
> +	.offsets		= &qmp_pcie_offsets_v6_30,
> +	.tbls = {
> +		.serdes			= x1e80100_qmp_gen4x8_pcie_serdes_tbl,
> +		.serdes_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_serdes_tbl),
> +		.rx			= x1e80100_qmp_gen4x8_pcie_rx_tbl,
> +		.rx_num			= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_rx_tbl),
> +		.pcs			= x1e80100_qmp_gen4x8_pcie_pcs_tbl,
> +		.pcs_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_pcs_tbl),
> +		.pcs_misc		= x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl,
> +		.pcs_misc_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl),
> +		.ln_shrd		= x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl,
> +		.ln_shrd_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl),
> +		.txz			= x1e80100_qmp_gen4x8_pcie_txz_tbl,
> +		.txz_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_txz_tbl),
> +		.rxz			= x1e80100_qmp_gen4x8_pcie_rxz_tbl,
> +		.rxz_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_rxz_tbl),

Try follow the order of the other SoCs here as well (e.g. use the order
defined in struct qmp_phy_cfg_tbls).

> +	},

>  static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
>  {
>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
> @@ -3751,6 +3953,9 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
>  
>  	qmp_configure(qmp->dev, serdes, tbls->serdes, tbls->serdes_num);

If your comment in the commit message implies that txz/rxz must be
programmed before tx/rx then you need to add a comment here as well.

> +	qmp_configure(qmp->dev, qmp->txz, tbls->txz, tbls->txz_num);
> +	qmp_configure(qmp->dev, qmp->rxz, tbls->rxz, tbls->rxz_num);
> +
>  	qmp_configure_lane(qmp->dev, tx, tbls->tx, tbls->tx_num, 1);
>  	qmp_configure_lane(qmp->dev, rx, tbls->rx, tbls->rx_num, 1);

Johan


From johan at kernel.org  Tue Sep 24 08:17:19 2024
From: johan at kernel.org (Johan Hovold)
Date: Tue, 24 Sep 2024 17:17:19 +0200
Subject: [PATCH v4 5/6] PCI: qcom: Add support for X1E80100 SoC
In-Reply-To: <20240924135021.ybpyoahlpuvedma5@thinkpad>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-6-quic_qianyu@quicinc.com>
 <20240924135021.ybpyoahlpuvedma5@thinkpad>
Message-ID: <ZvLX_wkh7_y7sjPZ@hovoldconsulting.com>

On Tue, Sep 24, 2024 at 03:50:21PM +0200, Manivannan Sadhasivam wrote:
> On Tue, Sep 24, 2024 at 03:14:43AM -0700, Qiang Yu wrote:
> > X1E80100 has PCIe ports that support up to Gen4 x8 based on hardware IP
> > version 1.38.0.
> > 
> > Currently the ops_1_9_0 which is being used for X1E80100 has config_sid
> > callback to config BDF to SID table. However, this callback is not
> > required for X1E80100 because it has smmuv3 support and BDF to SID table
> > will be not present.
> > 
> > Hence add support for X1E80100 by introducing a new ops and cfg structures
> > that don't require the config_sid callback. This could be reused by the
> > future platforms based on SMMUv3.
> > 
> 
> Oops... I completely overlooked that you are not adding the SoC support but
> fixing the existing one :( Sorry for suggesting a commit message that changed
> the context.
> 
> For this, you can have something like:
> 
> "PCI: qcom: Fix the ops for X1E80100 SoC
> 
> X1E80100 SoC is based on SMMUv3, hence it doesn't need the BDF2SID mapping
> present in the existing cfg_1_9_0 ops. This is fixed by introducing new ops
> 'ops_1_38_0' and cfg 'cfg_1_38_0' structures. These are exactly same as the
> 1_9_0 ones, but they don't have the 'config_sid()' callback that handles the
> BDF2SID mapping in the hardware. These new structures could also be used by the
> future SoCs making use of SMMUv3."

Don't we need something like this for sc8280xp and other platforms using
SMMUv3 as well?

Johan


From conor at kernel.org  Tue Sep 24 09:11:35 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 24 Sep 2024 17:11:35 +0100
Subject: [PATCH v2 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <20240924085510.20863-1-frawang.cn@gmail.com>
References: <20240924085510.20863-1-frawang.cn@gmail.com>
Message-ID: <20240924-overtly-curable-13df2e7fdc9b@spud>

On Tue, Sep 24, 2024 at 04:55:09PM +0800, Frank Wang wrote:
> From: Frank Wang <frank.wang at rock-chips.com>
> 
> Add compatible for the USB2 phy in the Rockchip RK3576 SoC.
> 
> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
> ---
> Changelog:
> v2:
>  - Categorize clock names by oneOf keyword.
> 
> v1:
>  - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-1-frank.wang at rock-chips.com/
> 
>  .../bindings/phy/rockchip,inno-usb2phy.yaml      | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
> index 5254413137c64..8af4e0f8637fc 100644
> --- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
> @@ -20,6 +20,7 @@ properties:
>        - rockchip,rk3366-usb2phy
>        - rockchip,rk3399-usb2phy
>        - rockchip,rk3568-usb2phy
> +      - rockchip,rk3576-usb2phy
>        - rockchip,rk3588-usb2phy
>        - rockchip,rv1108-usb2phy
>  
> @@ -34,10 +35,20 @@ properties:
>      const: 0
>  
>    clocks:
> -    maxItems: 1
> +    minItems: 1
> +    maxItems: 3
>  
>    clock-names:
> -    const: phyclk
> +    minItems: 1
> +    maxItems: 3

clock-names isn't a required property, you can't allow jumbling the order
like this does without breaking the ABI. Why can't the new device have
phyclk in position 1?

> +    items:
> +      oneOf:
> +        - description: aclk for USB MMU.
> +          const: aclk
> +        - description: aclk_slv for USB MMU.
> +          const: aclk_slv
> +        - description: PHY input reference clocks.
> +          const: phyclk
>  
>    assigned-clocks:
>      description:
> @@ -143,6 +154,7 @@ allOf:
>            contains:
>              enum:
>                - rockchip,rk3568-usb2phy
> +              - rockchip,rk3576-usb2phy
>                - rockchip,rk3588-usb2phy
>  
>      then:
> -- 
> 2.45.2
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20240924/425b4582/attachment.sig>

From stephan.gerhold at linaro.org  Tue Sep 24 09:41:35 2024
From: stephan.gerhold at linaro.org (Stephan Gerhold)
Date: Tue, 24 Sep 2024 18:41:35 +0200
Subject: [PATCH v2 1/2] dt-bindings: phy: add NXP PTN3222 eUSB2 to USB2
 redriver
In-Reply-To: <20240830-nxp-ptn3222-v2-1-4c6d8535cf6c@linaro.org>
References: <20240830-nxp-ptn3222-v2-0-4c6d8535cf6c@linaro.org>
 <20240830-nxp-ptn3222-v2-1-4c6d8535cf6c@linaro.org>
Message-ID: <ZvLrv4rW6vbOws8E@linaro.org>

On Fri, Aug 30, 2024 at 11:20:45AM +0300, Dmitry Baryshkov wrote:
> The NXP PTN3222 is the single-port eUSB2 to USB2 redriver that performs
> translation between eUSB2 and USB2 signalling schemes. It supports all
> three data rates: Low Speed, Full Speed and High Speed.
> 
> Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

FWIW:

Reviewed-by: Stephan Gerhold <stephan.gerhold at linaro.org>

> ---
>  .../devicetree/bindings/phy/nxp,ptn3222.yaml       | 55 ++++++++++++++++++++++
>  1 file changed, 55 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/nxp,ptn3222.yaml b/Documentation/devicetree/bindings/phy/nxp,ptn3222.yaml
> new file mode 100644
> index 000000000000..acec5bb2391d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/nxp,ptn3222.yaml
> @@ -0,0 +1,55 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/nxp,ptn3222.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NXP PTN3222 1-port eUSB2 to USB2 redriver
> +
> +maintainers:
> +  - Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - nxp,ptn3222
> +
> +  reg:
> +    maxItems: 1
> +
> +  "#phy-cells":
> +    const: 0
> +
> +  vdd1v8-supply:
> +    description: power supply (1.8V)
> +
> +  vdd3v3-supply:
> +    description: power supply (3.3V)
> +
> +  reset-gpios: true
> +
> +required:
> +  - compatible
> +  - reg
> +  - '#phy-cells'
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        redriver at 4f {
> +            compatible = "nxp,ptn3222";
> +            reg = <0x4f>;
> +            #phy-cells = <0>;
> +            vdd3v3-supply = <&vreg_3p3>;
> +            vdd1v8-supply = <&vreg_1p8>;
> +            reset-gpios = <&gpio_reset GPIO_ACTIVE_LOW>;
> +        };
> +    };
> +...
> 
> -- 
> 2.39.2
> 


From stephan.gerhold at linaro.org  Tue Sep 24 09:43:16 2024
From: stephan.gerhold at linaro.org (Stephan Gerhold)
Date: Tue, 24 Sep 2024 18:43:16 +0200
Subject: [PATCH v2 2/2] phy: add NXP PTN3222 eUSB2 to USB2 redriver
In-Reply-To: <20240830-nxp-ptn3222-v2-2-4c6d8535cf6c@linaro.org>
References: <20240830-nxp-ptn3222-v2-0-4c6d8535cf6c@linaro.org>
 <20240830-nxp-ptn3222-v2-2-4c6d8535cf6c@linaro.org>
Message-ID: <ZvLsJEa2PhIxFRDC@linaro.org>

On Fri, Aug 30, 2024 at 11:20:46AM +0300, Dmitry Baryshkov wrote:
> The NXP PTN3222 is the single-port eUSB2 to USB2 redriver that performs
> translation between eUSB2 and USB2 signalling schemes. It supports all
> three data rates: Low Speed, Full Speed and High Speed.
> 
> The reset state enables autonegotiation of the PHY role and of the data
> rate, so no additional programming is required.
> 
> Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
> Tested-by: Konrad Dybcio <konradybcio at kernel.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

This works well for the USB fingerprint reader on the Qualcomm X1E80100
CRD. Thanks a lot for the clean driver :-)

Reviewed-by: Stephan Gerhold <stephan.gerhold at linaro.org>
Tested-by: Stephan Gerhold <stephan.gerhold at linaro.org>

> ---
>  drivers/phy/Kconfig           |  11 ++++
>  drivers/phy/Makefile          |   1 +
>  drivers/phy/phy-nxp-ptn3222.c | 123 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 135 insertions(+)
> 
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index dfab1c66b3e5..cb06a7f79740 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -82,6 +82,17 @@ config PHY_AIROHA_PCIE
>  	  This driver create the basic PHY instance and provides initialize
>  	  callback for PCIe GEN3 port.
>  
> +config PHY_NXP_PTN3222
> +	tristate "NXP PTN3222 1-port eUSB2 to USB2 redriver"
> +	depends on I2C
> +	depends on OF
> +	select GENERIC_PHY
> +	help
> +	  Enable this to support NXP PTN3222 1-port eUSB2 to USB2 Redriver.
> +	  This redriver performs translation between eUSB2 and USB2 signalling
> +	  schemes. It supports all three USB 2.0 data rates: Low Speed, Full
> +	  Speed and High Speed.
> +
>  source "drivers/phy/allwinner/Kconfig"
>  source "drivers/phy/amlogic/Kconfig"
>  source "drivers/phy/broadcom/Kconfig"
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index 5fcbce5f9ab1..b64247046575 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -11,6 +11,7 @@ obj-$(CONFIG_PHY_XGENE)			+= phy-xgene.o
>  obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.o
>  obj-$(CONFIG_USB_LGM_PHY)		+= phy-lgm-usb.o
>  obj-$(CONFIG_PHY_AIROHA_PCIE)		+= phy-airoha-pcie.o
> +obj-$(CONFIG_PHY_NXP_PTN3222)		+= phy-nxp-ptn3222.o
>  obj-y					+= allwinner/	\
>  					   amlogic/	\
>  					   broadcom/	\
> diff --git a/drivers/phy/phy-nxp-ptn3222.c b/drivers/phy/phy-nxp-ptn3222.c
> new file mode 100644
> index 000000000000..c6179d8701e6
> --- /dev/null
> +++ b/drivers/phy/phy-nxp-ptn3222.c
> @@ -0,0 +1,123 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2024, Linaro Limited
> + */
> +
> +#include <linux/gpio/consumer.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/phy/phy.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
> +
> +#define NUM_SUPPLIES 2
> +
> +struct ptn3222 {
> +	struct i2c_client *client;
> +	struct phy *phy;
> +	struct gpio_desc *reset_gpio;
> +	struct regulator_bulk_data *supplies;
> +};
> +
> +static int ptn3222_init(struct phy *phy)
> +{
> +	struct ptn3222 *ptn3222 = phy_get_drvdata(phy);
> +	int ret;
> +
> +	ret = regulator_bulk_enable(NUM_SUPPLIES, ptn3222->supplies);
> +	if (ret)
> +		return ret;
> +
> +	gpiod_set_value_cansleep(ptn3222->reset_gpio, 0);
> +
> +	return 0;
> +}
> +
> +static int ptn3222_exit(struct phy *phy)
> +{
> +	struct ptn3222 *ptn3222 = phy_get_drvdata(phy);
> +
> +	gpiod_set_value_cansleep(ptn3222->reset_gpio, 1);
> +
> +	return regulator_bulk_disable(NUM_SUPPLIES, ptn3222->supplies);
> +}
> +
> +static const struct phy_ops ptn3222_ops = {
> +	.init		= ptn3222_init,
> +	.exit		= ptn3222_exit,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static const struct regulator_bulk_data ptn3222_supplies[NUM_SUPPLIES] = {
> +	{
> +		.supply = "vdd3v3",
> +		.init_load_uA = 11000,
> +	}, {
> +		.supply = "vdd1v8",
> +		.init_load_uA = 55000,
> +	}
> +};
> +
> +static int ptn3222_probe(struct i2c_client *client)
> +{
> +	struct device *dev = &client->dev;
> +	struct phy_provider *phy_provider;
> +	struct ptn3222 *ptn3222;
> +	int ret;
> +
> +	ptn3222 = devm_kzalloc(dev, sizeof(*ptn3222), GFP_KERNEL);
> +	if (!ptn3222)
> +		return -ENOMEM;
> +
> +	ptn3222->client = client;
> +
> +	ptn3222->reset_gpio = devm_gpiod_get_optional(dev, "reset",
> +						      GPIOD_OUT_HIGH);
> +	if (IS_ERR(ptn3222->reset_gpio))
> +		return dev_err_probe(dev, PTR_ERR(ptn3222->reset_gpio),
> +				     "unable to acquire reset gpio\n");
> +
> +	ret = devm_regulator_bulk_get_const(dev, NUM_SUPPLIES, ptn3222_supplies,
> +					    &ptn3222->supplies);
> +	if (ret)
> +		return ret;
> +
> +	ptn3222->phy = devm_phy_create(dev, dev->of_node, &ptn3222_ops);
> +	if (IS_ERR(ptn3222->phy)) {
> +		dev_err(dev, "failed to create PHY: %d\n", ret);
> +		return PTR_ERR(ptn3222->phy);
> +	}
> +
> +	phy_set_drvdata(ptn3222->phy, ptn3222);
> +
> +	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +
> +	return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct i2c_device_id ptn3222_table[] = {
> +	{ "ptn3222" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(i2c, ptn3222_table);
> +
> +static const struct of_device_id ptn3222_of_table[] = {
> +	{ .compatible = "nxp,ptn3222" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, ptn3222_of_table);
> +
> +static struct i2c_driver ptn3222_driver = {
> +	.driver = {
> +		.name = "ptn3222",
> +		.of_match_table = ptn3222_of_table,
> +	},
> +	.probe = ptn3222_probe,
> +	.id_table = ptn3222_table,
> +};
> +
> +module_i2c_driver(ptn3222_driver);
> +
> +MODULE_DESCRIPTION("NXP PTN3222 eUSB2 Redriver driver");
> +MODULE_LICENSE("GPL");
> 
> -- 
> 2.39.2
> 


From robh at kernel.org  Tue Sep 24 11:01:06 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 24 Sep 2024 13:01:06 -0500
Subject: [PATCH v17 3/8] dt-bindings: display: bridge: Add Cadence
 MHDP8501
In-Reply-To: <b2e1d26f964a03163ec7a1ba6ac8d7c88d6cb111.1727159906.git.Sandor.yu@nxp.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
 <b2e1d26f964a03163ec7a1ba6ac8d7c88d6cb111.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <172720086579.2917.61541648754055069.robh@kernel.org>


On Tue, 24 Sep 2024 15:36:48 +0800, Sandor Yu wrote:
> Add bindings for Cadence MHDP8501 DisplayPort/HDMI bridge.
> 
> Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
> v16->v17:
> - Add lane-mapping property
> 
> v9->v16:
>  *No change
> 
> .../display/bridge/cdns,mhdp8501.yaml         | 109 ++++++++++++++++++
>  1 file changed, 109 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml: lane-mapping: missing type definition

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/b2e1d26f964a03163ec7a1ba6ac8d7c88d6cb111.1727159906.git.Sandor.yu at nxp.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From krzk at kernel.org  Tue Sep 24 11:39:20 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 24 Sep 2024 20:39:20 +0200
Subject: [PATCH v4 2/6] dt-bindings: PCI: qcom: Move OPP table to
 qcom,pcie-common.yaml
In-Reply-To: <20240924101444.3933828-3-quic_qianyu@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-3-quic_qianyu@quicinc.com>
Message-ID: <50e0e837-1c70-4d6d-bb55-a68dec3dcd3b@kernel.org>

On 24/09/2024 12:14, Qiang Yu wrote:
> OPP table is a generic property that is also required by other qcom
> platforms. Hence move this property to qcom,pcie-common.yaml so that PCIe
> on other qcom platforms is able to adjust power domain performance state
> and ICC peak bw according to PCIe gen speed and link width.
> 
> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> ---

Reviewed-by: Krzysztof Kozlowski <krzk at kernel.org>

Best regards,
Krzysztof



From konstantin at linuxfoundation.org  Tue Sep 24 13:25:45 2024
From: konstantin at linuxfoundation.org (Konstantin Ryabitsev)
Date: Tue, 24 Sep 2024 16:25:45 -0400
Subject: Bouncing maintainer: Shengyang Chen
Message-ID: <20240924-radical-chirpy-hawk-3aa339@lemur>

Hello:

I'm reaching out to co-maintainers of the following subsystems:

  - STARFIVE JH7110 DPHY TX DRIVER

The email address for one of your maintainers is bouncing:

  M: Shengyang Chen <shengyang.chen at starfivetech.com>

There are several possible courses of action:

1. If you know the new email address for the maintainer, please ask them to
   submit a patch for MAINTAINERS and .mailmap files.

2. If this maintainer stepped away from their duties, or if co-maintainers are
   equally unable to reach them via any other means, please submit a patch to
   MAINTAINERS to remove their M: entry.

The goal is to have no bouncing M: entries in the maintainers file, so please
follow up as soon as you have decided on the correct course of action.

Best regards,
--
Konstantin Ryabitsev
Linux Foundation

bugspray track


From bugbot at kernel.org  Tue Sep 24 13:30:22 2024
From: bugbot at kernel.org (Bugspray Bot)
Date: Tue, 24 Sep 2024 20:30:22 +0000 (UTC)
Subject: Bouncing maintainer: Shengyang Chen
In-Reply-To: <20240924-radical-chirpy-hawk-3aa339@lemur>
References: <20240924-radical-chirpy-hawk-3aa339@lemur>
Message-ID: <20240924-b219314-c5fabf12d6c0@bugzilla.kernel.org>

Hello:

This conversation is now tracked by Kernel.org Bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=219314

There is no need to do anything else, just keep talking.
-- 
Deet-doot-dot, I am a bot.
Kernel.org Bugzilla (bugspray 0.1-dev)



From frawang.cn at gmail.com  Tue Sep 24 18:42:35 2024
From: frawang.cn at gmail.com (frawang)
Date: Wed, 25 Sep 2024 09:42:35 +0800
Subject: [PATCH v2 2/2] phy: rockchip: inno-usb2: Add usb2 phys support
 for rk3576
In-Reply-To: <15288441.JCcGWNJJiE@phil>
References: <20240924085510.20863-1-frawang.cn@gmail.com>
 <20240924085510.20863-2-frawang.cn@gmail.com> <15288441.JCcGWNJJiE@phil>
Message-ID: <29d80d30-dcbf-4fe1-b7aa-3f8c46fee714@gmail.com>

Hi Heiko,

On 2024/9/24 18:01, Heiko Stuebner wrote:
> Am Dienstag, 24. September 2024, 10:55:10 CEST schrieb Frank Wang:
>> From: William Wu <william.wu at rock-chips.com>
>>
>> The RK3576 SoC has two independent USB2.0 PHYs, and
>> each PHY has one port.
> Can you please split the content into "converting to clk_bulk" (see
> additional comment below) and "add rk3576" please?
>
> That would make the patch a lot cleaner.

OK, I shall amend in the next patch.

>
>> @@ -376,6 +378,7 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
>>   {
>>   	struct device_node *node = rphy->dev->of_node;
>>   	struct clk_init_data init;
>> +	struct clk *refclk = of_clk_get_by_name(node, "phyclk");
> Doesn't this create an imbalance - with the missing put?
> I think ideally just define clk_bulk_data structs for the
> 1-clock and 3-clock variant, attach that to the device-data
> and then use the regular devm_clk_bulk_get ?
>
> That way you can then retrieve the clock from that struct?

How about keep the clk_bulk_data and num_clks member in rockchip_usb2phy 
structs, and retrieve the clock by "clks.id" here?
Just like the following codes.

@@ -378,8 +378,9 @@ rockchip_usb2phy_clk480m_register(struct 
rockchip_usb2phy *rphy)
 ?{
 ??????? struct device_node *node = rphy->dev->of_node;
 ??????? struct clk_init_data init;
-?????? struct clk *refclk = of_clk_get_by_name(node, "phyclk");
+?????? struct clk *refclk = NULL;
 ??????? const char *clk_name;
+?????? int i;
 ??????? int ret = 0;

 ??????? init.flags = 0;
@@ -389,6 +390,13 @@ rockchip_usb2phy_clk480m_register(struct 
rockchip_usb2phy *rphy)
 ??????? /* optional override of the clockname */
 ??????? of_property_read_string(node, "clock-output-names", &init.name);

+?????? for (i = 0; i < rphy->num_clks; i++) {
+?????????????? if (!strncmp(rphy->clks[i].id, "phyclk", 6)) {
+?????????????????????? refclk = rphy->clks[i].clk;
+?????????????????????? break;
+?????????????? }
+?????? }
+

BR.
Frank

>
> Thanks
> Heiko
>


From frawang.cn at gmail.com  Tue Sep 24 18:49:43 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Wed, 25 Sep 2024 09:49:43 +0800
Subject: [PATCH v2 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <11146778.5MRjnR8RnV@phil>
References: <20240924085510.20863-1-frawang.cn@gmail.com>
 <11146778.5MRjnR8RnV@phil>
Message-ID: <285d7b52-956a-412d-ba85-7641e95226e5@gmail.com>

Hi Heiko,

On 2024/9/24 18:01, Heiko Stuebner wrote:
> Hi Frank,
>
> Am Dienstag, 24. September 2024, 10:55:09 CEST schrieb Frank Wang:
>> From: Frank Wang <frank.wang at rock-chips.com>
>>
>> Add compatible for the USB2 phy in the Rockchip RK3576 SoC.
> can you please add some details to the commit message, about those
> new clocks. I.e. what they do.

OK, I shall add in the next version.

BR.
Frank

> Thanks
> Heiko
>
>> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
>> ---
>> Changelog:
>> v2:
>>   - Categorize clock names by oneOf keyword.
>>
>> v1:
>>   - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-1-frank.wang at rock-chips.com/
>>
>>   .../bindings/phy/rockchip,inno-usb2phy.yaml      | 16 ++++++++++++++--
>>   1 file changed, 14 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>> index 5254413137c64..8af4e0f8637fc 100644
>> --- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>> +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>> @@ -20,6 +20,7 @@ properties:
>>         - rockchip,rk3366-usb2phy
>>         - rockchip,rk3399-usb2phy
>>         - rockchip,rk3568-usb2phy
>> +      - rockchip,rk3576-usb2phy
>>         - rockchip,rk3588-usb2phy
>>         - rockchip,rv1108-usb2phy
>>   
>> @@ -34,10 +35,20 @@ properties:
>>       const: 0
>>   
>>     clocks:
>> -    maxItems: 1
>> +    minItems: 1
>> +    maxItems: 3
>>   
>>     clock-names:
>> -    const: phyclk
>> +    minItems: 1
>> +    maxItems: 3
>> +    items:
>> +      oneOf:
>> +        - description: aclk for USB MMU.
>> +          const: aclk
>> +        - description: aclk_slv for USB MMU.
>> +          const: aclk_slv
>> +        - description: PHY input reference clocks.
>> +          const: phyclk
>>   
>>     assigned-clocks:
>>       description:
>> @@ -143,6 +154,7 @@ allOf:
>>             contains:
>>               enum:
>>                 - rockchip,rk3568-usb2phy
>> +              - rockchip,rk3576-usb2phy
>>                 - rockchip,rk3588-usb2phy
>>   
>>       then:
>>



From robh at kernel.org  Tue Sep 24 18:56:52 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 24 Sep 2024 20:56:52 -0500
Subject: [PATCH v17 0/8] Initial support Cadence MHDP8501(HDMI/DP) for
 i.MX8MQ
In-Reply-To: <cover.1727159906.git.Sandor.yu@nxp.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
Message-ID: <172722910962.836192.13554411095046576310.robh@kernel.org>


On Tue, 24 Sep 2024 15:36:45 +0800, Sandor Yu wrote:
> The patch set initial support Cadence MHDP8501(HDMI/DP) DRM bridge
> driver and Cadence HDP-TX PHY(HDMI/DP) driver for Freescale i.MX8MQ.
> 
> The patch set compose of DRM bridge drivers and PHY driver.
> 
> Both of them need by patch #1 and #2 to pass build.
> 
> DRM bridges driver patches:
>   #1: drm: bridge: Cadence: Creat mhdp helper driver
>   #2: phy: Add HDMI configuration options
>   #3: dt-bindings: display: bridge: Add Cadence MHDP8501
>   #4: drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
> 
> PHY driver patches:
>   #1: drm: bridge: Cadence: Creat mhdp helper driver
>   #2: phy: Add HDMI configuration options
>   #5: dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
>   #6: phy: freescale: Add DisplayPort/HDMI Combo-PHY driver for i.MX8MQ
> 
> i.MX8M/TQMa8Mx DT patches:
>   #7: Add DT nodes for DCSS/HDMI pipeline
>   #8: Enable HDMI for TQMa8Mx/MBa8Mx
> 
> v16->v17:
> Patch #1:
> - Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex
> Patch #2:
> - remove hdmi.h
> - add 2024 year to copyright
> - Add r-b tag.
> Patch #3:
> - Add lane-mapping property.
> Patch #4:
> - Reset the HDMI/DP link when an HPD (Hot Plug Detect) event is detected
> - Move the HDMI protocol settings from hdmi_ctrl_init() to a new function
>   cdns_hdmi_set_hdmi_mode_type(), to align with the introduced link reset functionality.
> - Implement logic to check the type of HDMI sink.
>   If the sink is not a hdmi display, set the default mode to DVI.
> - Implement hdmi_reset_infoframe function
> - Reorder certain bit definitions in the header file to follow a descending order.
> - Add "lane-mapping" property for both HDMI and DP, remove platform data from driver.
>   lane-mapping should be setting in dts according different board layout.
> - Remove variable mode in struct cdns_mhdp8501_device, video mode could get from struct drm_crtc_state
> - Remove variable char_rate in  struct cdns_mhdp8501_device, it could get from struct struct drm_connector_state.hdmi
> - Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex
> - Remove mutext protect for phy_api access functions.
> Patch #6:
> - Remove mbox_mutex
> 
> v15->v16:
> Patch #2:
> - Remove pixel_clk_rate, bpc and color_space fields from struct
>   phy_configure_opts_hdmi, they were replaced by
>   unsigned long long tmds_char_rate.
> - Remove r-b and a-c tags because this patch have important change.
> Patch #4:
> - Add DRM_BRIDGE_OP_HDMI flags for HDMI driver,
> - Introduce the hdmi info frame helper functions,
>   added hdmi_clear_infoframe(), hdmi_write_infoframe() and
>   hdmi_tmds_char_rate_valid() according Dmitry's patch
>   'make use of the HDMI connector infrastructure' patchset ([2]).
> - mode_fixup() is replaced by atomic_check().
> - Fix video mode 4Kp30 did not work on some displays that support
>   LTE_340Mcsc_scramble.
> - updated for tmds_char_rate added in patch #2.
> Patch #6:
> - updated for tmds_char_rate added in patch #2.
> 
> v14->v15:
> Patch #6 + #7:
> -  Merged PHY driver into a single combo PHY driver
> Patch #7 + #8:
> - Add DT patches for a running HDMI setup
> 
> v13->v14:
> Patch #4:
> - Rebase to next-20240219, replace get_edid function by edid_read
>   function as commits d807ad80d811b ("drm/bridge: add ->edid_read
>   hook and drm_bridge_edid_read()") and 27b8f91c08d99 ("drm/bridge:
>   remove ->get_edid callback") had change the API.
> 
> v12->v13:
> Patch #4:
> - Explicitly include linux/platform_device.h for cdns-mhdp8501-core.c
> - Fix build warning
> - Order bit bpc and color_space in descending shit.
> Patch #7:
> - Fix build warning
> 
> v11->v12:
> Patch #1:
> - Move status initialize out of mbox_mutex.
> - Reorder API functions in alphabetical.
> - Add notes for malibox access functions.
> - Add year 2024 to copyright.
> Patch #4:
> - Replace DRM_INFO with dev_info or dev_warn.
> - Replace DRM_ERROR with dev_err.
> - Return ret when cdns_mhdp_dpcd_read failed in function cdns_dp_aux_transferi().
> - Remove unused parmeter in function cdns_dp_get_msa_misc
>   and use two separate variables for color space and bpc.
> - Add year 2024 to copyright.
> Patch #6:
> - Return error code to replace -1 for function wait_for_ack().
> - Set cdns_phy->power_up = false in phy_power_down function.
> - Remove "RATE_8_1 = 810000", it is not used in driver.
> - Add year 2024 to copyright.
> Patch #7:
> - Adjust clk disable order.
> - Return error code to replace -1 for function wait_for_ack().
> - Use bool for variable pclk_in.
> - Add year 2024 to copyright.
> 
> v10->v11:
> - rewrite cdns_mhdp_set_firmware_active() in mhdp8546 core driver,
> use cdns_mhdp_mailbox_send() to replace cdns_mhdp_mailbox_write()
> same as the other mailbox access functions.
> - use static for cdns_mhdp_mailbox_write() and cdns_mhdp_mailbox_read()
> and remove them from EXPORT_SYMBOL_GPL().
> - remove MODULE_ALIAS() from mhdp8501 driver.
> 
> v9->v10:
> - Create mhdp helper driver to replace macro functions,
> move all mhdp mailbox access functions and common functions
> into the helper driver.
> Patch #1:drm: bridge: Cadence: Creat mhdp helper driver
> it is totaly different with v9.
> 
> v8->v9:
> - Remove compatible string "cdns,mhdp8501" that had removed
>   from dt-bindings file in v8.
> - Add Dmitry's R-b tag to patch #2
> - Add Krzysztof's R-b tag to patch #3
> 
> v7->v8:
> MHDP8501 HDMI/DP:
> - Correct DT node name to "display-bridge".
> - Remove "cdns,mhdp8501" from mhdp8501 dt-binding doc.
> 
> HDMI/DP PHY:
> - Introduced functions `wait_for_ack` and `wait_for_ack_clear` to handle
>   waiting with acknowledgment bits set and cleared respectively.
> - Use FIELD_PRE() to set bitfields for both HDMI and DP PHY.
> 
> v6->v7:
> MHDP8501 HDMI/DP:
> - Combine HDMI and DP driver into one mhdp8501 driver.
>   Use the connector type to load the corresponding functions.
> - Remove connector init functions.
> - Add <linux/hdmi.h> in phy_hdmi.h to reuse 'enum hdmi_colorspace'.
> 
> HDMI/DP PHY:
> - Lowercase hex values
> - Fix parameters indent issue on some functions
> - Replace 'udelay' with 'usleep_range'
> 
> v5->v6:
> HDMI/DP bridge driver
> - 8501 is the part number of Cadence MHDP on i.MX8MQ.
>   Use MHDP8501 to name hdmi/dp drivers and files.
> - Add compatible "fsl,imx8mq-mhdp8501-dp" for i.MX8MQ DP driver
> - Add compatible "fsl,imx8mq-mhdp8501-hdmi" for i.MX8MQ HDMI driver
> - Combine HDMI and DP dt-bindings into one file cdns,mhdp8501.yaml
> - Fix HDMI scrambling is not enable issue when driver working in 4Kp60
>   mode.
> - Add HDMI/DP PHY API mailbox protect.
> 
> HDMI/DP PHY driver:
> - Rename DP and HDMI PHY files and move to folder phy/freescale/
> - Remove properties num_lanes and link_rate from DP PHY driver.
> - Combine HDMI and DP dt-bindings into one file fsl,imx8mq-dp-hdmi-phy.yaml
> - Update compatible string to "fsl,imx8mq-dp-phy".
> - Update compatible string to "fsl,imx8mq-hdmi-phy".
> 
> v4->v5:
> - Drop "clk" suffix in clock name.
> - Add output port property in the example of hdmi/dp.
> 
> v3->v4:
> dt-bindings:
> - Correct dt-bindings coding style and address review comments.
> - Add apb_clk description.
> - Add output port for HDMI/DP connector
> PHY:
> - Alphabetically sorted in Kconfig and Makefile for DP and HDMI PHY
> - Remove unused registers define from HDMI and DP PHY drivers.
> - More description in phy_hdmi.h.
> - Add apb_clk to HDMI and DP phy driver.
> HDMI/DP:
> - Use get_unaligned_le32() to replace hardcode type conversion
>   in HDMI AVI infoframe data fill function.
> - Add mailbox mutex lock in HDMI/DP driver for phy functions
>   to reslove race conditions between HDMI/DP and PHY drivers.
> - Add apb_clk to both HDMI and DP driver.
> - Rename some function names and add prefix with "cdns_hdmi/cdns_dp".
> - Remove bpc 12 and 16 optional that not supported.
> 
> v2->v3:
> Address comments for dt-bindings files.
> - Correct dts-bindings file names
>   Rename phy-cadence-hdptx-dp.yaml to cdns,mhdp-imx8mq-dp.yaml
>   Rename phy-cadence-hdptx-hdmi.yaml to cdns,mhdp-imx8mq-hdmi.yaml
> - Drop redundant words and descriptions.
> - Correct hdmi/dp node name.
> 
> v2 is a completely different version compared to v1.
> Previous v1 can be available here [1].
> 
> v1->v2:
> - Reuse Cadence mailbox access functions from mhdp8546 instead of
>   rockchip DP.
> - Mailbox access functions be convert to marco functions
>   that will be referenced by HDP-TX PHY(HDMI/DP) driver too.
> - Plain bridge instead of component driver.
> - Standalone Cadence HDP-TX PHY(HDMI/DP) driver.
> - Audio driver are removed from the patch set, it will be add in another
>   patch set later.
> 
> [1] https://patchwork.kernel.org/project/linux-rockchip/cover/cover.1590982881.git.Sandor.yu at nxp.com/
> 
> Alexander Stein (2):
>   arm64: dts: imx8mq: Add DCSS + HDMI/DP display pipeline
>   arm64: dts: imx8mq: tqma8mq-mba8mx: Enable HDMI support
> 
> Sandor Yu (6):
>   drm: bridge: Cadence: Create mhdp helper driver
>   phy: Add HDMI configuration options
>   dt-bindings: display: bridge: Add Cadence MHDP8501
>   drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
>   dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
>   phy: freescale: Add DisplayPort/HDMI Combo-PHY driver for i.MX8MQ
> 
>  .../display/bridge/cdns,mhdp8501.yaml         |  109 ++
>  .../bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml  |   51 +
>  .../dts/freescale/imx8mq-tqma8mq-mba8mx.dts   |   20 +
>  arch/arm64/boot/dts/freescale/imx8mq.dtsi     |   68 +
>  arch/arm64/boot/dts/freescale/mba8mx.dtsi     |   11 +
>  drivers/gpu/drm/bridge/cadence/Kconfig        |   20 +
>  drivers/gpu/drm/bridge/cadence/Makefile       |    3 +
>  .../gpu/drm/bridge/cadence/cdns-mhdp-helper.c |  307 ++++
>  .../drm/bridge/cadence/cdns-mhdp8501-core.c   |  323 ++++
>  .../drm/bridge/cadence/cdns-mhdp8501-core.h   |  359 +++++
>  .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c |  737 +++++++++
>  .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   |  692 +++++++++
>  .../drm/bridge/cadence/cdns-mhdp8546-core.c   |  425 +-----
>  .../drm/bridge/cadence/cdns-mhdp8546-core.h   |   47 +-
>  .../drm/bridge/cadence/cdns-mhdp8546-hdcp.c   |   36 +-
>  drivers/phy/freescale/Kconfig                 |   10 +
>  drivers/phy/freescale/Makefile                |    1 +
>  drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c  | 1337 +++++++++++++++++
>  include/drm/bridge/cdns-mhdp-helper.h         |   94 ++
>  include/linux/phy/phy-hdmi.h                  |   19 +
>  include/linux/phy/phy.h                       |    7 +-
>  21 files changed, 4268 insertions(+), 408 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
>  create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
>  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
>  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
>  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
>  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
>  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
>  create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c
>  create mode 100644 include/drm/bridge/cdns-mhdp-helper.h
>  create mode 100644 include/linux/phy/phy-hdmi.h
> 
> --
> 2.34.1
> 
> 
> 


My bot found new DTB warnings on the .dts files added or changed in this
series.

Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.

If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:

  pip3 install dtschema --upgrade


New warnings running 'make CHECK_DTBS=y freescale/imx8mq-tqma8mq-mba8mx.dtb' for cover.1727159906.git.Sandor.yu at nxp.com:

arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb: bridge at 32c00000: 'lane-mapping' is a required property
	from schema $id: http://devicetree.org/schemas/display/bridge/cdns,mhdp8501.yaml#







From frawang.cn at gmail.com  Tue Sep 24 19:09:21 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Wed, 25 Sep 2024 10:09:21 +0800
Subject: [PATCH v2 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <20240924-overtly-curable-13df2e7fdc9b@spud>
References: <20240924085510.20863-1-frawang.cn@gmail.com>
 <20240924-overtly-curable-13df2e7fdc9b@spud>
Message-ID: <87146372-6d05-4994-8f64-47f4cb07e2b4@gmail.com>

Hi Conor,

On 2024/9/25 0:11, Conor Dooley wrote:
> On Tue, Sep 24, 2024 at 04:55:09PM +0800, Frank Wang wrote:
>> From: Frank Wang <frank.wang at rock-chips.com>
>>
>> Add compatible for the USB2 phy in the Rockchip RK3576 SoC.
>>
>> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
>> ---
>> Changelog:
>> v2:
>>   - Categorize clock names by oneOf keyword.
>>
>> v1:
>>   - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-1-frank.wang at rock-chips.com/
>>
>>   .../bindings/phy/rockchip,inno-usb2phy.yaml      | 16 ++++++++++++++--
>>   1 file changed, 14 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>> index 5254413137c64..8af4e0f8637fc 100644
>> --- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>> +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>> @@ -20,6 +20,7 @@ properties:
>>         - rockchip,rk3366-usb2phy
>>         - rockchip,rk3399-usb2phy
>>         - rockchip,rk3568-usb2phy
>> +      - rockchip,rk3576-usb2phy
>>         - rockchip,rk3588-usb2phy
>>         - rockchip,rv1108-usb2phy
>>   
>> @@ -34,10 +35,20 @@ properties:
>>       const: 0
>>   
>>     clocks:
>> -    maxItems: 1
>> +    minItems: 1
>> +    maxItems: 3
>>   
>>     clock-names:
>> -    const: phyclk
>> +    minItems: 1
>> +    maxItems: 3
> clock-names isn't a required property, you can't allow jumbling the order
> like this does without breaking the ABI. Why can't the new device have
> phyclk in position 1?

I sent a draft changes in patch v1 comments which put the "phyclk" in 
position 1, Krzysztof said I have messed the order, so I reorder them in v2.
Did I misunderstand? anyway, should the changes like the below?

@@ -34,10 +35,20 @@ properties:
 ????? const: 0

 ??? clocks:
-??? maxItems: 1
+??? minItems: 1
+??? maxItems: 3

 ??? clock-names:
-??? const: phyclk
+??? minItems: 1
+??? maxItems: 3
+??? items:
+????? oneOf:
+??????? - description: PHY input reference clocks.
+????????? const: phyclk
+??????? - description: aclk for USB MMU.
+????????? const: aclk
+??????? - description: aclk_slv for USB MMU.
+????????? const: aclk_slv


BR.
Frank

>> +    items:
>> +      oneOf:
>> +        - description: aclk for USB MMU.
>> +          const: aclk
>> +        - description: aclk_slv for USB MMU.
>> +          const: aclk_slv
>> +        - description: PHY input reference clocks.
>> +          const: phyclk
>>   
>>     assigned-clocks:
>>       description:
>> @@ -143,6 +154,7 @@ allOf:
>>             contains:
>>               enum:
>>                 - rockchip,rk3568-usb2phy
>> +              - rockchip,rk3576-usb2phy
>>                 - rockchip,rk3588-usb2phy
>>   
>>       then:
>> -- 
>> 2.45.2
>>



From quic_jingyw at quicinc.com  Tue Sep 24 20:16:28 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 25 Sep 2024 11:16:28 +0800
Subject: [PATCH v2] dt-bindings: phy: Add QMP UFS PHY comptible for
 QCS8300
In-Reply-To: <ztpetznwid2om6vylyl2boi665ch3wnkprkmzcq6bem6cqhqtf@ogsi657y4kex>
References: <20240911-qcs8300_ufs_phy_binding-v2-1-c801a2d27a84@quicinc.com>
 <ztpetznwid2om6vylyl2boi665ch3wnkprkmzcq6bem6cqhqtf@ogsi657y4kex>
Message-ID: <6656171b-12d3-490b-b53c-f907b7454f99@quicinc.com>



On 9/16/2024 10:53 PM, Krzysztof Kozlowski wrote:
> On Wed, Sep 11, 2024 at 02:56:16PM +0800, Jingyi Wang wrote:
>> From: Xin Liu <quic_liuxin at quicinc.com>
>>
>> Document the QMP UFS PHY compatible for Qualcomm QCS8300 to support
>> physical layer functionality for UFS found on the SoC. Use fallback to
>> indicate the compatibility of the QMP UFS PHY on the QCS8300 with that
>> on the SA8775P.
>>
>> Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
>> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
>> ---
>> Changes in v2:
>> - decoupled from the original series.
>> - Use fallback to indicate compatibility with SA8775P.
>> - typo fixup
>> - Link to v1: https://lore.kernel.org/r/20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007 at quicinc.com
>> ---
>>  .../bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml    | 46 ++++++++++++----------
>>  1 file changed, 26 insertions(+), 20 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
>> index f9cfbd0b2de6..626a2039e177 100644
>> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
>> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
>> @@ -15,26 +15,31 @@ description:
>>  
>>  properties:
>>    compatible:
>> -    enum:
>> -      - qcom,msm8996-qmp-ufs-phy
>> -      - qcom,msm8998-qmp-ufs-phy
>> -      - qcom,sa8775p-qmp-ufs-phy
>> -      - qcom,sc7180-qmp-ufs-phy
>> -      - qcom,sc7280-qmp-ufs-phy
>> -      - qcom,sc8180x-qmp-ufs-phy
>> -      - qcom,sc8280xp-qmp-ufs-phy
>> -      - qcom,sdm845-qmp-ufs-phy
>> -      - qcom,sm6115-qmp-ufs-phy
>> -      - qcom,sm6125-qmp-ufs-phy
>> -      - qcom,sm6350-qmp-ufs-phy
>> -      - qcom,sm7150-qmp-ufs-phy
>> -      - qcom,sm8150-qmp-ufs-phy
>> -      - qcom,sm8250-qmp-ufs-phy
>> -      - qcom,sm8350-qmp-ufs-phy
>> -      - qcom,sm8450-qmp-ufs-phy
>> -      - qcom,sm8475-qmp-ufs-phy
>> -      - qcom,sm8550-qmp-ufs-phy
>> -      - qcom,sm8650-qmp-ufs-phy
>> +    oneOf:
>> +      - items:
>> +          - enum:
>> +              - qcom,qcs8300-qmp-ufs-phy
>> +          - const: qcom,sa8775p-qmp-ufs-phy
>> +      - enum:
>> +          - qcom,msm8996-qmp-ufs-phy
>> +          - qcom,msm8998-qmp-ufs-phy
>> +          - qcom,sa8775p-qmp-ufs-phy
>> +          - qcom,sc7180-qmp-ufs-phy
>> +          - qcom,sc7280-qmp-ufs-phy
>> +          - qcom,sc8180x-qmp-ufs-phy
>> +          - qcom,sc8280xp-qmp-ufs-phy
>> +          - qcom,sdm845-qmp-ufs-phy
>> +          - qcom,sm6115-qmp-ufs-phy
>> +          - qcom,sm6125-qmp-ufs-phy
>> +          - qcom,sm6350-qmp-ufs-phy
>> +          - qcom,sm7150-qmp-ufs-phy
>> +          - qcom,sm8150-qmp-ufs-phy
>> +          - qcom,sm8250-qmp-ufs-phy
>> +          - qcom,sm8350-qmp-ufs-phy
>> +          - qcom,sm8450-qmp-ufs-phy
>> +          - qcom,sm8475-qmp-ufs-phy
>> +          - qcom,sm8550-qmp-ufs-phy
>> +          - qcom,sm8650-qmp-ufs-phy
>>  
>>    reg:
>>      maxItems: 1
>> @@ -85,6 +90,7 @@ allOf:
>>            contains:
>>              enum:
>>                - qcom,msm8998-qmp-ufs-phy
>> +              - qcom,qcs8300-qmp-ufs-phy
> 
> Not needed.
> 
Well noted.
> BTW, please be sure you organize your patchsets per subsystem. IOW, that
> you do not split same subsystem bindings patches into separate
> patchsets.
> 
Do you mean combine the binding of qmp-ufs-phy with ufs controller? I noticed
that this patch belongs to "GENERIC PHY FRAMEWORK" subsystem and ufs controller
binding belongs to "UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER". If necessary,
we can pay attention to combine them next time
> Best regards,
> Krzysztof
> 
Thanks,
Jingyi



From quic_qianyu at quicinc.com  Tue Sep 24 20:38:46 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Wed, 25 Sep 2024 11:38:46 +0800
Subject: [PATCH v4 3/6] phy: qcom: qmp: Add phy register and clk setting
 for x1e80100 PCIe3
In-Reply-To: <ZvLXjdpBpUS3lLn-@hovoldconsulting.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-4-quic_qianyu@quicinc.com>
 <ZvLXjdpBpUS3lLn-@hovoldconsulting.com>
Message-ID: <3d4a8243-5c2f-41c4-85ce-6e072331f4f3@quicinc.com>


On 9/24/2024 11:15 PM, Johan Hovold wrote:
> On Tue, Sep 24, 2024 at 03:14:41AM -0700, Qiang Yu wrote:
>> Currently driver supports only x4 lane based functionality using tx/rx and
>> tx2/rx2 pair of register sets. To support 8 lane functionality with PCIe3,
>> PCIe3 related QMP PHY provides additional programming which are available
>> as txz and rxz based register set. Hence adds txz and rxz based registers
>> usage and programming sequences.
>> Phy register setting for txz and rxz will
>> be applied to all 8 lanes. Some lanes may have different settings on
>> several registers than txz/rxz, these registers should be programmed after
>> txz/rxz programming sequences completing.
> Please expand and clarify what you mean by this.
PCIe3 supports 8 lanes, so in general, we have to program 8 pairs tx/rx
registers. However, most of tx/rx registers of different lanes have
same settings, so the configuration for all 8 lanes tx/rx registers is
a little repetitive.

Hence, txz/rxz registers are included. The values programmed into txz/rxz
registers by software will be "broadcasted" to all 8 lanes by hardware.
Some lanes may have different settings on several registers than txz/rxz.
In order to ensure the different values take effect, they need to be
programmed after txz/rxz programming sequences completing.
>   
>> Besides, x1e80100 SoC uses QMP phy with version v6.30 for PCIe Gen4 x8.
>> Add the new register offsets in a dedicated header file.
>>
>> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
>> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>> Reviewed-by: Konrad Dybcio <konradybcio at kernel.org>
>> ---
>>   drivers/phy/qualcomm/phy-qcom-qmp-pcie.c      | 211 ++++++++++++++++++
>>   .../qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h    |  25 +++
>>   drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h |  19 ++
>>   3 files changed, 255 insertions(+)
>>   create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
>>   create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
>> index f71787fb4d7e..d7bbd9df11d7 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
>> @@ -1344,6 +1346,155 @@ static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
>>   	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_FOM_EQ_CONFIG5, 0x8a),
>>   };
>>   
>> +static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_txz_tbl[] = {
> Please try to follow the sort order used for the other platforms for
> these tables (e.g.  serdes, tx, rx, pcr, pcr_misc).
OK, will follow this order.
>
>> +static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl[] = {
>> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1),
>> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_OSC_DTCT_ACTIONS, 0x00),
>> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_EQ_CONFIG1, 0x16),
>> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_EQ_CONFIG5, 0x02),
>> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_PRE_GAIN, 0x2e),
>> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG1, 0x03),
>> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG3, 0x28),
>> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG5, 0x18),
>> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G3_FOM_EQ_CONFIG5, 0x7a),
>> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_FOM_EQ_CONFIG5, 0x8a),
>> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G3_RXEQEVAL_TIME, 0x27),
>> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_RXEQEVAL_TIME, 0x27),
>> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_TX_RX_CONFIG, 0xc0),
>> +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_POWER_STATE_CONFIG2, 0x1d),
>> +
> Stray newline.
>
>> +};
>> +
>> +static const struct qmp_phy_cfg x1e80100_qmp_gen4x8_pciephy_cfg = {
>> +	.lanes = 8,
>> +
>> +	.offsets		= &qmp_pcie_offsets_v6_30,
>> +	.tbls = {
>> +		.serdes			= x1e80100_qmp_gen4x8_pcie_serdes_tbl,
>> +		.serdes_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_serdes_tbl),
>> +		.rx			= x1e80100_qmp_gen4x8_pcie_rx_tbl,
>> +		.rx_num			= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_rx_tbl),
>> +		.pcs			= x1e80100_qmp_gen4x8_pcie_pcs_tbl,
>> +		.pcs_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_pcs_tbl),
>> +		.pcs_misc		= x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl,
>> +		.pcs_misc_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl),
>> +		.ln_shrd		= x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl,
>> +		.ln_shrd_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl),
>> +		.txz			= x1e80100_qmp_gen4x8_pcie_txz_tbl,
>> +		.txz_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_txz_tbl),
>> +		.rxz			= x1e80100_qmp_gen4x8_pcie_rxz_tbl,
>> +		.rxz_num		= ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_rxz_tbl),
> Try follow the order of the other SoCs here as well (e.g. use the order
> defined in struct qmp_phy_cfg_tbls).

Will follow the order defined in struct qmp_phy_cfg_tbls.

>
>> +	},
>>   static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
>>   {
>>   	const struct qmp_phy_cfg *cfg = qmp->cfg;
>> @@ -3751,6 +3953,9 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
>>   
>>   	qmp_configure(qmp->dev, serdes, tbls->serdes, tbls->serdes_num);
> If your comment in the commit message implies that txz/rxz must be
> programmed before tx/rx then you need to add a comment here as well.

Will add a comment here.

Thanks,
Qiang Yu
>
>> +	qmp_configure(qmp->dev, qmp->txz, tbls->txz, tbls->txz_num);
>> +	qmp_configure(qmp->dev, qmp->rxz, tbls->rxz, tbls->rxz_num);
>> +
>>   	qmp_configure_lane(qmp->dev, tx, tbls->tx, tbls->tx_num, 1);
>>   	qmp_configure_lane(qmp->dev, rx, tbls->rx, tbls->rx_num, 1);
> Johan


From quic_qianyu at quicinc.com  Tue Sep 24 20:40:26 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Wed, 25 Sep 2024 11:40:26 +0800
Subject: [PATCH v4 4/6] clk: qcom: gcc-x1e80100: Fix halt_check for
 pipediv2 clocks
In-Reply-To: <ZvLNNDCOy68nK2B5@hovoldconsulting.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-5-quic_qianyu@quicinc.com>
 <ZvLNNDCOy68nK2B5@hovoldconsulting.com>
Message-ID: <dd16ff25-8f05-4137-9726-7f63ab82f30a@quicinc.com>


On 9/24/2024 10:31 PM, Johan Hovold wrote:
> On Tue, Sep 24, 2024 at 03:14:42AM -0700, Qiang Yu wrote:
>> The pipediv2_clk's source from the same mux as pipe clock. So they have
>> same limitation, which is that the PHY sequence requires to enable these
>> local CBCs before the PHY is actually outputting a clock to them. This
>> means the clock won't actually turn on when we vote them. Hence, let's
>> skip the halt bit check of the pipediv2_clk, otherwise pipediv2_clk may
>> stuck at off state during bootup.
>>
>> Suggested-by: Mike Tipton <quic_mdtipton at quicinc.com>
>> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
>> Reviewed-by: Konrad Dybcio <konradybcio at kernel.org>
> Looks like this one is missing a Fixes and CC stable tag. With that
> added:

Will add Fixes and CC stable tag.

Thanks,
Qiang Yu
> Reviewed-by: Johan Hovold <johan+linaro at kernel.org>
>
> Johan


From quic_qianyu at quicinc.com  Tue Sep 24 20:44:51 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Wed, 25 Sep 2024 11:44:51 +0800
Subject: [PATCH v4 5/6] PCI: qcom: Add support for X1E80100 SoC
In-Reply-To: <20240924135021.ybpyoahlpuvedma5@thinkpad>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-6-quic_qianyu@quicinc.com>
 <20240924135021.ybpyoahlpuvedma5@thinkpad>
Message-ID: <3f454d6f-b40e-49e5-89eb-b77bcca35043@quicinc.com>


On 9/24/2024 9:50 PM, Manivannan Sadhasivam wrote:
> On Tue, Sep 24, 2024 at 03:14:43AM -0700, Qiang Yu wrote:
>> X1E80100 has PCIe ports that support up to Gen4 x8 based on hardware IP
>> version 1.38.0.
>>
>> Currently the ops_1_9_0 which is being used for X1E80100 has config_sid
>> callback to config BDF to SID table. However, this callback is not
>> required for X1E80100 because it has smmuv3 support and BDF to SID table
>> will be not present.
>>
>> Hence add support for X1E80100 by introducing a new ops and cfg structures
>> that don't require the config_sid callback. This could be reused by the
>> future platforms based on SMMUv3.
>>
> Oops... I completely overlooked that you are not adding the SoC support but
> fixing the existing one :( Sorry for suggesting a commit message that changed
> the context.
>
> For this, you can have something like:
>
> "PCI: qcom: Fix the ops for X1E80100 SoC
>
> X1E80100 SoC is based on SMMUv3, hence it doesn't need the BDF2SID mapping
> present in the existing cfg_1_9_0 ops. This is fixed by introducing new ops
> 'ops_1_38_0' and cfg 'cfg_1_38_0' structures. These are exactly same as the
> 1_9_0 ones, but they don't have the 'config_sid()' callback that handles the
> BDF2SID mapping in the hardware. These new structures could also be used by the
> future SoCs making use of SMMUv3."
Never mind, thanks for your suggestions. Will update the commit msg in next
version.

Thanks,
Qiang Yu
>
> - Mani
>
>> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
>> ---
>>   drivers/pci/controller/dwc/pcie-qcom.c | 16 +++++++++++++++-
>>   1 file changed, 15 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
>> index 88a98be930e3..56ba8bc72f78 100644
>> --- a/drivers/pci/controller/dwc/pcie-qcom.c
>> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
>> @@ -1367,6 +1367,16 @@ static const struct qcom_pcie_ops ops_2_9_0 = {
>>   	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
>>   };
>>   
>> +/* Qcom IP rev.: 1.38.0 */
>> +static const struct qcom_pcie_ops ops_1_38_0 = {
>> +	.get_resources = qcom_pcie_get_resources_2_7_0,
>> +	.init = qcom_pcie_init_2_7_0,
>> +	.post_init = qcom_pcie_post_init_2_7_0,
>> +	.host_post_init = qcom_pcie_host_post_init_2_7_0,
>> +	.deinit = qcom_pcie_deinit_2_7_0,
>> +	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
>> +};
>> +
>>   static const struct qcom_pcie_cfg cfg_1_0_0 = {
>>   	.ops = &ops_1_0_0,
>>   };
>> @@ -1409,6 +1419,10 @@ static const struct qcom_pcie_cfg cfg_sc8280xp = {
>>   	.no_l0s = true,
>>   };
>>   
>> +static const struct qcom_pcie_cfg cfg_1_38_0 = {
>> +	.ops = &ops_1_38_0,
>> +};
>> +
>>   static const struct dw_pcie_ops dw_pcie_ops = {
>>   	.link_up = qcom_pcie_link_up,
>>   	.start_link = qcom_pcie_start_link,
>> @@ -1837,7 +1851,7 @@ static const struct of_device_id qcom_pcie_match[] = {
>>   	{ .compatible = "qcom,pcie-sm8450-pcie0", .data = &cfg_1_9_0 },
>>   	{ .compatible = "qcom,pcie-sm8450-pcie1", .data = &cfg_1_9_0 },
>>   	{ .compatible = "qcom,pcie-sm8550", .data = &cfg_1_9_0 },
>> -	{ .compatible = "qcom,pcie-x1e80100", .data = &cfg_1_9_0 },
>> +	{ .compatible = "qcom,pcie-x1e80100", .data = &cfg_1_38_0 },
>>   	{ }
>>   };
>>   
>> -- 
>> 2.34.1
>>


From quic_qianyu at quicinc.com  Tue Sep 24 20:47:02 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Wed, 25 Sep 2024 11:47:02 +0800
Subject: [PATCH v4 5/6] PCI: qcom: Add support for X1E80100 SoC
In-Reply-To: <ZvLX_wkh7_y7sjPZ@hovoldconsulting.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-6-quic_qianyu@quicinc.com>
 <20240924135021.ybpyoahlpuvedma5@thinkpad>
 <ZvLX_wkh7_y7sjPZ@hovoldconsulting.com>
Message-ID: <4368503f-fb33-4e6a-bef4-517e2b959400@quicinc.com>


On 9/24/2024 11:17 PM, Johan Hovold wrote:
> On Tue, Sep 24, 2024 at 03:50:21PM +0200, Manivannan Sadhasivam wrote:
>> On Tue, Sep 24, 2024 at 03:14:43AM -0700, Qiang Yu wrote:
>>> X1E80100 has PCIe ports that support up to Gen4 x8 based on hardware IP
>>> version 1.38.0.
>>>
>>> Currently the ops_1_9_0 which is being used for X1E80100 has config_sid
>>> callback to config BDF to SID table. However, this callback is not
>>> required for X1E80100 because it has smmuv3 support and BDF to SID table
>>> will be not present.
>>>
>>> Hence add support for X1E80100 by introducing a new ops and cfg structures
>>> that don't require the config_sid callback. This could be reused by the
>>> future platforms based on SMMUv3.
>>>
>> Oops... I completely overlooked that you are not adding the SoC support but
>> fixing the existing one :( Sorry for suggesting a commit message that changed
>> the context.
>>
>> For this, you can have something like:
>>
>> "PCI: qcom: Fix the ops for X1E80100 SoC
>>
>> X1E80100 SoC is based on SMMUv3, hence it doesn't need the BDF2SID mapping
>> present in the existing cfg_1_9_0 ops. This is fixed by introducing new ops
>> 'ops_1_38_0' and cfg 'cfg_1_38_0' structures. These are exactly same as the
>> 1_9_0 ones, but they don't have the 'config_sid()' callback that handles the
>> BDF2SID mapping in the hardware. These new structures could also be used by the
>> future SoCs making use of SMMUv3."
> Don't we need something like this for sc8280xp and other platforms using
> SMMUv3 as well?
 From what I know, sc8280xp and other qcom platforms are not using SMMUv3.
X1E80100 and newer platforms will use SMMUv3.

Thanks,
Qiang
>
> Johan


From quic_qianyu at quicinc.com  Tue Sep 24 20:57:07 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Wed, 25 Sep 2024 11:57:07 +0800
Subject: [PATCH v4 6/6] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <9a692c98-eb0a-4d86-b642-ea655981ff53@kernel.org>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-7-quic_qianyu@quicinc.com>
 <9a692c98-eb0a-4d86-b642-ea655981ff53@kernel.org>
Message-ID: <f9456f67-0425-4ed0-8de0-17ed61e2af8e@quicinc.com>


On 9/24/2024 10:26 PM, Konrad Dybcio wrote:
> On 24.09.2024 12:14 PM, Qiang Yu wrote:
>> Describe PCIe3 controller and PHY. Also add required system resources like
>> regulators, clocks, interrupts and registers configuration for PCIe3.
>>
>> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
>> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>> ---
> Qiang, Mani
>
> I have a RTS5261 mmc chip on PCIe3 on the Surface Laptop.
> Adding the global irq breaks sdcard detection (the chip still comes
> up fine) somehow. Removing the irq makes it work again :|
>
> I've confirmed that the irq number is correct
Actually, I verified this patch with several devices (SDX75, AIC100 and
R8169 of TP-LINK) attached to X1E80100 QCP. But I didn't meet this issue.
Each device was detected. Can you please share boot log if it is possible?

Mani, did you ever meet similar issue on other platforms?

0003:01:00.0 Class 0200: Device 10ec:8161 (rev 15)
 ??????? Subsystem: Device 10ec:8168
 ??????? I/O ports at 100000 [size=256]
 ??????? Memory at 78304000 (64-bit, non-prefetchable) [size=4K]
 ??????? Memory at 78300000 (64-bit, non-prefetchable) [size=16K]
 ??????? Kernel driver in use: r8169

0003:01:00.0 Class ff00: Device 17cb:0309
 ??????? Subsystem: Device 17cb:0309
 ??????? Memory at 78580000 (64-bit, non-prefetchable) [size=4K]
 ??????? Memory at 78581000 (64-bit, non-prefetchable) [size=4K]
 ??????? Kernel driver in use: mhi-pci-generic

0003:01:00.0 Class 1200: Device 17cb:a100
 ??????? Subsystem: Device 17cb:a100
 ??????? Region 0: Memory at 78300000 (64-bit, non-prefetchable) 
[disabled] [size=4K]
 ??????? Region 2: Memory at 78400000 (64-bit, non-prefetchable) 
[disabled] [size=2M]
 ??????? Region 4: Memory at 78600000 (64-bit, prefetchable) [disabled] 
[size=64K]

Thanks,
Qiang Yu
>
> Konrad


From quic_qianyu at quicinc.com  Tue Sep 24 23:37:41 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Wed, 25 Sep 2024 14:37:41 +0800
Subject: [PATCH v4 6/6] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <ZvLQFSjwR-TvHbm_@hovoldconsulting.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-7-quic_qianyu@quicinc.com>
 <ZvLQFSjwR-TvHbm_@hovoldconsulting.com>
Message-ID: <ee32742d-9daf-4bff-948b-cf2e705bc73f@quicinc.com>


On 9/24/2024 10:43 PM, Johan Hovold wrote:
> On Tue, Sep 24, 2024 at 03:14:44AM -0700, Qiang Yu wrote:
>> Describe PCIe3 controller and PHY. Also add required system resources like
>> regulators, clocks, interrupts and registers configuration for PCIe3.
>> @@ -2907,6 +2907,208 @@ mmss_noc: interconnect at 1780000 {
>>   			#interconnect-cells = <2>;
>>   		};
>>   
>> +		pcie3: pcie at 1bd0000 {
>> +			device_type = "pci";
>> +			compatible = "qcom,pcie-x1e80100";
>> +			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 769 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 671 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
>> +			interrupt-names = "msi0",
>> +					  "msi1",
>> +					  "msi2",
>> +					  "msi3",
>> +					  "msi4",
>> +					  "msi5",
>> +					  "msi6",
>> +					  "msi7",
>> +					  "global";
> This ninth "global" interrupt is not described by the bindings, which
> would also need to be updated. What is it used for?

As of now, the global interrupts is mainly used to get link up event so
that the device driver can enumerate the PCIe endpoint devices without
user intervention. You can refer to
https://lore.kernel.org/linux-pci/20240828-pci-qcom-hotplug-v4-11-263a385fbbcb at linaro.org.

I see this global interrupts has been documented in qcom,pcie-sm8450.yaml.
Do I need to move it to qcom,pcie-common.yaml?

Thanks,
Qiang
>
> Johan


From heiko at sntech.de  Tue Sep 24 23:59:33 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 25 Sep 2024 08:59:33 +0200
Subject: [PATCH v2 2/2] phy: rockchip: inno-usb2: Add usb2 phys support for rk3576
In-Reply-To: <29d80d30-dcbf-4fe1-b7aa-3f8c46fee714@gmail.com>
References: <20240924085510.20863-1-frawang.cn@gmail.com> <15288441.JCcGWNJJiE@phil>
 <29d80d30-dcbf-4fe1-b7aa-3f8c46fee714@gmail.com>
Message-ID: <5522095.29KlJPOoH8@phil>

Hi Frank,

Am Mittwoch, 25. September 2024, 03:42:35 CEST schrieb frawang:
> >> @@ -376,6 +378,7 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
> >>   {
> >>   	struct device_node *node = rphy->dev->of_node;
> >>   	struct clk_init_data init;
> >> +	struct clk *refclk = of_clk_get_by_name(node, "phyclk");
> > Doesn't this create an imbalance - with the missing put?
> > I think ideally just define clk_bulk_data structs for the
> > 1-clock and 3-clock variant, attach that to the device-data
> > and then use the regular devm_clk_bulk_get ?
> >
> > That way you can then retrieve the clock from that struct?
> 
> How about keep the clk_bulk_data and num_clks member in rockchip_usb2phy 
> structs, and retrieve the clock by "clks.id" here?
> Just like the following codes.
> 
> @@ -378,8 +378,9 @@ rockchip_usb2phy_clk480m_register(struct 
> rockchip_usb2phy *rphy)
>   {
>          struct device_node *node = rphy->dev->of_node;
>          struct clk_init_data init;
> -       struct clk *refclk = of_clk_get_by_name(node, "phyclk");
> +       struct clk *refclk = NULL;
>          const char *clk_name;
> +       int i;
>          int ret = 0;
> 
>          init.flags = 0;
> @@ -389,6 +390,13 @@ rockchip_usb2phy_clk480m_register(struct 
> rockchip_usb2phy *rphy)
>          /* optional override of the clockname */
>          of_property_read_string(node, "clock-output-names", &init.name);
> 
> +       for (i = 0; i < rphy->num_clks; i++) {
> +               if (!strncmp(rphy->clks[i].id, "phyclk", 6)) {
> +                       refclk = rphy->clks[i].clk;
> +                       break;
> +               }
> +       }
> +

this is exactly what I had in mind :-)

Thanks
Heiko




From krzk at kernel.org  Wed Sep 25 00:14:00 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 25 Sep 2024 09:14:00 +0200
Subject: [PATCH v2] dt-bindings: phy: Add QMP UFS PHY comptible for
 QCS8300
In-Reply-To: <6656171b-12d3-490b-b53c-f907b7454f99@quicinc.com>
References: <20240911-qcs8300_ufs_phy_binding-v2-1-c801a2d27a84@quicinc.com>
 <ztpetznwid2om6vylyl2boi665ch3wnkprkmzcq6bem6cqhqtf@ogsi657y4kex>
 <6656171b-12d3-490b-b53c-f907b7454f99@quicinc.com>
Message-ID: <01ea36e7-f4a7-4f1f-9596-3ed6ed13b47b@kernel.org>

On 25/09/2024 05:16, Jingyi Wang wrote:
> 
> 
> On 9/16/2024 10:53 PM, Krzysztof Kozlowski wrote:
>> On Wed, Sep 11, 2024 at 02:56:16PM +0800, Jingyi Wang wrote:
>>> From: Xin Liu <quic_liuxin at quicinc.com>
>>>
>>> Document the QMP UFS PHY compatible for Qualcomm QCS8300 to support
>>> physical layer functionality for UFS found on the SoC. Use fallback to
>>> indicate the compatibility of the QMP UFS PHY on the QCS8300 with that
>>> on the SA8775P.
>>>
>>> Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
>>> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
>>> ---
>>> Changes in v2:
>>> - decoupled from the original series.
>>> - Use fallback to indicate compatibility with SA8775P.
>>> - typo fixup
>>> - Link to v1: https://lore.kernel.org/r/20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007 at quicinc.com
>>> ---
>>>  .../bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml    | 46 ++++++++++++----------
>>>  1 file changed, 26 insertions(+), 20 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
>>> index f9cfbd0b2de6..626a2039e177 100644
>>> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
>>> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
>>> @@ -15,26 +15,31 @@ description:
>>>  
>>>  properties:
>>>    compatible:
>>> -    enum:
>>> -      - qcom,msm8996-qmp-ufs-phy
>>> -      - qcom,msm8998-qmp-ufs-phy
>>> -      - qcom,sa8775p-qmp-ufs-phy
>>> -      - qcom,sc7180-qmp-ufs-phy
>>> -      - qcom,sc7280-qmp-ufs-phy
>>> -      - qcom,sc8180x-qmp-ufs-phy
>>> -      - qcom,sc8280xp-qmp-ufs-phy
>>> -      - qcom,sdm845-qmp-ufs-phy
>>> -      - qcom,sm6115-qmp-ufs-phy
>>> -      - qcom,sm6125-qmp-ufs-phy
>>> -      - qcom,sm6350-qmp-ufs-phy
>>> -      - qcom,sm7150-qmp-ufs-phy
>>> -      - qcom,sm8150-qmp-ufs-phy
>>> -      - qcom,sm8250-qmp-ufs-phy
>>> -      - qcom,sm8350-qmp-ufs-phy
>>> -      - qcom,sm8450-qmp-ufs-phy
>>> -      - qcom,sm8475-qmp-ufs-phy
>>> -      - qcom,sm8550-qmp-ufs-phy
>>> -      - qcom,sm8650-qmp-ufs-phy
>>> +    oneOf:
>>> +      - items:
>>> +          - enum:
>>> +              - qcom,qcs8300-qmp-ufs-phy
>>> +          - const: qcom,sa8775p-qmp-ufs-phy
>>> +      - enum:
>>> +          - qcom,msm8996-qmp-ufs-phy
>>> +          - qcom,msm8998-qmp-ufs-phy
>>> +          - qcom,sa8775p-qmp-ufs-phy
>>> +          - qcom,sc7180-qmp-ufs-phy
>>> +          - qcom,sc7280-qmp-ufs-phy
>>> +          - qcom,sc8180x-qmp-ufs-phy
>>> +          - qcom,sc8280xp-qmp-ufs-phy
>>> +          - qcom,sdm845-qmp-ufs-phy
>>> +          - qcom,sm6115-qmp-ufs-phy
>>> +          - qcom,sm6125-qmp-ufs-phy
>>> +          - qcom,sm6350-qmp-ufs-phy
>>> +          - qcom,sm7150-qmp-ufs-phy
>>> +          - qcom,sm8150-qmp-ufs-phy
>>> +          - qcom,sm8250-qmp-ufs-phy
>>> +          - qcom,sm8350-qmp-ufs-phy
>>> +          - qcom,sm8450-qmp-ufs-phy
>>> +          - qcom,sm8475-qmp-ufs-phy
>>> +          - qcom,sm8550-qmp-ufs-phy
>>> +          - qcom,sm8650-qmp-ufs-phy
>>>  
>>>    reg:
>>>      maxItems: 1
>>> @@ -85,6 +90,7 @@ allOf:
>>>            contains:
>>>              enum:
>>>                - qcom,msm8998-qmp-ufs-phy
>>> +              - qcom,qcs8300-qmp-ufs-phy
>>
>> Not needed.
>>
> Well noted.
>> BTW, please be sure you organize your patchsets per subsystem. IOW, that
>> you do not split same subsystem bindings patches into separate
>> patchsets.
>>
> Do you mean combine the binding of qmp-ufs-phy with ufs controller? I noticed
> that this patch belongs to "GENERIC PHY FRAMEWORK" subsystem and ufs controller
> binding belongs to "UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER". If necessary,
> we can pay attention to combine them next time

No, I mean group patches targeting the same subsystem.

Best regards,
Krzysztof



From krzk at kernel.org  Wed Sep 25 00:16:37 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 25 Sep 2024 09:16:37 +0200
Subject: [PATCH v2 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <87146372-6d05-4994-8f64-47f4cb07e2b4@gmail.com>
References: <20240924085510.20863-1-frawang.cn@gmail.com>
 <20240924-overtly-curable-13df2e7fdc9b@spud>
 <87146372-6d05-4994-8f64-47f4cb07e2b4@gmail.com>
Message-ID: <2a4200ac-3ea2-4449-94ac-c4b9f37ad800@kernel.org>

On 25/09/2024 04:09, Frank Wang wrote:
> Hi Conor,
> 
> On 2024/9/25 0:11, Conor Dooley wrote:
>> On Tue, Sep 24, 2024 at 04:55:09PM +0800, Frank Wang wrote:
>>> From: Frank Wang <frank.wang at rock-chips.com>
>>>
>>> Add compatible for the USB2 phy in the Rockchip RK3576 SoC.
>>>
>>> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
>>> ---
>>> Changelog:
>>> v2:
>>>   - Categorize clock names by oneOf keyword.
>>>
>>> v1:
>>>   - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-1-frank.wang at rock-chips.com/
>>>
>>>   .../bindings/phy/rockchip,inno-usb2phy.yaml      | 16 ++++++++++++++--
>>>   1 file changed, 14 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>>> index 5254413137c64..8af4e0f8637fc 100644
>>> --- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>>> +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>>> @@ -20,6 +20,7 @@ properties:
>>>         - rockchip,rk3366-usb2phy
>>>         - rockchip,rk3399-usb2phy
>>>         - rockchip,rk3568-usb2phy
>>> +      - rockchip,rk3576-usb2phy
>>>         - rockchip,rk3588-usb2phy
>>>         - rockchip,rv1108-usb2phy
>>>   
>>> @@ -34,10 +35,20 @@ properties:
>>>       const: 0
>>>   
>>>     clocks:
>>> -    maxItems: 1
>>> +    minItems: 1
>>> +    maxItems: 3
>>>   
>>>     clock-names:
>>> -    const: phyclk
>>> +    minItems: 1
>>> +    maxItems: 3
>> clock-names isn't a required property, you can't allow jumbling the order
>> like this does without breaking the ABI. Why can't the new device have
>> phyclk in position 1?
> 
> I sent a draft changes in patch v1 comments which put the "phyclk" in 

No, you did not. You sent buggy code which was never tested.

> position 1, Krzysztof said I have messed the order, so I reorder them in v2.

No, I did not. I said your current code (from your reply or patch v2)
messes the order. Even though I sent you reply that this code is wrong,
you still decided to ignore my feedback and send it.

To be clear:
NAK

> Did I misunderstand? anyway, should the changes like the below?

Read all the answers again instead of putting wrong words to wrong patches.


Best regards,
Krzysztof



From krzk at kernel.org  Wed Sep 25 00:17:19 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 25 Sep 2024 09:17:19 +0200
Subject: [RESEND PATCH 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <e77cab18-155a-4174-bca0-5ff1ce1d2b6f@kernel.org>
References: <20240923025326.10467-1-frank.wang@rock-chips.com>
 <snccizbw6thn3lhwad4xppp7vqii4p56ttl2gufwc3ke7vfckf@e4b7nvwwtdfr>
 <1f996322-e6f6-4dd5-a1d7-c2bde92c876b@rock-chips.com>
 <e77cab18-155a-4174-bca0-5ff1ce1d2b6f@kernel.org>
Message-ID: <99409dd6-f474-432e-a8fc-687993ebf942@kernel.org>

On 24/09/2024 09:56, Krzysztof Kozlowski wrote:
> On 24/09/2024 04:24, Frank Wang wrote:
>> Hi Krzysztof,
>> On 2024/9/23 17:31, Krzysztof Kozlowski wrote:
>>> On Mon, Sep 23, 2024 at 10:53:25AM +0800, Frank Wang wrote:
>>>> Add compatible for the USB2 phy in the Rockchip RK3576 SoC.
>>>>
>>>> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
>>>> ---
>>>>   .../devicetree/bindings/phy/rockchip,inno-usb2phy.yaml | 10 +++++++++-
>>>>   1 file changed, 9 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>>>> index 5254413137c64..214917e55c0b6 100644
>>>> --- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>>>> +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>>>> @@ -20,6 +20,7 @@ properties:
>>>>         - rockchip,rk3366-usb2phy
>>>>         - rockchip,rk3399-usb2phy
>>>>         - rockchip,rk3568-usb2phy
>>>> +      - rockchip,rk3576-usb2phy
>>>>         - rockchip,rk3588-usb2phy
>>>>         - rockchip,rv1108-usb2phy
>>>>   
>>>> @@ -34,10 +35,16 @@ properties:
>>>>       const: 0
>>>>   
>>>>     clocks:
>>>> -    maxItems: 1
>>>> +    minItems: 1
>>>> +    items:
>>>> +      - description: phyclk - PHY input reference clocks.
>>>> +      - description: aclk and aclk_slv are optional and used for USB MMU.
>>>>   
>>>>     clock-names:
>>>> +    minItems: 1
>>>>       const: phyclk
>>>> +    const: aclk
>>>> +    const: aclk_slv
>>> Please test... Not sure what you wanted to achieve here, but maybe
>>> oneOf?
>>
>> The "aclk" and "aclk_slv" clocks are new in RK3576, you mean the changes 
>> should be like the below?
>>
>> @@ -34,10 +35,20 @@ properties:
>>  ???? const: 0
>>
>>  ?? clocks:
>> -??? maxItems: 1
>> +??? minItems: 1
>> +??? maxItems: 3
>>
>>  ?? clock-names:
>> -??? const: phyclk
>> +??? minItems: 1
>> +??? maxItems: 3
>> +??? items:
>> +????? oneOf:
>> +??????? - description: PHY input reference clocks.
>> +????????? const: phyclk
>> +??????? - description: aclk for USB MMU.
>> +????????? const: aclk
>> +??????? - description: aclk_slv for USB MMU.
>> +????????? const: aclk_slv
> 
> Nope, you just messed the order. Order is strict.

And you still sent v2 with this messed order. No. Order must be strict.
Cannot be oneOf.

Best regards,
Krzysztof



From quic_jingyw at quicinc.com  Wed Sep 25 00:34:32 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Wed, 25 Sep 2024 15:34:32 +0800
Subject: [PATCH v3] dt-bindings: phy: Add QMP UFS PHY compatible for
 QCS8300
Message-ID: <20240925-qcs8300_ufs_phy_binding-v3-1-c1eb5c393b09@quicinc.com>

From: Xin Liu <quic_liuxin at quicinc.com>

Document the QMP UFS PHY compatible for Qualcomm QCS8300 to support
physical layer functionality for UFS found on the SoC. Use fallback to
indicate the compatibility of the QMP UFS PHY on the QCS8300 with that
on the SA8775P.

Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
Changes in v3:
- remove redundant compatible.
- Link to v2: https://lore.kernel.org/r/20240911-qcs8300_ufs_phy_binding-v2-1-c801a2d27a84 at quicinc.com

Changes in v2:
- decoupled from the original series.
- Use fallback to indicate compatibility with SA8775P.
- typo fixup
- Link to v1: https://lore.kernel.org/r/20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007 at quicinc.com
---
 .../bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml    | 45 ++++++++++++----------
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
index f9cfbd0b2de6..8b7eda51b3ae 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
@@ -15,26 +15,31 @@ description:
 
 properties:
   compatible:
-    enum:
-      - qcom,msm8996-qmp-ufs-phy
-      - qcom,msm8998-qmp-ufs-phy
-      - qcom,sa8775p-qmp-ufs-phy
-      - qcom,sc7180-qmp-ufs-phy
-      - qcom,sc7280-qmp-ufs-phy
-      - qcom,sc8180x-qmp-ufs-phy
-      - qcom,sc8280xp-qmp-ufs-phy
-      - qcom,sdm845-qmp-ufs-phy
-      - qcom,sm6115-qmp-ufs-phy
-      - qcom,sm6125-qmp-ufs-phy
-      - qcom,sm6350-qmp-ufs-phy
-      - qcom,sm7150-qmp-ufs-phy
-      - qcom,sm8150-qmp-ufs-phy
-      - qcom,sm8250-qmp-ufs-phy
-      - qcom,sm8350-qmp-ufs-phy
-      - qcom,sm8450-qmp-ufs-phy
-      - qcom,sm8475-qmp-ufs-phy
-      - qcom,sm8550-qmp-ufs-phy
-      - qcom,sm8650-qmp-ufs-phy
+    oneOf:
+      - items:
+          - enum:
+              - qcom,qcs8300-qmp-ufs-phy
+          - const: qcom,sa8775p-qmp-ufs-phy
+      - enum:
+          - qcom,msm8996-qmp-ufs-phy
+          - qcom,msm8998-qmp-ufs-phy
+          - qcom,sa8775p-qmp-ufs-phy
+          - qcom,sc7180-qmp-ufs-phy
+          - qcom,sc7280-qmp-ufs-phy
+          - qcom,sc8180x-qmp-ufs-phy
+          - qcom,sc8280xp-qmp-ufs-phy
+          - qcom,sdm845-qmp-ufs-phy
+          - qcom,sm6115-qmp-ufs-phy
+          - qcom,sm6125-qmp-ufs-phy
+          - qcom,sm6350-qmp-ufs-phy
+          - qcom,sm7150-qmp-ufs-phy
+          - qcom,sm8150-qmp-ufs-phy
+          - qcom,sm8250-qmp-ufs-phy
+          - qcom,sm8350-qmp-ufs-phy
+          - qcom,sm8450-qmp-ufs-phy
+          - qcom,sm8475-qmp-ufs-phy
+          - qcom,sm8550-qmp-ufs-phy
+          - qcom,sm8650-qmp-ufs-phy
 
   reg:
     maxItems: 1

---
base-commit: 4d0326b60bb753627437fff0f76bf1525bcda422
change-id: 20240925-qcs8300_ufs_phy_binding-d2cc6b1280e9

Best regards,
-- 
Jingyi Wang <quic_jingyw at quicinc.com>



From claudiu.beznea at tuxon.dev  Wed Sep 25 00:50:24 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Wed, 25 Sep 2024 10:50:24 +0300
Subject: [PATCH 04/16] soc: renesas: Add SYSC driver for Renesas RZ/G3S
In-Reply-To: <CAMuHMdVQsHx0nC3xwQWVRWyWMnbXd1=RokNn8rkJv3bfG_0p-A@mail.gmail.com>
References: <20240822152801.602318-1-claudiu.beznea.uj@bp.renesas.com>
 <20240822152801.602318-5-claudiu.beznea.uj@bp.renesas.com>
 <CAMuHMdVQsHx0nC3xwQWVRWyWMnbXd1=RokNn8rkJv3bfG_0p-A@mail.gmail.com>
Message-ID: <23531a70-cf50-4b32-a9fd-81e6cfcbcf9d@tuxon.dev>

Hi, Geert,

On 24.09.2024 14:32, Geert Uytterhoeven wrote:
> Hi Claudiu,
> 
> On Thu, Aug 22, 2024 at 5:28?PM Claudiu <claudiu.beznea at tuxon.dev> wrote:
>> From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>>
>> The RZ/G3S SYS Controller has 2 registers (one for PCIE one for USB) that
>> need to be configured before/after powering off/on the PCI or USB
>> ares. The bits in these registers control signals to PCIE and USB that
>> need to be de-asserted/asserted after/before power on/off event. For this
>> add SYSC controller driver that registers a reset controller driver on
>> auxiliary bus which allows USB, PCIE drivers to control these signals.
>>
>> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> 
> Thanks for your patch!
> 
>> --- /dev/null
>> +++ b/drivers/reset/reset-rzg3s-sysc.c
>> @@ -0,0 +1,140 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Renesas RZ/G3S SYSC reset driver
>> + *
>> + * Copyright (C) 2024 Renesas Electronics Corp.
>> + */
>> +
>> +#include <linux/auxiliary_bus.h>
> 
> Using the Auxiliary Bus requires selecting AUXILIARY_BUS.

Thank you for pointing it. I'll adjust it in the next version, if it will
be one.


> Elsse you might run into build failures:
> 
> aarch64-linux-gnu-ld: drivers/soc/renesas/rzg3s-sysc.o: in function
> `rzg3s_sysc_probe':
> rzg3s-sysc.c:(.text+0x21c): undefined reference to `auxiliary_device_init'
> aarch64-linux-gnu-ld: rzg3s-sysc.c:(.text+0x264): undefined reference
> to `__auxiliary_device_add'
> aarch64-linux-gnu-ld: drivers/reset/reset-rzg3s-sysc.o: in function
> `rzg3s_sysc_reset_driver_init':
> reset-rzg3s-sysc.c:(.init.text+0x1c): undefined reference to
> `__auxiliary_driver_register'
> aarch64-linux-gnu-ld: drivers/reset/reset-rzg3s-sysc.o: in function
> `rzg3s_sysc_reset_driver_exit':
> reset-rzg3s-sysc.c:(.exit.text+0x10): undefined reference to
> `auxiliary_driver_unregister'
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 


From manivannan.sadhasivam at linaro.org  Wed Sep 25 00:58:59 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Wed, 25 Sep 2024 09:58:59 +0200
Subject: [PATCH v4 6/6] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <ee32742d-9daf-4bff-948b-cf2e705bc73f@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-7-quic_qianyu@quicinc.com>
 <ZvLQFSjwR-TvHbm_@hovoldconsulting.com>
 <ee32742d-9daf-4bff-948b-cf2e705bc73f@quicinc.com>
Message-ID: <20240925075859.4vbb4faaworc6eyz@thinkpad>

On Wed, Sep 25, 2024 at 02:37:41PM +0800, Qiang Yu wrote:
> 
> On 9/24/2024 10:43 PM, Johan Hovold wrote:
> > On Tue, Sep 24, 2024 at 03:14:44AM -0700, Qiang Yu wrote:
> > > Describe PCIe3 controller and PHY. Also add required system resources like
> > > regulators, clocks, interrupts and registers configuration for PCIe3.
> > > @@ -2907,6 +2907,208 @@ mmss_noc: interconnect at 1780000 {
> > >   			#interconnect-cells = <2>;
> > >   		};
> > > +		pcie3: pcie at 1bd0000 {
> > > +			device_type = "pci";
> > > +			compatible = "qcom,pcie-x1e80100";
> > > +			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <GIC_SPI 769 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <GIC_SPI 671 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
> > > +			interrupt-names = "msi0",
> > > +					  "msi1",
> > > +					  "msi2",
> > > +					  "msi3",
> > > +					  "msi4",
> > > +					  "msi5",
> > > +					  "msi6",
> > > +					  "msi7",
> > > +					  "global";
> > This ninth "global" interrupt is not described by the bindings, which
> > would also need to be updated. What is it used for?
> 
> As of now, the global interrupts is mainly used to get link up event so
> that the device driver can enumerate the PCIe endpoint devices without
> user intervention. You can refer to
> https://lore.kernel.org/linux-pci/20240828-pci-qcom-hotplug-v4-11-263a385fbbcb at linaro.org.
> 
> I see this global interrupts has been documented in qcom,pcie-sm8450.yaml.
> Do I need to move it to qcom,pcie-common.yaml?
> 

No, you need to describe it in qcom,pcie-x1e80100.yaml.

- Mani

-- 
????????? ????????


From manivannan.sadhasivam at linaro.org  Wed Sep 25 01:05:22 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Wed, 25 Sep 2024 10:05:22 +0200
Subject: [PATCH v4 6/6] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <9a692c98-eb0a-4d86-b642-ea655981ff53@kernel.org>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-7-quic_qianyu@quicinc.com>
 <9a692c98-eb0a-4d86-b642-ea655981ff53@kernel.org>
Message-ID: <20240925080522.qwjeyrpjtz64pccx@thinkpad>

On Tue, Sep 24, 2024 at 04:26:34PM +0200, Konrad Dybcio wrote:
> On 24.09.2024 12:14 PM, Qiang Yu wrote:
> > Describe PCIe3 controller and PHY. Also add required system resources like
> > regulators, clocks, interrupts and registers configuration for PCIe3.
> > 
> > Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > ---
> 
> Qiang, Mani
> 
> I have a RTS5261 mmc chip on PCIe3 on the Surface Laptop.

Is it based on x1e80100?

> Adding the global irq breaks sdcard detection (the chip still comes
> up fine) somehow. Removing the irq makes it work again :|
> 
> I've confirmed that the irq number is correct
> 

Yeah, I did see some issues with MSI on SM8250 (RB5) when global interrupts are
enabled and I'm working with the hw folks to understand what is going on. But
I didn't see the same issues on newer platforms (sa8775p etc...).

Can you please confirm if the issue is due to MSI not being received from the
device? Checking the /proc/interrutps is enough.

- Mani

-- 
????????? ????????


From manivannan.sadhasivam at linaro.org  Wed Sep 25 01:07:24 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Wed, 25 Sep 2024 10:07:24 +0200
Subject: [PATCH v4 5/6] PCI: qcom: Add support for X1E80100 SoC
In-Reply-To: <4368503f-fb33-4e6a-bef4-517e2b959400@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-6-quic_qianyu@quicinc.com>
 <20240924135021.ybpyoahlpuvedma5@thinkpad>
 <ZvLX_wkh7_y7sjPZ@hovoldconsulting.com>
 <4368503f-fb33-4e6a-bef4-517e2b959400@quicinc.com>
Message-ID: <20240925080724.vgkgmnqc44aoiarv@thinkpad>

On Wed, Sep 25, 2024 at 11:47:02AM +0800, Qiang Yu wrote:
> 
> On 9/24/2024 11:17 PM, Johan Hovold wrote:
> > On Tue, Sep 24, 2024 at 03:50:21PM +0200, Manivannan Sadhasivam wrote:
> > > On Tue, Sep 24, 2024 at 03:14:43AM -0700, Qiang Yu wrote:
> > > > X1E80100 has PCIe ports that support up to Gen4 x8 based on hardware IP
> > > > version 1.38.0.
> > > > 
> > > > Currently the ops_1_9_0 which is being used for X1E80100 has config_sid
> > > > callback to config BDF to SID table. However, this callback is not
> > > > required for X1E80100 because it has smmuv3 support and BDF to SID table
> > > > will be not present.
> > > > 
> > > > Hence add support for X1E80100 by introducing a new ops and cfg structures
> > > > that don't require the config_sid callback. This could be reused by the
> > > > future platforms based on SMMUv3.
> > > > 
> > > Oops... I completely overlooked that you are not adding the SoC support but
> > > fixing the existing one :( Sorry for suggesting a commit message that changed
> > > the context.
> > > 
> > > For this, you can have something like:
> > > 
> > > "PCI: qcom: Fix the ops for X1E80100 SoC
> > > 
> > > X1E80100 SoC is based on SMMUv3, hence it doesn't need the BDF2SID mapping
> > > present in the existing cfg_1_9_0 ops. This is fixed by introducing new ops
> > > 'ops_1_38_0' and cfg 'cfg_1_38_0' structures. These are exactly same as the
> > > 1_9_0 ones, but they don't have the 'config_sid()' callback that handles the
> > > BDF2SID mapping in the hardware. These new structures could also be used by the
> > > future SoCs making use of SMMUv3."
> > Don't we need something like this for sc8280xp and other platforms using
> > SMMUv3 as well?
> From what I know, sc8280xp and other qcom platforms are not using SMMUv3.

sc8280xp indeed has SMMUv3 for PCIe, but I'm not sure how it is configured. So
not completely sure whether we can avoid the mapping table or not.

Qiang, please check with the hw team and let us know.

- Mani

-- 
????????? ????????


From johan at kernel.org  Wed Sep 25 01:14:43 2024
From: johan at kernel.org (Johan Hovold)
Date: Wed, 25 Sep 2024 10:14:43 +0200
Subject: [PATCH v4 3/6] phy: qcom: qmp: Add phy register and clk setting
 for x1e80100 PCIe3
In-Reply-To: <3d4a8243-5c2f-41c4-85ce-6e072331f4f3@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-4-quic_qianyu@quicinc.com>
 <ZvLXjdpBpUS3lLn-@hovoldconsulting.com>
 <3d4a8243-5c2f-41c4-85ce-6e072331f4f3@quicinc.com>
Message-ID: <ZvPGc_pPkUfLp6hi@hovoldconsulting.com>

On Wed, Sep 25, 2024 at 11:38:46AM +0800, Qiang Yu wrote:
> 
> On 9/24/2024 11:15 PM, Johan Hovold wrote:
> > On Tue, Sep 24, 2024 at 03:14:41AM -0700, Qiang Yu wrote:
> > > Currently driver supports only x4 lane based functionality using tx/rx and
> > > tx2/rx2 pair of register sets. To support 8 lane functionality with PCIe3,
> > > PCIe3 related QMP PHY provides additional programming which are available
> > > as txz and rxz based register set. Hence adds txz and rxz based registers
> > > usage and programming sequences.
> > > Phy register setting for txz and rxz will
> > > be applied to all 8 lanes. Some lanes may have different settings on
> > > several registers than txz/rxz, these registers should be programmed after
> > > txz/rxz programming sequences completing.

> > Please expand and clarify what you mean by this.

> PCIe3 supports 8 lanes, so in general, we have to program 8 pairs tx/rx
> registers. However, most of tx/rx registers of different lanes have
> same settings, so the configuration for all 8 lanes tx/rx registers is
> a little repetitive.
> 
> Hence, txz/rxz registers are included. The values programmed into txz/rxz
> registers by software will be "broadcasted" to all 8 lanes by hardware.
> Some lanes may have different settings on several registers than txz/rxz.
> In order to ensure the different values take effect, they need to be
> programmed after txz/rxz programming sequences completing.

Thanks for clarifying. This is how I interpreted it, but please include
(some or all of of) what you just wrote to make this more clear in the
commit message.

Johan


From konradybcio at kernel.org  Wed Sep 25 02:30:58 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Wed, 25 Sep 2024 11:30:58 +0200
Subject: [PATCH v4 6/6] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <20240925080522.qwjeyrpjtz64pccx@thinkpad>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-7-quic_qianyu@quicinc.com>
 <9a692c98-eb0a-4d86-b642-ea655981ff53@kernel.org>
 <20240925080522.qwjeyrpjtz64pccx@thinkpad>
Message-ID: <4ee4d016-9d68-4925-9f49-e73a4e7fa794@kernel.org>

On 25.09.2024 10:05 AM, Manivannan Sadhasivam wrote:
> On Tue, Sep 24, 2024 at 04:26:34PM +0200, Konrad Dybcio wrote:
>> On 24.09.2024 12:14 PM, Qiang Yu wrote:
>>> Describe PCIe3 controller and PHY. Also add required system resources like
>>> regulators, clocks, interrupts and registers configuration for PCIe3.
>>>
>>> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
>>> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>>> ---
>>
>> Qiang, Mani
>>
>> I have a RTS5261 mmc chip on PCIe3 on the Surface Laptop.
> 
> Is it based on x1e80100?

You would think so :P

> 
>> Adding the global irq breaks sdcard detection (the chip still comes
>> up fine) somehow. Removing the irq makes it work again :|
>>
>> I've confirmed that the irq number is correct
>>
> 
> Yeah, I did see some issues with MSI on SM8250 (RB5) when global interrupts are
> enabled and I'm working with the hw folks to understand what is going on. But
> I didn't see the same issues on newer platforms (sa8775p etc...).
> 
> Can you please confirm if the issue is due to MSI not being received from the
> device? Checking the /proc/interrutps is enough.

There's no msi-map for PCIe3. I recall +Johan talking about some sort of
a bug that prevents us from adding it?

Konrad


From frawang.cn at gmail.com  Wed Sep 25 02:33:22 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Wed, 25 Sep 2024 17:33:22 +0800
Subject: [PATCH v2 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <2a4200ac-3ea2-4449-94ac-c4b9f37ad800@kernel.org>
References: <20240924085510.20863-1-frawang.cn@gmail.com>
 <20240924-overtly-curable-13df2e7fdc9b@spud>
 <87146372-6d05-4994-8f64-47f4cb07e2b4@gmail.com>
 <2a4200ac-3ea2-4449-94ac-c4b9f37ad800@kernel.org>
Message-ID: <ea3b0968-ffff-4629-b65b-db508f6e1395@gmail.com>

Hi Krzysztof,

On 2024/9/25 15:16, Krzysztof Kozlowski wrote:
> On 25/09/2024 04:09, Frank Wang wrote:
>> Hi Conor,
>>
>> On 2024/9/25 0:11, Conor Dooley wrote:
>>> On Tue, Sep 24, 2024 at 04:55:09PM +0800, Frank Wang wrote:
>>>> From: Frank Wang <frank.wang at rock-chips.com>
>>>>
>>>> Add compatible for the USB2 phy in the Rockchip RK3576 SoC.
>>>>
>>>> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
>>>> ---
>>>> Changelog:
>>>> v2:
>>>>    - Categorize clock names by oneOf keyword.
>>>>
>>>> v1:
>>>>    - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-1-frank.wang at rock-chips.com/
>>>>
>>>>    .../bindings/phy/rockchip,inno-usb2phy.yaml      | 16 ++++++++++++++--
>>>>    1 file changed, 14 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>>>> index 5254413137c64..8af4e0f8637fc 100644
>>>> --- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>>>> +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
>>>> @@ -20,6 +20,7 @@ properties:
>>>>          - rockchip,rk3366-usb2phy
>>>>          - rockchip,rk3399-usb2phy
>>>>          - rockchip,rk3568-usb2phy
>>>> +      - rockchip,rk3576-usb2phy
>>>>          - rockchip,rk3588-usb2phy
>>>>          - rockchip,rv1108-usb2phy
>>>>    
>>>> @@ -34,10 +35,20 @@ properties:
>>>>        const: 0
>>>>    
>>>>      clocks:
>>>> -    maxItems: 1
>>>> +    minItems: 1
>>>> +    maxItems: 3
>>>>    
>>>>      clock-names:
>>>> -    const: phyclk
>>>> +    minItems: 1
>>>> +    maxItems: 3
>>> clock-names isn't a required property, you can't allow jumbling the order
>>> like this does without breaking the ABI. Why can't the new device have
>>> phyclk in position 1?
>> I sent a draft changes in patch v1 comments which put the "phyclk" in
> No, you did not. You sent buggy code which was never tested.
>
>> position 1, Krzysztof said I have messed the order, so I reorder them in v2.
> No, I did not. I said your current code (from your reply or patch v2)
> messes the order. Even though I sent you reply that this code is wrong,
> you still decided to ignore my feedback and send it.
Sorry I misunderstood the 'oneOf' and "order" you said.

I shall amend the patch and send v3 later.

BR.
Frank

> To be clear:
> NAK
>
>> Did I misunderstand? anyway, should the changes like the below?
> Read all the answers again instead of putting wrong words to wrong patches.
>
>
> Best regards,
> Krzysztof
>



From konradybcio at kernel.org  Wed Sep 25 02:46:35 2024
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Wed, 25 Sep 2024 11:46:35 +0200
Subject: [PATCH v4 6/6] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <4ee4d016-9d68-4925-9f49-e73a4e7fa794@kernel.org>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-7-quic_qianyu@quicinc.com>
 <9a692c98-eb0a-4d86-b642-ea655981ff53@kernel.org>
 <20240925080522.qwjeyrpjtz64pccx@thinkpad>
 <4ee4d016-9d68-4925-9f49-e73a4e7fa794@kernel.org>
Message-ID: <2731e17d-c1ad-4fb4-ab60-82ceafeffbaf@kernel.org>

On 25.09.2024 11:30 AM, Konrad Dybcio wrote:
> On 25.09.2024 10:05 AM, Manivannan Sadhasivam wrote:
>> On Tue, Sep 24, 2024 at 04:26:34PM +0200, Konrad Dybcio wrote:
>>> On 24.09.2024 12:14 PM, Qiang Yu wrote:
>>>> Describe PCIe3 controller and PHY. Also add required system resources like
>>>> regulators, clocks, interrupts and registers configuration for PCIe3.
>>>>
>>>> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
>>>> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>>>> ---
>>>
>>> Qiang, Mani
>>>
>>> I have a RTS5261 mmc chip on PCIe3 on the Surface Laptop.
>>
>> Is it based on x1e80100?
> 
> You would think so :P
> 
>>
>>> Adding the global irq breaks sdcard detection (the chip still comes
>>> up fine) somehow. Removing the irq makes it work again :|
>>>
>>> I've confirmed that the irq number is correct
>>>
>>
>> Yeah, I did see some issues with MSI on SM8250 (RB5) when global interrupts are
>> enabled and I'm working with the hw folks to understand what is going on. But
>> I didn't see the same issues on newer platforms (sa8775p etc...).
>>
>> Can you please confirm if the issue is due to MSI not being received from the
>> device? Checking the /proc/interrutps is enough.
> 
> There's no msi-map for PCIe3. I recall +Johan talking about some sort of
> a bug that prevents us from adding it?

Unless you just meant the msi0..=7 interrupts, then yeah, I only get one irq
event with "global" in place and it seems to never get more

Konrad


From manivannan.sadhasivam at linaro.org  Wed Sep 25 05:52:24 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Wed, 25 Sep 2024 14:52:24 +0200
Subject: [PATCH v4 6/6] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <2731e17d-c1ad-4fb4-ab60-82ceafeffbaf@kernel.org>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-7-quic_qianyu@quicinc.com>
 <9a692c98-eb0a-4d86-b642-ea655981ff53@kernel.org>
 <20240925080522.qwjeyrpjtz64pccx@thinkpad>
 <4ee4d016-9d68-4925-9f49-e73a4e7fa794@kernel.org>
 <2731e17d-c1ad-4fb4-ab60-82ceafeffbaf@kernel.org>
Message-ID: <20240925125224.53g6rw46qufxsw6m@thinkpad>

On Wed, Sep 25, 2024 at 11:46:35AM +0200, Konrad Dybcio wrote:
> On 25.09.2024 11:30 AM, Konrad Dybcio wrote:
> > On 25.09.2024 10:05 AM, Manivannan Sadhasivam wrote:
> >> On Tue, Sep 24, 2024 at 04:26:34PM +0200, Konrad Dybcio wrote:
> >>> On 24.09.2024 12:14 PM, Qiang Yu wrote:
> >>>> Describe PCIe3 controller and PHY. Also add required system resources like
> >>>> regulators, clocks, interrupts and registers configuration for PCIe3.
> >>>>
> >>>> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> >>>> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> >>>> ---
> >>>
> >>> Qiang, Mani
> >>>
> >>> I have a RTS5261 mmc chip on PCIe3 on the Surface Laptop.
> >>
> >> Is it based on x1e80100?
> > 
> > You would think so :P
> > 
> >>
> >>> Adding the global irq breaks sdcard detection (the chip still comes
> >>> up fine) somehow. Removing the irq makes it work again :|
> >>>
> >>> I've confirmed that the irq number is correct
> >>>
> >>
> >> Yeah, I did see some issues with MSI on SM8250 (RB5) when global interrupts are
> >> enabled and I'm working with the hw folks to understand what is going on. But
> >> I didn't see the same issues on newer platforms (sa8775p etc...).
> >>
> >> Can you please confirm if the issue is due to MSI not being received from the
> >> device? Checking the /proc/interrutps is enough.
> > 
> > There's no msi-map for PCIe3. I recall +Johan talking about some sort of
> > a bug that prevents us from adding it?
> 

Yeah, that's for using GIC-ITS to receive MSIs. But the default one is the
internal MSI controller in DWC.

> Unless you just meant the msi0..=7 interrupts, then yeah, I only get one irq
> event with "global" in place and it seems to never get more
> 

Ok. Then most likely the same issue I saw on SM8250 as well. But I'm confused
why Qiang didn't see the issue. I specifically asked him to add the global
interrupt and test it with the endpoint to check if the issue arises or not.

Qiang, can you please confirm?

- Mani

-- 
????????? ????????


From krzk at kernel.org  Wed Sep 25 07:07:31 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 25 Sep 2024 16:07:31 +0200
Subject: [PATCH v3] dt-bindings: phy: Add QMP UFS PHY compatible for
 QCS8300
In-Reply-To: <20240925-qcs8300_ufs_phy_binding-v3-1-c1eb5c393b09@quicinc.com>
References: <20240925-qcs8300_ufs_phy_binding-v3-1-c1eb5c393b09@quicinc.com>
Message-ID: <0fcccdbe-ba46-4d0b-ab8b-ad659bec05d5@kernel.org>

On 25/09/2024 09:34, Jingyi Wang wrote:
> From: Xin Liu <quic_liuxin at quicinc.com>
> 
> Document the QMP UFS PHY compatible for Qualcomm QCS8300 to support
> physical layer functionality for UFS found on the SoC. Use fallback to
> indicate the compatibility of the QMP UFS PHY on the QCS8300 with that
> on the SA8775P.
> 
> Signed-off-by: Xin Liu <quic_liuxin at quicinc.com>
> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
> ---
> Changes in v3:
> - remove redundant compatible.
> - Link to v2: https://lore.kernel.org/r/20240911-qcs8300_ufs_phy_binding-v2-1-c801a2d27a84 at quicinc.com
> 
> Changes in v2:
> - decoupled from the original series.
> - Use fallback to indicate compatibility with SA8775P.
> - typo fixup
> - Link to v1: https://lore.kernel.org/r/20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007 at quicinc.com
> ---
>  .../bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml    | 45 ++++++++++++----------
>  1 file changed, 25 insertions(+), 20 deletions(-)
> 


Reviewed-by: Krzysztof Kozlowski <krzk at kernel.org>

Best regards,
Krzysztof



From quic_qianyu at quicinc.com  Wed Sep 25 20:15:34 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Thu, 26 Sep 2024 11:15:34 +0800
Subject: [PATCH v4 6/6] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <20240925125224.53g6rw46qufxsw6m@thinkpad>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-7-quic_qianyu@quicinc.com>
 <9a692c98-eb0a-4d86-b642-ea655981ff53@kernel.org>
 <20240925080522.qwjeyrpjtz64pccx@thinkpad>
 <4ee4d016-9d68-4925-9f49-e73a4e7fa794@kernel.org>
 <2731e17d-c1ad-4fb4-ab60-82ceafeffbaf@kernel.org>
 <20240925125224.53g6rw46qufxsw6m@thinkpad>
Message-ID: <1c6bf1a9-a781-4152-a7a1-7992c6f15829@quicinc.com>


On 9/25/2024 8:52 PM, Manivannan Sadhasivam wrote:
> On Wed, Sep 25, 2024 at 11:46:35AM +0200, Konrad Dybcio wrote:
>> On 25.09.2024 11:30 AM, Konrad Dybcio wrote:
>>> On 25.09.2024 10:05 AM, Manivannan Sadhasivam wrote:
>>>> On Tue, Sep 24, 2024 at 04:26:34PM +0200, Konrad Dybcio wrote:
>>>>> On 24.09.2024 12:14 PM, Qiang Yu wrote:
>>>>>> Describe PCIe3 controller and PHY. Also add required system resources like
>>>>>> regulators, clocks, interrupts and registers configuration for PCIe3.
>>>>>>
>>>>>> Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
>>>>>> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>>>>>> ---
>>>>> Qiang, Mani
>>>>>
>>>>> I have a RTS5261 mmc chip on PCIe3 on the Surface Laptop.
>>>> Is it based on x1e80100?
>>> You would think so :P
>>>
>>>>> Adding the global irq breaks sdcard detection (the chip still comes
>>>>> up fine) somehow. Removing the irq makes it work again :|
>>>>>
>>>>> I've confirmed that the irq number is correct
>>>>>
>>>> Yeah, I did see some issues with MSI on SM8250 (RB5) when global interrupts are
>>>> enabled and I'm working with the hw folks to understand what is going on. But
>>>> I didn't see the same issues on newer platforms (sa8775p etc...).
>>>>
>>>> Can you please confirm if the issue is due to MSI not being received from the
>>>> device? Checking the /proc/interrutps is enough.
>>> There's no msi-map for PCIe3. I recall +Johan talking about some sort of
>>> a bug that prevents us from adding it?
> Yeah, that's for using GIC-ITS to receive MSIs. But the default one is the
> internal MSI controller in DWC.
>
>> Unless you just meant the msi0..=7 interrupts, then yeah, I only get one irq
>> event with "global" in place and it seems to never get more
>>
> Ok. Then most likely the same issue I saw on SM8250 as well. But I'm confused
> why Qiang didn't see the issue. I specifically asked him to add the global
> interrupt and test it with the endpoint to check if the issue arises or not.
>
> Qiang, can you please confirm?
Sorry, I misunderstood what you mean. I only verified if link was up but 
ignored the status of ep device
driver.

But look like this issue is because snpsys MSI irq is msked during probe.
Can you please also unmask BIT(23) - BIT(30) when unmask 
PARF_INT_ALL_LINK_UP,
like this

@@ -1772,7 +1772,8 @@ static int qcom_pcie_probe(struct platform_device 
*pdev)
 ??????????????????????? goto err_host_deinit;
 ??????????????? }

-?????????????? writel_relaxed(PARF_INT_ALL_LINK_UP, pcie->parf + 
PARF_INT_ALL_MASK);
+?????????????? writel_relaxed(PARF_INT_ALL_LINK_UP | GENMASK(30, 23), 
pcie->parf + PARF_INT_ALL_MASK);
+?????????????? dev_err(dev, "INT_ALL_MASK: 0x%x\n", 
readl_relaxed(pcie->parf + PARF_INT_ALL_MASK));
 ??????? }

After that, this issue is fixed on my setup.

Thanks,
Qiang
>
> - Mani
>


From quic_qianyu at quicinc.com  Wed Sep 25 20:28:51 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Thu, 26 Sep 2024 11:28:51 +0800
Subject: [PATCH v4 5/6] PCI: qcom: Add support for X1E80100 SoC
In-Reply-To: <20240925080724.vgkgmnqc44aoiarv@thinkpad>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-6-quic_qianyu@quicinc.com>
 <20240924135021.ybpyoahlpuvedma5@thinkpad>
 <ZvLX_wkh7_y7sjPZ@hovoldconsulting.com>
 <4368503f-fb33-4e6a-bef4-517e2b959400@quicinc.com>
 <20240925080724.vgkgmnqc44aoiarv@thinkpad>
Message-ID: <1419ba07-5163-4126-8869-2213eea6c492@quicinc.com>


On 9/25/2024 4:07 PM, Manivannan Sadhasivam wrote:
> On Wed, Sep 25, 2024 at 11:47:02AM +0800, Qiang Yu wrote:
>> On 9/24/2024 11:17 PM, Johan Hovold wrote:
>>> On Tue, Sep 24, 2024 at 03:50:21PM +0200, Manivannan Sadhasivam wrote:
>>>> On Tue, Sep 24, 2024 at 03:14:43AM -0700, Qiang Yu wrote:
>>>>> X1E80100 has PCIe ports that support up to Gen4 x8 based on hardware IP
>>>>> version 1.38.0.
>>>>>
>>>>> Currently the ops_1_9_0 which is being used for X1E80100 has config_sid
>>>>> callback to config BDF to SID table. However, this callback is not
>>>>> required for X1E80100 because it has smmuv3 support and BDF to SID table
>>>>> will be not present.
>>>>>
>>>>> Hence add support for X1E80100 by introducing a new ops and cfg structures
>>>>> that don't require the config_sid callback. This could be reused by the
>>>>> future platforms based on SMMUv3.
>>>>>
>>>> Oops... I completely overlooked that you are not adding the SoC support but
>>>> fixing the existing one :( Sorry for suggesting a commit message that changed
>>>> the context.
>>>>
>>>> For this, you can have something like:
>>>>
>>>> "PCI: qcom: Fix the ops for X1E80100 SoC
>>>>
>>>> X1E80100 SoC is based on SMMUv3, hence it doesn't need the BDF2SID mapping
>>>> present in the existing cfg_1_9_0 ops. This is fixed by introducing new ops
>>>> 'ops_1_38_0' and cfg 'cfg_1_38_0' structures. These are exactly same as the
>>>> 1_9_0 ones, but they don't have the 'config_sid()' callback that handles the
>>>> BDF2SID mapping in the hardware. These new structures could also be used by the
>>>> future SoCs making use of SMMUv3."
>>> Don't we need something like this for sc8280xp and other platforms using
>>> SMMUv3 as well?
>>  From what I know, sc8280xp and other qcom platforms are not using SMMUv3.
> sc8280xp indeed has SMMUv3 for PCIe, but I'm not sure how it is configured. So
> not completely sure whether we can avoid the mapping table or not.
>
> Qiang, please check with the hw team and let us know.
Sure, will update once I get any response from hw team.

Thanks,
Qiang
>
> - Mani
>


From quic_qianyu at quicinc.com  Wed Sep 25 22:19:18 2024
From: quic_qianyu at quicinc.com (Qiang Yu)
Date: Thu, 26 Sep 2024 13:19:18 +0800
Subject: [PATCH v4 5/6] PCI: qcom: Add support for X1E80100 SoC
In-Reply-To: <1419ba07-5163-4126-8869-2213eea6c492@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-6-quic_qianyu@quicinc.com>
 <20240924135021.ybpyoahlpuvedma5@thinkpad>
 <ZvLX_wkh7_y7sjPZ@hovoldconsulting.com>
 <4368503f-fb33-4e6a-bef4-517e2b959400@quicinc.com>
 <20240925080724.vgkgmnqc44aoiarv@thinkpad>
 <1419ba07-5163-4126-8869-2213eea6c492@quicinc.com>
Message-ID: <fb40afe3-eb27-4136-8942-26a40fb395a7@quicinc.com>


On 9/26/2024 11:28 AM, Qiang Yu wrote:
>
> On 9/25/2024 4:07 PM, Manivannan Sadhasivam wrote:
>> On Wed, Sep 25, 2024 at 11:47:02AM +0800, Qiang Yu wrote:
>>> On 9/24/2024 11:17 PM, Johan Hovold wrote:
>>>> On Tue, Sep 24, 2024 at 03:50:21PM +0200, Manivannan Sadhasivam wrote:
>>>>> On Tue, Sep 24, 2024 at 03:14:43AM -0700, Qiang Yu wrote:
>>>>>> X1E80100 has PCIe ports that support up to Gen4 x8 based on 
>>>>>> hardware IP
>>>>>> version 1.38.0.
>>>>>>
>>>>>> Currently the ops_1_9_0 which is being used for X1E80100 has 
>>>>>> config_sid
>>>>>> callback to config BDF to SID table. However, this callback is not
>>>>>> required for X1E80100 because it has smmuv3 support and BDF to 
>>>>>> SID table
>>>>>> will be not present.
>>>>>>
>>>>>> Hence add support for X1E80100 by introducing a new ops and cfg 
>>>>>> structures
>>>>>> that don't require the config_sid callback. This could be reused 
>>>>>> by the
>>>>>> future platforms based on SMMUv3.
>>>>>>
>>>>> Oops... I completely overlooked that you are not adding the SoC 
>>>>> support but
>>>>> fixing the existing one :( Sorry for suggesting a commit message 
>>>>> that changed
>>>>> the context.
>>>>>
>>>>> For this, you can have something like:
>>>>>
>>>>> "PCI: qcom: Fix the ops for X1E80100 SoC
>>>>>
>>>>> X1E80100 SoC is based on SMMUv3, hence it doesn't need the BDF2SID 
>>>>> mapping
>>>>> present in the existing cfg_1_9_0 ops. This is fixed by 
>>>>> introducing new ops
>>>>> 'ops_1_38_0' and cfg 'cfg_1_38_0' structures. These are exactly 
>>>>> same as the
>>>>> 1_9_0 ones, but they don't have the 'config_sid()' callback that 
>>>>> handles the
>>>>> BDF2SID mapping in the hardware. These new structures could also 
>>>>> be used by the
>>>>> future SoCs making use of SMMUv3."
>>>> Don't we need something like this for sc8280xp and other platforms 
>>>> using
>>>> SMMUv3 as well?
>>> ?From what I know, sc8280xp and other qcom platforms are not using 
>>> SMMUv3.
>> sc8280xp indeed has SMMUv3 for PCIe, but I'm not sure how it is 
>> configured. So
>> not completely sure whether we can avoid the mapping table or not.
>>
>> Qiang, please check with the hw team and let us know.
> Sure, will update once I get any response from hw team.
HW team confirmed sc8280xp uses smmv3 for PCIe and doesn't support BDF2SID
map.

Besides, Abel once got confirmation from Joe that we also need to disable
L0s for X1E80100. So can we use cfg_sc8280xp for both X1E80100 and SC8280XP
and change its ops to ops_1_38_0?

Thanks,
Qiang
>
> Thanks,
> Qiang
>>
>> - Mani
>>


From xu.yang_2 at nxp.com  Thu Sep 26 00:39:46 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Thu, 26 Sep 2024 15:39:46 +0800
Subject: [PATCH 0/5] dtbs_check warning clean up against fsl,mxs-usbphy.yaml
Message-ID: <20240926073951.783869-1-xu.yang_2@nxp.com>

Some changes to clean up dtbs_check warning against fsl,mxs-usbphy.yaml.

The first 4 patches are used to fix below warning, "nxp,sim" is only
needed by i.MX7ULP:
 - 'nxp,sim' is a required property

The last patch is used to fix below warning:
 - fsl,tx-d-cal: 5 is less than the minimum of 79

Xu Yang (5):
  dt-bindings: phy: mxs-usb-phy: add imx8qxp compatible
  arm64: dts: imx8dxl-ss-conn: change usbphy1 compatible
  arm64: dts: imx8qm: change usbphy1 compatible
  arm64: dts: imx8qxp: change usbphy1 compatible
  ARM: dts: imx6qdl: convert fsl,tx-d-cal to correct value

 Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml | 1 +
 arch/arm/boot/dts/nxp/imx/imx6qdl-var-som.dtsi            | 4 ++--
 arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi        | 4 ++++
 arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi         | 4 ++++
 arch/arm64/boot/dts/freescale/imx8qxp-ss-conn.dtsi        | 4 ++++
 5 files changed, 15 insertions(+), 2 deletions(-)

-- 
2.34.1



From xu.yang_2 at nxp.com  Thu Sep 26 00:39:47 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Thu, 26 Sep 2024 15:39:47 +0800
Subject: [PATCH 1/5] dt-bindings: phy: mxs-usb-phy: add imx8qxp compatible
In-Reply-To: <20240926073951.783869-1-xu.yang_2@nxp.com>
References: <20240926073951.783869-1-xu.yang_2@nxp.com>
Message-ID: <20240926073951.783869-2-xu.yang_2@nxp.com>

Add "fsl,imx8qxp-usbphy" compatible.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
---
 Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml b/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml
index ce665a2779b7..d01b7d187040 100644
--- a/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml
+++ b/Documentation/devicetree/bindings/phy/fsl,mxs-usbphy.yaml
@@ -32,6 +32,7 @@ properties:
           - enum:
               - fsl,imx8dxl-usbphy
               - fsl,imx8qm-usbphy
+              - fsl,imx8qxp-usbphy
               - fsl,imx8ulp-usbphy
           - const: fsl,imx7ulp-usbphy
 
-- 
2.34.1



From xu.yang_2 at nxp.com  Thu Sep 26 00:39:48 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Thu, 26 Sep 2024 15:39:48 +0800
Subject: [PATCH 2/5] arm64: dts: imx8dxl-ss-conn: change usbphy1 compatible
In-Reply-To: <20240926073951.783869-1-xu.yang_2@nxp.com>
References: <20240926073951.783869-1-xu.yang_2@nxp.com>
Message-ID: <20240926073951.783869-3-xu.yang_2@nxp.com>

Make fsl,imx8dxl-usbphy compatible with fsl,imx7ulp-usbphy to fix below
warning:

/home/nxf75279/work/linux-next/arch/arm64/boot/dts/freescale/imx8dxl-evk.dtb: usbphy at 5b100000: 'nxp,sim' is a required property
        from schema $id: http://devicetree.org/schemas/phy/fsl,mxs-usbphy.yaml#

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi
index 1e02b04494e9..9b114bed084b 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi
@@ -138,6 +138,10 @@ &gpmi {
 	interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
 };
 
+&usbphy1 {
+	compatible = "fsl,imx8dxl-usbphy", "fsl,imx7ulp-usbphy";
+};
+
 &usdhc1 {
 	compatible = "fsl,imx8dxl-usdhc", "fsl,imx8qxp-usdhc";
 	interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.34.1



From xu.yang_2 at nxp.com  Thu Sep 26 00:39:49 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Thu, 26 Sep 2024 15:39:49 +0800
Subject: [PATCH 3/5] arm64: dts: imx8qm: change usbphy1 compatible
In-Reply-To: <20240926073951.783869-1-xu.yang_2@nxp.com>
References: <20240926073951.783869-1-xu.yang_2@nxp.com>
Message-ID: <20240926073951.783869-4-xu.yang_2@nxp.com>

Make fsl,imx8qm-usbphy compatible with fsl,imx7ulp-usbphy to fix below
warning:

/home/nxf75279/work/linux-next/arch/arm64/boot/dts/freescale/imx8qm-apalis-eval.dtb: usbphy at 5b100000: 'nxp,sim' is a required property
        from schema $id: http://devicetree.org/schemas/phy/fsl,mxs-usbphy.yaml#

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
index 545e175c88b3..ccf9f510e0f8 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
@@ -4,6 +4,10 @@
  *	Dong Aisheng <aisheng.dong at nxp.com>
  */
 
+&usbphy1 {
+	compatible = "fsl,imx8qm-usbphy", "fsl,imx7ulp-usbphy";
+};
+
 &fec1 {
 	compatible = "fsl,imx8qm-fec", "fsl,imx6sx-fec";
 	iommus = <&smmu 0x12 0x7f80>;
-- 
2.34.1



From xu.yang_2 at nxp.com  Thu Sep 26 00:39:50 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Thu, 26 Sep 2024 15:39:50 +0800
Subject: [PATCH 4/5] arm64: dts: imx8qxp: change usbphy1 compatible
In-Reply-To: <20240926073951.783869-1-xu.yang_2@nxp.com>
References: <20240926073951.783869-1-xu.yang_2@nxp.com>
Message-ID: <20240926073951.783869-5-xu.yang_2@nxp.com>

Make fsl,imx8qxp-usbphy compatible with fsl,imx7ulp-usbphy to fix below
warning:

/home/nxf75279/work/linux-next/arch/arm64/boot/dts/freescale/imx8qxp-colibri-aster.dtb: usbphy at 5b100000: 'nxp,sim' is a required property
        from schema $id: http://devicetree.org/schemas/phy/fsl,mxs-usbphy.yaml#

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8qxp-ss-conn.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-ss-conn.dtsi
index 46da21af3702..4eb48ad48745 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-ss-conn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-conn.dtsi
@@ -4,6 +4,10 @@
  *	Dong Aisheng <aisheng.dong at nxp.com>
  */
 
+&usbphy1 {
+	compatible = "fsl,imx8qxp-usbphy", "fsl,imx7ulp-usbphy";
+};
+
 &usdhc1 {
 	compatible = "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
 };
-- 
2.34.1



From xu.yang_2 at nxp.com  Thu Sep 26 00:39:51 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Thu, 26 Sep 2024 15:39:51 +0800
Subject: [PATCH 5/5] ARM: dts: imx6qdl: convert fsl,tx-d-cal to correct value
In-Reply-To: <20240926073951.783869-1-xu.yang_2@nxp.com>
References: <20240926073951.783869-1-xu.yang_2@nxp.com>
Message-ID: <20240926073951.783869-6-xu.yang_2@nxp.com>

make dtbs_check has below warning:

/home/nxf75279/work/usb/arch/arm/boot/dts/nxp/imx/imx6q-var-mx6customboard.dtb: usbphy at 20c9000: fsl,tx-d-cal: 5 is less than the minimum of 79
        from schema $id: http://devicetree.org/schemas/phy/fsl,mxs-usbphy.yaml#

According to schema, valid value of fsl,tx-d-cal is from 79 to 119. This
will convert register raw value <0x5> to corresponding <106>.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
---
 arch/arm/boot/dts/nxp/imx/imx6qdl-var-som.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-var-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-var-som.dtsi
index a1ea33c4eeb7..d3396cb81912 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-var-som.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-var-som.dtsi
@@ -529,11 +529,11 @@ &usbotg {
 };
 
 &usbphy1 {
-	fsl,tx-d-cal = <0x5>;
+	fsl,tx-d-cal = <106>;
 };
 
 &usbphy2 {
-	fsl,tx-d-cal = <0x5>;
+	fsl,tx-d-cal = <106>;
 };
 
 &usdhc1 {
-- 
2.34.1



From macpaul.lin at mediatek.com  Thu Sep 26 03:18:04 2024
From: macpaul.lin at mediatek.com (Macpaul Lin)
Date: Thu, 26 Sep 2024 18:18:04 +0800
Subject: [PATCH] dt-bindings: phy: mediatek: tphy: add a property for power-domains
Message-ID: <20240926101804.22471-1-macpaul.lin@mediatek.com>

Some platforms requires a dependency for power-domains.
So we add property 'power-domains' and set 'maxItems: 1' in the
DT Schema.

Signed-off-by: Macpaul Lin <macpaul.lin at mediatek.com>
---
 Documentation/devicetree/bindings/phy/mediatek,tphy.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
index 423b7c4e62f2..c77fe43c224a 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
@@ -125,6 +125,9 @@ properties:
     $ref: /schemas/types.yaml#/definitions/uint32
     default: 28
 
+  power-domains:
+    maxItems: 1
+
 # Required child node:
 patternProperties:
   "^(usb|pcie|sata)-phy@[0-9a-f]+$":
-- 
2.45.2



From angelogioacchino.delregno at collabora.com  Thu Sep 26 03:20:44 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 26 Sep 2024 12:20:44 +0200
Subject: [PATCH] dt-bindings: phy: mediatek: tphy: add a property for
 power-domains
In-Reply-To: <20240926101804.22471-1-macpaul.lin@mediatek.com>
References: <20240926101804.22471-1-macpaul.lin@mediatek.com>
Message-ID: <7b7605c4-aa8a-4e03-95c1-386bc5f1669a@collabora.com>

Il 26/09/24 12:18, Macpaul Lin ha scritto:
> Some platforms requires a dependency for power-domains.
> So we add property 'power-domains' and set 'maxItems: 1' in the
> DT Schema.
> 
> Signed-off-by: Macpaul Lin <macpaul.lin at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From frawang.cn at gmail.com  Thu Sep 26 03:32:22 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Thu, 26 Sep 2024 18:32:22 +0800
Subject: [PATCH v3 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add rk3576
Message-ID: <20240926103223.29538-1-frawang.cn@gmail.com>

From: Frank Wang <frank.wang at rock-chips.com>

Add compatible for the USB2 phy in the Rockchip RK3576 SoC.

In addition, since the RK3576 introduced the USB MMU, this change
also add the related clock properties for it.

Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
---
Changelog:
v3:
 - narrowed rk3576 clocks by compatible property.

v2:
 - Categorize clock names by oneOf keyword.

v1:
 - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-1-frank.wang at rock-chips.com/

 .../bindings/phy/rockchip,inno-usb2phy.yaml    | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
index 5254413137c6..d286753bd53f 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
@@ -20,6 +20,7 @@ properties:
       - rockchip,rk3366-usb2phy
       - rockchip,rk3399-usb2phy
       - rockchip,rk3568-usb2phy
+      - rockchip,rk3576-usb2phy
       - rockchip,rk3588-usb2phy
       - rockchip,rv1108-usb2phy
 
@@ -143,6 +144,7 @@ allOf:
           contains:
             enum:
               - rockchip,rk3568-usb2phy
+              - rockchip,rk3576-usb2phy
               - rockchip,rk3588-usb2phy
 
     then:
@@ -171,6 +173,22 @@ allOf:
           required:
             - interrupts
             - interrupt-names
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - rockchip,rk3576-usb2phy
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: phyclk
+            - const: aclk
+            - const: aclk_slv
 
 additionalProperties: false
 
-- 
2.34.1



From frawang.cn at gmail.com  Thu Sep 26 03:32:23 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Thu, 26 Sep 2024 18:32:23 +0800
Subject: [PATCH v3 2/2] phy: rockchip: inno-usb2: Add usb2 phys support for rk3576
In-Reply-To: <20240926103223.29538-1-frawang.cn@gmail.com>
References: <20240926103223.29538-1-frawang.cn@gmail.com>
Message-ID: <20240926103223.29538-2-frawang.cn@gmail.com>

From: William Wu <william.wu at rock-chips.com>

The RK3576 SoC has two independent USB2.0 PHYs, and each PHY has
one port.

This change also converts the clock management from single to bulk
as some Rockchip SoCs (e.g RK3576) have more than one clock.

Signed-off-by: William Wu <william.wu at rock-chips.com>
Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
---
Changelog:
v3:
 - amend the commit log adds clocks converting.
 - retrieve the clock by "clks.id" in *_clk480m_register() function.

v2:
 - no changes.
v1:
 - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-2-frank.wang at rock-chips.com/

 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 139 +++++++++++++++++-
 1 file changed, 131 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 4f71373ae6e1..642c7857c5ae 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -229,9 +229,10 @@ struct rockchip_usb2phy_port {
  * @dev: pointer to device.
  * @grf: General Register Files regmap.
  * @usbgrf: USB General Register Files regmap.
- * @clk: clock struct of phy input clk.
+ * @clks: array of phy input clocks.
  * @clk480m: clock struct of phy output clk.
  * @clk480m_hw: clock struct of phy output clk management.
+ * @num_clks: number of phy input clocks.
  * @phy_reset: phy reset control.
  * @chg_state: states involved in USB charger detection.
  * @chg_type: USB charger types.
@@ -246,9 +247,10 @@ struct rockchip_usb2phy {
 	struct device	*dev;
 	struct regmap	*grf;
 	struct regmap	*usbgrf;
-	struct clk	*clk;
+	struct clk_bulk_data	*clks;
 	struct clk	*clk480m;
 	struct clk_hw	clk480m_hw;
+	int			num_clks;
 	struct reset_control	*phy_reset;
 	enum usb_chg_state	chg_state;
 	enum power_supply_type	chg_type;
@@ -376,7 +378,9 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
 {
 	struct device_node *node = rphy->dev->of_node;
 	struct clk_init_data init;
+	struct clk *refclk = NULL;
 	const char *clk_name;
+	int i;
 	int ret = 0;
 
 	init.flags = 0;
@@ -386,8 +390,15 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
 	/* optional override of the clockname */
 	of_property_read_string(node, "clock-output-names", &init.name);
 
-	if (rphy->clk) {
-		clk_name = __clk_get_name(rphy->clk);
+	for (i = 0; i < rphy->num_clks; i++) {
+		if (!strncmp(rphy->clks[i].id, "phyclk", 6)) {
+			refclk = rphy->clks[i].clk;
+			break;
+		}
+	}
+
+	if (!IS_ERR(refclk)) {
+		clk_name = __clk_get_name(refclk);
 		init.parent_names = &clk_name;
 		init.num_parents = 1;
 	} else {
@@ -1406,22 +1417,29 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 	if (IS_ERR(rphy->phy_reset))
 		return PTR_ERR(rphy->phy_reset);
 
-	rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk");
-	if (IS_ERR(rphy->clk)) {
-		return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk),
+	ret = devm_clk_bulk_get_all(dev, &rphy->clks);
+	if (ret == -EPROBE_DEFER) {
+		return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
 				     "failed to get phyclk\n");
 	}
 
+	/* Clocks are optional */
+	rphy->num_clks = ret < 0 ? 0 : ret;
+
 	ret = rockchip_usb2phy_clk480m_register(rphy);
 	if (ret) {
 		dev_err(dev, "failed to register 480m output clock\n");
 		return ret;
 	}
 
+	ret = clk_bulk_prepare_enable(rphy->num_clks, rphy->clks);
+	if (ret)
+		return ret;
+
 	if (rphy->phy_cfg->phy_tuning) {
 		ret = rphy->phy_cfg->phy_tuning(rphy);
 		if (ret)
-			return ret;
+			goto disable_clks;
 	}
 
 	index = 0;
@@ -1484,6 +1502,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 
 put_child:
 	of_node_put(child_np);
+disable_clks:
+	clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks);
 	return ret;
 }
 
@@ -1495,6 +1515,30 @@ static int rk3128_usb2phy_tuning(struct rockchip_usb2phy *rphy)
 				BIT(2) << BIT_WRITEABLE_SHIFT | 0);
 }
 
+static int rk3576_usb2phy_tuning(struct rockchip_usb2phy *rphy)
+{
+	int ret;
+	u32 reg = rphy->phy_cfg->reg;
+
+	/* Deassert SIDDQ to power on analog block */
+	ret = regmap_write(rphy->grf, reg + 0x0010, GENMASK(29, 29) | 0x0000);
+	if (ret)
+		return ret;
+
+	/* Do reset after exit IDDQ mode */
+	ret = rockchip_usb2phy_reset(rphy);
+	if (ret)
+		return ret;
+
+	/* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */
+	ret |= regmap_write(rphy->grf, reg + 0x000c, GENMASK(27, 24) | 0x0900);
+
+	/* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
+	ret |= regmap_write(rphy->grf, reg + 0x0010, GENMASK(20, 19) | 0x0010);
+
+	return ret;
+}
+
 static int rk3588_usb2phy_tuning(struct rockchip_usb2phy *rphy)
 {
 	int ret;
@@ -1923,6 +1967,84 @@ static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
 	{ /* sentinel */ }
 };
 
+static const struct rockchip_usb2phy_cfg rk3576_phy_cfgs[] = {
+	{
+		.reg = 0x0,
+		.num_ports	= 1,
+		.phy_tuning	= rk3576_usb2phy_tuning,
+		.clkout_ctl	= { 0x0008, 0, 0, 1, 0 },
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x0000, 8, 0, 0, 0x1d1 },
+				.bvalid_det_en	= { 0x00c0, 1, 1, 0, 1 },
+				.bvalid_det_st	= { 0x00c4, 1, 1, 0, 1 },
+				.bvalid_det_clr = { 0x00c8, 1, 1, 0, 1 },
+				.ls_det_en	= { 0x00c0, 0, 0, 0, 1 },
+				.ls_det_st	= { 0x00c4, 0, 0, 0, 1 },
+				.ls_det_clr	= { 0x00c8, 0, 0, 0, 1 },
+				.disfall_en	= { 0x00c0, 6, 6, 0, 1 },
+				.disfall_st	= { 0x00c4, 6, 6, 0, 1 },
+				.disfall_clr	= { 0x00c8, 6, 6, 0, 1 },
+				.disrise_en	= { 0x00c0, 5, 5, 0, 1 },
+				.disrise_st	= { 0x00c4, 5, 5, 0, 1 },
+				.disrise_clr	= { 0x00c8, 5, 5, 0, 1 },
+				.utmi_avalid	= { 0x0080, 1, 1, 0, 1 },
+				.utmi_bvalid	= { 0x0080, 0, 0, 0, 1 },
+				.utmi_ls	= { 0x0080, 5, 4, 0, 1 },
+			}
+		},
+		.chg_det = {
+			.cp_det		= { 0x0080, 8, 8, 0, 1 },
+			.dcp_det	= { 0x0080, 8, 8, 0, 1 },
+			.dp_det		= { 0x0080, 9, 9, 1, 0 },
+			.idm_sink_en	= { 0x0010, 5, 5, 1, 0 },
+			.idp_sink_en	= { 0x0010, 5, 5, 0, 1 },
+			.idp_src_en	= { 0x0010, 14, 14, 0, 1 },
+			.rdm_pdwn_en	= { 0x0010, 14, 14, 0, 1 },
+			.vdm_src_en	= { 0x0010, 7, 6, 0, 3 },
+			.vdp_src_en	= { 0x0010, 7, 6, 0, 3 },
+		},
+	},
+	{
+		.reg = 0x2000,
+		.num_ports	= 1,
+		.phy_tuning	= rk3576_usb2phy_tuning,
+		.clkout_ctl	= { 0x2008, 0, 0, 1, 0 },
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x2000, 8, 0, 0, 0x1d1 },
+				.bvalid_det_en	= { 0x20c0, 1, 1, 0, 1 },
+				.bvalid_det_st	= { 0x20c4, 1, 1, 0, 1 },
+				.bvalid_det_clr = { 0x20c8, 1, 1, 0, 1 },
+				.ls_det_en	= { 0x20c0, 0, 0, 0, 1 },
+				.ls_det_st	= { 0x20c4, 0, 0, 0, 1 },
+				.ls_det_clr	= { 0x20c8, 0, 0, 0, 1 },
+				.disfall_en	= { 0x20c0, 6, 6, 0, 1 },
+				.disfall_st	= { 0x20c4, 6, 6, 0, 1 },
+				.disfall_clr	= { 0x20c8, 6, 6, 0, 1 },
+				.disrise_en	= { 0x20c0, 5, 5, 0, 1 },
+				.disrise_st	= { 0x20c4, 5, 5, 0, 1 },
+				.disrise_clr	= { 0x20c8, 5, 5, 0, 1 },
+				.utmi_avalid	= { 0x2080, 1, 1, 0, 1 },
+				.utmi_bvalid	= { 0x2080, 0, 0, 0, 1 },
+				.utmi_ls	= { 0x2080, 5, 4, 0, 1 },
+			}
+		},
+		.chg_det = {
+			.cp_det		= { 0x2080, 8, 8, 0, 1 },
+			.dcp_det	= { 0x2080, 8, 8, 0, 1 },
+			.dp_det		= { 0x2080, 9, 9, 1, 0 },
+			.idm_sink_en	= { 0x2010, 5, 5, 1, 0 },
+			.idp_sink_en	= { 0x2010, 5, 5, 0, 1 },
+			.idp_src_en	= { 0x2010, 14, 14, 0, 1 },
+			.rdm_pdwn_en	= { 0x2010, 14, 14, 0, 1 },
+			.vdm_src_en	= { 0x2010, 7, 6, 0, 3 },
+			.vdp_src_en	= { 0x2010, 7, 6, 0, 3 },
+		},
+	},
+	{ /* sentinel */ }
+};
+
 static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
 	{
 		.reg = 0x0000,
@@ -2094,6 +2216,7 @@ static const struct of_device_id rockchip_usb2phy_dt_match[] = {
 	{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
 	{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
 	{ .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
+	{ .compatible = "rockchip,rk3576-usb2phy", .data = &rk3576_phy_cfgs },
 	{ .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs },
 	{ .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
 	{}
-- 
2.34.1



From heiko at sntech.de  Thu Sep 26 03:48:36 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 26 Sep 2024 12:48:36 +0200
Subject: [PATCH v3 2/2] phy: rockchip: inno-usb2: Add usb2 phys support for rk3576
In-Reply-To: <20240926103223.29538-2-frawang.cn@gmail.com>
References: <20240926103223.29538-1-frawang.cn@gmail.com>
 <20240926103223.29538-2-frawang.cn@gmail.com>
Message-ID: <10867555.aFP6jjVeTY@phil>

Am Donnerstag, 26. September 2024, 12:32:23 CEST schrieb Frank Wang:
> From: William Wu <william.wu at rock-chips.com>
> 
> The RK3576 SoC has two independent USB2.0 PHYs, and each PHY has
> one port.
> 
> This change also converts the clock management from single to bulk
> as some Rockchip SoCs (e.g RK3576) have more than one clock.
> 
> Signed-off-by: William Wu <william.wu at rock-chips.com>
> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
> ---
> Changelog:
> v3:
>  - amend the commit log adds clocks converting.
>  - retrieve the clock by "clks.id" in *_clk480m_register() function.
> 
> v2:
>  - no changes.
> v1:
>  - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-2-frank.wang at rock-chips.com/
> 
>  drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 139 +++++++++++++++++-
>  1 file changed, 131 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> index 4f71373ae6e1..642c7857c5ae 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> @@ -229,9 +229,10 @@ struct rockchip_usb2phy_port {
>   * @dev: pointer to device.
>   * @grf: General Register Files regmap.
>   * @usbgrf: USB General Register Files regmap.
> - * @clk: clock struct of phy input clk.
> + * @clks: array of phy input clocks.
>   * @clk480m: clock struct of phy output clk.
>   * @clk480m_hw: clock struct of phy output clk management.
> + * @num_clks: number of phy input clocks.
>   * @phy_reset: phy reset control.
>   * @chg_state: states involved in USB charger detection.
>   * @chg_type: USB charger types.
> @@ -246,9 +247,10 @@ struct rockchip_usb2phy {
>  	struct device	*dev;
>  	struct regmap	*grf;
>  	struct regmap	*usbgrf;
> -	struct clk	*clk;
> +	struct clk_bulk_data	*clks;
>  	struct clk	*clk480m;
>  	struct clk_hw	clk480m_hw;
> +	int			num_clks;
>  	struct reset_control	*phy_reset;
>  	enum usb_chg_state	chg_state;
>  	enum power_supply_type	chg_type;
> @@ -376,7 +378,9 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
>  {
>  	struct device_node *node = rphy->dev->of_node;
>  	struct clk_init_data init;
> +	struct clk *refclk = NULL;
>  	const char *clk_name;
> +	int i;
>  	int ret = 0;
>  
>  	init.flags = 0;
> @@ -386,8 +390,15 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
>  	/* optional override of the clockname */
>  	of_property_read_string(node, "clock-output-names", &init.name);
>  
> -	if (rphy->clk) {
> -		clk_name = __clk_get_name(rphy->clk);
> +	for (i = 0; i < rphy->num_clks; i++) {
> +		if (!strncmp(rphy->clks[i].id, "phyclk", 6)) {
> +			refclk = rphy->clks[i].clk;
> +			break;
> +		}
> +	}
> +
> +	if (!IS_ERR(refclk)) {
> +		clk_name = __clk_get_name(refclk);
>  		init.parent_names = &clk_name;
>  		init.num_parents = 1;
>  	} else {
> @@ -1406,22 +1417,29 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
>  	if (IS_ERR(rphy->phy_reset))
>  		return PTR_ERR(rphy->phy_reset);
>  
> -	rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk");
> -	if (IS_ERR(rphy->clk)) {
> -		return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk),
> +	ret = devm_clk_bulk_get_all(dev, &rphy->clks);
> +	if (ret == -EPROBE_DEFER) {
> +		return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
>  				     "failed to get phyclk\n");
>  	}
>  
> +	/* Clocks are optional */
> +	rphy->num_clks = ret < 0 ? 0 : ret;
> +
>  	ret = rockchip_usb2phy_clk480m_register(rphy);
>  	if (ret) {
>  		dev_err(dev, "failed to register 480m output clock\n");
>  		return ret;
>  	}
>  
> +	ret = clk_bulk_prepare_enable(rphy->num_clks, rphy->clks);
> +	if (ret)
> +		return ret;
> +

Do you actually need that separate enable step?
There exists devm_clk_bulk_get_all_enable() 

https://elixir.bootlin.com/linux/v6.11/source/include/linux/clk.h#L511

which you could use above. Especially as otherwise you'd need a remove
callback to disable the clock on driver unbind?


>  	if (rphy->phy_cfg->phy_tuning) {
>  		ret = rphy->phy_cfg->phy_tuning(rphy);
>  		if (ret)
> -			return ret;
> +			goto disable_clks;
>  	}
>  
>  	index = 0;
> @@ -1484,6 +1502,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
>  
>  put_child:
>  	of_node_put(child_np);
> +disable_clks:
> +	clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks);
>  	return ret;
>  }
>  
> @@ -1495,6 +1515,30 @@ static int rk3128_usb2phy_tuning(struct rockchip_usb2phy *rphy)
>  				BIT(2) << BIT_WRITEABLE_SHIFT | 0);
>  }


I still maintain, that this maybe should be two separate patches.
And you even seem to have nice "cut-here" in it ;-)

The code above converts the driver to use clk_bulk to handle
multiple clocks for controller variants needing it.


And the code below adds the rk3576-specific data to the driver.



> +static int rk3576_usb2phy_tuning(struct rockchip_usb2phy *rphy)
> +{
> +	int ret;
> +	u32 reg = rphy->phy_cfg->reg;
> +
> +	/* Deassert SIDDQ to power on analog block */
> +	ret = regmap_write(rphy->grf, reg + 0x0010, GENMASK(29, 29) | 0x0000);
> +	if (ret)
> +		return ret;
> +
> +	/* Do reset after exit IDDQ mode */
> +	ret = rockchip_usb2phy_reset(rphy);
> +	if (ret)
> +		return ret;
> +
> +	/* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */
> +	ret |= regmap_write(rphy->grf, reg + 0x000c, GENMASK(27, 24) | 0x0900);
> +
> +	/* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
> +	ret |= regmap_write(rphy->grf, reg + 0x0010, GENMASK(20, 19) | 0x0010);
> +
> +	return ret;
> +}
> +
>  static int rk3588_usb2phy_tuning(struct rockchip_usb2phy *rphy)
>  {
>  	int ret;
> @@ -1923,6 +1967,84 @@ static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
>  	{ /* sentinel */ }
>  };
>  
> +static const struct rockchip_usb2phy_cfg rk3576_phy_cfgs[] = {
> +	{
> +		.reg = 0x0,
> +		.num_ports	= 1,
> +		.phy_tuning	= rk3576_usb2phy_tuning,
> +		.clkout_ctl	= { 0x0008, 0, 0, 1, 0 },
> +		.port_cfgs	= {
> +			[USB2PHY_PORT_OTG] = {
> +				.phy_sus	= { 0x0000, 8, 0, 0, 0x1d1 },
> +				.bvalid_det_en	= { 0x00c0, 1, 1, 0, 1 },
> +				.bvalid_det_st	= { 0x00c4, 1, 1, 0, 1 },
> +				.bvalid_det_clr = { 0x00c8, 1, 1, 0, 1 },
> +				.ls_det_en	= { 0x00c0, 0, 0, 0, 1 },
> +				.ls_det_st	= { 0x00c4, 0, 0, 0, 1 },
> +				.ls_det_clr	= { 0x00c8, 0, 0, 0, 1 },
> +				.disfall_en	= { 0x00c0, 6, 6, 0, 1 },
> +				.disfall_st	= { 0x00c4, 6, 6, 0, 1 },
> +				.disfall_clr	= { 0x00c8, 6, 6, 0, 1 },
> +				.disrise_en	= { 0x00c0, 5, 5, 0, 1 },
> +				.disrise_st	= { 0x00c4, 5, 5, 0, 1 },
> +				.disrise_clr	= { 0x00c8, 5, 5, 0, 1 },
> +				.utmi_avalid	= { 0x0080, 1, 1, 0, 1 },
> +				.utmi_bvalid	= { 0x0080, 0, 0, 0, 1 },
> +				.utmi_ls	= { 0x0080, 5, 4, 0, 1 },
> +			}
> +		},
> +		.chg_det = {
> +			.cp_det		= { 0x0080, 8, 8, 0, 1 },
> +			.dcp_det	= { 0x0080, 8, 8, 0, 1 },
> +			.dp_det		= { 0x0080, 9, 9, 1, 0 },
> +			.idm_sink_en	= { 0x0010, 5, 5, 1, 0 },
> +			.idp_sink_en	= { 0x0010, 5, 5, 0, 1 },
> +			.idp_src_en	= { 0x0010, 14, 14, 0, 1 },
> +			.rdm_pdwn_en	= { 0x0010, 14, 14, 0, 1 },
> +			.vdm_src_en	= { 0x0010, 7, 6, 0, 3 },
> +			.vdp_src_en	= { 0x0010, 7, 6, 0, 3 },
> +		},
> +	},
> +	{
> +		.reg = 0x2000,
> +		.num_ports	= 1,
> +		.phy_tuning	= rk3576_usb2phy_tuning,
> +		.clkout_ctl	= { 0x2008, 0, 0, 1, 0 },
> +		.port_cfgs	= {
> +			[USB2PHY_PORT_OTG] = {
> +				.phy_sus	= { 0x2000, 8, 0, 0, 0x1d1 },
> +				.bvalid_det_en	= { 0x20c0, 1, 1, 0, 1 },
> +				.bvalid_det_st	= { 0x20c4, 1, 1, 0, 1 },
> +				.bvalid_det_clr = { 0x20c8, 1, 1, 0, 1 },
> +				.ls_det_en	= { 0x20c0, 0, 0, 0, 1 },
> +				.ls_det_st	= { 0x20c4, 0, 0, 0, 1 },
> +				.ls_det_clr	= { 0x20c8, 0, 0, 0, 1 },
> +				.disfall_en	= { 0x20c0, 6, 6, 0, 1 },
> +				.disfall_st	= { 0x20c4, 6, 6, 0, 1 },
> +				.disfall_clr	= { 0x20c8, 6, 6, 0, 1 },
> +				.disrise_en	= { 0x20c0, 5, 5, 0, 1 },
> +				.disrise_st	= { 0x20c4, 5, 5, 0, 1 },
> +				.disrise_clr	= { 0x20c8, 5, 5, 0, 1 },
> +				.utmi_avalid	= { 0x2080, 1, 1, 0, 1 },
> +				.utmi_bvalid	= { 0x2080, 0, 0, 0, 1 },
> +				.utmi_ls	= { 0x2080, 5, 4, 0, 1 },
> +			}
> +		},
> +		.chg_det = {
> +			.cp_det		= { 0x2080, 8, 8, 0, 1 },
> +			.dcp_det	= { 0x2080, 8, 8, 0, 1 },
> +			.dp_det		= { 0x2080, 9, 9, 1, 0 },
> +			.idm_sink_en	= { 0x2010, 5, 5, 1, 0 },
> +			.idp_sink_en	= { 0x2010, 5, 5, 0, 1 },
> +			.idp_src_en	= { 0x2010, 14, 14, 0, 1 },
> +			.rdm_pdwn_en	= { 0x2010, 14, 14, 0, 1 },
> +			.vdm_src_en	= { 0x2010, 7, 6, 0, 3 },
> +			.vdp_src_en	= { 0x2010, 7, 6, 0, 3 },
> +		},
> +	},
> +	{ /* sentinel */ }
> +};
> +
>  static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
>  	{
>  		.reg = 0x0000,
> @@ -2094,6 +2216,7 @@ static const struct of_device_id rockchip_usb2phy_dt_match[] = {
>  	{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
>  	{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
>  	{ .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
> +	{ .compatible = "rockchip,rk3576-usb2phy", .data = &rk3576_phy_cfgs },
>  	{ .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs },
>  	{ .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
>  	{}
> 






From krzk at kernel.org  Thu Sep 26 07:19:19 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 26 Sep 2024 16:19:19 +0200
Subject: [PATCH v3 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <20240926103223.29538-1-frawang.cn@gmail.com>
References: <20240926103223.29538-1-frawang.cn@gmail.com>
Message-ID: <ed829240-d4f7-471f-84f6-3509f87f11a1@kernel.org>

On 26/09/2024 12:32, Frank Wang wrote:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - rockchip,rk3576-usb2phy
> +    then:
> +      properties:
> +        clocks:
> +          minItems: 3
> +          maxItems: 3

Read one more time the example I gave you. Top-level constraints are
saying max one clock.

Best regards,
Krzysztof



From conor at kernel.org  Thu Sep 26 09:05:39 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 26 Sep 2024 17:05:39 +0100
Subject: [PATCH 1/5] dt-bindings: phy: mxs-usb-phy: add imx8qxp compatible
In-Reply-To: <20240926073951.783869-2-xu.yang_2@nxp.com>
References: <20240926073951.783869-1-xu.yang_2@nxp.com>
 <20240926073951.783869-2-xu.yang_2@nxp.com>
Message-ID: <20240926-avid-underwire-b10f52de08e0@spud>

On Thu, Sep 26, 2024 at 03:39:47PM +0800, Xu Yang wrote:
> Add "fsl,imx8qxp-usbphy" compatible.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20240926/5501f4e1/attachment.sig>

From conor at kernel.org  Thu Sep 26 09:25:16 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 26 Sep 2024 17:25:16 +0100
Subject: [PATCH] dt-bindings: phy: mediatek: tphy: add a property for
 power-domains
In-Reply-To: <20240926101804.22471-1-macpaul.lin@mediatek.com>
References: <20240926101804.22471-1-macpaul.lin@mediatek.com>
Message-ID: <20240926-treadmill-purr-b2e3279a14a4@spud>

On Thu, Sep 26, 2024 at 06:18:04PM +0800, Macpaul Lin wrote:
> Some platforms requires a dependency for power-domains.

Some, so not all? Why isn't this restricted on a per compatible basis?

> So we add property 'power-domains' and set 'maxItems: 1' in the
> DT Schema.
> 
> Signed-off-by: Macpaul Lin <macpaul.lin at mediatek.com>
> ---
>  Documentation/devicetree/bindings/phy/mediatek,tphy.yaml | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
> index 423b7c4e62f2..c77fe43c224a 100644
> --- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
> +++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
> @@ -125,6 +125,9 @@ properties:
>      $ref: /schemas/types.yaml#/definitions/uint32
>      default: 28
>  
> +  power-domains:
> +    maxItems: 1
> +
>  # Required child node:
>  patternProperties:
>    "^(usb|pcie|sata)-phy@[0-9a-f]+$":
> -- 
> 2.45.2
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20240926/aa3d5717/attachment.sig>

From frawang.cn at gmail.com  Thu Sep 26 23:16:42 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Fri, 27 Sep 2024 14:16:42 +0800
Subject: [PATCH v3 2/2] phy: rockchip: inno-usb2: Add usb2 phys support
 for rk3576
In-Reply-To: <10867555.aFP6jjVeTY@phil>
References: <20240926103223.29538-1-frawang.cn@gmail.com>
 <20240926103223.29538-2-frawang.cn@gmail.com> <10867555.aFP6jjVeTY@phil>
Message-ID: <9cc2d594-a930-4c4a-86ee-47228af28936@gmail.com>

Hi Heiko,

On 2024/9/26 18:48, Heiko Stuebner wrote:
> Am Donnerstag, 26. September 2024, 12:32:23 CEST schrieb Frank Wang:
>> From: William Wu <william.wu at rock-chips.com>
>>
>> The RK3576 SoC has two independent USB2.0 PHYs, and each PHY has
>> one port.
>>
>> This change also converts the clock management from single to bulk
>> as some Rockchip SoCs (e.g RK3576) have more than one clock.
>>
>> Signed-off-by: William Wu <william.wu at rock-chips.com>
>> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
>> ---
>> Changelog:
>> v3:
>>   - amend the commit log adds clocks converting.
>>   - retrieve the clock by "clks.id" in *_clk480m_register() function.
>>
>> v2:
>>   - no changes.
>> v1:
>>   - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-2-frank.wang at rock-chips.com/
>>
>>   drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 139 +++++++++++++++++-
>>   1 file changed, 131 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
>> index 4f71373ae6e1..642c7857c5ae 100644
>> --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
>> +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
>> @@ -229,9 +229,10 @@ struct rockchip_usb2phy_port {
>>    * @dev: pointer to device.
>>    * @grf: General Register Files regmap.
>>    * @usbgrf: USB General Register Files regmap.
>> - * @clk: clock struct of phy input clk.
>> + * @clks: array of phy input clocks.
>>    * @clk480m: clock struct of phy output clk.
>>    * @clk480m_hw: clock struct of phy output clk management.
>> + * @num_clks: number of phy input clocks.
>>    * @phy_reset: phy reset control.
>>    * @chg_state: states involved in USB charger detection.
>>    * @chg_type: USB charger types.
>> @@ -246,9 +247,10 @@ struct rockchip_usb2phy {
>>   	struct device	*dev;
>>   	struct regmap	*grf;
>>   	struct regmap	*usbgrf;
>> -	struct clk	*clk;
>> +	struct clk_bulk_data	*clks;
>>   	struct clk	*clk480m;
>>   	struct clk_hw	clk480m_hw;
>> +	int			num_clks;
>>   	struct reset_control	*phy_reset;
>>   	enum usb_chg_state	chg_state;
>>   	enum power_supply_type	chg_type;
>> @@ -376,7 +378,9 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
>>   {
>>   	struct device_node *node = rphy->dev->of_node;
>>   	struct clk_init_data init;
>> +	struct clk *refclk = NULL;
>>   	const char *clk_name;
>> +	int i;
>>   	int ret = 0;
>>   
>>   	init.flags = 0;
>> @@ -386,8 +390,15 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
>>   	/* optional override of the clockname */
>>   	of_property_read_string(node, "clock-output-names", &init.name);
>>   
>> -	if (rphy->clk) {
>> -		clk_name = __clk_get_name(rphy->clk);
>> +	for (i = 0; i < rphy->num_clks; i++) {
>> +		if (!strncmp(rphy->clks[i].id, "phyclk", 6)) {
>> +			refclk = rphy->clks[i].clk;
>> +			break;
>> +		}
>> +	}
>> +
>> +	if (!IS_ERR(refclk)) {
>> +		clk_name = __clk_get_name(refclk);
>>   		init.parent_names = &clk_name;
>>   		init.num_parents = 1;
>>   	} else {
>> @@ -1406,22 +1417,29 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
>>   	if (IS_ERR(rphy->phy_reset))
>>   		return PTR_ERR(rphy->phy_reset);
>>   
>> -	rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk");
>> -	if (IS_ERR(rphy->clk)) {
>> -		return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk),
>> +	ret = devm_clk_bulk_get_all(dev, &rphy->clks);
>> +	if (ret == -EPROBE_DEFER) {
>> +		return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
>>   				     "failed to get phyclk\n");
>>   	}
>>   
>> +	/* Clocks are optional */
>> +	rphy->num_clks = ret < 0 ? 0 : ret;
>> +
>>   	ret = rockchip_usb2phy_clk480m_register(rphy);
>>   	if (ret) {
>>   		dev_err(dev, "failed to register 480m output clock\n");
>>   		return ret;
>>   	}
>>   
>> +	ret = clk_bulk_prepare_enable(rphy->num_clks, rphy->clks);
>> +	if (ret)
>> +		return ret;
>> +
> Do you actually need that separate enable step?
> There exists devm_clk_bulk_get_all_enable()
>
> https://elixir.bootlin.com/linux/v6.11/source/include/linux/clk.h#L511
>
> which you could use above. Especially as otherwise you'd need a remove
> callback to disable the clock on driver unbind?
>

Using devm_clk_bulk_get_all() just can get clocknumbers, 
anddevm_clk_bulk_get_all_enable() is not.
It seems that there is no other API can get the number of clocks separately.


>>   	if (rphy->phy_cfg->phy_tuning) {
>>   		ret = rphy->phy_cfg->phy_tuning(rphy);
>>   		if (ret)
>> -			return ret;
>> +			goto disable_clks;
>>   	}
>>   
>>   	index = 0;
>> @@ -1484,6 +1502,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
>>   
>>   put_child:
>>   	of_node_put(child_np);
>> +disable_clks:
>> +	clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks);
>>   	return ret;
>>   }
>>   
>> @@ -1495,6 +1515,30 @@ static int rk3128_usb2phy_tuning(struct rockchip_usb2phy *rphy)
>>   				BIT(2) << BIT_WRITEABLE_SHIFT | 0);
>>   }
>
> I still maintain, that this maybe should be two separate patches.
> And you even seem to have nice "cut-here" in it ;-)
>
> The code above converts the driver to use clk_bulk to handle
> multiple clocks for controller variants needing it.
>
>
> And the code below adds the rk3576-specific data to the driver.
>

Make sense, I shall split two separate patches in the next version.
BTW, should I send the clk_bulk process patch as a separate series? I 
mean I shouldn't send it together with this series, right?


Best regards,
Frank

>
>> [...]
>>
>> +
>>   static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
>>   	{
>>   		.reg = 0x0000,
>> @@ -2094,6 +2216,7 @@ static const struct of_device_id rockchip_usb2phy_dt_match[] = {
>>   	{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
>>   	{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
>>   	{ .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
>> +	{ .compatible = "rockchip,rk3576-usb2phy", .data = &rk3576_phy_cfgs },
>>   	{ .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs },
>>   	{ .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
>>   	{}
>>
>



From frawang.cn at gmail.com  Fri Sep 27 00:01:25 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Fri, 27 Sep 2024 15:01:25 +0800
Subject: [PATCH v3 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <ed829240-d4f7-471f-84f6-3509f87f11a1@kernel.org>
References: <20240926103223.29538-1-frawang.cn@gmail.com>
 <ed829240-d4f7-471f-84f6-3509f87f11a1@kernel.org>
Message-ID: <7944f4dd-96f0-40df-8c91-523409e3cb20@gmail.com>

Hi Krzysztof,

On 2024/9/26 22:19, Krzysztof Kozlowski wrote:
> On 26/09/2024 12:32, Frank Wang wrote:
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            enum:
>> +              - rockchip,rk3576-usb2phy
>> +    then:
>> +      properties:
>> +        clocks:
>> +          minItems: 3
>> +          maxItems: 3
> Read one more time the example I gave you. Top-level constraints are
> saying max one clock.
>
> Best regards,
> Krzysztof
>

Sorry for overlooking this, I will set both "clocks" and "clock-names" 
to true, and add the else case below the above codes for the "old" SoCs.
Just like the below.

-? clocks:
-??? maxItems: 1
+? clocks: true

-? clock-names:
-??? const: phyclk
+? clock-names: true

 ?? assigned-clocks:
 ???? description:
@@ -189,6 +187,13 @@ allOf:
 ???????????? - const: phyclk
 ???????????? - const: aclk
 ???????????? - const: aclk_slv
+??? else:
+????? properties:
+??????? clocks:
+????????? maxItems: 1
+??????? clock-names:
+????????? const: phyclk
+


Best regards,
Frank


From krzk at kernel.org  Fri Sep 27 00:30:30 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 27 Sep 2024 09:30:30 +0200
Subject: [PATCH v3 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <7944f4dd-96f0-40df-8c91-523409e3cb20@gmail.com>
References: <20240926103223.29538-1-frawang.cn@gmail.com>
 <ed829240-d4f7-471f-84f6-3509f87f11a1@kernel.org>
 <7944f4dd-96f0-40df-8c91-523409e3cb20@gmail.com>
Message-ID: <4b98196a-c898-4d08-9101-31feb4e59b5c@kernel.org>

On 27/09/2024 09:01, Frank Wang wrote:
> Hi Krzysztof,
> 
> On 2024/9/26 22:19, Krzysztof Kozlowski wrote:
>> On 26/09/2024 12:32, Frank Wang wrote:
>>> +  - if:
>>> +      properties:
>>> +        compatible:
>>> +          contains:
>>> +            enum:
>>> +              - rockchip,rk3576-usb2phy
>>> +    then:
>>> +      properties:
>>> +        clocks:
>>> +          minItems: 3
>>> +          maxItems: 3
>> Read one more time the example I gave you. Top-level constraints are
>> saying max one clock.
>>
>> Best regards,
>> Krzysztof
>>
> 
> Sorry for overlooking this, I will set both "clocks" and "clock-names" 
> to true, and add the else case below the above codes for the "old" SoCs.
> Just like the below.
> 
> -? clocks:
> -??? maxItems: 1
> +? clocks: true
> 
> -? clock-names:
> -??? const: phyclk
> +? clock-names: true

For the third time, read the code I gave you. Do you see something like
this there? Why doing all the time something different than existing code?

Best regards,
Krzysztof



From heiko at sntech.de  Fri Sep 27 00:42:58 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 27 Sep 2024 09:42:58 +0200
Subject: [PATCH v3 2/2] phy: rockchip: inno-usb2: Add usb2 phys support for rk3576
In-Reply-To: <9cc2d594-a930-4c4a-86ee-47228af28936@gmail.com>
References: <20240926103223.29538-1-frawang.cn@gmail.com> <10867555.aFP6jjVeTY@phil>
 <9cc2d594-a930-4c4a-86ee-47228af28936@gmail.com>
Message-ID: <9874721.ag9G3TJQzC@phil>

Hi Frank,

Am Freitag, 27. September 2024, 08:16:42 CEST schrieb Frank Wang:
> On 2024/9/26 18:48, Heiko Stuebner wrote:
> > Am Donnerstag, 26. September 2024, 12:32:23 CEST schrieb Frank Wang:
> >> From: William Wu <william.wu at rock-chips.com>
> >>
> >> The RK3576 SoC has two independent USB2.0 PHYs, and each PHY has
> >> one port.
> >>
> >> This change also converts the clock management from single to bulk
> >> as some Rockchip SoCs (e.g RK3576) have more than one clock.
> >>
> >> Signed-off-by: William Wu <william.wu at rock-chips.com>
> >> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
> >> ---
> >> Changelog:
> >> v3:
> >>   - amend the commit log adds clocks converting.
> >>   - retrieve the clock by "clks.id" in *_clk480m_register() function.
> >>
> >> v2:
> >>   - no changes.
> >> v1:
> >>   - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-2-frank.wang at rock-chips.com/
> >>
> >>   drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 139 +++++++++++++++++-
> >>   1 file changed, 131 insertions(+), 8 deletions(-)
> >>
> >> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> >> index 4f71373ae6e1..642c7857c5ae 100644
> >> --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> >> +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> >> @@ -229,9 +229,10 @@ struct rockchip_usb2phy_port {
> >>    * @dev: pointer to device.
> >>    * @grf: General Register Files regmap.
> >>    * @usbgrf: USB General Register Files regmap.
> >> - * @clk: clock struct of phy input clk.
> >> + * @clks: array of phy input clocks.
> >>    * @clk480m: clock struct of phy output clk.
> >>    * @clk480m_hw: clock struct of phy output clk management.
> >> + * @num_clks: number of phy input clocks.
> >>    * @phy_reset: phy reset control.
> >>    * @chg_state: states involved in USB charger detection.
> >>    * @chg_type: USB charger types.
> >> @@ -246,9 +247,10 @@ struct rockchip_usb2phy {
> >>   	struct device	*dev;
> >>   	struct regmap	*grf;
> >>   	struct regmap	*usbgrf;
> >> -	struct clk	*clk;
> >> +	struct clk_bulk_data	*clks;
> >>   	struct clk	*clk480m;
> >>   	struct clk_hw	clk480m_hw;
> >> +	int			num_clks;
> >>   	struct reset_control	*phy_reset;
> >>   	enum usb_chg_state	chg_state;
> >>   	enum power_supply_type	chg_type;
> >> @@ -376,7 +378,9 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
> >>   {
> >>   	struct device_node *node = rphy->dev->of_node;
> >>   	struct clk_init_data init;
> >> +	struct clk *refclk = NULL;
> >>   	const char *clk_name;
> >> +	int i;
> >>   	int ret = 0;
> >>   
> >>   	init.flags = 0;
> >> @@ -386,8 +390,15 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
> >>   	/* optional override of the clockname */
> >>   	of_property_read_string(node, "clock-output-names", &init.name);
> >>   
> >> -	if (rphy->clk) {
> >> -		clk_name = __clk_get_name(rphy->clk);
> >> +	for (i = 0; i < rphy->num_clks; i++) {
> >> +		if (!strncmp(rphy->clks[i].id, "phyclk", 6)) {
> >> +			refclk = rphy->clks[i].clk;
> >> +			break;
> >> +		}
> >> +	}
> >> +
> >> +	if (!IS_ERR(refclk)) {
> >> +		clk_name = __clk_get_name(refclk);
> >>   		init.parent_names = &clk_name;
> >>   		init.num_parents = 1;
> >>   	} else {
> >> @@ -1406,22 +1417,29 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
> >>   	if (IS_ERR(rphy->phy_reset))
> >>   		return PTR_ERR(rphy->phy_reset);
> >>   
> >> -	rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk");
> >> -	if (IS_ERR(rphy->clk)) {
> >> -		return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk),
> >> +	ret = devm_clk_bulk_get_all(dev, &rphy->clks);
> >> +	if (ret == -EPROBE_DEFER) {
> >> +		return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
> >>   				     "failed to get phyclk\n");
> >>   	}
> >>   
> >> +	/* Clocks are optional */
> >> +	rphy->num_clks = ret < 0 ? 0 : ret;
> >> +
> >>   	ret = rockchip_usb2phy_clk480m_register(rphy);
> >>   	if (ret) {
> >>   		dev_err(dev, "failed to register 480m output clock\n");
> >>   		return ret;
> >>   	}
> >>   
> >> +	ret = clk_bulk_prepare_enable(rphy->num_clks, rphy->clks);
> >> +	if (ret)
> >> +		return ret;
> >> +
> > Do you actually need that separate enable step?
> > There exists devm_clk_bulk_get_all_enable()
> >
> > https://elixir.bootlin.com/linux/v6.11/source/include/linux/clk.h#L511
> >
> > which you could use above. Especially as otherwise you'd need a remove
> > callback to disable the clock on driver unbind?
> >
> 
> Using devm_clk_bulk_get_all() just can get clocknumbers, 
> and devm_clk_bulk_get_all_enable() is not.
> It seems that there is no other API can get the number of clocks separately.

Hmm, didn't see that yesterday, but you're right.

>From a consistency standpoint I think it would actually make sense to
return the number of clocks from devm_clk_bulk_get_all_enable() .

Because right now, those clk_* functions are looking pretty similar
but behave differently. And looking at the function, the enable-variant
also just uses clk_bulk_get_all, just looses the number of clocks
because "ret" is reused by the enable call.


But if you don't want to touch the clk API that's also ok, but
you should then add a devm_add_action_or_reset call, to disable
the clocks on driver removal, before they are freed.


> >>   	if (rphy->phy_cfg->phy_tuning) {
> >>   		ret = rphy->phy_cfg->phy_tuning(rphy);
> >>   		if (ret)
> >> -			return ret;
> >> +			goto disable_clks;
> >>   	}
> >>   
> >>   	index = 0;
> >> @@ -1484,6 +1502,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
> >>   
> >>   put_child:
> >>   	of_node_put(child_np);
> >> +disable_clks:
> >> +	clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks);
> >>   	return ret;
> >>   }
> >>   
> >> @@ -1495,6 +1515,30 @@ static int rk3128_usb2phy_tuning(struct rockchip_usb2phy *rphy)
> >>   				BIT(2) << BIT_WRITEABLE_SHIFT | 0);
> >>   }
> >
> > I still maintain, that this maybe should be two separate patches.
> > And you even seem to have nice "cut-here" in it ;-)
> >
> > The code above converts the driver to use clk_bulk to handle
> > multiple clocks for controller variants needing it.
> >
> >
> > And the code below adds the rk3576-specific data to the driver.
> >
> 
> Make sense, I shall split two separate patches in the next version.
> BTW, should I send the clk_bulk process patch as a separate series? I 
> mean I shouldn't send it together with this series, right?

No, just one series, convert the driver to clk_bulk*, add rk3576 binding,
add rk3576-specific data :-) .

Because people will want to see where you're going with your change
and having "this series depends on this separate patch" creates confusion
and you're really only touching this one driver.

Heiko





From frawang.cn at gmail.com  Fri Sep 27 00:59:08 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Fri, 27 Sep 2024 15:59:08 +0800
Subject: [PATCH v3 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <4b98196a-c898-4d08-9101-31feb4e59b5c@kernel.org>
References: <20240926103223.29538-1-frawang.cn@gmail.com>
 <ed829240-d4f7-471f-84f6-3509f87f11a1@kernel.org>
 <7944f4dd-96f0-40df-8c91-523409e3cb20@gmail.com>
 <4b98196a-c898-4d08-9101-31feb4e59b5c@kernel.org>
Message-ID: <a06af01a-656b-4ef6-84a6-bc1c35d5bafa@gmail.com>

Hi Krzysztof,

On 2024/9/27 15:30, Krzysztof Kozlowski wrote:
> On 27/09/2024 09:01, Frank Wang wrote:
>> Hi Krzysztof,
>>
>> On 2024/9/26 22:19, Krzysztof Kozlowski wrote:
>>> On 26/09/2024 12:32, Frank Wang wrote:
>>>> +  - if:
>>>> +      properties:
>>>> +        compatible:
>>>> +          contains:
>>>> +            enum:
>>>> +              - rockchip,rk3576-usb2phy
>>>> +    then:
>>>> +      properties:
>>>> +        clocks:
>>>> +          minItems: 3
>>>> +          maxItems: 3
>>> Read one more time the example I gave you. Top-level constraints are
>>> saying max one clock.
>>>
>>> Best regards,
>>> Krzysztof
>>>
>> Sorry for overlooking this, I will set both "clocks" and "clock-names"
>> to true, and add the else case below the above codes for the "old" SoCs.
>> Just like the below.
>>
>> -? clocks:
>> -??? maxItems: 1
>> +? clocks: true
>>
>> -? clock-names:
>> -??? const: phyclk
>> +? clock-names: true
> For the third time, read the code I gave you. Do you see something like
> this there? Why doing all the time something different than existing code?

Refer to the link you sent me that I must add minItems property for 
clocks, just like the below codes:

@@ -35,7 +35,8 @@ properties:
 ???? const: 0

 ?? clocks:
-??? maxItems: 1
+??? minItems: 1
+??? maxItems: 3

That can pass dt_binding and dtb checking, however, "clocks" is the 
optional property for some old Rockchip PHYs,? I am not sure is it right 
to force set? minItems as 1 .
If just keep maxItems, the dt_binding checking is failure.


Best regards,
Frank

> Best regards,
> Krzysztof
>



From heiko at sntech.de  Fri Sep 27 01:02:05 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 27 Sep 2024 10:02:05 +0200
Subject: [PATCH v3 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add rk3576
In-Reply-To: <4b98196a-c898-4d08-9101-31feb4e59b5c@kernel.org>
References: <20240926103223.29538-1-frawang.cn@gmail.com>
 <7944f4dd-96f0-40df-8c91-523409e3cb20@gmail.com>
 <4b98196a-c898-4d08-9101-31feb4e59b5c@kernel.org>
Message-ID: <20816071.Yz81rIOvuz@phil>

Hi Krzysztof,

Am Freitag, 27. September 2024, 09:30:30 CEST schrieb Krzysztof Kozlowski:
> On 27/09/2024 09:01, Frank Wang wrote:
> > Hi Krzysztof,
> > 
> > On 2024/9/26 22:19, Krzysztof Kozlowski wrote:
> >> On 26/09/2024 12:32, Frank Wang wrote:
> >>> +  - if:
> >>> +      properties:
> >>> +        compatible:
> >>> +          contains:
> >>> +            enum:
> >>> +              - rockchip,rk3576-usb2phy
> >>> +    then:
> >>> +      properties:
> >>> +        clocks:
> >>> +          minItems: 3
> >>> +          maxItems: 3
> >> Read one more time the example I gave you. Top-level constraints are
> >> saying max one clock.
> >>
> >> Best regards,
> >> Krzysztof
> >>
> > 
> > Sorry for overlooking this, I will set both "clocks" and "clock-names" 
> > to true, and add the else case below the above codes for the "old" SoCs.
> > Just like the below.
> > 
> > -  clocks:
> > -    maxItems: 1
> > +  clocks: true
> > 
> > -  clock-names:
> > -    const: phyclk
> > +  clock-names: true
> 
> For the third time, read the code I gave you. Do you see something like
> this there? Why doing all the time something different than existing code?

On vacation right now so late to the party, and somewhat confused :-) .

I've tried to find the code you mentioned, but did fail.
In [0] you mention "maybe oneOf". The other replies in that version were
about the ordering needing to stay for the older phy variants.

[1] in v2 has that NAK thing and [2] from v3 references that example again

I am probably just blind, but could use a pointer.


Because I think going with a
  - if:
      properties:
        compatible:
          contains:
            enum:
              - rockchip,rk3576-usb2phy
    then:
      properties:
        clocks:
          minItems: 3
          maxItems: 3
        clock-names:
          items:
            - const: phyclk
            - const: aclk
            - const: aclk_slv
    else:
      properties:
        clocks:
          maxItems: 1
        clock-names:
          const: phyclk

block should actually make sure each variant will check for the appropriate
number of clocks?

And having clocks:true in the main part then makes sure that the property
is not getting marked as:
arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dtb: usb2-phy at 0: 'clock-names', 'clocks' do not match any of the regexes: 'pinctrl-[0-9]+'
        from schema $id: http://devicetree.org/schemas/phy/rockchip,inno-usb2phy.yaml#


Heiko


[0] https://lore.kernel.org/lkml/snccizbw6thn3lhwad4xppp7vqii4p56ttl2gufwc3ke7vfckf at e4b7nvwwtdfr/
[1] https://lore.kernel.org/lkml/2a4200ac-3ea2-4449-94ac-c4b9f37ad800 at kernel.org/#t
[2] https://lore.kernel.org/lkml/ed829240-d4f7-471f-84f6-3509f87f11a1 at kernel.org/




From krzk at kernel.org  Fri Sep 27 02:52:48 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 27 Sep 2024 11:52:48 +0200
Subject: [PATCH v3 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <a06af01a-656b-4ef6-84a6-bc1c35d5bafa@gmail.com>
References: <20240926103223.29538-1-frawang.cn@gmail.com>
 <ed829240-d4f7-471f-84f6-3509f87f11a1@kernel.org>
 <7944f4dd-96f0-40df-8c91-523409e3cb20@gmail.com>
 <4b98196a-c898-4d08-9101-31feb4e59b5c@kernel.org>
 <a06af01a-656b-4ef6-84a6-bc1c35d5bafa@gmail.com>
Message-ID: <2815219e-3a20-4a5b-8573-d8a4ad2df1c9@kernel.org>

On 27/09/2024 09:59, Frank Wang wrote:
>>>
>>> -? clocks:
>>> -??? maxItems: 1
>>> +? clocks: true
>>>
>>> -? clock-names:
>>> -??? const: phyclk
>>> +? clock-names: true
>> For the third time, read the code I gave you. Do you see something like
>> this there? Why doing all the time something different than existing code?
> 
> Refer to the link you sent me that I must add minItems property for 
> clocks, just like the below codes:
> 
> @@ -35,7 +35,8 @@ properties:
>  ???? const: 0
> 
>  ?? clocks:
> -??? maxItems: 1
> +??? minItems: 1
> +??? maxItems: 3

Yes, for all variable properties, so also names.

> 
> That can pass dt_binding and dtb checking, however, "clocks" is the 
> optional property for some old Rockchip PHYs,? I am not sure is it right 
> to force set? minItems as 1 .
> If just keep maxItems, the dt_binding checking is failure.

Please specify the question you want to ask.


Best regards,
Krzysztof



From krzk at kernel.org  Fri Sep 27 02:56:47 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 27 Sep 2024 11:56:47 +0200
Subject: [PATCH v3 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <20816071.Yz81rIOvuz@phil>
References: <20240926103223.29538-1-frawang.cn@gmail.com>
 <7944f4dd-96f0-40df-8c91-523409e3cb20@gmail.com>
 <4b98196a-c898-4d08-9101-31feb4e59b5c@kernel.org> <20816071.Yz81rIOvuz@phil>
Message-ID: <d6b275a6-5f6f-45e2-bd48-6529841a610a@kernel.org>

On 27/09/2024 10:02, Heiko Stuebner wrote:
> Hi Krzysztof,
> 
> Am Freitag, 27. September 2024, 09:30:30 CEST schrieb Krzysztof Kozlowski:
>> On 27/09/2024 09:01, Frank Wang wrote:
>>> Hi Krzysztof,
>>>
>>> On 2024/9/26 22:19, Krzysztof Kozlowski wrote:
>>>> On 26/09/2024 12:32, Frank Wang wrote:
>>>>> +  - if:
>>>>> +      properties:
>>>>> +        compatible:
>>>>> +          contains:
>>>>> +            enum:
>>>>> +              - rockchip,rk3576-usb2phy
>>>>> +    then:
>>>>> +      properties:
>>>>> +        clocks:
>>>>> +          minItems: 3
>>>>> +          maxItems: 3
>>>> Read one more time the example I gave you. Top-level constraints are
>>>> saying max one clock.
>>>>
>>>> Best regards,
>>>> Krzysztof
>>>>
>>>
>>> Sorry for overlooking this, I will set both "clocks" and "clock-names" 
>>> to true, and add the else case below the above codes for the "old" SoCs.
>>> Just like the below.
>>>
>>> -  clocks:
>>> -    maxItems: 1
>>> +  clocks: true
>>>
>>> -  clock-names:
>>> -    const: phyclk
>>> +  clock-names: true
>>
>> For the third time, read the code I gave you. Do you see something like
>> this there? Why doing all the time something different than existing code?
> 
> On vacation right now so late to the party, and somewhat confused :-) .
> 
> I've tried to find the code you mentioned, but did fail.
> In [0] you mention "maybe oneOf". The other replies in that version were
> about the ordering needing to stay for the older phy variants.
> 
> [1] in v2 has that NAK thing and [2] from v3 references that example again
> 
> I am probably just blind, but could use a pointer.

Oh, maybe I did not provide the link?

I apologize. I thought I gave reference to standard example. My bad.

Here it goes:
https://elixir.bootlin.com/linux/v6.11-rc6/source/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml#L127


Best regards,
Krzysztof



From frawang.cn at gmail.com  Fri Sep 27 03:49:57 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Fri, 27 Sep 2024 18:49:57 +0800
Subject: [PATCH v3 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <2815219e-3a20-4a5b-8573-d8a4ad2df1c9@kernel.org>
References: <20240926103223.29538-1-frawang.cn@gmail.com>
 <ed829240-d4f7-471f-84f6-3509f87f11a1@kernel.org>
 <7944f4dd-96f0-40df-8c91-523409e3cb20@gmail.com>
 <4b98196a-c898-4d08-9101-31feb4e59b5c@kernel.org>
 <a06af01a-656b-4ef6-84a6-bc1c35d5bafa@gmail.com>
 <2815219e-3a20-4a5b-8573-d8a4ad2df1c9@kernel.org>
Message-ID: <7eead817-fe37-472d-ab5a-f46133031e18@gmail.com>

Hi Krzysztof,

On 2024/9/27 17:52, Krzysztof Kozlowski wrote:
> On 27/09/2024 09:59, Frank Wang wrote:
>>>> -? clocks:
>>>> -??? maxItems: 1
>>>> +? clocks: true
>>>>
>>>> -? clock-names:
>>>> -??? const: phyclk
>>>> +? clock-names: true
>>> For the third time, read the code I gave you. Do you see something like
>>> this there? Why doing all the time something different than existing code?
>> Refer to the link you sent me that I must add minItems property for
>> clocks, just like the below codes:
>>
>> @@ -35,7 +35,8 @@ properties:
>>   ???? const: 0
>>
>>   ?? clocks:
>> -??? maxItems: 1
>> +??? minItems: 1
>> +??? maxItems: 3
> Yes, for all variable properties, so also names.
>
>> That can pass dt_binding and dtb checking, however, "clocks" is the
>> optional property for some old Rockchip PHYs,? I am not sure is it right
>> to force set? minItems as 1 .
>> If just keep maxItems, the dt_binding checking is failure.
> Please specify the question you want to ask.
>

Q1: The "clocks" is an optional property for some old Rockchip PHYs, so 
set "minItems: 1" likes the below, is this a suitable setting?

 ?? clocks:
-??? maxItems: 1
+??? minItems: 1
+??? maxItems: 3Q2: Do you want me to amend the code to like this? 
clocks: minItems: 1 maxItems: 3 clock-names: minItems: 1 maxItems: 3 
allOf: [...] - if: properties: compatible: contains: enum: - 
rockchip,px30-usb2phy - rockchip,rk3128-usb2phy - 
rockchip,rk3228-usb2phy - rockchip,rk3308-usb2phy - 
rockchip,rk3328-usb2phy - rockchip,rk3366-usb2phy - 
rockchip,rk3399-usb2phy - rockchip,rk3568-usb2phy - 
rockchip,rk3588-usb2phy - rockchip,rv1108-usb2phy then: properties: 
clocks: maxItems: 1 clock-names: const: phyclk - if: properties: 
compatible: contains: enum: - rockchip,rk3576-usb2phy then: properties: 
clocks: minItems: 3 maxItems: 3 clock-names: items: - const: phyclk - 
const: aclk - const: aclk_slv


Best regards,
Frank

> Best regards,
> Krzysztof
>



From frawang.cn at gmail.com  Fri Sep 27 03:59:15 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Fri, 27 Sep 2024 18:59:15 +0800
Subject: [PATCH v3 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <2815219e-3a20-4a5b-8573-d8a4ad2df1c9@kernel.org>
References: <20240926103223.29538-1-frawang.cn@gmail.com>
 <ed829240-d4f7-471f-84f6-3509f87f11a1@kernel.org>
 <7944f4dd-96f0-40df-8c91-523409e3cb20@gmail.com>
 <4b98196a-c898-4d08-9101-31feb4e59b5c@kernel.org>
 <a06af01a-656b-4ef6-84a6-bc1c35d5bafa@gmail.com>
 <2815219e-3a20-4a5b-8573-d8a4ad2df1c9@kernel.org>
Message-ID: <f5e547ac-cb5b-492d-8cfd-d77d3e9bbf9d@gmail.com>

Hi Krzysztof,

On 2024/9/27 17:52, Krzysztof Kozlowski wrote:
> On 27/09/2024 09:59, Frank Wang wrote:
>>>> -? clocks:
>>>> -??? maxItems: 1
>>>> +? clocks: true
>>>>
>>>> -? clock-names:
>>>> -??? const: phyclk
>>>> +? clock-names: true
>>> For the third time, read the code I gave you. Do you see something like
>>> this there? Why doing all the time something different than existing code?
>> Refer to the link you sent me that I must add minItems property for
>> clocks, just like the below codes:
>>
>> @@ -35,7 +35,8 @@ properties:
>>   ???? const: 0
>>
>>   ?? clocks:
>> -??? maxItems: 1
>> +??? minItems: 1
>> +??? maxItems: 3
> Yes, for all variable properties, so also names.
>
>> That can pass dt_binding and dtb checking, however, "clocks" is the
>> optional property for some old Rockchip PHYs,? I am not sure is it right
>> to force set? minItems as 1 .
>> If just keep maxItems, the dt_binding checking is failure.
> Please specify the question you want to ask.
>

Please ignore my last garbled email as mailbox client issue.

Q1: The "clocks" is an optional property for some old Rockchip PHYs, so 
set "minItems: 1" likes the below, is this a suitable setting?

 ??? clocks:
-??? maxItems: 1
+??? minItems: 1
+??? maxItems: 3

Q2: Do you want me to amend the code to like this?

 ?? clocks:
 ??? minItems: 1
 ??? maxItems: 3

 ?? clock-names:
 ??? minItems: 1
 ??? maxItems: 3

allOf:

[...]

 ? - if:
 ????? properties:
 ??????? compatible:
 ????????? contains:
 ??????????? enum:
 ????????????? - rockchip,px30-usb2phy
 ????????????? - rockchip,rk3128-usb2phy
 ????????????? - rockchip,rk3228-usb2phy
 ????????????? - rockchip,rk3308-usb2phy
 ????????????? - rockchip,rk3328-usb2phy
 ????????????? - rockchip,rk3366-usb2phy
 ????????????? - rockchip,rk3399-usb2phy
 ????????????? - rockchip,rk3568-usb2phy
 ????????????? - rockchip,rk3588-usb2phy
 ????????????? - rockchip,rv1108-usb2phy
 ??? then:
 ????? properties:
 ??????? clocks:
 ????????? maxItems: 1
 ??????? clock-names:
 ????????? const: phyclk

 ? - if:
 ????? properties:
 ??????? compatible:
 ????????? contains:
 ??????????? enum:
 ????????????? - rockchip,rk3576-usb2phy
 ??? then:
 ????? properties:
 ??????? clocks:
 ????????? minItems: 3
 ????????? maxItems: 3
 ??????? clock-names:
 ????????? items:
 ??????????? - const: phyclk
 ??????????? - const: aclk
 ??????????? - const: aclk_slv

BR.
Frank

> Best regards,
> Krzysztof
>



From krzk at kernel.org  Fri Sep 27 05:05:21 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 27 Sep 2024 14:05:21 +0200
Subject: [PATCH v3 1/2] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <f5e547ac-cb5b-492d-8cfd-d77d3e9bbf9d@gmail.com>
References: <20240926103223.29538-1-frawang.cn@gmail.com>
 <ed829240-d4f7-471f-84f6-3509f87f11a1@kernel.org>
 <7944f4dd-96f0-40df-8c91-523409e3cb20@gmail.com>
 <4b98196a-c898-4d08-9101-31feb4e59b5c@kernel.org>
 <a06af01a-656b-4ef6-84a6-bc1c35d5bafa@gmail.com>
 <2815219e-3a20-4a5b-8573-d8a4ad2df1c9@kernel.org>
 <f5e547ac-cb5b-492d-8cfd-d77d3e9bbf9d@gmail.com>
Message-ID: <417fa0ae-fe9c-4407-acbe-09173a0a2a47@kernel.org>

On 27/09/2024 12:59, Frank Wang wrote:
> Hi Krzysztof,
> 
> On 2024/9/27 17:52, Krzysztof Kozlowski wrote:
>> On 27/09/2024 09:59, Frank Wang wrote:
>>>>> -? clocks:
>>>>> -??? maxItems: 1
>>>>> +? clocks: true
>>>>>
>>>>> -? clock-names:
>>>>> -??? const: phyclk
>>>>> +? clock-names: true
>>>> For the third time, read the code I gave you. Do you see something like
>>>> this there? Why doing all the time something different than existing code?
>>> Refer to the link you sent me that I must add minItems property for
>>> clocks, just like the below codes:
>>>
>>> @@ -35,7 +35,8 @@ properties:
>>>   ???? const: 0
>>>
>>>   ?? clocks:
>>> -??? maxItems: 1
>>> +??? minItems: 1
>>> +??? maxItems: 3
>> Yes, for all variable properties, so also names.
>>
>>> That can pass dt_binding and dtb checking, however, "clocks" is the
>>> optional property for some old Rockchip PHYs,? I am not sure is it right
>>> to force set? minItems as 1 .
>>> If just keep maxItems, the dt_binding checking is failure.
>> Please specify the question you want to ask.
>>
> 
> Please ignore my last garbled email as mailbox client issue.
> 
> Q1: The "clocks" is an optional property for some old Rockchip PHYs, so 
> set "minItems: 1" likes the below, is this a suitable setting?
> 
>  ??? clocks:
> -??? maxItems: 1
> +??? minItems: 1
> +??? maxItems: 3
> 
> Q2: Do you want me to amend the code to like this?
> 
>  ?? clocks:
>  ??? minItems: 1
>  ??? maxItems: 3
> 
>  ?? clock-names:
>  ??? minItems: 1
>  ??? maxItems: 3

List should be here with minItems. Then you only define the constraints
in if:then:

Best regards,
Krzysztof



From sandor.yu at nxp.com  Sat Sep 28 19:34:21 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Sun, 29 Sep 2024 02:34:21 +0000
Subject: [PATCH v17 4/8] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <2mug3ii2vi735sk7nwwu2rcj63d3mlgazlhg4sydcxb6uf5nsc@qi5ut5pmajsv>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
 <8bdf573bfd7e3feb45d7ccb53765a978a685ce2d.1727159906.git.Sandor.yu@nxp.com>
 <20240924-mottled-psychedelic-lorikeet-ef8f4c@houat>
 <2mug3ii2vi735sk7nwwu2rcj63d3mlgazlhg4sydcxb6uf5nsc@qi5ut5pmajsv>
Message-ID: <DB9PR04MB9452A0E23FD29D7A8DB17DECF4752@DB9PR04MB9452.eurprd04.prod.outlook.com>

Hi Dmitry,

Thanks for your comments,

> 
> On Tue, Sep 24, 2024 at 12:16:27PM GMT, Maxime Ripard wrote:
> > On Tue, Sep 24, 2024 at 03:36:49PM GMT, Sandor Yu wrote:
> > > +static int cdns_mhdp8501_read_hpd(struct cdns_mhdp8501_device
> > > +*mhdp) {
> > > +   u8 status;
> > > +   int ret;
> > > +
> > > +   mutex_lock(&mhdp_mailbox_mutex);
> > > +
> > > +   ret = cdns_mhdp_mailbox_send(&mhdp->base,
> MB_MODULE_ID_GENERAL,
> > > +                                GENERAL_GET_HPD_STATE, 0,
> NULL);
> > > +   if (ret)
> > > +           goto err_get_hpd;
> > > +
> > > +   ret = cdns_mhdp_mailbox_recv_header(&mhdp->base,
> MB_MODULE_ID_GENERAL,
> > > +                                       GENERAL_GET_HPD_STATE,
> > > +                                       sizeof(status));
> > > +   if (ret)
> > > +           goto err_get_hpd;
> > > +
> > > +   ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &status,
> sizeof(status));
> > > +   if (ret)
> > > +           goto err_get_hpd;
> > > +
> > > +   mutex_unlock(&mhdp_mailbox_mutex);
> >
> > That's better I guess, but it's still not a good API design. If you
> > can't have concurrent accesses, then cdns_mhdp_mailbox_send et al.
> > should take the mutex themselves.
> 
> I think that a proper API might be:
> 
> int cdns_mhdp_mailbox_send_recv(struct cdns_mhdp_device *mhdp,
>                         u8 module_id, u8 opcode,
>                         u16 size, const u8 *message,
>                         u16 buf_size, u8 *buf);
> 
> Internally it should take the lock, exchange the data, then return.
> 

Thank you for your great suggestion. It seems like this should be able to solve the current problem.
I need to check each existing FW access functions one by one to see if they can all work under this API function.

B.R
Sandor

> --
> With best wishes
> Dmitry


From sandor.yu at nxp.com  Sat Sep 28 19:34:36 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Sun, 29 Sep 2024 02:34:36 +0000
Subject: [PATCH v17 4/8] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <20240924-mottled-psychedelic-lorikeet-ef8f4c@houat>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
 <8bdf573bfd7e3feb45d7ccb53765a978a685ce2d.1727159906.git.Sandor.yu@nxp.com>
 <20240924-mottled-psychedelic-lorikeet-ef8f4c@houat>
Message-ID: <DB9PR04MB945284B95FAE4FE127E6568FF4752@DB9PR04MB9452.eurprd04.prod.outlook.com>

Hi Maxime,

Thanks for your comments.

> 
> On Tue, Sep 24, 2024 at 03:36:49PM GMT, Sandor Yu wrote:
> > +static int cdns_mhdp8501_read_hpd(struct cdns_mhdp8501_device
> *mhdp)
> > +{
> > +	u8 status;
> > +	int ret;
> > +
> > +	mutex_lock(&mhdp_mailbox_mutex);
> > +
> > +	ret = cdns_mhdp_mailbox_send(&mhdp->base,
> MB_MODULE_ID_GENERAL,
> > +				     GENERAL_GET_HPD_STATE, 0, NULL);
> > +	if (ret)
> > +		goto err_get_hpd;
> > +
> > +	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base,
> MB_MODULE_ID_GENERAL,
> > +					    GENERAL_GET_HPD_STATE,
> > +					    sizeof(status));
> > +	if (ret)
> > +		goto err_get_hpd;
> > +
> > +	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &status,
> sizeof(status));
> > +	if (ret)
> > +		goto err_get_hpd;
> > +
> > +	mutex_unlock(&mhdp_mailbox_mutex);
> 
> That's better I guess, but it's still not a good API design. If you can't have
> concurrent accesses, then cdns_mhdp_mailbox_send et al.
> should take the mutex themselves.

I will check Dmitry's comments to add API like,
 int cdns_mhdp_mailbox_send_recv(struct cdns_mhdp_device *mhdp,
                         u8 module_id, u8 opcode,
                         u16 size, const u8 *message,
                         u16 buf_size, u8 *buf);

> 
> > +	return status;
> > +
> > +err_get_hpd:
> > +	dev_err(mhdp->dev, "read hpd  failed: %d\n", ret);
> > +	mutex_unlock(&mhdp_mailbox_mutex);
> > +
> > +	return ret;
> > +}
> > +
> > +enum drm_connector_status cdns_mhdp8501_detect(struct
> > +cdns_mhdp8501_device *mhdp) {
> > +	u8 hpd = 0xf;
> > +
> > +	hpd = cdns_mhdp8501_read_hpd(mhdp);
> > +	if (hpd == 1)
> > +		return connector_status_connected;
> > +	else if (hpd == 0)
> > +		return connector_status_disconnected;
> > +
> > +	dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n", hpd);
> 
> This is already logged, there's no need to add a message there.

OK, it will be removed.

> 
> > +	return connector_status_unknown;
> > +}
> > +
> > +static void hotplug_work_func(struct work_struct *work) {
> > +	struct cdns_mhdp8501_device *mhdp = container_of(work,
> > +						     struct cdns_mhdp8501_device,
> > +						     hotplug_work.work);
> > +	enum drm_connector_status status = cdns_mhdp8501_detect(mhdp);
> > +
> > +	drm_bridge_hpd_notify(&mhdp->bridge, status);
> > +
> > +	if (status == connector_status_connected) {
> > +		/* Cable connected  */
> > +		DRM_INFO("HDMI/DP Cable Plug In\n");
> 
> You might want to log it using drm_dev_debug, but anything else is a big
> stretch.

I will use the dev_dbg function to maintain consistency with the rest of the driver.

> 
> > +		enable_irq(mhdp->irq[IRQ_OUT]);
> > +
> > +		/* Reset HDMI/DP link with sink */
> > +		if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA)
> > +			cdns_hdmi_reset_link(mhdp);
> > +		else
> > +			cdns_dp_check_link_state(mhdp);
> > +
> > +	} else if (status == connector_status_disconnected) {
> > +		/* Cable Disconnected  */
> > +		DRM_INFO("HDMI/DP Cable Plug Out\n");
> > +		enable_irq(mhdp->irq[IRQ_IN]);
> > +	}
> > +}
> > +
> > +static irqreturn_t cdns_mhdp8501_irq_thread(int irq, void *data) {
> > +	struct cdns_mhdp8501_device *mhdp = data;
> > +
> > +	disable_irq_nosync(irq);
> > +
> > +	mod_delayed_work(system_wq, &mhdp->hotplug_work,
> > +			 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
> > +
> > +	return IRQ_HANDLED;
> > +}
> 
> disable_irq_nosync doesn't guarantee that you won't be called before
> interrupts are reenabled. What will happen if this handler is called multiple
> times?

If this handler is called multiple times, function will hotplug_work_func() excute multiple times too,
driver will working in the latest HPD status.

> 
> > +
> > +static int cdns_mhdp8501_dt_parse(struct cdns_mhdp8501_device *mhdp,
> > +				  struct platform_device *pdev)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct device_node *np = dev->of_node;
> > +	struct device_node *remote;
> > +
> > +	remote = of_graph_get_remote_node(np, 1, 0);
> > +	if (!remote) {
> > +		dev_err(dev, "fail to get remote node\n");
> > +		of_node_put(remote);
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* get connector type */
> > +	if (of_device_is_compatible(remote, "hdmi-connector")) {
> > +		mhdp->connector_type = DRM_MODE_CONNECTOR_HDMIA;
> > +
> > +	} else if (of_device_is_compatible(remote, "dp-connector")) {
> > +		mhdp->connector_type = DRM_MODE_CONNECTOR_DisplayPort;
> > +
> > +	} else {
> > +		dev_err(dev, "Unknown connector type\n");
> > +		of_node_put(remote);
> > +		return -EINVAL;
> > +	}
> > +
> > +	of_node_put(remote);
> > +
> > +	if (of_property_read_u32(np, "lane-mapping", &mhdp->lane_mapping)) {
> > +		dev_warn(dev, "Failed to get lane_mapping - using default\n");
> 
> debug logging as well.
use dev_dbg here too?
> 
> > +		mhdp->lane_mapping = LANE_MAPPING_FLIPPED;
> > +	}
> > +
> > +	return true;
> > +}
> > +
> > +static void cdns_mhdp8501_add_bridge(struct cdns_mhdp8501_device
> > +*mhdp) {
> > +	mhdp->bridge.type = mhdp->connector_type;
> > +	mhdp->bridge.driver_private = mhdp;
> > +	mhdp->bridge.of_node = mhdp->dev->of_node;
> > +	mhdp->bridge.vendor = "NXP";
> > +	mhdp->bridge.product = "i.MX8";
> > +	mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
> |
> > +			   DRM_BRIDGE_OP_HPD;
> > +
> > +	if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA) {
> > +		mhdp->bridge.funcs = &cdns_hdmi_bridge_funcs;
> > +		mhdp->bridge.ops |= DRM_BRIDGE_OP_HDMI;
> > +	} else if (mhdp->connector_type ==
> DRM_MODE_CONNECTOR_DisplayPort) {
> > +		mhdp->bridge.funcs = &cdns_dp_bridge_funcs;
> > +	} else {
> > +		dev_err(mhdp->dev, "Unsupported connector type!\n");
> > +		return;
> > +	}
> 
> If this function can error out, then it should return an error code.
OK.

> 
> > +static int cdns_hdmi_scdc_write(struct cdns_mhdp8501_device *mhdp, u8
> > +addr, u8 value) {
> > +	u8 msg[5], reg[5];
> > +	int ret;
> > +
> > +	msg[0] = 0x54;
> > +	msg[1] = addr;
> > +	msg[2] = 0;
> > +	msg[3] = 1;
> > +	msg[4] = value;
> > +
> > +	mutex_lock(&mhdp_mailbox_mutex);
> > +
> > +	ret = cdns_mhdp_mailbox_send(&mhdp->base,
> MB_MODULE_ID_HDMI_TX, HDMI_TX_WRITE,
> > +				     sizeof(msg), msg);
> > +	if (ret)
> > +		goto err_scdc_write;
> > +
> > +	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base,
> MB_MODULE_ID_HDMI_TX,
> > +					    HDMI_TX_WRITE, sizeof(reg));
> > +	if (ret)
> > +		goto err_scdc_write;
> > +
> > +	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg, sizeof(reg));
> > +	if (ret)
> > +		goto err_scdc_write;
> > +
> > +	if (reg[0] != 0)
> > +		ret = -EINVAL;
> > +
> > +err_scdc_write:
> > +
> > +	mutex_unlock(&mhdp_mailbox_mutex);
> > +
> > +	if (ret)
> > +		dev_err(mhdp->dev, "scdc write failed: %d\n", ret);
> > +	return ret;
> > +}
> 
> You should be using SCDC helpers there instead of hand crafting your
> messages.

OK, I will try create i2c_adapter/DDC for SCDC.

> 
> > +static void cdns_hdmi_sink_config(struct cdns_mhdp8501_device *mhdp)
> > +{
> > +	struct drm_display_info *display = &mhdp->curr_conn->display_info;
> > +	struct drm_connector_state *conn_state = mhdp->curr_conn->state;
> 
> That looks a bit hackish to me. We should probably provide a helper to get the
> connector state the bridge is attached to.

How about code change to followed, is it more clear?
370         struct drm_connector *connector = mhdp->curr_conn;
371         struct drm_connector_state *conn_state = connector->state;
372         struct drm_display_info *display = &connector->display_info;
373         struct drm_scdc *scdc = &display->hdmi.scdc;

> 
> > +	struct drm_scdc *scdc = &mhdp->curr_conn->display_info.hdmi.scdc;
> > +	u8 buff = 0;
> > +
> > +	/* check sink type (HDMI or DVI) */
> > +	if (!display->is_hdmi) {
> > +		mhdp->hdmi.hdmi_type = MODE_DVI;
> > +		return;
> > +	}
> > +
> > +	/* Default work in HDMI1.4 */
> > +	mhdp->hdmi.hdmi_type = MODE_HDMI_1_4;
> > +
> > +	/* check sink support SCDC or not */
> > +	if (!scdc->supported) {
> > +		dev_info(mhdp->dev, "Sink Not Support SCDC\n");
> 
> drm_dev_debug

dev_dbg

> 
> > +static enum drm_mode_status
> > +cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
> > +			       const struct drm_display_mode *mode,
> > +			       unsigned long long tmds_rate) {
> > +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +	union phy_configure_opts phy_cfg;
> > +	int ret;
> > +
> > +	phy_cfg.hdmi.tmds_char_rate = tmds_rate;
> > +
> > +	ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
> > +	if (ret < 0)
> > +		return MODE_CLOCK_RANGE;
> > +
> > +	return MODE_OK;
> > +}
> > +
> > +static enum drm_mode_status
> > +cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
> > +			    const struct drm_display_info *info,
> > +			    const struct drm_display_mode *mode) {
> > +	unsigned long long tmds_rate;
> > +
> > +	/* We don't support double-clocked and Interlaced modes */
> > +	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
> > +	    mode->flags & DRM_MODE_FLAG_INTERLACE)
> > +		return MODE_BAD;
> > +
> > +	if (mode->hdisplay > 3840)
> > +		return MODE_BAD_HVALUE;
> > +
> > +	if (mode->vdisplay > 2160)
> > +		return MODE_BAD_VVALUE;
> > +
> > +	tmds_rate = mode->clock * 1000ULL;
> > +	return cdns_hdmi_tmds_char_rate_valid(bridge, mode, tmds_rate); }
> 
> Didn't we agree on creating a mode_valid helper?

In fact, now I'm no idea where should add the mode_valid helper function.

In struct drm_bridge_funcs, it had mode_valid() and hdmi_tmds_char_rate_valid().

If create a new mode_valid helper function in struct drm_connector_hdmi_funcs,
Is it appropriate to call another API function(tmds_char_rate_valid)
at the same level within this API function?

> 
> > +static void cdns_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
> > +					   struct drm_bridge_state *old_state) {
> > +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +	struct drm_atomic_state *state = old_state->base.state;
> > +	struct drm_connector *connector;
> > +	struct video_info *video_info = &mhdp->video_info;
> > +	struct drm_crtc_state *crtc_state;
> > +	struct drm_connector_state *conn_state;
> > +	union phy_configure_opts phy_cfg;
> > +	int ret;
> > +
> > +	connector = drm_atomic_get_new_connector_for_encoder(state,
> > +							     bridge->encoder);
> > +	if (WARN_ON(!connector))
> > +		return;
> > +
> > +	mhdp->curr_conn = connector;
> > +
> > +	conn_state = drm_atomic_get_new_connector_state(state, connector);
> > +	if (WARN_ON(!conn_state))
> > +		return;
> > +
> > +	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
> > +	if (WARN_ON(!crtc_state))
> > +		return;
> > +
> > +	video_info->color_fmt = conn_state->hdmi.output_format;
> > +	video_info->bpc = conn_state->hdmi.output_bpc;
> > +
> > +	drm_atomic_helper_connector_hdmi_update_infoframes(connector,
> > +state);
> > +
> > +	/* Line swapping */
> > +	cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000 |
> > +mhdp->lane_mapping);
> > +
> > +	phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate;
> > +
> > +	ret = phy_configure(mhdp->phy, &phy_cfg);
> > +	if (ret) {
> > +		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
> > +			__func__, ret);
> > +		return;
> > +	}
> > +
> > +	cdns_hdmi_sink_config(mhdp);
> > +
> > +	ret = cdns_hdmi_ctrl_init(mhdp);
> > +	if (ret < 0) {
> > +		dev_err(mhdp->dev, "hdmi ctrl init failed = %d\n",  ret);
> > +		return;
> > +	}
> > +
> > +	/* Config GCP */
> > +	if (video_info->bpc == 8)
> > +		cdns_hdmi_disable_gcp(mhdp);
> > +	else
> > +		cdns_hdmi_enable_gcp(mhdp);
> > +
> > +	ret = cdns_hdmi_mode_config(mhdp, &crtc_state->adjusted_mode,
> video_info);
> > +	if (ret < 0) {
> > +		dev_err(mhdp->dev, "CDN_API_HDMITX_SetVic_blocking ret = %d\n",
> ret);
> > +		return;
> > +	}
> 
> If the only thing you're doing is filling video_info and passing it there, why do
> you need that structure at all? Just pass the connector_state pointer.


OK, video_info will remove from hdmi driver.

B.R
Sandor

> 
> Maxime

From sandor.yu at nxp.com  Sat Sep 28 19:36:54 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Sun, 29 Sep 2024 02:36:54 +0000
Subject: [PATCH v17 3/8] dt-bindings: display: bridge: Add Cadence
 MHDP8501
In-Reply-To: <wfdanj6ibwybx2puqvi6xjy6h5t4yagnb2mod7ln3zca4dl5wz@4mvbe6wjavb6>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
 <b2e1d26f964a03163ec7a1ba6ac8d7c88d6cb111.1727159906.git.Sandor.yu@nxp.com>
 <wfdanj6ibwybx2puqvi6xjy6h5t4yagnb2mod7ln3zca4dl5wz@4mvbe6wjavb6>
Message-ID: <DB9PR04MB94529379E1947D66848B7BE2F4752@DB9PR04MB9452.eurprd04.prod.outlook.com>

Hi Krzysztof?

Thanks for your comments,

> 
> 
> On Tue, Sep 24, 2024 at 03:36:48PM +0800, Sandor Yu wrote:
> > Add bindings for Cadence MHDP8501 DisplayPort/HDMI bridge.
> >
> > Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> Drop
OK, I will remove it in the next version.

> 
> > ---
> > v16->v17:
> > - Add lane-mapping property
> 
> That's a significant change.
OK.

> 
> >
> > v9->v16:
> >  *No change
> >
> > .../display/bridge/cdns,mhdp8501.yaml         | 109
> ++++++++++++++++++
> >  1 file changed, 109 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
> >
> > diff --git
> > a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
> > b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
> > new file mode 100644
> > index 0000000000000..3f79f328c7425
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.y
> > +++ aml
> 
> > @@ -0,0 +1,109 @@
> > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2
> > +---
> > +$id:
> > +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevi
> >
> +cetree.org%2Fschemas%2Fdisplay%2Fbridge%2Fcdns%2Cmhdp8501.yaml%2
> 3&dat
> >
> +a=05%7C02%7CSandor.yu%40nxp.com%7C40a6bd4ff1cd4d934da008dcdc72
> 9fd0%7C
> >
> +686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63862763207998660
> 8%7CUnkno
> >
> +wn%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1h
> aWwi
> >
> +LCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=Uw%2FQQ0Qg36Y8Q6wFPC7Zg
> LzLHvOj8GjH1
> > +k8McgcjrqI%3D&reserved=0
> > +$schema:
> > +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevi
> >
> +cetree.org%2Fmeta-schemas%2Fcore.yaml%23&data=05%7C02%7CSandor.y
> u%40n
> >
> +xp.com%7C40a6bd4ff1cd4d934da008dcdc729fd0%7C686ea1d3bc2b4c6fa92
> cd99c5
> >
> +c301635%7C0%7C0%7C638627632080031124%7CUnknown%7CTWFpbGZs
> b3d8eyJWIjoi
> >
> +MC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%
> 7C%7C%
> >
> +7C&sdata=IG9Em3AWOwzlpR1Wk0Vw%2FF161YcOxuMHbA4Y%2FzftgYA%3D
> &reserved=
> > +0
> > +
> > +title: Cadence MHDP8501 DP/HDMI bridge
> > +
> > +maintainers:
> > +  - Sandor Yu <Sandor.yu at nxp.com>
> > +
> > +description:
> > +  Cadence MHDP8501 DisplayPort/HDMI interface.
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - fsl,imx8mq-mhdp8501
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    maxItems: 1
> > +    description: MHDP8501 DP/HDMI APB clock.
> > +
> > +  phys:
> > +    maxItems: 1
> > +    description:
> > +      phandle to the DP/HDMI PHY
> > +
> > +  interrupts:
> > +    items:
> > +      - description: Hotplug cable plugin.
> > +      - description: Hotplug cable plugout.
> > +
> > +  interrupt-names:
> > +    items:
> > +      - const: plug_in
> > +      - const: plug_out
> > +
> > +  lane-mapping:
> > +    description: lane mapping for HDMI or DisplayPort interface.
> 
> Where is the definition of this property? I do not see any $ref here, so did you
> add it to dtschema?

My apologies, the $ref is missing, will add it in the next version..

B.R
Sandor

> 
> Best regards,
> Krzysztof


From frawang.cn at gmail.com  Sat Sep 28 23:10:23 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Sun, 29 Sep 2024 14:10:23 +0800
Subject: [PATCH v4 1/3] phy: rockchip: inno-usb2: convert clock management to bulk
Message-ID: <20240929061025.3704-1-frawang.cn@gmail.com>

From: Frank Wang <frank.wang at rock-chips.com>

Since some Rockchip SoCs (e.g RK3576) have more than one clock,
this converts the clock management from single to bulk method to
make the driver more flexible.

Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
---
Changelog:
v4:
 - a new patch split from the [PATCH v3 2/2], suggestions from Heiko.

v1-v3:
 - none

 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 43 ++++++++++++++++---
 1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 4f71373ae6e1..ad3e65dc6aa4 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -229,9 +229,10 @@ struct rockchip_usb2phy_port {
  * @dev: pointer to device.
  * @grf: General Register Files regmap.
  * @usbgrf: USB General Register Files regmap.
- * @clk: clock struct of phy input clk.
+ * @clks: array of phy input clocks.
  * @clk480m: clock struct of phy output clk.
  * @clk480m_hw: clock struct of phy output clk management.
+ * @num_clks: number of phy input clocks.
  * @phy_reset: phy reset control.
  * @chg_state: states involved in USB charger detection.
  * @chg_type: USB charger types.
@@ -246,9 +247,10 @@ struct rockchip_usb2phy {
 	struct device	*dev;
 	struct regmap	*grf;
 	struct regmap	*usbgrf;
-	struct clk	*clk;
+	struct clk_bulk_data	*clks;
 	struct clk	*clk480m;
 	struct clk_hw	clk480m_hw;
+	int			num_clks;
 	struct reset_control	*phy_reset;
 	enum usb_chg_state	chg_state;
 	enum power_supply_type	chg_type;
@@ -310,6 +312,13 @@ static int rockchip_usb2phy_reset(struct rockchip_usb2phy *rphy)
 	return 0;
 }
 
+static void rockchip_usb2phy_clk_bulk_disable(void *data)
+{
+	struct rockchip_usb2phy *rphy = data;
+
+	clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks);
+}
+
 static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
 {
 	struct rockchip_usb2phy *rphy =
@@ -376,7 +385,9 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
 {
 	struct device_node *node = rphy->dev->of_node;
 	struct clk_init_data init;
+	struct clk *refclk = NULL;
 	const char *clk_name;
+	int i;
 	int ret = 0;
 
 	init.flags = 0;
@@ -386,8 +397,15 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
 	/* optional override of the clockname */
 	of_property_read_string(node, "clock-output-names", &init.name);
 
-	if (rphy->clk) {
-		clk_name = __clk_get_name(rphy->clk);
+	for (i = 0; i < rphy->num_clks; i++) {
+		if (!strncmp(rphy->clks[i].id, "phyclk", 6)) {
+			refclk = rphy->clks[i].clk;
+			break;
+		}
+	}
+
+	if (!IS_ERR(refclk)) {
+		clk_name = __clk_get_name(refclk);
 		init.parent_names = &clk_name;
 		init.num_parents = 1;
 	} else {
@@ -1406,18 +1424,29 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 	if (IS_ERR(rphy->phy_reset))
 		return PTR_ERR(rphy->phy_reset);
 
-	rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk");
-	if (IS_ERR(rphy->clk)) {
-		return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk),
+	ret = devm_clk_bulk_get_all(dev, &rphy->clks);
+	if (ret == -EPROBE_DEFER) {
+		return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
 				     "failed to get phyclk\n");
 	}
 
+	/* Clocks are optional */
+	rphy->num_clks = ret < 0 ? 0 : ret;
+
 	ret = rockchip_usb2phy_clk480m_register(rphy);
 	if (ret) {
 		dev_err(dev, "failed to register 480m output clock\n");
 		return ret;
 	}
 
+	ret = clk_bulk_prepare_enable(rphy->num_clks, rphy->clks);
+	if (ret)
+		return ret;
+
+	ret = devm_add_action_or_reset(dev, rockchip_usb2phy_clk_bulk_disable, rphy);
+	if (ret)
+		return ret;
+
 	if (rphy->phy_cfg->phy_tuning) {
 		ret = rphy->phy_cfg->phy_tuning(rphy);
 		if (ret)
-- 
2.34.1



From frawang.cn at gmail.com  Sat Sep 28 23:10:24 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Sun, 29 Sep 2024 14:10:24 +0800
Subject: [PATCH v4 2/3] dt-bindings: phy: rockchip,inno-usb2phy: add rk3576
In-Reply-To: <20240929061025.3704-1-frawang.cn@gmail.com>
References: <20240929061025.3704-1-frawang.cn@gmail.com>
Message-ID: <20240929061025.3704-2-frawang.cn@gmail.com>

From: Frank Wang <frank.wang at rock-chips.com>

Add compatible for the USB2 phy in the Rockchip RK3576 SoC.

This change also refactor the clocks list as there are new clocks
adding used for the USB MMU in RK3576 SoC.

Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
---
Changelog:
v4:
 - refactor the clocks list used if:then:

v3:
 - narrowed rk3576 clocks by compatible property.

v2:
 - Categorize clock names by oneOf keyword.

v1:
 - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-1-frank.wang at rock-chips.com/

 .../bindings/phy/rockchip,inno-usb2phy.yaml   | 46 ++++++++++++++++++-
 1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
index 5254413137c6..fc2c03d01a20 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
@@ -20,6 +20,7 @@ properties:
       - rockchip,rk3366-usb2phy
       - rockchip,rk3399-usb2phy
       - rockchip,rk3568-usb2phy
+      - rockchip,rk3576-usb2phy
       - rockchip,rk3588-usb2phy
       - rockchip,rv1108-usb2phy
 
@@ -34,10 +35,12 @@ properties:
     const: 0
 
   clocks:
-    maxItems: 1
+    minItems: 1
+    maxItems: 3
 
   clock-names:
-    const: phyclk
+    minItems: 1
+    maxItems: 3
 
   assigned-clocks:
     description:
@@ -172,6 +175,45 @@ allOf:
             - interrupts
             - interrupt-names
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - rockchip,px30-usb2phy
+              - rockchip,rk3128-usb2phy
+              - rockchip,rk3228-usb2phy
+              - rockchip,rk3308-usb2phy
+              - rockchip,rk3328-usb2phy
+              - rockchip,rk3366-usb2phy
+              - rockchip,rk3399-usb2phy
+              - rockchip,rk3568-usb2phy
+              - rockchip,rk3588-usb2phy
+              - rockchip,rv1108-usb2phy
+    then:
+      properties:
+        clocks:
+          maxItems: 1
+        clock-names:
+          const: phyclk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - rockchip,rk3576-usb2phy
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: phyclk
+            - const: aclk
+            - const: aclk_slv
+
 additionalProperties: false
 
 examples:
-- 
2.34.1



From frawang.cn at gmail.com  Sat Sep 28 23:10:25 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Sun, 29 Sep 2024 14:10:25 +0800
Subject: [PATCH v4 3/3] phy: rockchip: inno-usb2: Add usb2 phys support for rk3576
In-Reply-To: <20240929061025.3704-1-frawang.cn@gmail.com>
References: <20240929061025.3704-1-frawang.cn@gmail.com>
Message-ID: <20240929061025.3704-3-frawang.cn@gmail.com>

From: William Wu <william.wu at rock-chips.com>

The RK3576 SoC has two independent USB2.0 PHYs, and each PHY has
one port. This adds device specific data for it.

Signed-off-by: William Wu <william.wu at rock-chips.com>
Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
---
Changelog:
v4:
 - split the bulk clock management as a new patch, and this just leave
   adding rk3576-specific data.

v3:
 - amend the commit log adds clocks converting.
 - retrieve the clock by "clks.id" in *_clk480m_register() function.

v2:
 - no changes.

v1:
 - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-2-frank.wang at rock-chips.com/


 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 103 ++++++++++++++++++
 1 file changed, 103 insertions(+)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index ad3e65dc6aa4..629f71e7cd1b 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -1524,6 +1524,30 @@ static int rk3128_usb2phy_tuning(struct rockchip_usb2phy *rphy)
 				BIT(2) << BIT_WRITEABLE_SHIFT | 0);
 }
 
+static int rk3576_usb2phy_tuning(struct rockchip_usb2phy *rphy)
+{
+	int ret;
+	u32 reg = rphy->phy_cfg->reg;
+
+	/* Deassert SIDDQ to power on analog block */
+	ret = regmap_write(rphy->grf, reg + 0x0010, GENMASK(29, 29) | 0x0000);
+	if (ret)
+		return ret;
+
+	/* Do reset after exit IDDQ mode */
+	ret = rockchip_usb2phy_reset(rphy);
+	if (ret)
+		return ret;
+
+	/* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */
+	ret |= regmap_write(rphy->grf, reg + 0x000c, GENMASK(27, 24) | 0x0900);
+
+	/* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
+	ret |= regmap_write(rphy->grf, reg + 0x0010, GENMASK(20, 19) | 0x0010);
+
+	return ret;
+}
+
 static int rk3588_usb2phy_tuning(struct rockchip_usb2phy *rphy)
 {
 	int ret;
@@ -1952,6 +1976,84 @@ static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
 	{ /* sentinel */ }
 };
 
+static const struct rockchip_usb2phy_cfg rk3576_phy_cfgs[] = {
+	{
+		.reg = 0x0,
+		.num_ports	= 1,
+		.phy_tuning	= rk3576_usb2phy_tuning,
+		.clkout_ctl	= { 0x0008, 0, 0, 1, 0 },
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x0000, 8, 0, 0, 0x1d1 },
+				.bvalid_det_en	= { 0x00c0, 1, 1, 0, 1 },
+				.bvalid_det_st	= { 0x00c4, 1, 1, 0, 1 },
+				.bvalid_det_clr = { 0x00c8, 1, 1, 0, 1 },
+				.ls_det_en	= { 0x00c0, 0, 0, 0, 1 },
+				.ls_det_st	= { 0x00c4, 0, 0, 0, 1 },
+				.ls_det_clr	= { 0x00c8, 0, 0, 0, 1 },
+				.disfall_en	= { 0x00c0, 6, 6, 0, 1 },
+				.disfall_st	= { 0x00c4, 6, 6, 0, 1 },
+				.disfall_clr	= { 0x00c8, 6, 6, 0, 1 },
+				.disrise_en	= { 0x00c0, 5, 5, 0, 1 },
+				.disrise_st	= { 0x00c4, 5, 5, 0, 1 },
+				.disrise_clr	= { 0x00c8, 5, 5, 0, 1 },
+				.utmi_avalid	= { 0x0080, 1, 1, 0, 1 },
+				.utmi_bvalid	= { 0x0080, 0, 0, 0, 1 },
+				.utmi_ls	= { 0x0080, 5, 4, 0, 1 },
+			}
+		},
+		.chg_det = {
+			.cp_det		= { 0x0080, 8, 8, 0, 1 },
+			.dcp_det	= { 0x0080, 8, 8, 0, 1 },
+			.dp_det		= { 0x0080, 9, 9, 1, 0 },
+			.idm_sink_en	= { 0x0010, 5, 5, 1, 0 },
+			.idp_sink_en	= { 0x0010, 5, 5, 0, 1 },
+			.idp_src_en	= { 0x0010, 14, 14, 0, 1 },
+			.rdm_pdwn_en	= { 0x0010, 14, 14, 0, 1 },
+			.vdm_src_en	= { 0x0010, 7, 6, 0, 3 },
+			.vdp_src_en	= { 0x0010, 7, 6, 0, 3 },
+		},
+	},
+	{
+		.reg = 0x2000,
+		.num_ports	= 1,
+		.phy_tuning	= rk3576_usb2phy_tuning,
+		.clkout_ctl	= { 0x2008, 0, 0, 1, 0 },
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x2000, 8, 0, 0, 0x1d1 },
+				.bvalid_det_en	= { 0x20c0, 1, 1, 0, 1 },
+				.bvalid_det_st	= { 0x20c4, 1, 1, 0, 1 },
+				.bvalid_det_clr = { 0x20c8, 1, 1, 0, 1 },
+				.ls_det_en	= { 0x20c0, 0, 0, 0, 1 },
+				.ls_det_st	= { 0x20c4, 0, 0, 0, 1 },
+				.ls_det_clr	= { 0x20c8, 0, 0, 0, 1 },
+				.disfall_en	= { 0x20c0, 6, 6, 0, 1 },
+				.disfall_st	= { 0x20c4, 6, 6, 0, 1 },
+				.disfall_clr	= { 0x20c8, 6, 6, 0, 1 },
+				.disrise_en	= { 0x20c0, 5, 5, 0, 1 },
+				.disrise_st	= { 0x20c4, 5, 5, 0, 1 },
+				.disrise_clr	= { 0x20c8, 5, 5, 0, 1 },
+				.utmi_avalid	= { 0x2080, 1, 1, 0, 1 },
+				.utmi_bvalid	= { 0x2080, 0, 0, 0, 1 },
+				.utmi_ls	= { 0x2080, 5, 4, 0, 1 },
+			}
+		},
+		.chg_det = {
+			.cp_det		= { 0x2080, 8, 8, 0, 1 },
+			.dcp_det	= { 0x2080, 8, 8, 0, 1 },
+			.dp_det		= { 0x2080, 9, 9, 1, 0 },
+			.idm_sink_en	= { 0x2010, 5, 5, 1, 0 },
+			.idp_sink_en	= { 0x2010, 5, 5, 0, 1 },
+			.idp_src_en	= { 0x2010, 14, 14, 0, 1 },
+			.rdm_pdwn_en	= { 0x2010, 14, 14, 0, 1 },
+			.vdm_src_en	= { 0x2010, 7, 6, 0, 3 },
+			.vdp_src_en	= { 0x2010, 7, 6, 0, 3 },
+		},
+	},
+	{ /* sentinel */ }
+};
+
 static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
 	{
 		.reg = 0x0000,
@@ -2123,6 +2225,7 @@ static const struct of_device_id rockchip_usb2phy_dt_match[] = {
 	{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
 	{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
 	{ .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
+	{ .compatible = "rockchip,rk3576-usb2phy", .data = &rk3576_phy_cfgs },
 	{ .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs },
 	{ .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
 	{}
-- 
2.34.1



From krzk at kernel.org  Sun Sep 29 12:36:13 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 29 Sep 2024 21:36:13 +0200
Subject: [PATCH v4 2/3] dt-bindings: phy: rockchip,inno-usb2phy: add
 rk3576
In-Reply-To: <20240929061025.3704-2-frawang.cn@gmail.com>
References: <20240929061025.3704-1-frawang.cn@gmail.com>
 <20240929061025.3704-2-frawang.cn@gmail.com>
Message-ID: <4czjtesext2ulsmcym2cpjavni7zuve2sdgyiqxkjkaxrl2gpf@7nqylzgd5f55>

On Sun, Sep 29, 2024 at 02:10:24PM +0800, Frank Wang wrote:
> From: Frank Wang <frank.wang at rock-chips.com>
> 
> Add compatible for the USB2 phy in the Rockchip RK3576 SoC.
> 
> This change also refactor the clocks list as there are new clocks
> adding used for the USB MMU in RK3576 SoC.
> 
> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
> ---
> Changelog:
> v4:
>  - refactor the clocks list used if:then:
> 
> v3:
>  - narrowed rk3576 clocks by compatible property.
> 
> v2:
>  - Categorize clock names by oneOf keyword.
> 
> v1:
>  - https://patchwork.kernel.org/project/linux-phy/patch/20240923025326.10467-1-frank.wang at rock-chips.com/
> 
>  .../bindings/phy/rockchip,inno-usb2phy.yaml   | 46 ++++++++++++++++++-
>  1 file changed, 44 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
> index 5254413137c6..fc2c03d01a20 100644
> --- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
> @@ -20,6 +20,7 @@ properties:
>        - rockchip,rk3366-usb2phy
>        - rockchip,rk3399-usb2phy
>        - rockchip,rk3568-usb2phy
> +      - rockchip,rk3576-usb2phy
>        - rockchip,rk3588-usb2phy
>        - rockchip,rv1108-usb2phy
>  
> @@ -34,10 +35,12 @@ properties:
>      const: 0
>  
>    clocks:
> -    maxItems: 1
> +    minItems: 1
> +    maxItems: 3
>  
>    clock-names:
> -    const: phyclk
> +    minItems: 1
> +    maxItems: 3
>  
>    assigned-clocks:
>      description:
> @@ -172,6 +175,45 @@ allOf:
>              - interrupts
>              - interrupt-names
>  
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - rockchip,px30-usb2phy
> +              - rockchip,rk3128-usb2phy
> +              - rockchip,rk3228-usb2phy
> +              - rockchip,rk3308-usb2phy
> +              - rockchip,rk3328-usb2phy
> +              - rockchip,rk3366-usb2phy
> +              - rockchip,rk3399-usb2phy
> +              - rockchip,rk3568-usb2phy
> +              - rockchip,rk3588-usb2phy
> +              - rockchip,rv1108-usb2phy
> +    then:
> +      properties:
> +        clocks:
> +          maxItems: 1
> +        clock-names:
> +          const: phyclk

maxItems: 1 instead

> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - rockchip,rk3576-usb2phy
> +    then:
> +      properties:
> +        clocks:
> +          minItems: 3
> +          maxItems: 3
> +        clock-names:
> +          items:
> +            - const: phyclk
> +            - const: aclk
> +            - const: aclk_slv

This list goes to the top property with minItems: 1. Here you have only
minItems: 3.

This way you have only one definition of entire list with same order of
items between variants.

Best regards,
Krzysztof



From krzk at kernel.org  Sun Sep 29 12:38:12 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 29 Sep 2024 21:38:12 +0200
Subject: [PATCH v4 1/3] phy: rockchip: inno-usb2: convert clock
 management to bulk
In-Reply-To: <20240929061025.3704-1-frawang.cn@gmail.com>
References: <20240929061025.3704-1-frawang.cn@gmail.com>
Message-ID: <jx55slsincpzq6mugfsyc6qpbku2555azj7lithwggo733ggnb@rkqsxpsyoaw7>

On Sun, Sep 29, 2024 at 02:10:23PM +0800, Frank Wang wrote:
> From: Frank Wang <frank.wang at rock-chips.com>
> 
> Since some Rockchip SoCs (e.g RK3576) have more than one clock,
> this converts the clock management from single to bulk method to
> make the driver more flexible.
> 
> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
> ---
> Changelog:
> v4:
>  - a new patch split from the [PATCH v3 2/2], suggestions from Heiko.
> 
> v1-v3:
>  - none
> 
>  drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 43 ++++++++++++++++---
>  1 file changed, 36 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> index 4f71373ae6e1..ad3e65dc6aa4 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> @@ -229,9 +229,10 @@ struct rockchip_usb2phy_port {
>   * @dev: pointer to device.
>   * @grf: General Register Files regmap.
>   * @usbgrf: USB General Register Files regmap.
> - * @clk: clock struct of phy input clk.
> + * @clks: array of phy input clocks.
>   * @clk480m: clock struct of phy output clk.
>   * @clk480m_hw: clock struct of phy output clk management.
> + * @num_clks: number of phy input clocks.
>   * @phy_reset: phy reset control.
>   * @chg_state: states involved in USB charger detection.
>   * @chg_type: USB charger types.
> @@ -246,9 +247,10 @@ struct rockchip_usb2phy {
>  	struct device	*dev;
>  	struct regmap	*grf;
>  	struct regmap	*usbgrf;
> -	struct clk	*clk;
> +	struct clk_bulk_data	*clks;
>  	struct clk	*clk480m;
>  	struct clk_hw	clk480m_hw;
> +	int			num_clks;
>  	struct reset_control	*phy_reset;
>  	enum usb_chg_state	chg_state;
>  	enum power_supply_type	chg_type;
> @@ -310,6 +312,13 @@ static int rockchip_usb2phy_reset(struct rockchip_usb2phy *rphy)
>  	return 0;
>  }
>  
> +static void rockchip_usb2phy_clk_bulk_disable(void *data)
> +{
> +	struct rockchip_usb2phy *rphy = data;
> +
> +	clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks);
> +}
> +
>  static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
>  {
>  	struct rockchip_usb2phy *rphy =
> @@ -376,7 +385,9 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
>  {
>  	struct device_node *node = rphy->dev->of_node;
>  	struct clk_init_data init;
> +	struct clk *refclk = NULL;
>  	const char *clk_name;
> +	int i;
>  	int ret = 0;
>  
>  	init.flags = 0;
> @@ -386,8 +397,15 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
>  	/* optional override of the clockname */
>  	of_property_read_string(node, "clock-output-names", &init.name);
>  
> -	if (rphy->clk) {
> -		clk_name = __clk_get_name(rphy->clk);
> +	for (i = 0; i < rphy->num_clks; i++) {
> +		if (!strncmp(rphy->clks[i].id, "phyclk", 6)) {
> +			refclk = rphy->clks[i].clk;
> +			break;
> +		}
> +	}
> +
> +	if (!IS_ERR(refclk)) {
> +		clk_name = __clk_get_name(refclk);
>  		init.parent_names = &clk_name;
>  		init.num_parents = 1;
>  	} else {
> @@ -1406,18 +1424,29 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
>  	if (IS_ERR(rphy->phy_reset))
>  		return PTR_ERR(rphy->phy_reset);
>  
> -	rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk");
> -	if (IS_ERR(rphy->clk)) {
> -		return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk),
> +	ret = devm_clk_bulk_get_all(dev, &rphy->clks);
> +	if (ret == -EPROBE_DEFER) {

This does not make much sense. Why would you proceed on other critical
errors?

You want to use optional variant, I guess?

Best regards,
Krzysztof



From manivannan.sadhasivam at linaro.org  Mon Sep 30 00:25:53 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Mon, 30 Sep 2024 09:25:53 +0200
Subject: [PATCH v4 5/6] PCI: qcom: Add support for X1E80100 SoC
In-Reply-To: <fb40afe3-eb27-4136-8942-26a40fb395a7@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-6-quic_qianyu@quicinc.com>
 <20240924135021.ybpyoahlpuvedma5@thinkpad>
 <ZvLX_wkh7_y7sjPZ@hovoldconsulting.com>
 <4368503f-fb33-4e6a-bef4-517e2b959400@quicinc.com>
 <20240925080724.vgkgmnqc44aoiarv@thinkpad>
 <1419ba07-5163-4126-8869-2213eea6c492@quicinc.com>
 <fb40afe3-eb27-4136-8942-26a40fb395a7@quicinc.com>
Message-ID: <20240930072553.n2tj5jjtltowswbf@thinkpad>

On Thu, Sep 26, 2024 at 01:19:18PM +0800, Qiang Yu wrote:
> 
> On 9/26/2024 11:28 AM, Qiang Yu wrote:
> > 
> > On 9/25/2024 4:07 PM, Manivannan Sadhasivam wrote:
> > > On Wed, Sep 25, 2024 at 11:47:02AM +0800, Qiang Yu wrote:
> > > > On 9/24/2024 11:17 PM, Johan Hovold wrote:
> > > > > On Tue, Sep 24, 2024 at 03:50:21PM +0200, Manivannan Sadhasivam wrote:
> > > > > > On Tue, Sep 24, 2024 at 03:14:43AM -0700, Qiang Yu wrote:
> > > > > > > X1E80100 has PCIe ports that support up to Gen4 x8
> > > > > > > based on hardware IP
> > > > > > > version 1.38.0.
> > > > > > > 
> > > > > > > Currently the ops_1_9_0 which is being used for
> > > > > > > X1E80100 has config_sid
> > > > > > > callback to config BDF to SID table. However, this callback is not
> > > > > > > required for X1E80100 because it has smmuv3 support
> > > > > > > and BDF to SID table
> > > > > > > will be not present.
> > > > > > > 
> > > > > > > Hence add support for X1E80100 by introducing a new
> > > > > > > ops and cfg structures
> > > > > > > that don't require the config_sid callback. This
> > > > > > > could be reused by the
> > > > > > > future platforms based on SMMUv3.
> > > > > > > 
> > > > > > Oops... I completely overlooked that you are not adding
> > > > > > the SoC support but
> > > > > > fixing the existing one :( Sorry for suggesting a commit
> > > > > > message that changed
> > > > > > the context.
> > > > > > 
> > > > > > For this, you can have something like:
> > > > > > 
> > > > > > "PCI: qcom: Fix the ops for X1E80100 SoC
> > > > > > 
> > > > > > X1E80100 SoC is based on SMMUv3, hence it doesn't need
> > > > > > the BDF2SID mapping
> > > > > > present in the existing cfg_1_9_0 ops. This is fixed by
> > > > > > introducing new ops
> > > > > > 'ops_1_38_0' and cfg 'cfg_1_38_0' structures. These are
> > > > > > exactly same as the
> > > > > > 1_9_0 ones, but they don't have the 'config_sid()'
> > > > > > callback that handles the
> > > > > > BDF2SID mapping in the hardware. These new structures
> > > > > > could also be used by the
> > > > > > future SoCs making use of SMMUv3."
> > > > > Don't we need something like this for sc8280xp and other
> > > > > platforms using
> > > > > SMMUv3 as well?
> > > > ?From what I know, sc8280xp and other qcom platforms are not
> > > > using SMMUv3.
> > > sc8280xp indeed has SMMUv3 for PCIe, but I'm not sure how it is
> > > configured. So
> > > not completely sure whether we can avoid the mapping table or not.
> > > 
> > > Qiang, please check with the hw team and let us know.
> > Sure, will update once I get any response from hw team.
> HW team confirmed sc8280xp uses smmv3 for PCIe and doesn't support BDF2SID
> map.
> 
> Besides, Abel once got confirmation from Joe that we also need to disable
> L0s for X1E80100. So can we use cfg_sc8280xp for both X1E80100 and SC8280XP
> and change its ops to ops_1_38_0?
> 

Sounds good. But, OPS naming should be based on the baseline version i.e., it
should be based on the IP version of SC8280XP and reused by X1E80100. Not the
other way around.

- Mani

> Thanks,
> Qiang
> > 
> > Thanks,
> > Qiang
> > > 
> > > - Mani
> > > 

-- 
????????? ????????


From manivannan.sadhasivam at linaro.org  Mon Sep 30 00:32:17 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Mon, 30 Sep 2024 09:32:17 +0200
Subject: [PATCH v4 6/6] arm64: dts: qcom: x1e80100: Add support for PCIe3
 on x1e80100
In-Reply-To: <1c6bf1a9-a781-4152-a7a1-7992c6f15829@quicinc.com>
References: <20240924101444.3933828-1-quic_qianyu@quicinc.com>
 <20240924101444.3933828-7-quic_qianyu@quicinc.com>
 <9a692c98-eb0a-4d86-b642-ea655981ff53@kernel.org>
 <20240925080522.qwjeyrpjtz64pccx@thinkpad>
 <4ee4d016-9d68-4925-9f49-e73a4e7fa794@kernel.org>
 <2731e17d-c1ad-4fb4-ab60-82ceafeffbaf@kernel.org>
 <20240925125224.53g6rw46qufxsw6m@thinkpad>
 <1c6bf1a9-a781-4152-a7a1-7992c6f15829@quicinc.com>
Message-ID: <20240930073217.5vcg5codqa25xfco@thinkpad>

On Thu, Sep 26, 2024 at 11:15:34AM +0800, Qiang Yu wrote:
> 
> On 9/25/2024 8:52 PM, Manivannan Sadhasivam wrote:
> > On Wed, Sep 25, 2024 at 11:46:35AM +0200, Konrad Dybcio wrote:
> > > On 25.09.2024 11:30 AM, Konrad Dybcio wrote:
> > > > On 25.09.2024 10:05 AM, Manivannan Sadhasivam wrote:
> > > > > On Tue, Sep 24, 2024 at 04:26:34PM +0200, Konrad Dybcio wrote:
> > > > > > On 24.09.2024 12:14 PM, Qiang Yu wrote:
> > > > > > > Describe PCIe3 controller and PHY. Also add required system resources like
> > > > > > > regulators, clocks, interrupts and registers configuration for PCIe3.
> > > > > > > 
> > > > > > > Signed-off-by: Qiang Yu <quic_qianyu at quicinc.com>
> > > > > > > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > > > > > > ---
> > > > > > Qiang, Mani
> > > > > > 
> > > > > > I have a RTS5261 mmc chip on PCIe3 on the Surface Laptop.
> > > > > Is it based on x1e80100?
> > > > You would think so :P
> > > > 
> > > > > > Adding the global irq breaks sdcard detection (the chip still comes
> > > > > > up fine) somehow. Removing the irq makes it work again :|
> > > > > > 
> > > > > > I've confirmed that the irq number is correct
> > > > > > 
> > > > > Yeah, I did see some issues with MSI on SM8250 (RB5) when global interrupts are
> > > > > enabled and I'm working with the hw folks to understand what is going on. But
> > > > > I didn't see the same issues on newer platforms (sa8775p etc...).
> > > > > 
> > > > > Can you please confirm if the issue is due to MSI not being received from the
> > > > > device? Checking the /proc/interrutps is enough.
> > > > There's no msi-map for PCIe3. I recall +Johan talking about some sort of
> > > > a bug that prevents us from adding it?
> > Yeah, that's for using GIC-ITS to receive MSIs. But the default one is the
> > internal MSI controller in DWC.
> > 
> > > Unless you just meant the msi0..=7 interrupts, then yeah, I only get one irq
> > > event with "global" in place and it seems to never get more
> > > 
> > Ok. Then most likely the same issue I saw on SM8250 as well. But I'm confused
> > why Qiang didn't see the issue. I specifically asked him to add the global
> > interrupt and test it with the endpoint to check if the issue arises or not.
> > 
> > Qiang, can you please confirm?
> Sorry, I misunderstood what you mean. I only verified if link was up but
> ignored the status of ep device
> driver.
> 
> But look like this issue is because snpsys MSI irq is msked during probe.
> Can you please also unmask BIT(23) - BIT(30) when unmask
> PARF_INT_ALL_LINK_UP,
> like this
> 
> @@ -1772,7 +1772,8 @@ static int qcom_pcie_probe(struct platform_device
> *pdev)
> ??????????????????????? goto err_host_deinit;
> ??????????????? }
> 
> -?????????????? writel_relaxed(PARF_INT_ALL_LINK_UP, pcie->parf +
> PARF_INT_ALL_MASK);
> +?????????????? writel_relaxed(PARF_INT_ALL_LINK_UP | GENMASK(30, 23),
> pcie->parf + PARF_INT_ALL_MASK);
> +?????????????? dev_err(dev, "INT_ALL_MASK: 0x%x\n",
> readl_relaxed(pcie->parf + PARF_INT_ALL_MASK));
> ??????? }
> 
> After that, this issue is fixed on my setup.
> 

I did see those bits, but they were mentioned as diagnostic interrupts. So I was
not sure why disabling them masks MSI. Furthermore, MSI seems to work on SM8450
without enabling these bits.

Anyway, since you mentioned that it helps in bringing back MSI on this platform,
it doesn't hurt to enable these interrupts. I will post a patch for that,
thanks!

- Mani

-- 
????????? ????????


From mripard at kernel.org  Mon Sep 30 01:18:06 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 30 Sep 2024 10:18:06 +0200
Subject: [PATCH v17 4/8] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <DB9PR04MB945284B95FAE4FE127E6568FF4752@DB9PR04MB9452.eurprd04.prod.outlook.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
 <8bdf573bfd7e3feb45d7ccb53765a978a685ce2d.1727159906.git.Sandor.yu@nxp.com>
 <20240924-mottled-psychedelic-lorikeet-ef8f4c@houat>
 <DB9PR04MB945284B95FAE4FE127E6568FF4752@DB9PR04MB9452.eurprd04.prod.outlook.com>
Message-ID: <wdelo4zco6v5qchdupfvbrqin4n7fyjyo6yaqbpfihdkkhceoi@ja4zxmhk5isq>

On Sun, Sep 29, 2024 at 02:34:36AM GMT, Sandor Yu wrote:
> > > +static void cdns_hdmi_sink_config(struct cdns_mhdp8501_device *mhdp)
> > > +{
> > > +	struct drm_display_info *display = &mhdp->curr_conn->display_info;
> > > +	struct drm_connector_state *conn_state = mhdp->curr_conn->state;
> > 
> > That looks a bit hackish to me. We should probably provide a helper to get the
> > connector state the bridge is attached to.
> 
> How about code change to followed, is it more clear?
> 370         struct drm_connector *connector = mhdp->curr_conn;
> 371         struct drm_connector_state *conn_state = connector->state;
> 372         struct drm_display_info *display = &connector->display_info;
> 373         struct drm_scdc *scdc = &display->hdmi.scdc;

What I meant was that I wish bridges had a way to get their connector
pointer. It doesn't look like it's possible with drm_bridge_connector,
and we don't have access to drm_display_info anymore.

I don't really see a good way to do this yet, so maybe that kind of
workaround is ok. Eventually, I guess we'll have the scrambler setup in
the HDMI connector helpers anyway.

Dmitry, any idea?

> > > +static enum drm_mode_status
> > > +cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
> > > +			       const struct drm_display_mode *mode,
> > > +			       unsigned long long tmds_rate) {
> > > +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > > +	union phy_configure_opts phy_cfg;
> > > +	int ret;
> > > +
> > > +	phy_cfg.hdmi.tmds_char_rate = tmds_rate;
> > > +
> > > +	ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
> > > +	if (ret < 0)
> > > +		return MODE_CLOCK_RANGE;
> > > +
> > > +	return MODE_OK;
> > > +}
> > > +
> > > +static enum drm_mode_status
> > > +cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
> > > +			    const struct drm_display_info *info,
> > > +			    const struct drm_display_mode *mode) {
> > > +	unsigned long long tmds_rate;
> > > +
> > > +	/* We don't support double-clocked and Interlaced modes */
> > > +	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
> > > +	    mode->flags & DRM_MODE_FLAG_INTERLACE)
> > > +		return MODE_BAD;
> > > +
> > > +	if (mode->hdisplay > 3840)
> > > +		return MODE_BAD_HVALUE;
> > > +
> > > +	if (mode->vdisplay > 2160)
> > > +		return MODE_BAD_VVALUE;
> > > +
> > > +	tmds_rate = mode->clock * 1000ULL;
> > > +	return cdns_hdmi_tmds_char_rate_valid(bridge, mode, tmds_rate); }
> > 
> > Didn't we agree on creating a mode_valid helper?
> 
> In fact, now I'm no idea where should add the mode_valid helper function.
> 
> In struct drm_bridge_funcs, it had mode_valid() and hdmi_tmds_char_rate_valid().
> 
> If create a new mode_valid helper function in struct drm_connector_hdmi_funcs,
> Is it appropriate to call another API function(tmds_char_rate_valid)
> at the same level within this API function?

I'm not quite sure what you mean, but a reasonable approach to me would
be to turn drm_hdmi_state_helper.c hdmi_clock_valid into a public
function, and then call it from drm_bridge_connector mode_valid hook.

It's a similar discussion to the previous one really: in order to
implement it properly, we need access to drm_display_info.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 273 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20240930/d0c0205c/attachment.sig>

From s-vadapalli at ti.com  Mon Sep 30 02:51:45 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Mon, 30 Sep 2024 15:21:45 +0530
Subject: [PATCH v2] dt-bindings: phy: cadence-sierra: Allow PHY types QSGMII and SGMII
Message-ID: <20240930095145.3004053-1-s-vadapalli@ti.com>

The Sierra SERDES can be configured for QSGMII and SGMII protocols. Hence,
update the bindings to treat "PHY_TYPE_QSGMII" and "PHY_TYPE_SGMII" as
valid values for the "cdns,phy-type" property.

Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---

Hello,

This patch is based on linux-next tagged next-20240930.

v1:
https://lore.kernel.org/r/20240830105316.1824319-1-s-vadapalli at ti.com/
Changes since v1:
- Rebased patch on next-20240930.
- Collected Acked-by tag from Conor Dooley <conor.dooley at microchip.com>

Regards,
Siddharth.

 Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml b/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml
index 37f028f7a095..137ac5703853 100644
--- a/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml
@@ -96,7 +96,7 @@ patternProperties:
           Specifies the type of PHY for which the group of PHY lanes is used.
           Refer include/dt-bindings/phy/phy.h. Constants from the header should be used.
         $ref: /schemas/types.yaml#/definitions/uint32
-        enum: [2, 4]
+        enum: [2, 4, 8, 9]
 
       cdns,num-lanes:
         description:
-- 
2.40.1



From s-vadapalli at ti.com  Mon Sep 30 02:57:45 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Mon, 30 Sep 2024 15:27:45 +0530
Subject: [PATCH v2] phy: ti: phy-j721e-wiz: fix usxgmii configuration
Message-ID: <20240930095745.3007057-1-s-vadapalli@ti.com>

Commit b64a85fb8f53 ("phy: ti: phy-j721e-wiz.c: Add usxgmii support in
wiz driver") added support for USXGMII mode. In doing so, P0_REFCLK_SEL
was set to "pcs_mac_clk_divx1_ln_0" (0x3) and P0_STANDARD_MODE was set to
LANE_MODE_GEN1, which results in a data rate of 5.15625 Gbps. However,
since the USXGMII mode can support up to 10.3125 Gbps data rate, the
aforementioned fields should be set to "pcs_mac_clk_divx0_ln_0" (0x2) and
LANE_MODE_GEN2 respectively. Fix the configuration accordingly to truly
support USXGMII up to 10G.

Fixes: b64a85fb8f53 ("phy: ti: phy-j721e-wiz.c: Add usxgmii support in wiz driver")
Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---

Hello,

This patch is based on commit
9852d85ec9d4 Linux 6.12-rc1
of mainline Linux.

v1:
https://lore.kernel.org/r/20240910091714.1082191-1-s-vadapalli at ti.com/
Changes since v1:
- Rebased to Linux 6.12-rc1.

Regards,
Siddharth.

 drivers/phy/ti/phy-j721e-wiz.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index a6c0c5607ffd..c6e846d385d2 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -450,8 +450,8 @@ static int wiz_mode_select(struct wiz *wiz)
 		} else if (wiz->lane_phy_type[i] == PHY_TYPE_USXGMII) {
 			ret = regmap_field_write(wiz->p0_mac_src_sel[i], 0x3);
 			ret = regmap_field_write(wiz->p0_rxfclk_sel[i], 0x3);
-			ret = regmap_field_write(wiz->p0_refclk_sel[i], 0x3);
-			mode = LANE_MODE_GEN1;
+			ret = regmap_field_write(wiz->p0_refclk_sel[i], 0x2);
+			mode = LANE_MODE_GEN2;
 		} else {
 			continue;
 		}
-- 
2.40.1



From krzysztof.kozlowski at linaro.org  Mon Sep 30 04:06:49 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 30 Sep 2024 13:06:49 +0200
Subject: [PATCH v17 3/8] dt-bindings: display: bridge: Add Cadence
 MHDP8501
In-Reply-To: <DB9PR04MB94529379E1947D66848B7BE2F4752@DB9PR04MB9452.eurprd04.prod.outlook.com>
References: <cover.1727159906.git.Sandor.yu@nxp.com>
 <b2e1d26f964a03163ec7a1ba6ac8d7c88d6cb111.1727159906.git.Sandor.yu@nxp.com>
 <wfdanj6ibwybx2puqvi6xjy6h5t4yagnb2mod7ln3zca4dl5wz@4mvbe6wjavb6>
 <DB9PR04MB94529379E1947D66848B7BE2F4752@DB9PR04MB9452.eurprd04.prod.outlook.com>
Message-ID: <e235f275-b9ef-40b8-929d-faddd58c17aa@linaro.org>

On 29/09/2024 04:36, Sandor Yu wrote:
> Hi Krzysztof?
> 
> Thanks for your comments,
> 
>>
>>
>> On Tue, Sep 24, 2024 at 03:36:48PM +0800, Sandor Yu wrote:
>>> Add bindings for Cadence MHDP8501 DisplayPort/HDMI bridge.
>>>
>>> Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
>>> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>>
>> Drop
> OK, I will remove it in the next version.
> 
>>
>>> ---
>>> v16->v17:
>>> - Add lane-mapping property
>>
>> That's a significant change.
> OK.
> 
>>
>>>
>>> v9->v16:
>>>  *No change
>>>
>>> .../display/bridge/cdns,mhdp8501.yaml         | 109
>> ++++++++++++++++++
>>>  1 file changed, 109 insertions(+)
>>>  create mode 100644
>>> Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
>>>
>>> diff --git
>>> a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
>>> b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
>>> new file mode 100644
>>> index 0000000000000..3f79f328c7425
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.y
>>> +++ aml
>>
>>> @@ -0,0 +1,109 @@
>>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2
>>> +---
>>> +$id:
>>> +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevi
>>>
>> +cetree.org%2Fschemas%2Fdisplay%2Fbridge%2Fcdns%2Cmhdp8501.yaml%2
>> 3&dat
>>>
>> +a=05%7C02%7CSandor.yu%40nxp.com%7C40a6bd4ff1cd4d934da008dcdc72
>> 9fd0%7C
>>>
>> +686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63862763207998660
>> 8%7CUnkno
>>>
>> +wn%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1h
>> aWwi
>>>
>> +LCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=Uw%2FQQ0Qg36Y8Q6wFPC7Zg
>> LzLHvOj8GjH1
>>> +k8McgcjrqI%3D&reserved=0
>>> +$schema:
>>> +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevi
>>>
>> +cetree.org%2Fmeta-schemas%2Fcore.yaml%23&data=05%7C02%7CSandor.y
>> u%40n
>>>
>> +xp.com%7C40a6bd4ff1cd4d934da008dcdc729fd0%7C686ea1d3bc2b4c6fa92
>> cd99c5
>>>
>> +c301635%7C0%7C0%7C638627632080031124%7CUnknown%7CTWFpbGZs
>> b3d8eyJWIjoi
>>>
>> +MC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%
>> 7C%7C%
>>>
>> +7C&sdata=IG9Em3AWOwzlpR1Wk0Vw%2FF161YcOxuMHbA4Y%2FzftgYA%3D
>> &reserved=
>>> +0
>>> +
>>> +title: Cadence MHDP8501 DP/HDMI bridge
>>> +
>>> +maintainers:
>>> +  - Sandor Yu <Sandor.yu at nxp.com>
>>> +
>>> +description:
>>> +  Cadence MHDP8501 DisplayPort/HDMI interface.
>>> +
>>> +properties:
>>> +  compatible:
>>> +    enum:
>>> +      - fsl,imx8mq-mhdp8501
>>> +
>>> +  reg:
>>> +    maxItems: 1
>>> +
>>> +  clocks:
>>> +    maxItems: 1
>>> +    description: MHDP8501 DP/HDMI APB clock.
>>> +
>>> +  phys:
>>> +    maxItems: 1
>>> +    description:
>>> +      phandle to the DP/HDMI PHY
>>> +
>>> +  interrupts:
>>> +    items:
>>> +      - description: Hotplug cable plugin.
>>> +      - description: Hotplug cable plugout.
>>> +
>>> +  interrupt-names:
>>> +    items:
>>> +      - const: plug_in
>>> +      - const: plug_out
>>> +
>>> +  lane-mapping:
>>> +    description: lane mapping for HDMI or DisplayPort interface.
>>
>> Where is the definition of this property? I do not see any $ref here, so did you
>> add it to dtschema?
> 
> My apologies, the $ref is missing, will add it in the next version..

And that's different than existing properties, e.g. data-lanes or
lane-polarities? There is no description here except copying property
name, which is not useful at all.

Come with solution matching other bridges and media devices.

Best regards,
Krzysztof



From rogerq at kernel.org  Mon Sep 30 07:06:35 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Mon, 30 Sep 2024 17:06:35 +0300
Subject: [PATCH v2] phy: ti: phy-j721e-wiz: fix usxgmii configuration
In-Reply-To: <20240930095745.3007057-1-s-vadapalli@ti.com>
References: <20240930095745.3007057-1-s-vadapalli@ti.com>
Message-ID: <4b42b8e5-3246-4f58-b494-735930d2424a@kernel.org>

Hi Siddharth,

On 30/09/2024 12:57, Siddharth Vadapalli wrote:
> Commit b64a85fb8f53 ("phy: ti: phy-j721e-wiz.c: Add usxgmii support in
> wiz driver") added support for USXGMII mode. In doing so, P0_REFCLK_SEL
> was set to "pcs_mac_clk_divx1_ln_0" (0x3) and P0_STANDARD_MODE was set to
> LANE_MODE_GEN1, which results in a data rate of 5.15625 Gbps. However,
> since the USXGMII mode can support up to 10.3125 Gbps data rate, the
> aforementioned fields should be set to "pcs_mac_clk_divx0_ln_0" (0x2) and
> LANE_MODE_GEN2 respectively. Fix the configuration accordingly to truly
> support USXGMII up to 10G.
> 
> Fixes: b64a85fb8f53 ("phy: ti: phy-j721e-wiz.c: Add usxgmii support in wiz driver")
> Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
> ---
> 
> Hello,
> 
> This patch is based on commit
> 9852d85ec9d4 Linux 6.12-rc1
> of mainline Linux.
> 
> v1:
> https://lore.kernel.org/r/20240910091714.1082191-1-s-vadapalli at ti.com/
> Changes since v1:
> - Rebased to Linux 6.12-rc1.
> 
> Regards,
> Siddharth.
> 
>  drivers/phy/ti/phy-j721e-wiz.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
> index a6c0c5607ffd..c6e846d385d2 100644
> --- a/drivers/phy/ti/phy-j721e-wiz.c
> +++ b/drivers/phy/ti/phy-j721e-wiz.c
> @@ -450,8 +450,8 @@ static int wiz_mode_select(struct wiz *wiz)
>  		} else if (wiz->lane_phy_type[i] == PHY_TYPE_USXGMII) {
>  			ret = regmap_field_write(wiz->p0_mac_src_sel[i], 0x3);
>  			ret = regmap_field_write(wiz->p0_rxfclk_sel[i], 0x3);

I'm not sure. Don't we have to change rxfclk as well?

> -			ret = regmap_field_write(wiz->p0_refclk_sel[i], 0x3);
> -			mode = LANE_MODE_GEN1;
> +			ret = regmap_field_write(wiz->p0_refclk_sel[i], 0x2);
> +			mode = LANE_MODE_GEN2;
>  		} else {
>  			continue;
>  		}

-- 
cheers,
-roger


From keith.zhao at starfivetech.com  Fri Sep 27 01:14:51 2024
From: keith.zhao at starfivetech.com (Keith Zhao)
Date: Fri, 27 Sep 2024 08:14:51 +0000
Subject: Bouncing maintainer: Shengyang Chen
Message-ID: <NTZPR01MB1050F6BD9AF195812C3FB7CCEE6B2@NTZPR01MB1050.CHNPR01.prod.partner.outlook.cn>

Hi Konstantin:

I will submit a patch to update the MAINTAINERS file.
M: Shengyang Chen <shengyang.chen at starfivetech.com>

Thank you for the reminder.


> -----Original Message-----
> From: Konstantin Ryabitsev <konstantin at linuxfoundation.org>
> Sent: 2024?9?25? 4:26
> To: Keith Zhao <keith.zhao at starfivetech.com>
> Cc: linux-phy at lists.infradead.org; helpdesk at kernel.org
> Subject: Bouncing maintainer: Shengyang Chen
> 
> Hello:
> 
> I'm reaching out to co-maintainers of the following subsystems:
> 
>   - STARFIVE JH7110 DPHY TX DRIVER
> 
> The email address for one of your maintainers is bouncing:
> 
>   M: Shengyang Chen <shengyang.chen at starfivetech.com>
> 
> There are several possible courses of action:
> 
> 1. If you know the new email address for the maintainer, please ask them to
>    submit a patch for MAINTAINERS and .mailmap files.
> 
> 2. If this maintainer stepped away from their duties, or if co-maintainers are
>    equally unable to reach them via any other means, please submit a patch to
>    MAINTAINERS to remove their M: entry.
> 
> The goal is to have no bouncing M: entries in the maintainers file, so please
> follow up as soon as you have decided on the correct course of action.
> 
> Best regards,
> --
> Konstantin Ryabitsev
> Linux Foundation
> 
> bugspray track

From christian.bruel at foss.st.com  Mon Sep 30 10:08:45 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Mon, 30 Sep 2024 19:08:45 +0200
Subject: [PATCH v9 3/5] MAINTAINERS: add entry for ST STM32MP25 COMBOPHY driver
In-Reply-To: <20240930170847.948779-1-christian.bruel@foss.st.com>
References: <20240930170847.948779-1-christian.bruel@foss.st.com>
Message-ID: <20240930170847.948779-4-christian.bruel@foss.st.com>

Add myself as STM32MP25 COMBOPHY maintainer

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index a70b7c9c3533..73fd76dab699 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21908,6 +21908,12 @@ F:	drivers/*/stm32-*timer*
 F:	drivers/pwm/pwm-stm32*
 F:	include/linux/*/stm32-*tim*
 
+STM32MP25 USB3/PCIE COMBOPHY DRIVER
+M:	Christian Bruel <christian.bruel at foss.st.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
+F:	drivers/phy/st/phy-stm32-combophy.c
+
 STMMAC ETHERNET DRIVER
 M:	Alexandre Torgue <alexandre.torgue at foss.st.com>
 M:	Jose Abreu <joabreu at synopsys.com>
-- 
2.34.1



From christian.bruel at foss.st.com  Mon Sep 30 10:08:46 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Mon, 30 Sep 2024 19:08:46 +0200
Subject: [PATCH v9 4/5] arm64: dts: st: Add combophy node on stm32mp251
In-Reply-To: <20240930170847.948779-1-christian.bruel@foss.st.com>
References: <20240930170847.948779-1-christian.bruel@foss.st.com>
Message-ID: <20240930170847.948779-5-christian.bruel@foss.st.com>

Add support for COMBOPHY which is used either by the USB3 and PCIe
controller.
USB3 or PCIe mode is done with phy_set_mode().
PCIe internal reference clock can be generated from the internal clock
source or optionnaly from an external 100Mhz pad.

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp251.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 1167cf63d7e8..b596afec1b6e 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -7,6 +7,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset/st,stm32mp25-rcc.h>
 #include <dt-bindings/regulator/st,stm32mp25-regulator.h>
+#include <dt-bindings/phy/phy.h>
 
 / {
 	#address-cells = <2>;
@@ -518,6 +519,21 @@ i2c8: i2c at 46040000 {
 				status = "disabled";
 			};
 
+			combophy: phy at 480c0000 {
+				compatible = "st,stm32mp25-combophy";
+				reg = <0x480c0000 0x1000>;
+				#phy-cells = <1>;
+				clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>;
+				clock-names = "apb", "ker";
+				resets = <&rcc USB3PCIEPHY_R>;
+				reset-names = "phy";
+				access-controllers = <&rifsc 67>;
+				power-domains = <&CLUSTER_PD>;
+				wakeup-source;
+				interrupts-extended = <&exti1 45 IRQ_TYPE_EDGE_FALLING>;
+				status = "disabled";
+			};
+
 			sdmmc1: mmc at 48220000 {
 				compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell";
 				arm,primecell-periphid = <0x00353180>;
-- 
2.34.1



From christian.bruel at foss.st.com  Mon Sep 30 10:08:42 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Mon, 30 Sep 2024 19:08:42 +0200
Subject: [PATCH v9 0/5] Add STM32MP25 USB3/PCIE COMBOPHY driver 
Message-ID: <20240930170847.948779-1-christian.bruel@foss.st.com>

Changes in v9:
   - Fix bot clang warnings: uninitialized variables and
     include bitfield.h for FIELD_GET

Changes in v7/v8:
   - MAINTAINERS: Reorder STM32MP25 DRIVER entry

Changes in v6:
   - stm32_combophy_pll_init: merge combophy_cr1 accesses and error path.
   - Use devm_reset_control_get_exclusive

Changes in v5:
   - Drop syscfg phandle and change driver to use lookup_by_compatible
   - Use clk_bulk API and drop stm32_combophy_enable/disable_clocks
   - Reorder required: list.
   - Fix access-controllers maxItems

Changes in v4:
   - "#phy-cells": Drop type item description since it is specified
     by user node phandle.
   - Rename stm32-combophy.yaml to match compatible
   - Drop wakeup-source from bindings (should be generic)
   - Alphabetically reorder required: list.
   - Drop "Reviewed-by" since those previous changes

Changes in v3:
   - Reorder MAINTAINERS patch

Changes in v2:
   - Reorder entries
   - Rename clock_names and reset_names bindings
   - Rename and clarify rx-equalizer binding

Christian Bruel (5):
  dt-bindings: phy: Add STM32MP25 COMBOPHY bindings
  phy: stm32: Add support for STM32MP25 COMBOPHY.
  MAINTAINERS: add entry for ST STM32MP25 COMBOPHY driver
  arm64: dts: st: Add combophy node on stm32mp251
  arm64: dts: st: Enable COMBOPHY on the stm32mp257f-ev1 board

 .../bindings/phy/st,stm32mp25-combophy.yaml   | 119 ++++
 MAINTAINERS                                   |   6 +
 arch/arm64/boot/dts/st/stm32mp251.dtsi        |  16 +
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts    |  14 +
 drivers/phy/st/Kconfig                        |  11 +
 drivers/phy/st/Makefile                       |   1 +
 drivers/phy/st/phy-stm32-combophy.c           | 598 ++++++++++++++++++
 7 files changed, 765 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
 create mode 100644 drivers/phy/st/phy-stm32-combophy.c


base-commit: 9bd8e1ba97b1f2d0410db9ff182d677992084770
-- 
2.34.1



From christian.bruel at foss.st.com  Mon Sep 30 10:08:44 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Mon, 30 Sep 2024 19:08:44 +0200
Subject: [PATCH v9 2/5] phy: stm32: Add support for STM32MP25 COMBOPHY.
In-Reply-To: <20240930170847.948779-1-christian.bruel@foss.st.com>
References: <20240930170847.948779-1-christian.bruel@foss.st.com>
Message-ID: <20240930170847.948779-3-christian.bruel@foss.st.com>

Addition of the COMBOPHY driver found on STM32MP25 platforms

This single lane PHY is shared (exclusive) between the USB3 and PCIE
controllers.
Supports 5Gbit/s for PCIE gen2 or 2.5Gbit/s for PCIE gen1.

Supports wakeup-source capability to wakeup system using remote-wakeup
capable USB device

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 drivers/phy/st/Kconfig              |  11 +
 drivers/phy/st/Makefile             |   1 +
 drivers/phy/st/phy-stm32-combophy.c | 598 ++++++++++++++++++++++++++++
 3 files changed, 610 insertions(+)
 create mode 100644 drivers/phy/st/phy-stm32-combophy.c

diff --git a/drivers/phy/st/Kconfig b/drivers/phy/st/Kconfig
index 3fc3d0781fb8..304614b6dabf 100644
--- a/drivers/phy/st/Kconfig
+++ b/drivers/phy/st/Kconfig
@@ -33,6 +33,17 @@ config PHY_STIH407_USB
 	  Enable this support to enable the picoPHY device used by USB2
 	  and USB3 controllers on STMicroelectronics STiH407 SoC families.
 
+config PHY_STM32_COMBOPHY
+	tristate "STMicroelectronics COMBOPHY driver for STM32MP25"
+	depends on ARCH_STM32 || COMPILE_TEST
+	select GENERIC_PHY
+	help
+	  Enable this to support the COMBOPHY device used by USB3 or PCIe
+	  controllers on STMicroelectronics STM32MP25 SoC.
+	  This driver controls the COMBOPHY block to generate the PCIe 100Mhz
+	  reference clock from either the external clock generator or HSE
+	  internal SoC clock source.
+
 config PHY_STM32_USBPHYC
 	tristate "STMicroelectronics STM32 USB HS PHY Controller driver"
 	depends on ARCH_STM32 || COMPILE_TEST
diff --git a/drivers/phy/st/Makefile b/drivers/phy/st/Makefile
index c862dd937b64..cb80e954ea9f 100644
--- a/drivers/phy/st/Makefile
+++ b/drivers/phy/st/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_PHY_MIPHY28LP) 		+= phy-miphy28lp.o
 obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)	+= phy-spear1310-miphy.o
 obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)	+= phy-spear1340-miphy.o
 obj-$(CONFIG_PHY_STIH407_USB)		+= phy-stih407-usb.o
+obj-$(CONFIG_PHY_STM32_COMBOPHY)	+= phy-stm32-combophy.o
 obj-$(CONFIG_PHY_STM32_USBPHYC) 	+= phy-stm32-usbphyc.o
diff --git a/drivers/phy/st/phy-stm32-combophy.c b/drivers/phy/st/phy-stm32-combophy.c
new file mode 100644
index 000000000000..e1e7083ccb5f
--- /dev/null
+++ b/drivers/phy/st/phy-stm32-combophy.c
@@ -0,0 +1,598 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * STMicroelectronics COMBOPHY STM32MP25 Controller driver.
+ *
+ * Copyright (C) 2024 STMicroelectronics
+ * Author: Christian Bruel <christian.bruel at foss.st.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <dt-bindings/phy/phy.h>
+
+#define SYSCFG_COMBOPHY_CR1 0x4c00
+#define SYSCFG_COMBOPHY_CR2 0x4c04
+#define SYSCFG_COMBOPHY_CR4 0x4c0c
+#define SYSCFG_COMBOPHY_CR5 0x4c10
+#define SYSCFG_COMBOPHY_SR  0x4c14
+#define SYSCFG_PCIEPRGCR    0x6080
+
+/* SYSCFG PCIEPRGCR */
+#define STM32MP25_PCIEPRGCR_EN	  BIT(0)
+#define STM32MP25_PCIEPRG_IMPCTRL_OHM     GENMASK(3, 1)
+#define STM32MP25_PCIEPRG_IMPCTRL_VSWING  GENMASK(5, 4)
+
+/* SYSCFG SYSCFG_COMBOPHY_SR */
+#define STM32MP25_PIPE0_PHYSTATUS BIT(1)
+
+/* SYSCFG CR1 */
+#define SYSCFG_COMBOPHY_CR1_REFUSEPAD BIT(0)
+#define SYSCFG_COMBOPHY_CR1_MPLLMULT GENMASK(7, 1)
+#define SYSCFG_COMBOPHY_CR1_REFCLKSEL GENMASK(16, 8)
+#define SYSCFG_COMBOPHY_CR1_REFCLKDIV2 BIT(17)
+#define SYSCFG_COMBOPHY_CR1_REFSSPEN BIT(18)
+#define SYSCFG_COMBOPHY_CR1_SSCEN BIT(19)
+
+/* SYSCFG CR4 */
+#define SYSCFG_COMBOPHY_CR4_RX0_EQ GENMASK(2, 0)
+
+#define MPLLMULT_19_2 (0x02u << 1)
+#define MPLLMULT_20   (0x7du << 1)
+#define MPLLMULT_24   (0x68u << 1)
+#define MPLLMULT_25   (0x64u << 1)
+#define MPLLMULT_26   (0x60u << 1)
+#define MPLLMULT_38_4 (0x41u << 1)
+#define MPLLMULT_48   (0x6cu << 1)
+#define MPLLMULT_50   (0x32u << 1)
+#define MPLLMULT_52   (0x30u << 1)
+#define MPLLMULT_100  (0x19u << 1)
+
+#define REFCLKSEL_0   0
+#define REFCLKSEL_1   (0x108u << 8)
+
+#define REFCLDIV_0    0
+
+/* SYSCFG CR2 */
+#define SYSCFG_COMBOPHY_CR2_MODESEL GENMASK(1, 0)
+#define SYSCFG_COMBOPHY_CR2_ISO_DIS BIT(15)
+
+#define COMBOPHY_MODESEL_PCIE 0
+#define COMBOPHY_MODESEL_USB  3
+
+/* SYSCFG CR5 */
+#define SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS BIT(12)
+
+#define COMBOPHY_SUP_ANA_MPLL_LOOP_CTL 0xc0
+#define COMBOPHY_PROP_CNTRL GENMASK(7, 4)
+
+/* Required apb/ker clocks first, optional pad last. */
+static const char * const combophy_clks[] = {"apb", "ker", "pad"};
+#define APB_CLK 0
+#define KER_CLK 1
+#define PAD_CLK 2
+
+struct stm32_combophy {
+	struct phy *phy;
+	struct regmap *regmap;
+	struct device *dev;
+	void __iomem *base;
+	struct reset_control *phy_reset;
+	struct clk_bulk_data clks[ARRAY_SIZE(combophy_clks)];
+	int num_clks;
+	bool have_pad_clk;
+	unsigned int type;
+	bool is_init;
+	int irq_wakeup;
+};
+
+struct clk_impedance  {
+	u32 microohm;
+	u32 vswing[4];
+};
+
+/*
+ * lookup table to hold the settings needed for a ref clock frequency
+ * impedance, the offset is used to set the IMP_CTL and DE_EMP bit of the
+ * PRG_IMP_CTRL register. Use ordered discrete values in the table
+ */
+static const struct clk_impedance imp_lookup[] = {
+	{ 6090000, { 442000, 564000, 684000, 802000 } },
+	{ 5662000, { 528000, 621000, 712000, 803000 } },
+	{ 5292000, { 491000, 596000, 700000, 802000 } },
+	{ 4968000, { 558000, 640000, 722000, 803000 } },
+	{ 4684000, { 468000, 581000, 692000, 802000 } },
+	{ 4429000, { 554000, 613000, 717000, 803000 } },
+	{ 4204000, { 511000, 609000, 706000, 802000 } },
+	{ 3999000, { 571000, 648000, 726000, 803000 } }
+};
+
+static int stm32_impedance_tune(struct stm32_combophy *combophy)
+{
+	u8 imp_size = ARRAY_SIZE(imp_lookup);
+	u8 vswing_size = ARRAY_SIZE(imp_lookup[0].vswing);
+	u8 imp_of, vswing_of;
+	u32 max_imp = imp_lookup[0].microohm;
+	u32 min_imp = imp_lookup[imp_size - 1].microohm;
+	u32 max_vswing = imp_lookup[imp_size - 1].vswing[vswing_size - 1];
+	u32 min_vswing = imp_lookup[0].vswing[0];
+	u32 val;
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,output-micro-ohms", &val)) {
+		if (val < min_imp || val > max_imp) {
+			dev_err(combophy->dev, "Invalid value %u for output ohm\n", val);
+			return -EINVAL;
+		}
+
+		for (imp_of = 0; imp_of < ARRAY_SIZE(imp_lookup); imp_of++)
+			if (imp_lookup[imp_of].microohm <= val)
+				break;
+
+		dev_dbg(combophy->dev, "Set %u micro-ohms output impedance\n",
+			imp_lookup[imp_of].microohm);
+
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRG_IMPCTRL_OHM,
+				   FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_OHM, imp_of));
+	} else {
+		regmap_read(combophy->regmap, SYSCFG_PCIEPRGCR, &val);
+		imp_of = FIELD_GET(STM32MP25_PCIEPRG_IMPCTRL_OHM, val);
+	}
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,output-vswing-microvolt", &val)) {
+		if (val < min_vswing || val > max_vswing) {
+			dev_err(combophy->dev, "Invalid value %u for output vswing\n", val);
+			return -EINVAL;
+		}
+
+		for (vswing_of = 0; vswing_of < ARRAY_SIZE(imp_lookup[imp_of].vswing); vswing_of++)
+			if (imp_lookup[imp_of].vswing[vswing_of] >= val)
+				break;
+
+		dev_dbg(combophy->dev, "Set %u microvolt swing\n",
+			 imp_lookup[imp_of].vswing[vswing_of]);
+
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRG_IMPCTRL_VSWING,
+				   FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of));
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_pll_init(struct stm32_combophy *combophy)
+{
+	int ret;
+	u32 refclksel, pllmult, propcntrl, val;
+	u32 clk_rate;
+	struct clk *clk;
+	u32 cr1_val = 0, cr1_mask = 0;
+
+	if (combophy->have_pad_clk)
+		clk = combophy->clks[PAD_CLK].clk;
+	else
+		clk = combophy->clks[KER_CLK].clk;
+
+	clk_rate = clk_get_rate(clk);
+
+	dev_dbg(combophy->dev, "%s pll init rate %d\n",
+		combophy->have_pad_clk ? "External" : "Ker", clk_rate);
+
+	if (combophy->type != PHY_TYPE_PCIE) {
+		cr1_mask |= SYSCFG_COMBOPHY_CR1_REFSSPEN;
+		cr1_val |= SYSCFG_COMBOPHY_CR1_REFSSPEN;
+	}
+
+	if (of_property_present(combophy->dev->of_node, "st,ssc-on")) {
+		dev_dbg(combophy->dev, "Enabling clock with SSC\n");
+		cr1_mask |= SYSCFG_COMBOPHY_CR1_SSCEN;
+		cr1_val |= SYSCFG_COMBOPHY_CR1_SSCEN;
+	}
+
+	switch (clk_rate) {
+	case 100000000:
+		pllmult = MPLLMULT_100;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0x8u << 4;
+		break;
+	case 19200000:
+		pllmult = MPLLMULT_19_2;
+		refclksel = REFCLKSEL_1;
+		propcntrl = 0x8u << 4;
+		break;
+	case 25000000:
+		pllmult = MPLLMULT_25;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0xeu << 4;
+		break;
+	case 24000000:
+		pllmult = MPLLMULT_24;
+		refclksel = REFCLKSEL_1;
+		propcntrl = 0xeu << 4;
+		break;
+	case 20000000:
+		pllmult = MPLLMULT_20;
+		refclksel = REFCLKSEL_0;
+		propcntrl = 0xeu << 4;
+		break;
+	default:
+		dev_err(combophy->dev, "Invalid rate 0x%x\n", clk_rate);
+		return -EINVAL;
+	};
+
+	cr1_mask |= SYSCFG_COMBOPHY_CR1_REFCLKDIV2;
+	cr1_val |= REFCLDIV_0;
+
+	cr1_mask |= SYSCFG_COMBOPHY_CR1_REFCLKSEL;
+	cr1_val |= refclksel;
+
+	cr1_mask |= SYSCFG_COMBOPHY_CR1_MPLLMULT;
+	cr1_val |= pllmult;
+
+	/*
+	 * vddcombophy is interconnected with vddcore. Isolation bit should be unset
+	 * before using the ComboPHY.
+	 */
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, SYSCFG_COMBOPHY_CR2_ISO_DIS);
+
+	reset_control_assert(combophy->phy_reset);
+
+	if (combophy->type == PHY_TYPE_PCIE) {
+		ret = stm32_impedance_tune(combophy);
+		if (ret)
+			goto out_iso;
+
+		cr1_mask |= SYSCFG_COMBOPHY_CR1_REFUSEPAD;
+		cr1_val |= combophy->have_pad_clk ? SYSCFG_COMBOPHY_CR1_REFUSEPAD : 0;
+	}
+
+	if (!of_property_read_u32(combophy->dev->of_node, "st,rx-equalizer", &val)) {
+		dev_dbg(combophy->dev, "Set RX equalizer %u\n", val);
+		if (val > SYSCFG_COMBOPHY_CR4_RX0_EQ) {
+			dev_err(combophy->dev, "Invalid value %u for rx0 equalizer\n", val);
+			ret = -EINVAL;
+			goto out_iso;
+		}
+
+		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR4,
+			   SYSCFG_COMBOPHY_CR4_RX0_EQ, val);
+	}
+
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1, cr1_mask, cr1_val);
+
+	/*
+	 * Force elasticity buffer to be tuned for the reference clock as
+	 * the separated clock model is not supported
+	 */
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR5,
+			   SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS, SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS);
+
+	reset_control_deassert(combophy->phy_reset);
+
+	ret = regmap_read_poll_timeout(combophy->regmap, SYSCFG_COMBOPHY_SR, val,
+				       !(val & STM32MP25_PIPE0_PHYSTATUS),
+				       10, 1000);
+	if (ret) {
+		dev_err(combophy->dev, "timeout, cannot lock PLL\n");
+		if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
+			regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+					   STM32MP25_PCIEPRGCR_EN, 0);
+
+		if (combophy->type != PHY_TYPE_PCIE)
+			regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+					   SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
+
+		goto out;
+	}
+
+
+	if (combophy->type == PHY_TYPE_PCIE) {
+		if (!combophy->have_pad_clk)
+			regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+					   STM32MP25_PCIEPRGCR_EN, STM32MP25_PCIEPRGCR_EN);
+
+		val = readl_relaxed(combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
+		val &= ~COMBOPHY_PROP_CNTRL;
+		val |= propcntrl;
+		writel_relaxed(val, combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
+	}
+
+	return 0;
+
+out_iso:
+	reset_control_deassert(combophy->phy_reset);
+
+out:
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
+
+	return ret;
+}
+
+static struct phy *stm32_combophy_xlate(struct device *dev,
+					const struct of_phandle_args *args)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+	unsigned int type;
+
+	if (args->args_count != 1) {
+		dev_err(dev, "invalid number of cells in 'phy' property\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	type = args->args[0];
+	if (type != PHY_TYPE_USB3 && type != PHY_TYPE_PCIE) {
+		dev_err(dev, "unsupported device type: %d\n", type);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (combophy->have_pad_clk && type != PHY_TYPE_PCIE) {
+		dev_err(dev, "Invalid use of clk_pad for USB3 mode\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	combophy->type = type;
+
+	return combophy->phy;
+}
+
+static int stm32_combophy_set_mode(struct stm32_combophy *combophy)
+{
+	int type = combophy->type;
+	u32 val;
+
+	switch (type) {
+	case PHY_TYPE_PCIE:
+		dev_dbg(combophy->dev, "setting PCIe ComboPHY\n");
+		val = COMBOPHY_MODESEL_PCIE;
+		break;
+	case PHY_TYPE_USB3:
+		dev_dbg(combophy->dev, "setting USB3 ComboPHY\n");
+		val = COMBOPHY_MODESEL_USB;
+		break;
+	default:
+		dev_err(combophy->dev, "Invalid PHY mode %d\n", type);
+		return -EINVAL;
+	}
+
+	return regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+				  SYSCFG_COMBOPHY_CR2_MODESEL, val);
+}
+
+static int stm32_combophy_suspend_noirq(struct device *dev)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+
+	/*
+	 * Clocks should be turned off since it is not needed for
+	 * wakeup capability. In case usb-remote wakeup is not enabled,
+	 * combo-phy is already turned off by HCD driver using exit callback
+	 */
+	if (combophy->is_init) {
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+
+		/* since wakeup is enabled for ctrl */
+		enable_irq_wake(combophy->irq_wakeup);
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_resume_noirq(struct device *dev)
+{
+	struct stm32_combophy *combophy = dev_get_drvdata(dev);
+	int ret;
+
+	/*
+	 * If clocks was turned off by suspend call for wakeup then needs
+	 * to be turned back ON in resume. In case usb-remote wakeup is not
+	 * enabled, clocks already turned ON by HCD driver using init callback
+	 */
+	if (combophy->is_init) {
+		/* since wakeup was enabled for ctrl */
+		disable_irq_wake(combophy->irq_wakeup);
+
+		ret = clk_bulk_prepare_enable(combophy->num_clks, combophy->clks);
+		if (ret) {
+			dev_err(dev, "can't enable clocks (%d)\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_exit(struct phy *phy)
+{
+	struct stm32_combophy *combophy = phy_get_drvdata(phy);
+	struct device *dev = combophy->dev;
+
+	combophy->is_init = false;
+
+	if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
+		regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
+				   STM32MP25_PCIEPRGCR_EN, 0);
+
+	if (combophy->type != PHY_TYPE_PCIE)
+		regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
+				   SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
+
+	regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
+			   SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
+
+	clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+
+	pm_runtime_put_noidle(dev);
+
+	return 0;
+}
+
+static int stm32_combophy_init(struct phy *phy)
+{
+	struct stm32_combophy *combophy = phy_get_drvdata(phy);
+	struct device *dev = combophy->dev;
+	int ret;
+
+	pm_runtime_get_noresume(dev);
+
+	ret = clk_bulk_prepare_enable(combophy->num_clks, combophy->clks);
+	if (ret) {
+		dev_err(dev, "can't enable clocks (%d)\n", ret);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	ret = stm32_combophy_set_mode(combophy);
+	if (ret) {
+		dev_err(dev, "combophy mode not set\n");
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	ret = stm32_combophy_pll_init(combophy);
+	if (ret) {
+		clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	pm_runtime_disable(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+
+	combophy->is_init = true;
+
+	return ret;
+}
+
+static const struct phy_ops stm32_combophy_phy_data = {
+	.init = stm32_combophy_init,
+	.exit = stm32_combophy_exit,
+	.owner = THIS_MODULE
+};
+
+static irqreturn_t stm32_combophy_irq_wakeup_handler(int irq, void *dev_id)
+{
+	return IRQ_HANDLED;
+}
+
+static int stm32_combophy_get_clocks(struct stm32_combophy *combophy)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(combophy_clks); i++)
+		combophy->clks[i].id = combophy_clks[i];
+
+	combophy->num_clks = ARRAY_SIZE(combophy_clks) - 1;
+
+	ret = devm_clk_bulk_get(combophy->dev, combophy->num_clks, combophy->clks);
+	if (ret)
+		return ret;
+
+	ret = devm_clk_bulk_get_optional(combophy->dev, 1, combophy->clks + combophy->num_clks);
+	if (ret)
+		return ret;
+
+	if (combophy->clks[combophy->num_clks].clk != NULL) {
+		combophy->have_pad_clk = true;
+		combophy->num_clks++;
+	}
+
+	return 0;
+}
+
+static int stm32_combophy_probe(struct platform_device *pdev)
+{
+	struct stm32_combophy *combophy;
+	struct device *dev = &pdev->dev;
+	struct phy_provider *phy_provider;
+	int ret, irq;
+
+	combophy = devm_kzalloc(dev, sizeof(*combophy), GFP_KERNEL);
+	if (!combophy)
+		return -ENOMEM;
+
+	combophy->dev = dev;
+
+	dev_set_drvdata(dev, combophy);
+
+	combophy->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(combophy->base))
+		return PTR_ERR(combophy->base);
+
+	ret = stm32_combophy_get_clocks(combophy);
+	if (ret)
+		return ret;
+
+	combophy->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
+	if (IS_ERR(combophy->phy_reset))
+		return dev_err_probe(dev, PTR_ERR(combophy->phy_reset),
+				     "Failed to get PHY reset\n");
+
+	combophy->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg");
+	if (IS_ERR(combophy->regmap))
+		return dev_err_probe(dev, PTR_ERR(combophy->regmap),
+				     "No syscfg specified\n");
+
+	combophy->phy = devm_phy_create(dev, NULL, &stm32_combophy_phy_data);
+	if (IS_ERR(combophy->phy))
+		return dev_err_probe(dev, PTR_ERR(combophy->phy),
+				     "failed to create PCIe/USB3 ComboPHY\n");
+
+	if (device_property_read_bool(dev, "wakeup-source")) {
+		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return dev_err_probe(dev, irq, "failed to get IRQ\n");
+		combophy->irq_wakeup = irq;
+
+		ret = devm_request_threaded_irq(dev, combophy->irq_wakeup, NULL,
+						stm32_combophy_irq_wakeup_handler, IRQF_ONESHOT,
+						NULL, NULL);
+		if (ret)
+			return dev_err_probe(dev, ret, "unable to request wake IRQ %d\n",
+						 combophy->irq_wakeup);
+	}
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to enable pm runtime\n");
+
+	phy_set_drvdata(combophy->phy, combophy);
+
+	phy_provider = devm_of_phy_provider_register(dev, stm32_combophy_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct dev_pm_ops stm32_combophy_pm_ops = {
+	NOIRQ_SYSTEM_SLEEP_PM_OPS(stm32_combophy_suspend_noirq,
+				  stm32_combophy_resume_noirq)
+};
+
+static const struct of_device_id stm32_combophy_of_match[] = {
+	{ .compatible = "st,stm32mp25-combophy", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, stm32_combophy_of_match);
+
+static struct platform_driver stm32_combophy_driver = {
+	.probe = stm32_combophy_probe,
+	.driver = {
+		   .name = "stm32-combophy",
+		   .of_match_table = stm32_combophy_of_match,
+		   .pm = pm_sleep_ptr(&stm32_combophy_pm_ops)
+	}
+};
+
+module_platform_driver(stm32_combophy_driver);
+
+MODULE_AUTHOR("Christian Bruel <christian.bruel at foss.st.com>");
+MODULE_DESCRIPTION("STM32MP25 Combophy USB3/PCIe controller driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From christian.bruel at foss.st.com  Mon Sep 30 10:08:43 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Mon, 30 Sep 2024 19:08:43 +0200
Subject: [PATCH v9 1/5] dt-bindings: phy: Add STM32MP25 COMBOPHY bindings
In-Reply-To: <20240930170847.948779-1-christian.bruel@foss.st.com>
References: <20240930170847.948779-1-christian.bruel@foss.st.com>
Message-ID: <20240930170847.948779-2-christian.bruel@foss.st.com>

Document the bindings for STM32 COMBOPHY interface, used to support
the PCIe and USB3 stm32mp25 drivers.
Following entries can be used to tune caracterisation parameters
 - st,output-micro-ohms and st,output-vswing-microvolt bindings entries
to tune the impedance and voltage swing using discrete simulation results
 - st,rx-equalizer register to set the internal rx equalizer filter value.

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 .../bindings/phy/st,stm32mp25-combophy.yaml   | 119 ++++++++++++++++++
 1 file changed, 119 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml

diff --git a/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml b/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
new file mode 100644
index 000000000000..a2e82c0bb56b
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/st,stm32mp25-combophy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32MP25 USB3/PCIe COMBOPHY
+
+maintainers:
+  - Christian Bruel <christian.bruel at foss.st.com>
+
+description:
+  Single lane PHY shared (exclusive) between the USB3 and PCIe controllers.
+  Supports 5Gbit/s for USB3 and PCIe gen2 or 2.5Gbit/s for PCIe gen1.
+
+properties:
+  compatible:
+    const: st,stm32mp25-combophy
+
+  reg:
+    maxItems: 1
+
+  "#phy-cells":
+    const: 1
+
+  clocks:
+    minItems: 2
+    items:
+      - description: apb Bus clock mandatory to access registers.
+      - description: ker Internal RCC reference clock for USB3 or PCIe
+      - description: pad Optional on board clock input for PCIe only. Typically an
+                     external 100Mhz oscillator wired on dedicated CLKIN pad. Used as reference
+                     clock input instead of the ker
+
+  clock-names:
+    minItems: 2
+    items:
+      - const: apb
+      - const: ker
+      - const: pad
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    const: phy
+
+  power-domains:
+    maxItems: 1
+
+  wakeup-source: true
+
+  interrupts:
+    maxItems: 1
+    description: interrupt used for wakeup
+
+  access-controllers:
+    maxItems: 1
+    description: Phandle to the rifsc device to check access right.
+
+  st,ssc-on:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      A property whose presence indicates that the Spread Spectrum Clocking is active.
+
+  st,rx-equalizer:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 7
+    default: 2
+    description:
+      A 3 bit value to tune the RX fixed equalizer setting for optimal eye compliance
+
+  st,output-micro-ohms:
+    minimum: 3999000
+    maximum: 6090000
+    default: 4968000
+    description:
+      A value property to tune the Single Ended Output Impedance, simulations results
+      at 25C for a VDDP=0.8V. The hardware accepts discrete values in this range.
+
+  st,output-vswing-microvolt:
+    minimum: 442000
+    maximum: 803000
+    default: 803000
+    description:
+      A value property in microvolt to tune the Single Ended Output Voltage Swing to change the
+      Vlo, Vhi for a VDDP = 0.8V. The hardware accepts discrete values in this range.
+
+required:
+  - compatible
+  - reg
+  - "#phy-cells"
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/reset/st,stm32mp25-rcc.h>
+
+    phy at 480c0000 {
+        compatible = "st,stm32mp25-combophy";
+        reg = <0x480c0000 0x1000>;
+        #phy-cells = <1>;
+        clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>;
+        clock-names = "apb", "ker";
+        resets = <&rcc USB3PCIEPHY_R>;
+        reset-names = "phy";
+        access-controllers = <&rifsc 67>;
+        power-domains = <&CLUSTER_PD>;
+        wakeup-source;
+        interrupts-extended = <&exti1 45 IRQ_TYPE_EDGE_FALLING>;
+    };
-- 
2.34.1



From christian.bruel at foss.st.com  Mon Sep 30 10:08:47 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Mon, 30 Sep 2024 19:08:47 +0200
Subject: [PATCH v9 5/5] arm64: dts: st: Enable COMBOPHY on the stm32mp257f-ev1 board
In-Reply-To: <20240930170847.948779-1-christian.bruel@foss.st.com>
References: <20240930170847.948779-1-christian.bruel@foss.st.com>
Message-ID: <20240930170847.948779-6-christian.bruel@foss.st.com>

Enable the COMBOPHY with external pad clock on stm32mp257f-ev1
board, to be used for the PCIe clock provider.

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
index 214191a8322b..bcf84d533cb2 100644
--- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
+++ b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
@@ -27,6 +27,14 @@ chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
+	clocks {
+		pad_clk: pad-clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+		};
+	};
+
 	memory at 80000000 {
 		device_type = "memory";
 		reg = <0x0 0x80000000 0x1 0x0>;
@@ -50,6 +58,12 @@ &arm_wdt {
 	status = "okay";
 };
 
+&combophy {
+	clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>, <&pad_clk>;
+	clock-names = "apb", "ker", "pad";
+	status = "okay";
+};
+
 &ethernet2 {
 	pinctrl-names = "default", "sleep";
 	pinctrl-0 = <&eth2_rgmii_pins_a>;
-- 
2.34.1



From kdipendra88 at gmail.com  Mon Sep 30 12:11:00 2024
From: kdipendra88 at gmail.com (Dipendra Khadka)
Date: Mon, 30 Sep 2024 19:11:00 +0000
Subject: [PATCH] phy: tegra: xusb: Add error pointer check in xusb.c
Message-ID: <20240930191101.13184-1-kdipendra88@gmail.com>

Add error pointer check after tegra_xusb_find_lane().

Fixes: e8f7d2f409a1 ("phy: tegra: xusb: Add usb-phy support")
Signed-off-by: Dipendra Khadka <kdipendra88 at gmail.com>
---
 drivers/phy/tegra/xusb.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index cfdb54b6070a..342f5ccf611d 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -699,6 +699,8 @@ static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port)
 		return -ENOMEM;
 
 	lane = tegra_xusb_find_lane(port->padctl, "usb2", port->index);
+	if (IS_ERR(lane))
+		return PTR_ERR(lane);
 
 	/*
 	 * Assign phy dev to usb-phy dev. Host/device drivers can use phy
-- 
2.43.0



From s-vadapalli at ti.com  Mon Sep 30 20:10:27 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Tue, 1 Oct 2024 08:40:27 +0530
Subject: [PATCH v2] phy: ti: phy-j721e-wiz: fix usxgmii configuration
In-Reply-To: <4b42b8e5-3246-4f58-b494-735930d2424a@kernel.org>
References: <20240930095745.3007057-1-s-vadapalli@ti.com>
 <4b42b8e5-3246-4f58-b494-735930d2424a@kernel.org>
Message-ID: <c5ef5303-6390-4f2b-b9d2-3d1f3085e15f@ti.com>

On Mon, Sep 30, 2024 at 05:06:35PM +0300, Roger Quadros wrote:

Hello Roger,

> Hi Siddharth,
> 
> On 30/09/2024 12:57, Siddharth Vadapalli wrote:
> > Commit b64a85fb8f53 ("phy: ti: phy-j721e-wiz.c: Add usxgmii support in
> > wiz driver") added support for USXGMII mode. In doing so, P0_REFCLK_SEL
> > was set to "pcs_mac_clk_divx1_ln_0" (0x3) and P0_STANDARD_MODE was set to
> > LANE_MODE_GEN1, which results in a data rate of 5.15625 Gbps. However,
> > since the USXGMII mode can support up to 10.3125 Gbps data rate, the
> > aforementioned fields should be set to "pcs_mac_clk_divx0_ln_0" (0x2) and
> > LANE_MODE_GEN2 respectively. Fix the configuration accordingly to truly
> > support USXGMII up to 10G.
> > 
> > Fixes: b64a85fb8f53 ("phy: ti: phy-j721e-wiz.c: Add usxgmii support in wiz driver")
> > Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>

[...]

> > diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
> > index a6c0c5607ffd..c6e846d385d2 100644
> > --- a/drivers/phy/ti/phy-j721e-wiz.c
> > +++ b/drivers/phy/ti/phy-j721e-wiz.c
> > @@ -450,8 +450,8 @@ static int wiz_mode_select(struct wiz *wiz)
> >  		} else if (wiz->lane_phy_type[i] == PHY_TYPE_USXGMII) {
> >  			ret = regmap_field_write(wiz->p0_mac_src_sel[i], 0x3);
> >  			ret = regmap_field_write(wiz->p0_rxfclk_sel[i], 0x3);
> 
> I'm not sure. Don't we have to change rxfclk as well?

This patch was validated on a custom board with the J7200 SR 2.0 SoC.
The signal corresponding to the USXGMII lane of the SERDES was measured
to be 5 Gbps without this patch and 10 Gbps with this patch applied,
with no other changes required. Apart from measuring the signal, ping
was also validated.

Regards,
Siddharth.


